# -*- coding: utf-8 -*- # !/usr/bin/env python """ web.device.views ~~~~~~~~~ """ import datetime import itertools import logging from collections import Counter import simplejson as json from bson.objectid import ObjectId from django.conf import settings from django.core.cache import cache from django.core.handlers.wsgi import WSGIRequest from mongoengine.errors import NotUniqueError, DoesNotExist from typing import List, TYPE_CHECKING, Dict, Union from voluptuous import MultipleInvalid from apilib.utils import alphanum_key, natural_sort from apilib.utils_json import JsonResponse from apps.dispatch.commands import TopicCommand from apps.web.agent.models import Agent from apps.web.common.models import AddressType from apps.web.common.models import District from apps.web.constant import Const, DeviceCmdCode, DeviceOnlineStatus, support_policy_weifule, \ support_policy_device from apps.web.core import ROLE from apps.web.core.exceptions import ServiceException from apps.web.core.helpers import ActionDeviceBuilder from apps.web.core.models import DriverCode, DriverAdapter, DriverEventer from apps.web.core.networking import MessageSender from apps.web.core.utils import JsonErrorResponse, JsonOkResponse from apps.web.dealer.models import Dealer from apps.web.device.define import DeviceChannelType from apps.web.device.models import Device, DeviceType, Group, MajorDeviceType, DeviceCommand, Cell, Town, \ ManagerInputDev, SwapGroup, FaultRecord from apps.web.device.timescale import OfflineCoinsManager from apps.web.device.validation import equipGroupSchema from apps.web.exceptions import CustomizedValidationError from apps.web.helpers import DeviceTypeVisitor, get_user_manager_agent from apps.web.management.models import Manager from apps.web.south_intf.swap_carcharger import SwapContract from apps.web.south_intf.yuhuan_fire import YuhuanNorther from apps.web.user.models import MyUser, Card from apps.web.utils import ( translate_sendmsg_error, permission_required, pluckPayload, error_tolerate, check_role, record_operation_behavior, concat_user_login_entry_url, concat_user_center_entry_url ) from apps.web.wrapper import request_limit_by_user from taskmanager.mediator import task_caller logger = logging.getLogger(__name__) if TYPE_CHECKING: from apps.web.device.models import GroupDict from apps.web.device.models import DeviceDict from apps.web.dealer.models import SubAccount @permission_required(ROLE.dealer, ROLE.subaccount) def updateEquipmentRemarks(request): # type: (WSGIRequest)->JsonResponse curr_user = request.user # type: Union[Dealer, SubAccount] if not curr_user.normal: return JsonErrorResponse(description = u'账号异常,不能进行该操作') ownerId = str(request.user.bossId) devNo = request.POST.get('eValue', None) remarks = request.POST.get('remarks', None) if devNo is None or remarks is None: return JsonResponse({"result": 0, "description": u"缺少参数", 'payload': {}}) dev = Device.get_dev(devNo) if dev is None: return JsonResponse({"result": 0, "description": u"找不到设备", 'payload': {}}) if dev['remarks'] == remarks: # 已经改了 return JsonResponse({"result": 1, "description": None, 'payload': {}}) try: dev['remarks'] = remarks Device.get_collection().update_one({'devNo': devNo}, {'$set': {'remarks': remarks}}) Device.invalid_device_cache(dev['devNo']) return JsonResponse({"result": 1, "description": None, 'payload': {}}) except Exception, e: logger.exception('update collection error=%s,devNo=%s,ownerId=%s' % (e, devNo, ownerId)) return JsonResponse({"result": 0, "description": u'修改失败', 'payload': {}}) @permission_required(ROLE.dealer, ROLE.subaccount) def batchUpdateEquipment(request): # type: (WSGIRequest)->JsonResponse curr_user = request.user # type: Union[Dealer, SubAccount] if not curr_user.normal: return JsonErrorResponse(description = u'账号异常,不能进行该操作') if 'value[]' in request.POST: instructions = request.POST.get('instructions') devNoList = request.POST.getlist('value[]') else: payload = json.loads(request.body) instructions = payload.get('instructions') devNoList = payload.get('value') if not devNoList: return JsonResponse({'result': 0, 'description': u'请选择设备', 'payload': {}}) filterDevNoList = [] for devNo in devNoList: device = Device.get_dev(devNo) if not device: continue group = Group.get_group(device['groupId']) if group['ownerId'] != str(request.user.bossId): return JsonResponse({'result': 0, 'description': u'不能修改合伙人设备', 'payload': {}}) filterDevNoList.append(devNo) if not filterDevNoList: return JsonResponse({'result': 0, 'description': u'设备不存在,请刷新后再试', 'payload': {}}) Device.get_collection().update({'devNo': {'$in': filterDevNoList}}, {'$set': {'instructions': instructions}}, multi = True, upsert = False) Device.invalid_many_device_cache(devNoList) return JsonResponse({'result': 1, 'description': None, 'payload': {}}) @permission_required(ROLE.dealer, ROLE.subaccount) def batchUpdateEquipmentPriceDescription(request): # type: (WSGIRequest)->JsonResponse curr_user = request.user # type: Union[Dealer, SubAccount] if not curr_user.normal: return JsonErrorResponse(description = u'账号异常,不能进行该操作') if 'logicalCode[]' in request.POST: priceDescription = request.POST.get('priceDescription') logicalCodeList = request.POST.getlist('logicalCode[]') else: payload = json.loads(request.body) priceDescription = payload.get('priceDescription') logicalCodeList = payload.get('logicalCode') if not logicalCodeList: return JsonResponse({'result': 0, 'description': u'请选择设备', 'payload': {}}) filterDevNoList = [] devNos = [] for logicalCode in logicalCodeList: device = Device.get_dev_by_l(logicalCode) if not device: continue else: devNos.append(device.devNo) group = Group.get_group(device['groupId']) if group['ownerId'] != str(request.user.bossId): return JsonResponse({'result': 0, 'description': u'不能修改合伙人设备', 'payload': {}}) filterDevNoList.append(logicalCode) if not filterDevNoList: return JsonResponse({'result': 0, 'description': u'设备不存在,请刷新后再试', 'payload': {}}) Device.get_collection().update({'devNo': {'$in': devNos}}, {'$set': {'priceDescription': priceDescription}}, multi = True, upsert = False) Device.invalid_many_device_cache(devNos) return JsonResponse({'result': 1, 'description': None, 'payload': {}}) @permission_required(ROLE.dealer, ROLE.agent, ROLE.subaccount) def getEquipmentNumAndAddressList(request): # type: (WSGIRequest)->JsonResponse ownerId = request.POST.get('dealerId') or str(request.user.bossId) groupIds = Group.get_group_ids_of_dealer(ownerId) partnerGroupIds = Group.get_group_ids_of_partner(ownerId) groupIds.extend(partnerGroupIds) groupList = Group.get_groups_by_group_ids(groupIds).values() for group in groupList: group['name'] = group['groupName'] if group['groupId'] not in partnerGroupIds: group['isManager'] = True else: group['isManager'] = False return JsonResponse({ "result": 1, "description": None, 'payload': { "groups": sorted(groupList, key = lambda d: alphanum_key(d["name"])) } }) @permission_required(ROLE.dealer, ROLE.subaccount) def placeInfo(request): # type: (WSGIRequest)->JsonResponse ownerId = str(request.user.bossId) groupIds = Group.get_group_ids_of_dealer(ownerId) groupPartnerList = Group.get_group_ids_of_partner(ownerId) groupIds.extend(groupPartnerList) groupList = Group.get_groups_by_group_ids(groupIds).values() dataList = [] for group in groupList: item = { 'address': group['address'], 'name': group['groupName'], 'groupId': group['groupId'], 'ownerId': group['ownerId'] } if group['groupId'] in groupPartnerList: item.update({ 'isManager': False }) return JsonResponse({"result": 1, "description": None, 'payload': dataList}) @permission_required(ROLE.dealer, ROLE.subaccount) def devices(request): # type: (WSGIRequest)->JsonResponse groupId = request.GET.get('groupId', None) if groupId is None: return JsonResponse({"result": 0, "description": u'没有传入正确的参数', 'payload': {}}) devNoList = Device.get_devNos_by_group([groupId]) devDict = Device.get_dev_by_nos(devNoList) dataList = [] for devNo, dev in devDict.items(): dataList.append({ 'logicalCode': dev['logicalCode'], 'devNo': dev['devNo'], 'ownerId': dev['ownerId'], 'groupNum': dev['groupNumber'], 'equipmentId': dev['devNo'], 'equipmentType': dev['devType']['name'], 'equipmentValue': dev['groupNumber']}) return JsonResponse({"result": 1, "description": None, 'payload': dataList}) @permission_required(ROLE.dealer, ROLE.subaccount) def getEquipmentsByGroupId(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) if request.body else {} groupId = payload.get('groupId', None) if not groupId: return JsonErrorResponse(description = u'参数错误,请刷新') groupId = groupId.split("###")[0] devNoList = Device.get_devNos_by_group([groupId]) devDict = Device.get_dev_by_nos(devNoList) # type: Dict[str, DeviceDict] dataList = [ { 'ownerId': device['ownerId'], 'groupNumber': device['groupNumber'], 'remarks': device['remarks'], 'devType': device.devTypeName, 'logicalCode': device.logicalCode, 'devNo': device.devNo, 'groupId': device.groupId, 'online': device.online, 'status': device.status, 'statusInfo': device.statusInfo } for devNo, device in devDict.items() ] return JsonOkResponse(payload = dataList) @permission_required(ROLE.dealer, ROLE.subaccount) def readNewEquipment(request): # type: (WSGIRequest)->JsonResponse logicalCode = request.GET.get('logicalCode', None) devNo = Device.get_devNo_by_logicalCode(logicalCode) if devNo is None: return JsonResponse({'result': 0, 'description': u"设备号对应错误", 'payload': {}}) # 因为需要获取电平信息,必须从数据库中获取 dev = Device.get_dev(devNo) if dev is None: return JsonResponse({'result': 0, 'description': u"找不到设备", 'payload': {}}) return JsonResponse({ "result": 1, "description": None, 'payload': { 'battery': dev.get('battery', 1), 'pulseInterval1': dev.get('pulseInterval1', 200), 'pulseWidth1': dev.get('pulseWidth1', 50) } }) @permission_required(ROLE.dealer, ROLE.subaccount) def setEquipmentGroupNumber(request): # type: (WSGIRequest)->JsonResponse logicalCode = request.POST.get('logicalCode', None) # todo groupNumber必须得填 groupNumber = request.POST.get('groupNumber', None) if logicalCode is None or groupNumber is None: return JsonResponse({'result': 0, 'description': u'输入的参数非法', 'payload': {}}) dev = Device.get_dev_by_l(logicalCode) dev['groupNumber'] = groupNumber try: Device.get_collection().update_one({'logicalCode': logicalCode}, {'$set': {'groupNumber': groupNumber}}) Device.invalid_device_cache(dev['devNo']) except Exception, e: logger.exception('update device groupNumber error=%s,logicalCode=%s,groupNumber=%s' % (e, logicalCode, groupNumber)) return JsonResponse({"result": 0, "description": u'保存编号出错,请稍候再试', 'payload': {}}) YuhuanNorther.send_dev_info(dev) return JsonResponse({"result": 1, "description": None, 'payload': {}}) @permission_required(ROLE.dealer, ROLE.subaccount) def szNewEquipment(request): # type: (WSGIRequest)->JsonResponse logicalCode = request.POST.get('logicalCode', None) pulseInterval1 = request.POST.get('pulseInterval1', None) pulseWidth1 = request.POST.get('pulseWidth1', None) battery = request.POST.get('battery', None) devNo = Device.get_devNo_by_logicalCode(logicalCode) if devNo is None or pulseWidth1 is None or pulseInterval1 is None or battery is None: return JsonResponse({'result': 0, 'description': u'输入的参数非法', 'payload': {}}) dev = Device.get_dev(devNo) # type: DeviceDict if not dev: return JsonResponse({'result': 0, 'description': u'找不到该设备', 'payload': {}}) if not dev.online: return JsonResponse({'result': 0, 'description': u'当前设备不在线,无法进行设置', 'payload': {}}) result = {'rst': 0} if dev.channelType != DeviceChannelType.Channel_BT: result = MessageSender.send(dev, DeviceCmdCode.SET_DEVINFO, { 'IMEI': devNo, 'pulse_set': { 'pwm_inter': int(pulseInterval1), 'pwm_wid': int(pulseWidth1), 'pwm_idle': int(battery) } }) if result['rst'] == 0: try: Device.get_collection().update_one( {'devNo': devNo}, {'$set': { 'pulseInterval1': pulseInterval1, 'pulseWidth1': pulseWidth1, 'battery': battery } } ) Device.invalid_device_cache(devNo) except Exception as e: logger.exception(e) return JsonResponse({'result': 0, 'description': u'数据库操作异常,请稍候重试', 'payload': {}}) else: return JsonResponse({'result': 0, 'description': translate_sendmsg_error(result['rst']), 'payload': {}}) return JsonResponse({'result': 1, 'description': None, 'payload': {}}) @permission_required(ROLE.dealer, ROLE.subaccount) def equipmentInfoDetail(request): # type: (WSGIRequest)->JsonResponse logicalCode = request.GET.get('logicalCode', None) ownerId = str(request.user.bossId) agentId = str(request.user.agentId) dealer = Dealer.objects(id = ownerId).first() if dealer is None: return JsonErrorResponse(description = u'不存在的经销商') if logicalCode is None: return JsonErrorResponse(description = u"缺少参数devNo") dev = Device.get_dev_by_logicalCode(logicalCode) # type: DeviceDict if dev is None: return JsonErrorResponse(description = u"找不到设备") device = dev.my_obj # type: Device if device is None: return JsonErrorResponse(description = u"设备不存在") tempElecPrice = device.otherConf.get('tempElecPrice', '') item = { 'devNo': dev.devNo, 'logicalCode': dev.logicalCode, 'groupNumber': dev['groupNumber'], 'online': dev.online, 'url': concat_user_login_entry_url(l=logicalCode), 'agentId': agentId, 'iccid': dev.iccid, 'sim': dev.imsi, 'simStatus': dev.simStatus, 'isFault': dev['isFault'], 'isDND': dev.get('isDND', False), 'isRent': dev.get("isRent", False), 'isDNDTimeInterval': dev.get('isDNDTimeInterval', []), 'autoRefund': dev.is_auto_refund, 'status': dev.status, 'statusInfo': dev.statusInfo, 'dateTimeAdded': dev['dateTimeAdded'], 'remarks': dev['remarks'], 'instructions': dev['instructions'], 'priceDescription': dev.get('priceDescription', ''), 'channelType': dev.channelType, 'lng': dev.lng, 'lat': dev.lat, 'isManager': True if dev.ownerId == ownerId else False, 'devType': dev.devType, 'remoteOperationOrder': dev.devTypeFeatures.get('remoteOperationOrder', False), 'tempElecPrice': tempElecPrice, 'quantity': getattr(device, 'quantity', 0), 'consumptionQuantity': getattr(device, 'consumptionQuantity', 0), 'itemType': getattr(device, 'itemType', 0), 'simChargeAuto': getattr(device, 'simChargeAuto', False), 'deviceWarning': dev.is_warning } item.update({'simExpireDate': dev.formatSimExpireDate}) if dev.devTypeCode in [Const.DEVICE_TYPE_CODE_WEIFULE_POLICY_CLASSIC]: item.update({'hasTempPackage': False}) elif dev.devTypeCode in support_policy_device + support_policy_weifule: item.update({'hasTempPackage': True}) else: item.update({'hasTempPackage': dealer.hasTempPackage}) item.update({'liveUrl': device.otherConf.get('liveUrl', '#')}) item.update({'liveLimitedPrice': device.otherConf.get('liveLimitedPrice', '0.0')}) if device.devType.get('code') in support_policy_weifule: pass elif device.devType.get('code') in support_policy_device: pass else: # TODO 根据主类型判断是否需要显示临时电价(只有jndz在用) if (u"电" in dev["majorDeviceType"]) and (u'电吹风' not in dev["majorDeviceType"]): item.update({"hasTempElecPrice": dealer.hasTempPackage}) # 特殊处理网关一体化设备 if dev.devTypeCode == Const.DEVICE_TYPE_CODE_CHARGING_BL_GATEWAYPLUG: rcd = Device.get_collection().find({'logicalCode':logicalCode})[0] item['gatewayImei'] = rcd['gateImei'] if not dev.groupId: item['address'] = '' else: group = Group.get_group(dev.groupId) item['groupId'] = dev.groupId item['address'] = group['address'] item['name'] = group['groupName'] item['groupName'] = group['groupName'] item['defaultInstructions'] = dev.devType.get('instructions', '') item['autoRefundEnable'] = dev.devType.get('autoRefundEnable', DeviceType.autoRefundEnable.default) item['devTypeName'] = dev.devTypeName try: devTypeDriver = DriverCode.objects.get(code=dev.devTypeCode) dev.update(devTypeDriver.features) except Exception as e: logger.exception('get driver error,dev=%s, e=%s' % (dev, e)) if dev.devTypeCode == Const.DEVICE_TYPE_CODE_TIMESWITCH7: item['pricePerHour'] = dev['otherConf'].get('pricePerHour', 2.0) if dev.bill_as_service_feature.support: item['billAsService'] = dict(dev.bill_as_service_feature) return JsonOkResponse(payload=item) @permission_required(ROLE.dealer, ROLE.agent, ROLE.subaccount) def groupUsedNumber(request): # type: (WSGIRequest)->JsonResponse groupId = request.GET.get('groupId', None) if groupId is None: return JsonErrorResponse(description = u"缺少参数groupId") devNoList = Device.get_devNos_by_group([groupId]) devs = Device.get_dev_by_nos(devNoList).values() para = [{'groupNumber': dev['groupNumber']} for dev in devs] return JsonOkResponse(payload = sorted(para, key = lambda d: alphanum_key(str(d['groupNumber'])))) @permission_required(ROLE.dealer, ROLE.subaccount) def groupEquipmentTransfer(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) toGroupId = payload.get('toGroupId', None) devNo = payload.get('equipmentId', None) groupNumber = payload.get('groupNumber', None) if toGroupId is None or devNo is None or groupNumber is None: return JsonResponse({"result": 0, "description": u"缺少参数", 'payload': {}}) dev = Device.get_dev(devNo) if dev is None: return JsonResponse({"result": 0, "description": u"找不到设备", 'payload': {}}) group = Group.get_group(toGroupId) if group is None: return JsonResponse({"result": 0, "description": u"无法找到您想要修改到的组", 'payload': devNo}) if dev['groupId'] == toGroupId and dev['groupNumber'] == groupNumber: return JsonResponse({"result": 1, "description": u"数据一模一样,不需要更新", 'payload': devNo}) # 更新数据库中的数据 try: Device.get_collection() \ .update_one({'devNo': devNo}, {'$set': {'groupId': toGroupId, 'groupNumber': groupNumber}}) except Exception, e: logger.exception('update device error=%s,devNo=%s,togroupId=%s,newgroupNumber=%s' % (e, devNo, toGroupId, groupNumber)) finally: Device.invalid_device_cache(devNo) Device.invalid_group_device_list_cache([dev['groupId'], toGroupId]) return JsonResponse({"result": 1, "description": None, 'payload': devNo}) @permission_required(ROLE.dealer, ROLE.subaccount) def delGroup(request): # type: (WSGIRequest)->JsonResponse ownerId = str(request.user.bossId) groupId = request.POST.get('groupId', None) if groupId is None: return JsonErrorResponse(description = u"缺少参数") group = Group.get_group(groupId) if group.ownerId != ownerId: return JsonErrorResponse(description = u"参数错误") devNos = Device.get_devNos_by_group([groupId]) if len(devNos) > 0: return JsonErrorResponse(description = u"该地址下还有设备,请您转移设备到其他地址后,再删除该地址") userCount = MyUser.get_collection().find({'groupId': groupId}).count() if userCount > 0: return JsonErrorResponse(description = u"该地址下还有用户的充值,无法删除地址,建议编辑地址") card = Card.objects(groupId = groupId).first() if card: return JsonErrorResponse(description = u"该地址下还有用户绑定的实体卡,无法删除地址,建议编辑地址") # 对接丰图平台 if request.user.myBoss.supports('supportFengTu'): from apps.web.api.ft_north.utils import deleteStationReport deleteStationReport(groupId) # 北京丰台平台删除组 if request.user.myBoss.supports('supportBeiJingFengTai'): from apps.web.south_intf.bj_north.api import delete_station_info delete_station_info(groupId) if group.get('swapFlag',False): SwapGroup.delete_group(groupId) result = Group.delete_Group(ownerId, groupId) if not result: return JsonErrorResponse(description = u'删除地址失败') return JsonOkResponse() @permission_required(ROLE.dealer, ROLE.agent, ROLE.subaccount) def saveEquipmentGroup(request): """ 地址的修改 :param request: :return: """ payload = json.loads(request.body) try: data = equipGroupSchema(payload) except MultipleInvalid as me: return JsonErrorResponse(description=u"参数校验异常【】".format(me.path[0])) logger.info("[saveEquipmentGroupDefault], request user = {}; payload = {}".format(request.user.id, data)) # TODO zjl 这个场景需要详细测试 if "customerId" not in payload: ownerId = str(request.user.bossId) else: ownerId = str(payload.get("customerId")) groupId = data.get('groupId', None) dealer = Dealer.objects.get(id=ownerId) # 最后去更新组地址的信息 if groupId is None: success, description, group_id = Group.add_group( ownerId=ownerId, name=data["name"], districtId=data["districtId"], address=data["address"], addressType=data["addressType"], isDefault=data["isDefault"], discountRuleDict=dealer.format_default_discount, discountCardRuleDict=dealer.format_card_discount, country=data["country"], tag=data["tag"], beforeCharge=data["beforeCharge"] ) else: success, description, group_id = Group.update_group( group_id=groupId, ownerId=ownerId, groupName=data["name"], districtId=data["districtId"], address=data["address"], addressType=data["addressType"], isDefault=data["isDefault"], beforeCharge=data["beforeCharge"], popPriceDescriptionButton=data.get("popPriceDescriptionButton", False), country=data["country"], tag=data["tag"], ) return JsonOkResponse() if success else JsonErrorResponse( description=description, payload={'groupId': group_id} ) # 经销商扫描设备 @permission_required(ROLE.dealer, ROLE.agent, ROLE.subaccount) def checkEquipment(request): # type: (WSGIRequest)->JsonResponse scannedURL = request.GET.get('uniqueCode', None) if not scannedURL: return JsonResponse({'result': 100, 'description': u'错误的二维码或二维码已损坏'}) logger.debug('scan url is {}'.format(scannedURL)) try: from urlparse import urlparse, parse_qs if urlparse(scannedURL).hostname != settings.MY_DOMAIN: return JsonResponse({'result': 100, 'description': u'二维码错误'}) parsedQueryParams = parse_qs(urlparse(scannedURL).query) if ('l' not in parsedQueryParams) and ('devNo' not in parsedQueryParams): return JsonResponse({'result': 100, 'description': u'错误的二维码或二维码已损坏'}) devNo = logicalCode = None if 'l' in parsedQueryParams: logicalCode = parsedQueryParams['l'][0].strip() devNo = Device.get_devNo_by_logicalCode(logicalCode) elif 'devNo' in parsedQueryParams: # 通过devNo扫描进入系统的为遗留设备,这里做兼容处理,devNo == logicalCode devNo = logicalCode = parsedQueryParams['devNo'][0].strip() if devNo is None: return JsonResponse({'result': 101, 'description': u'该机器尚未与软件绑定,请联系客服完成绑定之后再操作'}) dev = Device.get_dev(devNo) if dev and dev.get('groupId', None): return JsonResponse( {'result': 102, 'description': u'设备已经注册', 'payload': {'logicalCode': logicalCode, 'devNo': devNo}}) #: 防止跨代理商绑定,防止串货 #: 暂时停止限制 # if dev and dev.get('ownerId',None): # oldDealer = Dealer.objects(id=str(dev['ownerId'])).first() # if oldDealer and request.user.agentId != oldDealer.agentId: # return JsonResponse({'result': 101, 'description': u'该设备移动支付模块不允许更换到其他代理商名下'}) return JsonResponse({'result': 1, 'description': u'开始注册', 'payload': {'devNo': devNo, 'logicalCode': logicalCode, 'typeId': '', 'eType': ''}}) except Exception as e: logger.exception(e) return JsonResponse({'result': 0, 'description': u'获取设备出错'}) # 设备未注册,获取默认地址 @permission_required(ROLE.dealer, ROLE.agent, ROLE.subaccount) def defaultEquipmentGroup(request): # type: (WSGIRequest)->JsonResponse # 如果获取的到customerId,即为代理商为经销商注册设备场景 ownerId = request.GET.get('customerId', None) if ownerId is None: ownerId = str(request.user.bossId) group = Group.get_default_group(ownerId) if not group: return JsonResponse({"result": 0, "description": u"您还没有设置默认地址喔", 'payload': {}}) district = District.get_district(group['districtId']) group['district'] = district data = {'gid': str(group['groupId']), 'name': group['groupName'], 'districtId': group['districtId'], 'district': group['district'], 'address': group['address'], 'addressType': group['addressType'], 'isDefault': group['isDefault']} return JsonResponse({"result": 1, "description": None, 'payload': data}) @permission_required(ROLE.agent, ROLE.dealer, ROLE.subaccount) @request_limit_by_user(operation='registerEquipment', limit=100, period=8 * 60 * 60, logger=logger) def registerEquipment(request): return registerEquipmentDefault(request) def registerEquipmentDefault(request): # type: (WSGIRequest)->JsonResponse """ 注册设备 :param request: :return: """ payload = json.loads(request.body) logger.debug('registerEquipmentDefault: {}'.format(payload)) if check_role(request.user, ROLE.agent): ownerId = payload.get('customerId') else: ownerId = str(request.user.bossId) logicalCode = payload.get('logicalCode', None) devNo = payload.get('devNo') or None logger.debug('devNo is: {}'.format(devNo)) if devNo is None and logicalCode is not None: devNo = Device.get_devNo_by_logicalCode(logicalCode) logger.debug('devNo from cache is: {}'.format(devNo)) if not devNo: return JsonErrorResponse(description = u'设备绑定关系不存在') dealer = Dealer.get_dealer(ownerId) if dealer is None: return JsonErrorResponse(description = u'经销商不存在') agent = Agent.get_agent(dealer.get("agentId")) if agent is None: return JsonErrorResponse(description = u'代理商不存在') # 温州郎鑫经销商注册需要 设备必须先被郎鑫录入 manager = Manager.objects.filter(id = agent.get("managerId")).first() if manager is None: return JsonErrorResponse(description = u'厂商不存在') if "inputDevice" in manager.features: if not ManagerInputDev.objects.filter(devNo = devNo, managerId = str(manager.id)): return JsonErrorResponse(description = u'设备不存在,请联系厂家') else: # 只要是录入的设备, 没有inputDevice特性的厂家所属经销商, 都不允许注册 if ManagerInputDev.objects.filter(devNo=devNo).first() is not None: return JsonErrorResponse(description=u'设备不允许注册,请联系厂家') groupId = payload.get('groupId', None) groupNumber = payload.get('groupNumber', '') remarks = payload.get('remarks', '') washConfigs = payload.get('washConfigs', None) devTypeId = payload.get('typeId', '') qrCodeUrl = payload.get('qrCodeUrl', '') policyTemp = payload.get('policyTemp', {}) if not all([devNo, groupId, washConfigs, devTypeId]): return JsonErrorResponse(description = u"缺少参数") if qrCodeUrl and settings.MY_DOMAIN not in qrCodeUrl: return JsonErrorResponse(description = u"不能识别的二维码") # 获取设备类型和逻辑编码 devType = DeviceType.objects(id = str(devTypeId)).first() # type: DeviceType if not devType: return JsonErrorResponse(description = u"设备类型不识别") devType.update(inc__popularity = 1) dev = Device.get_dev(devNo) # type: DeviceDict if not dev: return JsonErrorResponse(description = u"设备尚未与软件绑定,请联系软件开发公司") if dev.is_registered: return JsonErrorResponse(description = u'设备已经注册') driverCode = DriverCode.objects(code = devType.code).first() if not driverCode: return JsonErrorResponse(description = u"设备驱动错误, 请联系软件开发公司") if devType.autoRefundEnable != driverCode.features.get('autoRefundEnable', True): devType.update(autoRefundEnable=driverCode.features.get('autoRefundEnable', True)) group = Group.get_group(groupId) # type: GroupDict if not group: return JsonErrorResponse(description = u"选择的地址不存在,请刷新后再试") if group['ownerId'] != ownerId: return JsonErrorResponse(description = u"必须选择经销商自己创建的地址") dealer = Dealer.objects(id = ownerId).first() devCount = len(dealer.get_own_devices()) if devCount >= dealer.limitDevNum: return JsonErrorResponse(description = u'您已达到最大设备注册数量') districtId = group.get('districtId', '') result, description = Device.register_device( dealer, devNo, dev['logicalCode'], groupId, districtId, groupNumber, remarks, washConfigs, devType, agentId = request.user.id if check_role(request.user, ROLE.agent) else None, policyTemp=policyTemp) if not result: return JsonErrorResponse(description = description) # 更新otherConf开关字段,以及自动充值字段 displaySwitchs = payload.get('displaySwitchs', {}) simChargeAuto = payload.get('simChargeAuto', False) devObj = Device.objects.get(devNo = devNo) devObj.otherConf.update({"displaySwitchs": displaySwitchs}) devObj.simChargeAuto = simChargeAuto devObj.save() dealer.devCount = devCount + 1 dealer.save() # 如果经销商支持丰图平台,在注册设备时添加到丰图平台 if dealer.supports("supportFengTu"): from apps.web.api.ft_north.utils import addDeviceReport addDeviceReport(devNo) # 如果经销商支持北京丰台平台,在注册设备时添加到丰图平台 if dealer.supports('supportBeiJingFengTai'): from apps.web.south_intf.bj_north.api import push_device_info push_device_info(devNo) # 如果地址属于互联互通,就更新下相关时间 if group.get('swapFlag',False): devNum = 0 if u'直流' in devType.majorDeviceType or u'交流' in devType.majorDeviceType: devNum = 1 SwapGroup.update_swap_time_and_num(groupId,devNum) SwapContract.update_swap_time_and_num(groupId, ownerId, agent.id, agent.managerId, devNum) return JsonOkResponse() @permission_required(ROLE.agent, ROLE.dealer, ROLE.manager, ROLE.subaccount) def sendSignal(request): # type: (WSGIRequest)->JsonResponse logicalCode = request.GET.get('logicalCode', None) devNo = Device.get_devNo_by_logicalCode(logicalCode) if devNo is None: return JsonErrorResponse(description = u"无法获取IMEI") dev = Device.get_dev(devNo) if not dev: return JsonErrorResponse(description = u'找不到该设备') try: box = ActionDeviceBuilder.create_action_device(dev) except Exception, e: return JsonErrorResponse(description = u'设备异常,无法通讯,请检查网络情况') result = box.get_signal() if result['rst'] == -1: return JsonErrorResponse(description = u'设备离线,无法获取网络信号情况') elif result['rst'] != 0: return JsonErrorResponse(description = translate_sendmsg_error(result['rst'])) signal = result.get('signal', 0) return JsonOkResponse(description = signal, payload = signal) @permission_required(ROLE.dealer, ROLE.subaccount) def getLastDistrict(request): # type: (WSGIRequest)->JsonResponse ownerId = str(request.user.bossId) lastDistrict = cache.get('%s_lastDistrict' % ownerId, None) if lastDistrict: return JsonOkResponse(payload = json.loads(lastDistrict)) else: group = Group.get_default_group(ownerId) if group: return JsonOkResponse(payload = { 'districtId': group['districtId'], 'district': District.get_district(group['districtId']) }) else: return JsonOkResponse() @permission_required(ROLE.supermanager, ROLE.manager) def editDevType(request): # type: (WSGIRequest)->JsonResponse def check_package_unit(package): dic = map(lambda x: {'unit': x.get('unit'), }, package) res = reduce(lambda x, y: x if x == y else None, dic) return res try: payload = json.loads(request.body) # TODO 校验传入的package package = payload.get('package') if not package: return JsonErrorResponse(description = u"缺少套餐信息") if not check_package_unit(package): return JsonErrorResponse(description = u"修改失败,套餐计量单位填写错误") result = DeviceType.objects(id = payload['id']).update_one(**payload) if not result: return JsonErrorResponse(description = u"编辑错误") else: return JsonOkResponse() except CustomizedValidationError, e: return JsonErrorResponse(description = e.message) except Exception as e: logger.exception('edit devType error=%s' % e) return JsonErrorResponse(description = u"系统错误") @error_tolerate(logger = logger, nil = JsonErrorResponse(u'删除设备类型列表失败,请重试')) @permission_required(ROLE.supermanager, ROLE.manager) def deleteDevType(request): # type: (WSGIRequest)->JsonResponse ids = json.loads(request.body)['ids'] for _ in ids: devType = DeviceType.objects(id = str(_)).first() if not devType: return JsonErrorResponse(description = u"没有找到设备类型") if devType.popularity != 0: return JsonErrorResponse(description = u"无法删除已经注册的设备类型") map(lambda _: _.delete(), DeviceType.get_by_ids(ids)) return JsonOkResponse() @permission_required(ROLE.supermanager, ROLE.manager) def addDevType(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) editId = payload['id'] if payload['role'] == 'manager': manager = Manager.objects(id = editId).first() if not manager: return JsonErrorResponse(description = u"该厂商不存在") payload['agentId'] = str(manager.primeAgentId) elif payload['role'] == 'agent': agent = Agent.objects(id = editId).first() if not agent: return JsonErrorResponse(description = u"该代理商不存在") payload['agentId'] = str(agent.id) try: payload.pop('id') DeviceType(**payload).save() except NotUniqueError: return JsonErrorResponse(description = u"该条数据已经存在,请检查") return JsonOkResponse() @error_tolerate(logger = logger, nil = JsonErrorResponse(u'获取设备类型列表失败,请重试')) @permission_required(ROLE.dealer, ROLE.agent, ROLE.manager, ROLE.advertisement, ROLE.advertiser, ROLE.supermanager, ROLE.subaccount) def getDevTypeList(request): # type: (WSGIRequest)->JsonResponse """ 分两种情况获取 1、超级管理员获取厂商或者代理商的设备类型列表, 或者厂商获取代理商的设备类型列表 2、各角色获取自己的设备类型列表 :param request: :return: """ def visit(user): try: devTypes = DeviceTypeVisitor().visit(user) return JsonOkResponse(payload = {"total": len(devTypes), "dataList": [_.to_dict() for _ in devTypes]}) except DoesNotExist: return JsonErrorResponse(description = u'用户不存在或配置错误') currentUser = request.user role = request.GET.get('role') if role: if role == 'agent': agentId = request.GET.get('id') if not agentId: return JsonErrorResponse(description = u'未选择代理商') model = request.GET.get('model') if model != 'parent': return visit(Agent.objects(id = str(agentId)).get()) else: agent = Agent.objects(id = str(agentId)).get() return visit(agent.primary_agent) elif role == 'manager': managerId = request.GET.get('id') if managerId is None: return JsonErrorResponse(description = u'未选择厂商') else: manager = Manager.objects(id = managerId).get() return visit(manager) else: return visit(currentUser) @permission_required(ROLE.manager) def getDevMapChart(request): # type: (WSGIRequest)->JsonResponse """ 查看设备全国分布情况 :param request: :return: """ mid = str(request.user.id) agentIds = [str(agent.id) for agent in Agent.objects(managerId = mid)] dealerIds = [str(dealer.id) for dealer in Dealer.objects(agentId__in = agentIds)] registered_devices_devNos = [str(_.devNo) for _ in Device.objects(ownerId__in = dealerIds).only('devNo')] devices = Device.get_dev_by_nos(registered_devices_devNos).values() # type: List[DeviceDict] device_count = len(devices) offline_device_count = len([d.online == DeviceOnlineStatus.DEV_STATUS_OFFLINE for d in devices]) online_device_count = device_count - offline_device_count sanitize = lambda city_name: city_name.strip(u'市') if u'市' in city_name else city_name registered_devices_groupIds = [ObjectId(d['groupId']) for d in Device.objects(ownerId__in = dealerIds)] districts = dict(Counter( [District.get_district(g.districtId).split(' ')[1] for g in Group.objects(id__in = registered_devices_groupIds)])) dataList = [{'name': sanitize(city_name), 'value': count} for city_name, count in districts.items()] return JsonResponse({ "result": 1, "description": "", "payload": { "online": online_device_count, "offline": offline_device_count, "dataList": dataList } }) @permission_required(ROLE.dealer, ROLE.agent, ROLE.subaccount) def groupList(request): # type: (WSGIRequest)->JsonResponse # 如果获取的到customerId,即为代理商为经销商注册设备场景 ownerId = request.GET.get('dealerId', None) if ownerId is None: ownerId = str(request.user.bossId) openId = request.GET.get('userId', None) pageIndex = int(request.GET.get('pageIndex', 1)) pageSize = int(request.GET.get('pageSize', 10)) searchKey = str(request.GET.get('searchKey', '')) groupIds = Group.get_group_ids_of_dealer(ownerId) # 过滤下只显示用户的groupId if openId: users = MyUser.objects.filter(openId = openId, groupId__in = groupIds).only('groupId') groupIds = [user.groupId for user in users] groupList = Group.get_groups_by_group_ids(groupIds).values() groupList = natural_sort(groupList, 'groupName', False) dataList = [] # 把addressLabel翻译好 objs = AddressType.objects.all() typeDict = {} for obj in objs: typeDict[obj.value] = obj.label for grp in groupList: if searchKey not in grp['groupName']: continue devNos = Device.get_devNos_by_group([grp['groupId']]) grp['equipmentCount'] = len(devNos) grp['isManager'] = True if grp['isDefault']: dataList.insert(0, grp) else: dataList.append(grp) groupIds = Group.get_group_ids_of_partner(ownerId) groupList = Group.get_groups_by_group_ids(groupIds).values() groupList = natural_sort(groupList, 'groupName', False) for grp in groupList: if searchKey not in grp['groupName']: continue devNos = Device.get_devNos_by_group([grp['groupId']]) grp['equipmentCount'] = len(devNos) grp['isManager'] = False grp['isDefault'] = False grp['addressLabel'] = typeDict.get(grp['addressType'], u'其他') if 'swapFlag' not in grp: grp['swapFlag'] = False dataList.append(grp) return JsonResponse({ "result": 1, "description": None, 'payload': { "total": len(dataList) or 1, "dataList": dataList[(pageIndex - 1) * pageSize: pageIndex * pageSize] } }) @permission_required(ROLE.manager) def getGroupListByDealer(request): # type: (WSGIRequest)->JsonResponse """ :param request: :return: """ dealerIds = json.loads(request.body).get('dealerIds', []) dealers = {str(_.id): _.nickname for _ in Dealer.objects(id__in = dealerIds)} if not dealers: return JsonResponse({'result': 1, 'payload': []}) dataList = [ { 'dealerName': dealers[str(group['ownerId'])], 'dealerId': group['ownerId'], 'groupId': group['groupId'], 'groupName': group['groupName'] } for group in itertools.ifilter( lambda _: bool(all(_) and _), itertools.imap( lambda _: Group.get_groups_of_dealer(_), dealerIds)) ] return JsonResponse({'result': 1, 'payload': {'dataList': dataList, 'total': len(dataList)}}) @permission_required(ROLE.dealer, ROLE.subaccount) def getInstructionsByType(request): # type: (WSGIRequest)->JsonResponse """ :param request: :return: """ typeId = request.GET.get('typeId') devType = DeviceType.objects(id = typeId).first() instructions = devType.instructions if devType is not None else '' return JsonResponse({ "result": 1, "description": None, 'payload': instructions }) @record_operation_behavior() @permission_required(ROLE.dealer, ROLE.subaccount) def setDevSwitch(request): # type: (WSGIRequest)->JsonResponse data = {} lc = request.POST.get('logicalCode') if lc is None: data = json.loads(request.body) if request.body else {} lc = data.get('logicalCode') dev = Device.get_dev_by_logicalCode(lc) # type: DeviceDict if 'autoRefund' in request.POST: strAutoRefund = request.POST.get('autoRefund', 'false') autoRefund = True if strAutoRefund == 'true' else False try: obj = Device.objects.get(logicalCode = lc) obj.autoRefundLeftMoney = autoRefund obj.save() except Exception as e: logger.info('set dev=%s switch error=%s' % (lc, e)) return JsonResponse({"result": 0, "description": u"操作出现异常,请您重试", "payload": {}}) elif 'isFault' in request.POST: isFault = request.POST.get('isFault', False) try: obj = Device.objects.get(logicalCode = lc) obj.isFault = True if isFault == 'true' else False obj.save() Device.invalid_device_cache(obj.devNo) box = ActionDeviceBuilder.create_action_device(dev) box.set_dev_fault(isFault) except Exception as e: logger.info('set dev=%s switch error=%s' % (lc, e)) return JsonResponse({"result": 0, "description": u"操作出现异常,请您重试", "payload": {}}) elif 'simChargeAuto' in request.POST: strAuto = request.POST.get('simChargeAuto', 'false') simChargeAuto = True if strAuto == 'true' else False try: obj = Device.objects.get(logicalCode = lc) obj.simChargeAuto = simChargeAuto obj.save() except Exception as e: logger.info('set dev=%s switch error=%s' % (lc, e)) return JsonResponse({"result": 0, "description": u"操作出现异常,请您重试", "payload": {}}) elif 'billAsServiceSwitch' in request.POST: billAsServiceSwitch = request.POST.get('billAsServiceSwitch') billAsServiceSwitch = True if billAsServiceSwitch == 'true' else False dev.deviceAdapter.switch_bill_as_service(billAsServiceSwitch) return JsonResponse({"result": 1, "description": "", "payload": {}}) @permission_required(ROLE.dealer, ROLE.subaccount) def setBatchDNDSwitch(request): data = json.loads(request.body) if request.body else {} logicalCodes = data.get('logicalCodes', []) isDND = data.get('isDND', False) DNDRange = data.get('isDNDTimeInterval', []) for t in DNDRange: if 'isDNDEndTime' not in t or 'isDNDStartTime' not in t: return JsonErrorResponse(description = u'必须同时指定起始时间和结束时间') start_time = t['isDNDStartTime'] end_time = t['isDNDEndTime'] if start_time > end_time: return JsonErrorResponse(description = u'时间设置错误, 开始时间不能大于结束时间') try: for _ in logicalCodes: d = Device.objects(logicalCode = _).first() d.isDND = isDND d.isDNDTimeInterval = DNDRange d.save() Device.invalid_device_cache(d.devNo) except Exception as e: logger.info('set DND switch error=%s' % (e)) return JsonErrorResponse(description = u'操作出现异常, 请刷新重试') return JsonOkResponse() def updateLocation(request): # type: (WSGIRequest)->JsonResponse try: lc = request.POST.get('logicalCode', None) devNo = Device.get_devNo_by_logicalCode(lc) lng = float(request.POST.get('lng')) lat = float(request.POST.get('lat')) logger.debug('get lbs succeed. devNo = %s; lng = %s; lat = %s' % (devNo, lng, lat)) dev = Device.get_dev(devNo) if dev is None: return JsonResponse({'result': 0, 'description': u'设备不存在'}) Device.get_collection().update({'devNo': devNo}, {'$set': {'location': { 'type': 'Point', 'coordinates': [lng, lat] }, 'dateTimeUpdated': datetime.datetime.now()}}) Device.invalid_device_cache(devNo) YuhuanNorther.send_dev_info(dev) return JsonResponse({'result': 1, 'description': None, 'payload': None}) except Exception as e: logger.exception(e) return JsonResponse({'result': 0, 'description': u'更新设备位置出错'}) @record_operation_behavior() @error_tolerate(logger = logger, nil = JsonErrorResponse(u'系统错误')) def operDevicePort(request): # type: (WSGIRequest)->JsonResponse lc = request.POST.get('logicalCode', None) devNo = Device.get_devNo_by_logicalCode(lc) if request.POST.has_key('active'): strActive = request.POST.get('active', 'false') lock = False if strActive == 'true' else True if str(request.POST.get('portIndex', None)).isdigit(): portIndex = int(request.POST.get('portIndex', None)) else: portIndex = request.POST.get('portIndex', None) dev = Device.get_dev(devNo) if dev is None: return JsonResponse({'result': 0, 'description': u'设备不存在'}) smartBox = ActionDeviceBuilder.create_action_device(dev) try: smartBox.lock_unlock_port(portIndex, lock) except ServiceException, e: return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': None}) return JsonResponse({'result': 1, 'description': None, 'payload': None}) elif request.POST.has_key('stop'): strStop = request.POST.get('stop', 'false') active = False if strStop == 'true' else True if str(request.POST.get('portIndex', None)).isdigit(): portIndex = int(request.POST.get('portIndex', None)) else: portIndex = request.POST.get('portIndex', None) dev = Device.get_dev(devNo) if dev is None: return JsonResponse({'result': 0, 'description': u'设备不存在'}) stopType = request.POST.get('type', '') if stopType != '': Device.update_dev_control_cache(devNo, {str(portIndex): {'stopType': stopType}}) smartBox = ActionDeviceBuilder.create_action_device(dev) try: smartBox.active_deactive_port(portIndex, active) except ServiceException, e: return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': None}) return JsonResponse({'result': 1, 'description': None, 'payload': None}) # 换电柜独有的 elif request.POST.has_key('charge'): strCharge = request.POST.get('charge', 'false') charge = strCharge == 'true' if str(request.POST.get('portIndex', None)).isdigit(): portIndex = int(request.POST.get('portIndex', None)) else: portIndex = request.POST.get('portIndex', None) dev = Device.get_dev(devNo) if dev is None: return JsonResponse({'result': 0, 'description': u'设备不存在'}) smartBox = ActionDeviceBuilder.create_action_device(dev) try: smartBox.active_deactive_port(portIndex, charge) except ServiceException, e: return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': None}) return JsonResponse({'result': 1, 'description': None, 'payload': None}) return JsonResponse({'result': 0, 'description': u'缺少合法参数', 'payload': None}) def getDeviceFunctionByKey(request): # type: (WSGIRequest)->JsonResponse try: # key = request.GET.get('key', None) # logicalCode = request.GET.get('logicalCode', None) # if logicalCode: # logicalCode = json.loads(logicalCode)[0] payload = json.loads(request.body) key = payload.get("key") logicalCode = payload.get("logicalCode") if isinstance(logicalCode, list) and len(logicalCode): logicalCode = logicalCode[0] else: return JsonErrorResponse(description = u"错误的设备编号") devNo = Device.get_devNo_by_logicalCode(logicalCode) dev = Device.get_dev(devNo) box = ActionDeviceBuilder.create_action_device(dev) value = box.get_device_function_by_key(key) payload = {key: value} except ServiceException as e: return JsonResponse({"result": 0, "description": e.result.get('description', ''), "payload": {}}) except Exception as e: logger.exception(e) return JsonResponse({"result": 0, "description": u'未知错误', "payload": {}}) return JsonResponse({"result": 1, "description": "", "payload": payload}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'系统错误')) def setDeviceFunctionByKey(request): # type: (WSGIRequest)->JsonResponse try: data = json.loads(request.body) logicalCode = data.get('logicalCode', None) if isinstance(logicalCode, list) and len(logicalCode): logicalCode = logicalCode[0] else: return JsonErrorResponse(description = u"错误的设备编号") devNo = Device.get_devNo_by_logicalCode(logicalCode) dev = Device.get_dev(devNo) config = data.get('config', None) for key, value in config.items(): box = ActionDeviceBuilder.create_action_device(dev) box.press_down_key(key, value) return JsonResponse({"result": 1, "description": '', "payload": {}}) except ServiceException, e: return JsonResponse({"result": 0, "description": e.result.get('description', ''), "payload": {}}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'系统错误')) def getTotalCoins(request): # type: (WSGIRequest)->JsonResponse logicalCode = request.GET.get('logicalCode', None) devNo = Device.get_devNo_by_logicalCode(logicalCode) dev = Device.get_dev(devNo) try: device_adapter = ActionDeviceBuilder.create_action_device(dev) total = device_adapter.get_total_coin() return JsonResponse({"result": 1, "description": '', "payload": total}) except ServiceException, e: return JsonResponse({"result": 0, "description": e.result.get('description'), "payload": {}}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'系统错误')) def getMajorDevTypeList(request): # type: (WSGIRequest)->JsonResponse majorDevTypeList = [a.to_dict() for a in MajorDeviceType.objects.all()] return JsonResponse( { 'result': 1, 'description': '', 'payload': { 'total': len(majorDevTypeList), 'dataList': majorDevTypeList } }) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'设置价格失败,请刷新页面重新试试')) @permission_required(ROLE.dealer, ROLE.subaccount) def setPricePerHour(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) lc = payload.get('logicalCode') pricePerHour = float(payload.get('pricePerHour')) dev = Device.objects.get(logicalCode = lc) dev.otherConf['pricePerHour'] = pricePerHour dev.save() return JsonOkResponse(description = u'设置成功') ############# ## Commands # ############# @error_tolerate(logger = logger, nil = JsonErrorResponse(u'获取诊断设备命令列表失败')) @permission_required(ROLE.dealer, ROLE.subaccount) def getDiagCommands(request): # type: (WSGIRequest)->JsonResponse # TODO zjl 需要搞清楚这个接口是否有用 哪里有用 logicalCode = request.GET.get('logicalCode') if not logicalCode: return JsonErrorResponse(description = u'逻辑码为空') dev = Device.get_dev_by_l(logicalCode) commands = DeviceCommand.objects(devTypeCode = dev.devType['code']) return JsonOkResponse(payload = [command.to_dict() for command in commands]) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'发送失败')) @permission_required(ROLE.dealer, ROLE.subaccount) def diagDevice(request): # type: (WSGIRequest)->JsonResponse # TODO zjl 需要搞清楚这个接口是否有用 哪里有用 if not request.body: return JsonErrorResponse(description = u'传入数据为空') currentDealer = request.user # type: Dealer payload = json.loads(request.body) logicalCode = payload.get('logicalCode') commandId = payload.get('commandId') params = payload.get('params') command = DeviceCommand.objects(id = commandId).first() # type: DeviceCommand if not command: return JsonErrorResponse(description = u'未找到命令') device = Device.get_dev_by_l(logicalCode) if not device: return JsonErrorResponse(description = u'未找到设备') if not command.supports(device): return JsonErrorResponse(description = u'该设备不支持所提供命令') topic_command = TopicCommand(cmdNo = command.cmd, devNo = device['devNo'], params = params, prefix = 'diag') task_caller('send_topic_command', cmdNo = command.cmd, devNo = device['devNo'], params = params, prefix = 'diag') return JsonOkResponse(payload = {'topic': topic_command.result_topic, 'pushBrokerUrl': currentDealer.pushBrokerUrl}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'查询格子失败')) @permission_required(ROLE.dealer, ROLE.subaccount) def getDeviceCells(request): payload = json.loads(request.body) logicalCode = payload.get('logicalCode') objs = Cell.objects.filter(logicalCode = logicalCode) dev = Device.get_dev_by_logicalCode(logicalCode) box = ActionDeviceBuilder.create_action_device(dev) lockStatusDict = box.get_all_lock_status() dataList = [{'id': str(obj.id), 'cellNo': obj.cellNo, 'boardNo': obj.boardNo, 'lockNo': obj.lockNo, 'itemTitle': obj.itemTitle, 'itemDesc': obj.itemDesc, 'itemPicUrl': obj.itemPicUrl, 'itemPrice': round(obj.itemPrice / 100.0, 2), 'lockStatus': lockStatusDict.get(obj.cellNo, 'close')} for obj in objs] return JsonResponse({'result': 1, 'description': '', 'payload': {'dataList': dataList}}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'编辑格子失败')) @permission_required(ROLE.dealer, ROLE.subaccount) def addEditCell(request): payload = json.loads(request.body) logicalCode = payload.get('logicalCode') cellId = payload.get('id', None) cellNo = payload.get('cellNo') boardNo = payload.get('boardNo') lockNo = payload.get('lockNo') itemTitle = payload.get('itemTitle') itemDesc = payload.get('itemDesc') itemPicUrl = payload.get('itemPicUrl') itemPrice = payload.get('itemPrice') try: obj = Cell.objects.get(id = cellId) obj.cellNo, obj.boardNo, obj.lockNo, obj.itemTitle, obj.itemDesc, obj.itemPicUrl, obj.itemPrice = cellNo, boardNo, lockNo, itemTitle, itemDesc, itemPicUrl, itemPrice obj.save() except DoesNotExist, e: newObj = Cell(logicalCode = logicalCode, cellNo = cellNo, boardNo = boardNo, lockNo = lockNo, itemTitle = itemTitle, itemDesc = itemDesc, itemPicUrl = itemPicUrl, itemPrice = itemPrice) newObj.save() except Exception, e: return JsonErrorResponse(description = u'未知错误') return JsonResponse({"result": 1, "description": '', "payload": None}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'操作失败')) @permission_required(ROLE.dealer, ROLE.subaccount) def deleteCell(request): payload = json.loads(request.body) cellId = payload.get('id') Cell.objects.delete(id = cellId) return JsonResponse({"result": 1, "description": '', "payload": None}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'操作失败')) @permission_required(ROLE.dealer, ROLE.subaccount) def getElecMeterReading(request): logicalCode = request.GET.get('logicalCode') dev = Device.get_dev_by_logicalCode(logicalCode) box = ActionDeviceBuilder.create_action_device(dev) result = box.get_elec_meter() meter = result['meter'] return JsonResponse({"result": 1, "description": '', "payload": meter}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'操作失败')) def getDeviceSlave(request): def cmp_by_port(x, y): if int(x['index']) < int(y['index']): return -1 elif int(x['index']) > int(y['index']): return 1 return 0 def cmd_by_sortIndex(x, y): if int(x['sortIndex']) < int(y['sortIndex']): return -1 elif int(x['sortIndex']) > int(y['sortIndex']): return 1 return 0 logicalCode = request.GET.get('logicalCode') dev = Device.get_dev_by_logicalCode(logicalCode) box = ActionDeviceBuilder.create_action_device(dev) portDict = box.get_port_status() smartBox = ActionDeviceBuilder.create_action_device(dev) statsMap = {str(Const.DEV_WORK_STATUS_IDLE): 'idle', str(Const.DEV_WORK_STATUS_WORKING): 'busy', str(Const.DEV_WORK_STATUS_FAULT): 'fault', str(Const.DEV_WORK_STATUS_FORBIDDEN): 'ban'} portList = [] ctrInfo = Device.get_dev_control_cache(dev['devNo']) for port, valueDict in portDict.items(): vStatus = valueDict.get('status', None) if vStatus == Const.DEV_WORK_STATUS_WORKING: portDetail = smartBox.get_port_using_detail(port, ctrInfo) portDetail.update({"id": str(port), "index": str(port), "status": 'busy'}) tempList = [] for k, v in portDetail.items(): if not Const.TRANS_DICT.has_key(k): continue kConfigDict = Const.TRANS_DICT.get(k) attrDict = {'key': k, 'value': v, 'name': kConfigDict['name'], 'sortIndex': kConfigDict['sortIndex']} if kConfigDict.has_key('unit'): attrDict.update({'unit': kConfigDict.get('unit')}) tempList.append(attrDict) tempList.sort(cmp = cmd_by_sortIndex) portDetail['attr'] = tempList portList.append(portDetail) else: portList.append({"id": str(port), 'index': str(port), 'status': statsMap[str(vStatus)]}) portList.sort(cmp = cmp_by_port) return JsonResponse({"result": 1, "description": "", "payload": {"total": len(portList), "dataList": portList}}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'操作失败')) @permission_required(ROLE.dealer, ROLE.subaccount) def editDeviceSlave(request): payload = json.loads(request.body) logicalCode = payload['logicalCode'] slaveIndex = int(payload['slaveIndex']) dev = Device.get_dev_by_logicalCode(logicalCode) box = ActionDeviceBuilder.create_action_device(dev) slaveId = payload.get('slaveId', None) try: if slaveId is not None: box.edit_address(int(slaveId), slaveIndex) else: box.add_address(slaveIndex) except ServiceException, e: return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': None}) return JsonResponse({"result": 1, "description": '', "payload": {"id": slaveIndex}}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'操作失败')) @permission_required(ROLE.dealer, ROLE.subaccount) def operDeviceSlave(request): payload = json.loads(request.body) logicalCode = payload.get('logicalCode', None) portIndex = payload.get('index') devNo = Device.get_devNo_by_logicalCode(logicalCode) dev = Device.get_dev_by_logicalCode(logicalCode) if payload.has_key('status'): status = payload.get('status') devObj = Device.objects.get(devNo = devNo) portDict = devObj.otherConf.get('portDict', {}) if status == 'ban': portDict.update({portIndex: Const.DEV_WORK_STATUS_FORBIDDEN}) else: portDict.update({portIndex: Const.DEV_WORK_STATUS_IDLE}) devObj.save() return JsonResponse({'result': 1, 'description': None, 'payload': None}) elif payload.has_key('stop') and payload['stop']: box = ActionDeviceBuilder.create_action_device(dev) try: box.stop(portIndex) except ServiceException, e: return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': None}) return JsonResponse({'result': 1, 'description': u'停止指令已经下发,请您稍后刷新页面,检查端口实时数据,以确定是否停止成功', 'payload': None}) return JsonResponse({'result': 0, 'description': u'缺少合法参数', 'payload': None}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'操作失败')) @permission_required(ROLE.dealer, ROLE.subaccount) def deleteSlave(request): payload = json.loads(request.body) ids = payload.get('ids', []) logicalCode = payload.get('logicalCode') devObj = Device.objects.get(logicalCode = logicalCode) for slaveId in ids: try: devObj.otherConf['portDict'].pop(slaveId) except Exception, e: continue devObj.save() return JsonResponse({'result': 0, 'description': u'缺少合法参数', 'payload': None}) @permission_required(ROLE.dealer, ROLE.subaccount) def setDevAutoRefund(request): # type: (WSGIRequest)->JsonResponse """ 1. 设备注册 -> 通过DriverCode 给 DeviceType 里面加 auto 字段, 并记录到 dev 缓存里面的 devType 中 2. 设备详情 -> 通过查到 dev 缓存中的 devType 里面的 auto 字段来控制自动退款的显示与不显示 3. 批量设置自动退款 -> 通过 dev 缓存中的 devType 中的 auto 为 true 来控制批量设置显示不显示 4. 设置批量的自动退款 -> 直接设置 Device 中的 autoRefundLeftMoney 来控制设备是否支持自动退款 5. autoRefundLeftMoney -> 可以全部都设置, 不会影响不退款的设备, 也不会影响不退款设备的自动退款显示 :param request: :return: """ data = json.loads(request.body) if request.body else {} if not data: return JsonErrorResponse(u'数据为空,请重试') devNos = data['logicalCodes'] autoRefundStatus = True if data['autoRefund'] == 1 else False objs = Device.objects.filter(devNo__in = devNos) for obj in objs: obj.autoRefundLeftMoney = autoRefundStatus try: obj.save() except Exception as e: logger.exception(e) continue return JsonResponse({"result": 1, "description": u"操作成功", "payload": {}}) def viewOfflineCoinStatistics(request): pageIndex = int(request.GET.get('pageIndex', 1)) pageSize = int(request.GET.get('pageSize', 10)) l = request.GET['logicalCode'] devNo = Device.get_devNo_by_logicalCode(logicalCode = l) now_time = datetime.datetime.now() before_seven = now_time - datetime.timedelta(days = 7) rv = OfflineCoinsManager.instence().get(devNo = devNo, sTime = before_seven, eTime = now_time) total = len(rv) return JsonResponse({'result': 1, 'description': '', 'payload': {'total': total, 'dataList': rv[(pageIndex - 1) * pageSize: pageIndex * pageSize]}}) @permission_required(ROLE.dealer, ROLE.subaccount) def setTempElecPrice(request): data = json.loads(request.body) if request.body else {} if not data: return JsonErrorResponse(u'数据为空,请重试') logicalCode = data['logicalCode'] tempElecPrice = data['tempElecPrice'] device = Device.objects(logicalCode = logicalCode).first() if device is None: return JsonErrorResponse(u'设备不存在, 系统错误') device.otherConf['tempElecPrice'] = tempElecPrice try: device.save() except Exception as e: logger.exception(e) return JsonResponse({"result": 1, "description": u"操作成功", "payload": {}}) @permission_required(ROLE.dealer) def unlockPort(request): payload = request.POST logicalCode = payload.get("logicalCode") portIndex = payload.get("portIndex") if not portIndex: return JsonResponse({"result": 2, "description": "数据有误", }) dev = Device.get_dev_by_l(logicalCode) box = ActionDeviceBuilder.create_action_device(dev) try: box.unlockPort(portIndex) except ServiceException: return JsonResponse({"result": 2, "description": "连接设备失败,请重试", }) return JsonResponse({"result": 1, "description": ""}) @permission_required(ROLE.dealer) def saveLiveConfig(request): payload = json.loads(request.body) logicalCode = payload.get('logicalCode', '') liveUrl = payload.get('liveUrl', '#') liveLimitedPrice = payload.get('liveLimitedPrice', '0.0') if logicalCode == '': return JsonResponse({"result": 2, "description": "系统异常"}) try: device = Device.objects(logicalCode=logicalCode).first() device.otherConf.update({'liveUrl': liveUrl}) device.otherConf.update({'liveLimitedPrice': liveLimitedPrice}) device.save() Device.invalid_device_cache(device.devNo) except Exception as e: return JsonResponse({"result": 2, "description": "参数设置失败,请重试"}) return JsonResponse({"result": 1, "description": ""}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'操作失败')) @permission_required(ROLE.manager) def getDevicePort(request): # type: (WSGIRequest)->JsonResponse def cmp_by_port(x, y): if (str(x['index']).isdigit() and str(y['index']).isdigit()): if int(x['index']) < int(y['index']): return -1 elif int(x['index']) > int(y['index']): return 1 return 0 else: if x['index'] < y['index']: return -1 elif x['index'] > y['index']: return 1 return 0 def charge_pay_coin_unit(p, u): """ 给端口信息中的付费添加上单位 :param p: :param u: :return: """ _coins = p.get("coins") if not _coins: return p.update({"coins": "{}{}".format(_coins, u)}) currentDealer = request.user dev = Device.get_dev_by_logicalCode(request.GET.get('logicalCode')) # type: DeviceDict group = dev.group # type: GroupDict devTypeCode = dev.devType['code'] smartBox = dev.deviceAdapter if hasattr(smartBox, 'dealer_get_device_port'): portList = getattr(smartBox, 'dealer_get_device_port')() return JsonResponse({"result": 1, "description": "", "payload": {"portList": portList}}) if devTypeCode in [Const.DEVICE_TYPE_CODE_GEZIGUI_485, Const.DEVICE_TYPE_CODE_CHARGE_ZHONGSHAN,Const.DEVICE_TYPE_CODE_CHARGE_WEIFULE_CAR, Const.DEVICE_TYPE_CODE_CAR_WEIFULE_CHARGING_DOUB, Const.DEVICE_TYPE_CODE_CAR_WEIFULE_21KW, Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_JFPG, Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_DOUB_JFPG, Const.DEVICE_TYPE_CODE_CHARGE_ZHONGSHAN_BILLASSERVICE]: portList = smartBox.get_port_status_from_dev() return JsonResponse({"result": 1, "description": "", "payload": {"portList": portList}}) if devTypeCode == Const.DEVICE_TYPE_CODE_WATER_DISPENSER: ctrInfo = Device.get_dev_control_cache(dev.devNo) if ctrInfo is None or ('1' not in ctrInfo and '2' not in ctrInfo): portList = {} else: statusDict = {} statusInfoDict = {} for _ in range(1, 3): tempPort = str(_) if ctrInfo[tempPort].get('status', 0) == 0: statusDict[tempPort] = 'idle' statusInfoDict[tempPort] = ctrInfo[tempPort].get('statusErrorInfo', u'无') elif ctrInfo[tempPort].get('status', 0) == 1: statusDict[tempPort] = 'busy' statusInfoDict[tempPort] = ctrInfo[tempPort].get('statusErrorInfo', u'无') elif ctrInfo[tempPort].get('status', 0) == 3: statusDict[tempPort] = 'fault' statusInfoDict[tempPort] = ctrInfo[tempPort].get('statusErrorInfo', u'无') else: statusDict[tempPort] = 'fault' statusInfoDict[tempPort] = ctrInfo[tempPort].get('statusErrorInfo', u'无') portList = [ {'index': '1', 'status': statusDict['1'], 'statusErrorInfo': statusInfoDict.get('1', u'无')}, {'index': '2', 'status': statusDict['2'], 'statusErrorInfo': statusInfoDict.get('2', u'无')} ] return JsonResponse({"result": 1, "description": "", "payload": {"portList": portList}}) try: # 先从设备上取信息,然后从缓存中取信息 portDict = smartBox.dealer_get_port_status() smartBox.async_update_portinfo_from_dev() except ServiceException as e: logger.exception(e) return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': None}) except Exception as e: logger.exception(e) return JsonResponse({"result": 0, "description": u"从设备上获取端口信息失败,请您重试", "payload": {}}) portList = [] unit = smartBox.show_pay_unit statsMap = {str(Const.DEV_WORK_STATUS_IDLE): 'idle', str(Const.DEV_WORK_STATUS_WORKING): 'busy', str(Const.DEV_WORK_STATUS_FAULT): 'fault', str(Const.DEV_WORK_STATUS_FORBIDDEN): 'ban', str(Const.DEV_WORK_STATUS_CONNECTED): 'connected', str(Const.DEV_WORK_STATUS_FINISHED): 'finished'} # TODO zjl get_port_using_detail 这块太复杂 后续一定要整改!!! 目前先做if分支处理 if devTypeCode in [Const.DEVICE_TYPE_CODE_CHARGING_AQKJ, Const.DEVICE_TYPE_CODE_CHARGING_AQKJ_NEW]: elecInfo = smartBox._query_elec() for port, valueDict in portDict.items(): voltage = "{:.2f}".format(float(valueDict.get("voltage", "0"))) batteryImei = valueDict.get("batteryImei", "") doorStatus = valueDict.get("doorStatus") doorStatus = smartBox.translate_door_status_to_unicode(doorStatus) tempStatus = statsMap.get(str(valueDict.get("status"))) elecPoint = valueDict.get("elec") tempDict = { "index": port, "status": tempStatus, "doorStatus": doorStatus, "voltage": voltage, "batteryImei": batteryImei if batteryImei else u"无电池", "elecPoint": elecPoint } tempDict.update(elecInfo.get(port)) portList.append(tempDict) portList.sort(cmp=cmp_by_port) return JsonResponse({"result": 1, "description": "", "payload": {"portList": portList}}) if devTypeCode in [Const.DEVICE_TYPE_CODE_CABINET_NEW]: doorStatus = smartBox._get_door_status() for port, valueDict in portDict.items(): voltage = "{:.2f}".format(float(valueDict.get("voltage", "0"))) tempDict = { "index": port, "status": valueDict["status"], "doorStatus": doorStatus.get(port, u"未知"), } valueDict.update(tempDict) portList.append(valueDict) portList.sort( key=lambda x: int(x['index']) if isinstance(x['index'], str) and x["index"].isdigit() else x['index']) return JsonResponse({"result": 1, "description": "", "payload": {"portList": portList}}) if devTypeCode in [Const.DEVICE_TYPE_CODE_CABINET]: for port, valueDict in portDict.items(): tempStatus = statsMap.get(str(valueDict.get("status"))) tempDict = { "index": port, "status": tempStatus, } valueDict.update(tempDict) portList.append(valueDict) portList.sort(cmp=cmp_by_port) return JsonResponse({"result": 1, "description": "", "payload": {"portList": portList}}) busyPortList = [] for port, valueDict in portDict.items(): vStatus = valueDict.get('status', None) if vStatus == Const.DEV_WORK_STATUS_WORKING: busyPortList.append(port) else: portList.append({'index': str(port), 'status': statsMap.get(str(vStatus), "idle")}) busyPortInfoDict = smartBox.get_many_port_info(busyPortList) if devTypeCode in [Const.DEVICE_TYPE_CODE_CHARGING_HAINIAO_DOUBLE]: ctrInfo = Device.get_dev_control_cache(dev.devNo) for port, valueDict in portDict.items(): vStatus = valueDict.get('status', None) if vStatus == Const.DEV_WORK_STATUS_WORKING: portDetail = smartBox.get_port_using_detail(port, ctrInfo) if portDetail.get('timeUnit',None)==u'秒': portDetail.update({'needTime':str(portDetail['needTime'][:-2])+'秒'}) portDetail.update({"index": str(port), "status": 'busy'}) portList.append(portDetail) portList.sort( key=lambda x: int(x['index']) if isinstance(x['index'], str) and x["index"].isdigit() else x['index']) map(charge_pay_coin_unit, portList, [unit for x in xrange(len(portList))]) for _ in portList: if 'elec' in _: _.pop('elec') portList.sort(cmp=cmp_by_port) return JsonOkResponse(payload={"isManager": False, "portList": portList}) if busyPortInfoDict: for info in busyPortInfoDict.values(): if info['status'] == Const.DEV_WORK_STATUS_WORKING: info.update({'status':statsMap[str(info['status'])]}) if info.has_key('needTime') and str(info['needTime']).isdigit(): info.update({'needTime':u'%s分钟' % info['needTime']}) else: info = {'status':'idle','index':str(info['index'])} portList.append(info) else: ctrInfo = Device.get_dev_control_cache(dev.devNo) for port, valueDict in portDict.items(): vStatus = valueDict.get('status', None) if vStatus == Const.DEV_WORK_STATUS_WORKING: portDetail = smartBox.get_port_using_detail(port, ctrInfo) portDetail.update({"index": str(port), "status": 'busy'}) portList.append(portDetail) portList.sort(key=lambda x: int(x['index']) if isinstance(x['index'], str) and x["index"].isdigit() else x['index']) map(charge_pay_coin_unit, portList, [unit for x in xrange(len(portList))]) # todo 删掉已充电量, 只保留订购电量 (微付乐的板子需要电量,不能去掉。按道理,这个是业务自己不返回elec,不能放在公共代码这里改) if devTypeCode not in [Const.DEVICE_TYPE_CODE_CHANGING_WEIFULE, Const.DEVICE_TYPE_CODE_CHANGING_WEIFULE2,Const.DEVICE_TYPE_CODE_CHANGING_DIANCHUANCARCHARGING]: for _ in portList: if 'elec' in _: _.pop('elec') if dev.support_power_graph and ( 'showPG_in_port_detail' in dev.owner.features or dev.driverCode in [Const.DEVICE_TYPE_CODE_WEIFULE_ANJIAN]): for item in portList: item['showPG'] = True portList.sort(cmp=cmp_by_port) return JsonOkResponse(payload={"isManager": False, "portList": portList}) @permission_required(ROLE.manager) @error_tolerate(logger=logger, nil=JsonErrorResponse(u'系统错误,请稍后再试')) def getAlarmList(request): # type: (WSGIRequest)->JsonResponse pageIndex = int(request.GET.get('pageIndex', 1)) pageSize = int(request.GET.get('pageSize', 10)) searchKey = request.GET.get('searchKey', '') agentIds = [str(_.id) for _ in Agent.objects(managerId = str(request.user.id))] dealerIds = [str(_.id) for _ in Dealer.objects(agentId__in = agentIds)] if searchKey: queryset = FaultRecord.objects(logicalCode = searchKey,dealerId__in=dealerIds).order_by('-createdTime') else: queryset = FaultRecord.objects(dealerId__in=dealerIds).order_by('-createdTime') records = queryset.paginate(pageIndex = pageIndex, pageSize = pageSize) # type: Iterable[FaultRecord] total = queryset.count() return JsonOkResponse(payload={'dataList': [ _.to_dict() for _ in records ], 'total': total}) @permission_required(ROLE.dealer, ROLE.subaccount) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'系统错误,请稍后再试')) def findDevTypeCandidate(request): logicalCode = request.GET.get('logicalCode') devObj = Device.objects(logicalCode = logicalCode).first() # type: Device if not devObj: return JsonErrorResponse(description = u'设备不存在,请扫正确的设备二维码') recommend, all = DeviceType.find_candidate(devObj, request.user) return JsonOkResponse(payload = {'recommend': recommend, 'all': all}) @permission_required(ROLE.supermanager, ROLE.manager) def getDriverCodeList(request): # type: (WSGIRequest)->JsonResponse devTypes = [d.to_dict() for d in DriverCode.objects()] # type: List[DriverCode] return JsonResponse( { 'result': 1, 'description': "", 'payload': { 'total': len(devTypes), 'dataList': devTypes } } ) @permission_required(ROLE.supermanager) def addDriverCode(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) # type: dict try: DriverCode(code = payload['code'], name = payload['name'], description = payload['description']).save() except NotUniqueError: return JsonErrorResponse(description = u'重复数据') return JsonResponse({'result': 1, 'description': u'保存成功'}) @permission_required(ROLE.supermanager) def editDriverCode(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) # type: dict try: DriverCode.objects(id = payload.pop('id')).update(**payload) except NotUniqueError: return JsonErrorResponse(description = u'重复数据') return JsonResponse({'result': 1, 'description': u'保存成功'}) @error_tolerate(logger = logger, nil = JsonErrorResponse(u'删除设备类型列表失败,请重试')) @permission_required(ROLE.supermanager) def deleteDriverCode(request): # type: (WSGIRequest)->JsonResponse ids = json.loads(request.body)['ids'] for _ in ids: driverCode = DriverCode.objects(id = str(_)).first() if not driverCode: return JsonErrorResponse(description = u"没有找到设备驱动编码{}".format(driverCode.code)) refDevType = DeviceType.objects(code = driverCode.code).first() if refDevType: return JsonErrorResponse(description = u"{}已经被使用,无法删除".format(driverCode.code)) map(lambda _: _.delete(), DriverCode.objects(id__in = ids).all()) return JsonOkResponse() @permission_required(ROLE.supermanager) def getDriverAdapterList(request): # type: (WSGIRequest)->JsonResponse rv = [d.to_dict() for d in DriverAdapter.objects()] return JsonResponse( { 'result': 1, 'description': "", 'payload': { 'total': len(rv), 'dataList': rv } } ) @permission_required(ROLE.supermanager) def addDriverAdapter(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) # type: dict if not payload['adapterFile'] or not payload['adapter'] or not payload['adapterVer']: return JsonErrorResponse(description = u'参数错误') try: DriverAdapter( adapterFile = payload['adapterFile'], adapter = payload['adapter'], adapterVer = payload['adapterVer']).save() except NotUniqueError: return JsonErrorResponse(description = u'重复数据') return JsonResponse({'result': 1, 'description': u'保存成功'}) @permission_required(ROLE.supermanager) def editDriverAdapter(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) # type: dict if not payload['adapterFile'] or not payload['adapter'] or not payload['adapterVer']: return JsonErrorResponse(description = u'参数错误') try: DriverAdapter.objects(id = payload.pop('id')).update(**payload) except NotUniqueError: return JsonErrorResponse(description = u'重复数据') return JsonResponse({'result': 1, 'description': u'保存成功'}) @permission_required(ROLE.supermanager) def deleteDriverAdapter(request): # type: (WSGIRequest)->JsonResponse ids = json.loads(request.body)['ids'] for _ in ids: driverAdapter = DriverAdapter.objects(id = str(_)).first() if not driverAdapter: return JsonErrorResponse(description = u"没有找到设备适配器{}".format(driverAdapter.adapterFile)) if not driverAdapter.adapterFile: continue refDriverCode = DriverCode.objects(adapterFile = driverAdapter.adapterFile).first() if refDriverCode: return JsonErrorResponse(description = u"{}已经被使用,无法删除".format(driverAdapter.adapterFile)) map(lambda _: _.delete(), DriverAdapter.objects(id__in = ids).all()) return JsonOkResponse() @permission_required(ROLE.supermanager) def getDriverEventerList(request): # type: (WSGIRequest)->JsonResponse rv = [d.to_dict() for d in DriverEventer.objects()] return JsonResponse( { 'result': 1, 'description': "", 'payload': { 'total': len(rv), 'dataList': rv } } ) @permission_required(ROLE.supermanager) def addDriverEventer(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) # type: dict if not payload['eventerFile'] or not payload['eventerVer']: return JsonErrorResponse(description = u'参数错误') try: DriverAdapter( eventerFile = payload['eventerFile'], eventerVer = payload['eventerVer']).save() except NotUniqueError: return JsonErrorResponse(description = u'重复数据') return JsonResponse({'result': 1, 'description': u'保存成功'}) @permission_required(ROLE.supermanager) def editDriverEventer(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) # type: dict if not payload['eventerFile'] or not payload['eventerVer']: return JsonErrorResponse(description = u'参数错误') try: DriverEventer.objects(id = payload.pop('id')).update(**payload) except NotUniqueError: return JsonErrorResponse(description = u'重复数据') return JsonResponse({'result': 1, 'description': u'保存成功'}) @permission_required(ROLE.supermanager) def deleteDriverEventer(request): # type: (WSGIRequest)->JsonResponse ids = json.loads(request.body)['ids'] for _ in ids: driverEventer = DriverEventer.objects(id = str(_)).first() if not driverEventer: return JsonErrorResponse(description = u"没有找到设备适配器{}".format(driverEventer.eventerFile)) if not driverEventer.eventerFile: continue refDriverCode = DriverCode.objects(eventerFile = driverEventer.eventerFile).first() if refDriverCode: return JsonErrorResponse(description = u"{}已经被使用,无法删除".format(driverEventer.eventerFile)) map(lambda _: _.delete(), DriverEventer.objects(id__in = ids).all()) return JsonOkResponse() @permission_required(ROLE.manager, ROLE.supermanager) def assignDeviceTypeToAgent(request): # type: (WSGIRequest)->JsonResponse payload = json.loads(request.body) agent = Agent.objects(id = payload['id']).first() if not agent: return JsonResponse({'result': 0, 'description': u'该代理商用户不存在'}) for deviceType in payload['deviceType']: deviceType['agentId'] = str(agent.id) deviceType.pop('id') DeviceType(**deviceType).save() return JsonResponse({'result': 1, 'description': u'配置成功'}) @permission_required(ROLE.dealer, ROLE.subaccount) def getDeviceVirtualQrCode(request): """ 生成设备的二维码推广码 """ logicalCode = request.GET.get('logicalCode') dev = Device.get_dev_by_l(logicalCode) # type: DeviceDict if not dev: return JsonErrorResponse(description=u"生成二维码错误(10001)") deviceOwner = dev.owner if not deviceOwner: return JsonErrorResponse(description=u"生成二维码错误(10002)") productionAgent = get_user_manager_agent(deviceOwner) redirect = '/user/index.html#?path=ticket&logicalCode={}&groupId={}'.format(dev.logicalCode, dev.groupId) url = concat_user_center_entry_url(str(productionAgent.id), redirect=redirect) logger.debug('{} virtual qr code is: {}'.format(dev, url)) return JsonOkResponse(payload={'url': url})