mopybird 2 年之前
父节点
当前提交
2988b420e4

+ 1 - 1
apps/web/agent/models.py

@@ -29,7 +29,7 @@ from apps.web.common.transaction import WITHDRAW_PAY_TYPE
 from apps.web.constant import Const, AppPlatformType, DEALER_CONSUMPTION_AGG_KIND, MoniAppStatus
 from apps.web.constant import Const, AppPlatformType, DEALER_CONSUMPTION_AGG_KIND, MoniAppStatus
 from apps.web.core import PayAppType, APP_KEY_DELIMITER, ROLE
 from apps.web.core import PayAppType, APP_KEY_DELIMITER, ROLE
 from apps.web.core.db import Searchable, MonetaryField, StrictDictField, PermillageField, PercentField
 from apps.web.core.db import Searchable, MonetaryField, StrictDictField, PermillageField, PercentField
-from apps.web.core.exceptions import InvalidParameter, NoAgentFound, NoManagerFound
+from apps.web.core.exceptions import InvalidParameter, NoAgentFound, NoManagerFound, ServiceException
 from apps.web.core.messages.sms import agentWithdrawSMSProvider
 from apps.web.core.messages.sms import agentWithdrawSMSProvider
 from apps.web.core.models import WechatManagerApp, WechatAuthApp, BoundOpenInfo, AliApp, WechatPayApp, \
 from apps.web.core.models import WechatManagerApp, WechatAuthApp, BoundOpenInfo, AliApp, WechatPayApp, \
     WechatUserManagerApp, WithdrawEntity, WechatUserSubscribeManagerApp, WechatDealerSubscribeManagerApp
     WechatUserManagerApp, WithdrawEntity, WechatUserSubscribeManagerApp, WechatDealerSubscribeManagerApp

+ 0 - 522
apps/web/core/adapter/mxzv2.py

@@ -1,522 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from apps.web.core.adapter.base import *
-from apps.web.device.models import Device
-
-
-class ChargingMXZ2Box(SmartBox):
-    def __init__(self, device):
-        super(ChargingMXZ2Box, self).__init__(device)
-    
-    def translate_funcode(self,funCode):
-        funCodeDict = {
-                       '31':u'获取端口数量',
-                       '20':u'操作端口',
-                       '02':u'回复刷卡余额',
-                       '03':u'回复刷卡充电',
-                       '04':u'回复结束报文',
-                       '23':u'获取功率',
-                       }
-        return funCodeDict.get(funCode,'')
-    
-    def translate_event_cmdcode(self,cmdCode):
-        cmdDict = {
-                       '02':u'刷卡事件',
-                       '03':u'刷卡启动或者关闭端口',
-                       '04':u'充电结束',
-                       '20':u'端口开始或者结束',
-                       }
-        return cmdDict.get(cmdCode,'')
-    
-    def get_port_info(self,line):
-        portDict = self.get_power()
-        if portDict.has_key(line):
-            return {'power':portDict[line]}
-  
-    def is_port_can_use(self, port, canAdd=False):
-        return super(ChargingMXZ2Box, self).is_port_can_use(port, True)
-
-    def get_port_status(self, force = False):
-        if force:
-            return self.get_port_status_from_dev()
-
-        ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
-        if not ctrInfo.has_key('allPorts'):
-            self.get_port_status_from_dev()
-            ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
-            
-        allPorts = ctrInfo.get('allPorts',10)
-        statusDict = {}
-        for ii in range(allPorts):
-            tempDict = ctrInfo.get(str(ii+1),{})
-            if tempDict.has_key('status'):
-                statusDict[str(ii+1)] = {'status':tempDict.get('status')}
-            elif tempDict.has_key('isStart'):
-                if tempDict['isStart']:
-                    statusDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_WORKING}
-                else:
-                    statusDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_IDLE}
-            else:
-                statusDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_IDLE}
-
-        allPorts,usedPorts,usePorts = self.get_port_static_info(statusDict)
-        Device.update_dev_control_cache(self._device['devNo'], {'allPorts':allPorts,'usedPorts':usedPorts,'usePorts':usePorts})
-
-        return statusDict
-
-    def get_port_status_from_dev(self, attachParas=None):
-        devInfo = MessageSender.send_for_moxiaozhiv2(self.device, self.make_random_cmdcode(),
-                                      {'IMEI': self._device['devNo'],"funCode":'31','data':'00'})
-        if devInfo.has_key('rst') and devInfo['rst'] != 0:
-            if devInfo['rst'] == -1:
-                raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,建议您试试旁边其他设备,或者稍后再试哦'})
-            elif devInfo['rst'] == 1:
-                raise ServiceException({'result': 2, 'description': u'充电桩繁忙,无响应,请试试其他线路,或者稍后再试哦'})
-
-        data = devInfo['data'][18::]
-        if data[0:2] == '01':#表示成功
-            pass
-        else:
-            raise ServiceException({'result': 2, 'description': u'获取设备信息失败,,建议您试试旁边其他设备,或者稍后再试哦'})
-        portNum = int(data[2:4],16)
-
-        #充电板那边说,用获取功率的方式更加稳定一些
-        try:
-            confDict = Device.objects.get(devNo = self._device['devNo']).otherConf
-        except Exception,e:
-            logger.error('update dev=%s coin enable ic enable e=%s' %(self._device['devNo'],e))
-            raise ServiceException({'result': 2, 'description': u'没有找到该设备的配置信息,请稍候重试,或者换周围其他的设备吧'})
-
-        devInfo = Device.get_dev_control_cache(self._device['devNo'])
-        nowTime = datetime.datetime.now()
-        resultDict = {}
-        powerDict = self.get_power()
-        for port,power in powerDict.items():
-            portCtrInfo = devInfo.get(str(port))
-            if int(port) > portNum:
-                continue
-            if power <= 25:
-                resultDict[str(port)] ={'status':Const.DEV_WORK_STATUS_IDLE}
-                if portCtrInfo is not None:
-                    strStartTime = portCtrInfo.get('startTime',None)
-                    if portCtrInfo.get('isStart',False) and strStartTime:
-                        startTime = to_datetime(strStartTime)
-                        timeDelta = (nowTime - startTime).total_seconds()
-                        if timeDelta <= 60:
-                            resultDict[str(port)] ={'status':Const.DEV_WORK_STATUS_WORKING}
-            else:#设备功率是按照分钟来取的,端口停掉后,设备一分钟内的状态不会马上变化,所以需要刷新
-                if portCtrInfo is None:
-                    resultDict[str(port)] ={'status':Const.DEV_WORK_STATUS_WORKING}
-                else:
-                    strEndTime = portCtrInfo.get('endTime',None)
-                    if not strEndTime:
-                        resultDict[str(port)] ={'status':Const.DEV_WORK_STATUS_WORKING}
-                    else:
-                        endTime = to_datetime(strEndTime)
-                        timeDelta = (nowTime - endTime).total_seconds()
-                        if timeDelta <= 60:
-                            resultDict[str(port)] ={'status':Const.DEV_WORK_STATUS_IDLE}
-                        else:
-                            resultDict[str(port)] ={'status':Const.DEV_WORK_STATUS_WORKING}
-            portKey = 'port%s' % port
-
-            if confDict.has_key(portKey) and confDict[portKey] == Const.DEV_WORK_STATUS_FORBIDDEN:
-                    resultDict[str(port)] = {'status':Const.DEV_WORK_STATUS_FORBIDDEN}
-
-        allPorts,usedPorts,usePorts = self.get_port_static_info(resultDict)
-        Device.update_dev_control_cache(self._device['devNo'], {'allPorts':allPorts,'usedPorts':usedPorts,'usePorts':usePorts})
-
-        #这里存在多线程更新缓存的场景,可能性比较低,但是必须先取出来,然后逐个更新状态,然后再记录缓存
-        ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
-        for strPort,info in resultDict.items():
-            if ctrInfo.has_key(strPort):
-                ctrInfo[strPort].update({'status':info['status']})
-            else:
-                ctrInfo[strPort] = info
-        Device.update_dev_control_cache(self._device['devNo'],ctrInfo)
-
-        return resultDict
-
-    def stop_charging_port(self,port):
-        self.active_deactive_port(port, False)
-
-    def lock_unlock_port(self,port,lock):
-        dev = Device.objects.get(devNo = self._device['devNo'])
-        portKey = 'port%s' % port
-        if lock:
-            dev.otherConf.update({portKey:Const.DEV_WORK_STATUS_FORBIDDEN})
-        else:
-            dev.otherConf.update({portKey:Const.DEV_WORK_STATUS_IDLE})
-
-        dev.save()
-
-        if lock:
-            self.stop_charging_port(port)
-
-        if lock:
-            Device.update_dev_control_cache(self._device['devNo'], {str(port):{'status':Const.DEV_WORK_STATUS_FORBIDDEN}})
-        else:
-            Device.update_dev_control_cache(self._device['devNo'], {str(port):{'status':Const.DEV_WORK_STATUS_IDLE}})
-
-    def active_deactive_port(self,port,active,duration=None):
-        tmpPort = hex(int(port))
-        hexPort = fill_2_hexByte(tmpPort,2)
-
-        if active:
-            strOp = '01'
-        else:
-            strOp = '00'
-        if duration:
-            cmdDict = {'IMEI': self._device['devNo'],"funCode":'20','data':'00' + hexPort + strOp,'duration':int(duration) }
-        else:
-            cmdDict = {'IMEI': self._device['devNo'],"funCode":'20','data':'00' + hexPort + strOp }
-
-        devInfo = MessageSender.send_for_moxiaozhiv2(self.device, self.make_random_cmdcode(),cmdDict)
-
-        if devInfo.has_key('rst') and devInfo['rst'] != 0:
-            if devInfo['rst'] == -1:
-                raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,建议您试试旁边其他设备,或者稍后再试哦'})
-            elif devInfo['rst'] == 1:
-                raise ServiceException({'result': 2, 'description': u'充电桩繁忙,无响应,请试试其他线路,或者稍后再试哦'})
-
-        data = devInfo['data'][18::]
-        if data[0:2] == '01':#表示成功
-            pass
-        else:
-            raise ServiceException({'result': 2, 'description': u'操作和预期不符合,请您选择其他线路,或者稍候再试哦'})
-
-        if not active:#关闭充电桩的端口
-            devInfo = Device.get_dev_control_cache(self._device['devNo'])
-            portCtrInfo = devInfo.get(str(port),{})
-            portCtrInfo.update({'isStart':False,'status':Const.DEV_WORK_STATUS_IDLE,'needTime':0,'leftTime':0,'endTime':datetime.datetime.now().strftime(Const.DATETIME_FMT)})
-            newValue = {str(port):portCtrInfo}
-            Device.update_dev_control_cache(self._device['devNo'], newValue)
-
-        return devInfo
-
-    def test(self, coins):
-        hexPort = fill_2_hexByte(1,2)
-        cmdDict = {'duration':5}
-        cmdDict.update({'IMEI': self._device['devNo'],"funCode":'20','data':'00' + hexPort + '01' })
-
-        devInfo = MessageSender.send_for_moxiaozhiv2(self.device, self.make_random_cmdcode(), cmdDict)
-
-        return devInfo
-
-    def start_device(self, package, openId, attachParas):
-        if attachParas is None:
-            raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
-        if not attachParas.has_key('chargeIndex'):
-            raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
-
-        #如果端口正在使用,不允许重复付款
-        strPort = str(attachParas['chargeIndex'])
-        ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
-        if ctrInfo.__class__.__name__ == 'dict' and ctrInfo.has_key(strPort):
-            portInfo = ctrInfo[strPort]
-            if portInfo.has_key('isStart') and portInfo['isStart']:
-                raise ServiceException({'result': 2, 'description': u'您选择的充电端口正在使用,不允许使用此端口,建议您换其他端口哦!'})
-
-        coins = float(package['coins'])
-        unit = package.get('unit',u'分钟')
-        if unit in [u'分钟',u'小时',u'天']:
-            time1 = int(package['time'])
-            if unit == u'小时':
-                time1 = time1 * 60
-            elif unit == u'天':
-                time1 = time1 * 1440
-
-            devObj = Device.objects.get(devNo = self._device['devNo'])
-            billingType = devObj.otherConf.get('billingType','time')
-            if billingType == 'time':
-                minuteFee = devObj.otherConf.get('minuteFee',0.03)
-                time2 = int(coins/minuteFee)
-                maxValue = int(min(time1,time2))
-                cmdDict = {'duration':maxValue}
-            else:
-                elecFee = devObj.otherConf.get('elecFee',0.9)
-                maxValue = int(coins/elecFee*3600)
-                cmdDict = {'elec':maxValue,'duration':time1}
-        elif unit == u'次':
-            devObj = Device.objects.get(devNo = self._device['devNo'])
-            billingType = devObj.otherConf.get('billingType','time')
-            if billingType == 'time':
-                minuteFee = devObj.otherConf.get('minuteFee',0.03)
-                time2 = int(coins/minuteFee)
-                cmdDict = {'duration':time2}
-            else:
-                elecFee = devObj.otherConf.get('elecFee',0.9)
-                maxValue = int(coins/elecFee*3600)
-                cmdDict = {'elec':maxValue}
-        elif unit == u'度':
-            devObj = Device.objects.get(devNo = self._device['devNo'])
-            billingType = devObj.otherConf.get('billingType','time')
-            if billingType == 'time':
-                minuteFee = devObj.otherConf.get('minuteFee',0.03)
-                time2 = int(coins/minuteFee)
-                cmdDict = {'duration':time2}
-            else:
-                elecConf = float(package['time'])
-                elecFee = devObj.otherConf.get('elecFee',0.9)
-                maxValue = int(min(coins/elecFee*3600,elecConf*3600))
-                cmdDict = {'elec':maxValue}
-
-        tmpPort = hex(int(attachParas['chargeIndex']))
-        hexPort = fill_2_hexByte(tmpPort,2)
-
-        cmdDict.update({'IMEI': self._device['devNo'],"funCode":'20','data':'00' + hexPort + '01' })
-
-        devInfo = MessageSender.send_for_moxiaozhiv2(self.device, self.make_random_cmdcode(),cmdDict,timeout=120)
-
-        if devInfo.has_key('rst') and devInfo['rst'] != 0:
-            if devInfo['rst'] == -1:
-                raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
-            elif devInfo['rst'] == 1:
-                raise ServiceException({'result': 2, 'description': u'充电桩繁忙,无响应,您的金币还在,请试试其他线路,或者稍后再试哦'})
-
-        data = devInfo['data'][18::]
-        if data[0:2] == '01':#表示成功
-            pass
-        else:
-            raise ServiceException({'result': 2, 'description': u'操作和预期不符合,请您选择其他线路,或者稍候再试哦'})
-
-        #刷新状态
-        if package.has_key('time'):
-            needTime = int(float(package.get('time')))
-            newValue = {
-                str(attachParas['chargeIndex']):
-                    {
-                        'status': Const.DEV_WORK_STATUS_WORKING,
-                        'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
-                        'coins': coins,
-                        'isStart': True,
-                        'refunded': False,
-                        'openId': openId,
-                        'needTime': needTime,
-                        'vCardId': self._vcard_id
-                    }
-            }
-        elif package.has_key('power'):
-            newValue = {
-                str(attachParas['chargeIndex']):
-                    {
-                        'status': Const.DEV_WORK_STATUS_WORKING,
-                        'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
-                        'coins': coins,
-                        'isStart': True,
-                        'refunded': False,
-                        'openId': openId,
-                        'needPower': package.get('power'),
-                        'vCardId': self._vcard_id
-                    }
-            }
-
-        Device.update_dev_control_cache(self._device['devNo'], newValue)
-
-        return devInfo
-
-    def analyze_event_data(self,data):
-        cmdCode = data[12:14]
-        if cmdCode == '02':#刷卡
-            cardNo = str(int(data[20:36][-10::]))
-            return {'cardNo':cardNo,'cmdCode':cmdCode}
-        elif cmdCode == '03':#刷卡,启动或者关闭设备
-            portNo = int(data[20:22],16)
-            cardNo = str(int(data[24:40][-10::]))
-            flag = int(data[22:24])
-            if flag == 0:
-                isStart = False
-                return {'cmdCode':cmdCode,'cardNo':cardNo,'port':portNo,'isStart':isStart,'endTime':datetime.datetime.now().strftime(Const.DATETIME_FMT)}
-            else:
-                isStart = True
-                return {'cmdCode':cmdCode,'cardNo':cardNo,'port':portNo,'isStart':isStart,'startTime':datetime.datetime.now().strftime(Const.DATETIME_FMT)}
-        elif cmdCode == '04':
-            portNo = int(data[20:22],16)
-            flag = int(data[22:24])
-            reason = ''
-            if flag == 0:
-                isStart = False
-            else:
-                isStart = True
-                return {'cmdCode':cmdCode,'port':portNo,'isStart':isStart,'reason':reason,'startTime':datetime.datetime.now().strftime(Const.DATETIME_FMT)}
-
-            if not isStart:
-                flag = data[24:26]
-                if flag == '00':
-                    reason = u'电池没有充满!原因未知。'
-                elif flag == '01':
-                    reason = u'可能是电池没有接好,或者电池本身就是满电的。建议您到现场检查是否有人误操作,以尽快恢复充电。'
-                elif flag == '02':
-                    reason =  u'恭喜您!电池已经充满电!'
-                elif flag == '03':
-                    reason = u'警告!您的电池功率超过本机最大限制,已经停止充电,为了公共安全,不建议您在该充电桩充电!提醒您,为了安全大功率的电池不要放入楼道、室内等位置充电哦'
-
-            return {'cmdCode':cmdCode,'port':portNo,'isStart':isStart,'reason':reason,'endTime':datetime.datetime.now().strftime(Const.DATETIME_FMT),'flag':flag}
-        elif cmdCode == '20':
-            portNo = int(data[20:22],16)
-            flag = int(data[22:24])
-            reason = ''
-            if flag == 0:
-                isStart = False
-            else:
-                isStart = True
-                return {'cmdCode':cmdCode,'port':portNo,'isStart':isStart,'reason':reason,'startTime':datetime.datetime.now().strftime(Const.DATETIME_FMT)}
-
-            if not isStart:
-                reason = u'管理人员可能远程断电了,建议您根据已经充电的时间评估是否需要到现场换到其他端口充电。'
-            return {'cmdCode':cmdCode,'port':portNo,'isStart':isStart,'reason':reason,'endTime':datetime.datetime.now().strftime(Const.DATETIME_FMT),'flag':flag}
-
-        return None
-
-    def response_card_balance(self,cardNo,balance):
-        devObj = Device.objects.get(devNo = self._device['devNo'])
-        billingType = devObj.otherConf.get('billingType','time')
-        if billingType == 'time':
-            minuteFee = devObj.otherConf.get('minuteFee',0.03)
-            maxValue = int(float(str(balance))/minuteFee)
-            maxType = 'duration'
-        else:
-            elecFee = devObj.otherConf.get('elecFee',0.9)
-            maxValue = int(float(str(balance))/elecFee*3600)
-            maxType = 'elec'
-
-        data = ''
-        try:
-            if balance == 0:
-                data = '03'
-            else:
-                data = '01' + fill_2_hexByte(hex(int(balance*100)),8)
-        except Exception,e:
-            logger.error('can not find the card=%s' % cardNo)
-            data = '05'
-
-        devInfo = MessageSender.send_for_moxiaozhiv2(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
-                                                     {maxType:maxValue,'IMEI': self._device['devNo'],"funCode":'02','data':data})
-
-        if devInfo.has_key('rst') and devInfo['rst'] != 0:
-            if devInfo['rst'] == -1:
-                raise ServiceException(
-                    {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
-            elif devInfo['rst'] == 1:#等于1的时候,说明服务器和远程模块通讯OK,响应已经收到,不需要异常处理
-                pass
-
-    def response_card_charging(self,result):
-        if result:
-            data = '01'
-        else:
-            data = '00'
-        devInfo = MessageSender.send_for_moxiaozhiv2(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
-                                                     {'IMEI': self._device['devNo'],"funCode":'03','data':data})
-
-        if devInfo.has_key('rst') and devInfo['rst'] != 0:
-            if devInfo['rst'] == -1:
-                raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,建议您试试旁边其他设备,或者稍后再试哦'})
-            elif devInfo['rst'] == 1:
-                pass
-
-    def response_finished_back(self, result):
-        if result:
-            data = '01'
-        else:
-            data = '00'
-        devInfo = MessageSender.send_for_moxiaozhiv2(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
-                                                     {'IMEI': self._device['devNo'],"funCode":'04','data':data})
-
-        if devInfo.has_key('rst') and devInfo['rst'] != 0:
-            if devInfo['rst'] == -1:
-                raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,建议您试试旁边其他设备,或者稍后再试哦'})
-            elif devInfo['rst'] == 1:
-                pass
-
-    def get_power(self):
-        devInfo = MessageSender.send_for_moxiaozhiv2(self.device, self.make_random_cmdcode(),
-                                      {'IMEI': self._device['devNo'],"funCode":'23','data':'00'})
-
-        if devInfo.has_key('rst') and devInfo['rst'] != 0:
-            if devInfo['rst'] == -1:
-                raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,建议您试试旁边其他设备,或者稍后再试哦'})
-            elif devInfo['rst'] == 1:
-                raise ServiceException({'result': 2, 'description': u'充电桩繁忙,无响应,请试试其他线路,或者稍后再试哦'})
-
-        data = devInfo['data'][18::]
-        if data[0:2] == '01':#表示成功
-            pass
-        else:
-            raise ServiceException({'result': 2, 'description': u'获取功率失,请试试其他线路,或者稍后再试哦'})
-
-        powerData = data[2:-8]
-        resultDict = {}
-        for ii in range(len(powerData)/4):
-            port = ii + 1
-            status = powerData[ii*4:ii*4+4]
-            resultDict[str(port)] = int(status,16)
-
-        return resultDict
-
-
-    #目前支持按时间计费,后续支持按照电量计费的方式
-    def calc_consume_money(self, spendTime, elec):
-
-        try:
-            dev = Device.objects.get(devNo = self._device['devNo'])
-        except Exception, e:
-            logger.error('can not find the dev=%s' % self._device['devNo'])
-            return RMB(0)
-
-        billingType = dev.otherConf.get('billingType', 'time')
-        if billingType == 'time':
-            minuteFee = dev.otherConf.get('minuteFee', 0.03)
-            return RMB(1) * spendTime * minuteFee, u'时间计费'
-        else:
-            elecFee = dev.otherConf.get('elecFee', 0.9)
-            return RMB(1) * elecFee * elec, u'电度计费'
-
-    def get_dev_setting(self):
-        try:
-            dev = Device.objects.get(devNo = self._device['devNo'])
-        except Exception,e:
-            logger.error('can not find the dev=%s' % self._device['devNo'])
-            return {}
-
-        minuteFee = dev.otherConf.get('minuteFee',0.03)
-        elecFee = dev.otherConf.get('elecFee',0.9)
-        billingType = dev.otherConf.get('billingType','time')
-
-        return {'minuteFee':minuteFee,'elecFee':elecFee,'billingType':billingType}
-
-    def set_dev_setting(self,conf):
-        try:
-            dev = Device.objects.get(devNo = self._device['devNo'])
-        except Exception,e:
-            logger.error('can not find the dev=%s' % self._device['devNo'])
-            return 0
-        if conf.has_key('minuteFee'):
-            dev.otherConf.update({'minuteFee':conf['minuteFee']})
-        if conf.has_key('elecFee'):
-            dev.otherConf.update({'elecFee':conf['elecFee']})
-        if conf.has_key('billingType'):
-            dev.otherConf.update({'billingType':conf['billingType']})
-
-        try:
-            dev.save()
-        except Exception,e:
-            logger.exception('save dev=%s conf error=%s' % (self._device['devNo'],e))
-
-    def set_device_function_param(self,request,lastSetConf):
-        minuteFee = float(request.POST.get('minuteFee', None))
-        if minuteFee:
-            lastSetConf.update({'minuteFee': float(minuteFee)})
-
-        elecFee = float(request.POST.get('elecFee', None))
-        if elecFee:
-            lastSetConf.update({'elecFee': float(elecFee)})
-
-        billingType = request.POST.get('billingType', 'time')
-        if billingType:
-            lastSetConf.update({'billingType': billingType})
-
-        minuteFee = request.POST.get('minuteFee', None)
-        if minuteFee:
-            lastSetConf.update({'minuteFee': float(minuteFee)})
-
-        self.set_dev_setting(lastSetConf)

+ 0 - 64
apps/web/core/adapter/mxzv3.py

@@ -1,64 +0,0 @@
-# -*- coding: utf-8 -*-
-import apps.web.core.adapter.jndz
-reload(apps.web.core.adapter.jndz)
-
-from apps.web.core.adapter.jndz import *
-
-class ChargingMXZ3Box(ChargingJNDZBox):
-    def __init__(self, device):
-        super(ChargingMXZ3Box, self).__init__(device)
-    
-    def get_dev_setting(self):
-        resultDict = super(ChargingMXZ3Box,self).get_dev_setting()
-        #针对墨小智V3的,还有几个参数,需要特殊处理下
-        devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
-                                     {'IMEI': self._device['devNo'], "funCode": '1F', 'data': '00'})
-        
-        if devInfo.has_key('rst') and devInfo['rst'] != 0:
-            if devInfo['rst'] == -1:
-                raise ServiceException(
-                    {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
-            elif devInfo['rst'] == 1:
-                raise ServiceException(
-                    {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
-
-        data = devInfo['data'][6::]
-        if data[0:2] == '01':#表示成功
-            pass
-        else:
-            raise ServiceException({'result': 2, 'description': u'操作端口失败,请重试看能否解决'})
-
-        confData = data[2:-2]
-        stWTime = int(confData[0:2],16)
-        temThre = int(confData[2:4],16)
-        freeUse = int(confData[4:6],16)
-        temValue = int(confData[6:8],16)
-        
-        resultDict.update({'stWTime':stWTime,'temThre':temThre,'freeUse':freeUse,'temValue':temValue})
-        
-        return resultDict
-    
-    def set_dev_setting(self,setConf):
-        super(ChargingMXZ3Box,self).set_dev_setting(setConf)
-        data = ''
-        data += fill_2_hexByte(hex(int(setConf['stWTime'])),2)
-        data += fill_2_hexByte(hex(int(setConf['temThre'])),2)
-        data += fill_2_hexByte(hex(int(setConf['freeUse'])),2)
-        
-        devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
-                                     {'IMEI': self._device['devNo'], "funCode": '19', 'data': data})
-        
-        if devInfo.has_key('rst') and devInfo['rst'] != 0:
-            if devInfo['rst'] == -1:
-                raise ServiceException(
-                    {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
-            elif devInfo['rst'] == 1:
-                raise ServiceException(
-                    {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
-
-        data = devInfo['data'][6::]
-        if data[0:2] == '01':#表示成功
-            pass
-        else:
-            raise ServiceException({'result': 2, 'description': u'操作端口失败,请重试看能否解决'})
-        

+ 2 - 0
apps/web/dealer/tasks.py

@@ -28,7 +28,9 @@ from apps.web.constant import Const, RechargeRecordVia, USER_RECHARGE_TYPE, AppP
 from apps.web.constant import DEALER_CONSUMPTION_AGG_KIND_TRANSLATION, MONTH_DATE_KEY
 from apps.web.constant import DEALER_CONSUMPTION_AGG_KIND_TRANSLATION, MONTH_DATE_KEY
 from apps.web.core.exceptions import InsufficientFundsError
 from apps.web.core.exceptions import InsufficientFundsError
 from apps.web.core.helpers import ActionDeviceBuilder
 from apps.web.core.helpers import ActionDeviceBuilder
+from apps.web.core.messages import SmsVendorCode
 from apps.web.core.messages.sms import SMSSender
 from apps.web.core.messages.sms import SMSSender
+from apps.web.core.sysparas import SysParas
 from apps.web.core.utils import generate_excel_report, gernerate_excel_report_for_sheet
 from apps.web.core.utils import generate_excel_report, gernerate_excel_report_for_sheet
 from apps.web.dealer.accessors import income_business_stat, consume_business_stat, monthly_business_stat
 from apps.web.dealer.accessors import income_business_stat, consume_business_stat, monthly_business_stat
 from apps.web.dealer.define import DEALER_INCOME_TYPE, DEALER_INCOME_SOURCE
 from apps.web.dealer.define import DEALER_INCOME_TYPE, DEALER_INCOME_SOURCE

+ 3 - 3
apps/web/device/views.py

@@ -34,8 +34,8 @@ from apps.web.core.networking import MessageSender
 from apps.web.core.utils import JsonErrorResponse, JsonOkResponse
 from apps.web.core.utils import JsonErrorResponse, JsonOkResponse
 from apps.web.dealer.models import Dealer
 from apps.web.dealer.models import Dealer
 from apps.web.device.define import DeviceChannelType
 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.models import Device, DeviceType, Group, MajorDeviceType, DeviceCommand, Cell, ManagerInputDev, \
+    SwapGroup, FaultRecord
 from apps.web.device.timescale import OfflineCoinsManager
 from apps.web.device.timescale import OfflineCoinsManager
 from apps.web.device.validation import equipGroupSchema
 from apps.web.device.validation import equipGroupSchema
 from apps.web.exceptions import CustomizedValidationError
 from apps.web.exceptions import CustomizedValidationError
@@ -45,7 +45,7 @@ from apps.web.south_intf.swap_carcharger import SwapContract
 from apps.web.south_intf.yuhuan_fire import YuhuanNorther
 from apps.web.south_intf.yuhuan_fire import YuhuanNorther
 from apps.web.user.models import MyUser, Card
 from apps.web.user.models import MyUser, Card
 from apps.web.utils import (
 from apps.web.utils import (
-    translate_sendmsg_error, permission_required, pluckPayload, error_tolerate,
+    translate_sendmsg_error, permission_required, error_tolerate,
     check_role, record_operation_behavior, concat_user_login_entry_url, concat_user_center_entry_url
     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 apps.web.wrapper import request_limit_by_user

+ 0 - 274
apps/web/eventer/mxzv2.py

@@ -1,274 +0,0 @@
-# -*- coding: utf-8 -*-
-# !/usr/bin/env python
-
-import datetime
-import logging
-
-from mongoengine import DoesNotExist
-
-from apilib.monetary import RMB
-from apilib.utils_datetime import to_datetime
-from apps.web.constant import Const
-from apps.web.device.models import Group, Device
-from apps.web.eventer.base import WorkEvent
-from apps.web.eventer import EventBuilder
-from apps.web.south_intf.platform import notify_event_to_north
-from apps.web.user.models import ServiceProgress, UserVirtualCard, VCardConsumeRecord, Card, MyUser, CardRechargeOrder
-from apps.web.user.transaction_deprecated import refund_money
-
-logger = logging.getLogger(__name__)
-
-
-class builder(EventBuilder):
-    def __getEvent__(self, device_event):
-        event_data = self.deviceAdapter.analyze_event_data(device_event['data'])
-
-        if event_data is None or 'cmdCode' not in event_data:
-            return None
-
-        if 'duration' in device_event:
-            event_data.update({'duration': device_event['duration']})
-
-        if 'elec' in device_event:
-            event_data.update({'elec': device_event['elec']})
-
-        if event_data['cmdCode'] in ['02', '03', '04', '20']:
-            return ChargingMOXIAOZHI2WorkEvent(self.deviceAdapter, event_data)
-
-        return None
-
-
-class ChargingMOXIAOZHI2WorkEvent(WorkEvent):
-    def do(self, **args):
-        devNo = self.device['devNo']
-
-        logger.info('moxiaozhi2 charging event detected, devNo=%s' % (devNo,))
-
-        smartBox = self.deviceAdapter
-        if self.event_data['cmdCode'] == '02':  # 刷卡,用于查询余额.如果发现有充值订单,马上下发充值
-            cardNo = self.event_data['cardNo']
-
-            card = self.update_card_dealer_and_type(cardNo, 'ID')  # type: Card
-
-            card_recharge_order = CardRechargeOrder.get_last_to_do_one(str(card.id))  # type: CardRechargeOrder
-            result = self.recharge_id_card(card = card,
-                                           rechargeType = 'append',
-                                           order = card_recharge_order)
-
-            card.reload()
-
-            # 如果卡挂失,直接余额为0
-            if card.frozen:
-                balance = RMB(0)
-            else:
-                balance = result['balance']
-
-            try:
-                smartBox.response_card_balance(cardNo, balance)
-            except Exception, e:
-                logger.error('response card balance error=%s' % e)
-                return
-
-        elif self.event_data['cmdCode'] == '03':  # 刷卡,开始结束充电。刷卡是后扣费,移动支付是先扣费,后退费
-            group = Group.get_group(self.device['groupId'])
-            portInfo = Device.update_port_control_cache(self.device['devNo'], self.event_data, 'overwrite')
-            port = portInfo['port']
-            card = self.update_card_dealer_and_type(portInfo['cardNo'], 'ID')
-            portInfo['openId'] = card.openId
-            portInfo['cardId'] = str(card.id)
-            portInfo['startTime'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-            self.event_data.update({'isStart': True, 'status': Const.DEV_WORK_STATUS_WORKING})
-            Device.update_port_control_cache(self.device['devNo'], portInfo)
-
-            # 如果是开始报文,最重要的是刷新内存计费相关数据,前面代码已经完成.刷卡不预扣费,等待结束后,直接扣费
-            if portInfo['isStart']:  # 如果是刷卡启动的,禁用的端口不允许充电
-                isNormal = True
-                otherConf = Device.objects.get(devNo = self.device['devNo']).otherConf
-                if otherConf.has_key(str(port)) and otherConf[str(port)] == Const.DEV_WORK_STATUS_FORBIDDEN:
-                    logger.info('this port is forbidden port=%s' % (port,))
-                    isNormal = False
-
-                # 刷卡启动,需要等级正在服务的progress
-                ServiceProgress.register_card_service(self.device, port, card)
-
-                try:
-                    smartBox.response_card_charging(isNormal)
-                except Exception, e:
-                    logger.exception('response card=%s e=%s' % (portInfo['cardNo'], e))
-
-            else:
-                #: 结束,就需要扣费咯.先支持按时间扣费,后续再支持按电量扣费 ------------比较奇怪,从来没有收到这个协议
-                #: 回复设备
-                try:
-                    smartBox.response_card_charging(True)
-                except Exception, e:
-                    logger.exception('response devNo=%s card charging e=%s' % (self.device['devNo'], e))
-
-                if self.event_data.has_key('duration') and self.event_data['duration'] > 0:
-                    duration = self.event_data['duration']
-                else:
-                    duration = (to_datetime(portInfo['endTime']) - to_datetime(
-                        portInfo['startTime'])).total_seconds() / 60.0
-
-                if duration < 0:
-                    duration = 0
-
-                if self.event_data.has_key('elec'):
-                    consumeElec = round(self.event_data['elec'] / 3600.0, 4)
-                else:
-                    consumeElec = 0.03 * duration / 0.9  # 这里做个特殊的保护,只有模块出现异常的时候,但是需要计费
-
-                if consumeElec < 0:
-                    consumeElec = 0
-
-                consumeMoney, desc = smartBox.calc_consume_money(duration, consumeElec)
-                card = self.update_card_dealer_and_type(portInfo['cardNo'], 'ID')
-                self.consume_money_for_card(card, consumeMoney)
-                self.record_consume_for_card(card, consumeMoney, desc = u'充电时间:%s分钟,充电电量%s度' % (duration, consumeElec))
-
-                desc = u'您本次充电约:%s分钟,收费标准为:%s,共计花费:%s元' % (duration, desc, consumeMoney)
-
-                self.notify_balance_has_consume_for_card(card, consumeMoney)
-                self.notify_user(card.managerialOpenId if card else '', 'service_complete',
-                                 **{
-                                     'title': desc,
-                                     'service': u'充电服务(设备编号:%s,端口:%s 地址:%s)' % (
-                                         self.device['logicalCode'], port, group['address']),
-                                     'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
-                                     'remark': u'谢谢您的支持'
-                                 })
-
-        elif self.event_data['cmdCode'] in ['04', '20']:  # 收到的结束事件
-            portInfo = Device.update_port_control_cache(self.device['devNo'], self.event_data)
-            port = self.event_data['port']
-
-            try:
-                # 回复设备,04号报文是设备主动停止的,所以需要我们回复一条消息过去
-                if self.event_data['cmdCode'] == '04':
-                    try:
-                        smartBox.response_finished_back(True)
-                    except Exception, e:
-                        logger.error('response devNo=%s card charging e=%s' % (self.device['devNo'], e))
-
-                # 如果是开始报文,最重要的是刷新内存计费相关数据,前面代码已经完成.刷卡不预扣费,等待结束后,直接扣费
-                if self.event_data['isStart']:
-                    pass
-                else:  # 结束,就需要扣费咯.支持按时间扣费,也支持按电量扣费
-                    if self.event_data.has_key('duration') and self.event_data['duration'] > 0:
-                        duration = self.event_data['duration']
-                    else:
-                        duration = (datetime.datetime.now() - to_datetime(portInfo['startTime'])).total_seconds() / 60.0
-                    if duration < 0:
-                        duration = 0
-
-                    if self.event_data.has_key('elec'):
-                        consumeElec = round(self.event_data['elec'] / 3600.0, 4)
-                    else:
-                        consumeElec = 0.03 * duration / 0.9  # 这里做个特殊的保护,只有模块出现异常的时候,但是需要计费
-                    if consumeElec < 0:
-                        consumeElec = 0
-
-                    if (not portInfo.has_key('cardNo')) and portInfo.has_key('openId') and (
-                    not portInfo.has_key('consumeRcdId')):  # 非刷卡的是退费,刷卡的结束扣费。两种方式不一样
-                        consumeMoney, descFee = smartBox.calc_consume_money(duration, consumeElec)
-                        backMoney = RMB(portInfo['coins']) - consumeMoney
-                        if backMoney > RMB(0):
-                            refund_money(self.device, backMoney, portInfo['openId'])
-                        else:
-                            backMoney = RMB(0)
-
-                        desc = u'您本次充电使用%s号端口,共计:%s分钟,收费标准为:%s,共计花费:%s元,您预支了:%s元,退回:%s元到您的个人中心中。' % \
-                               (port, duration, descFee, consumeMoney, portInfo['coins'], backMoney)
-
-                        consumeDict = {'reason': self.event_data['reason'], 'duration': duration,
-                                       'feeType': descFee, 'refundedMoney': str(backMoney),
-                                       'spendMoney': str(consumeMoney), 'chargeIndex': port}
-                        ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
-                                                                        {'open_id': portInfo['openId'], 'port': port,
-                                                                         'device_imei': self.device['devNo'],
-                                                                         'isFinished': False},
-                                                                        consumeDict)
-
-                        user = MyUser.objects(openId = portInfo['openId'], groupId = self.device['groupId']).first()
-                        self.notify_user(user.managerialOpenId if user else '', 'refund_coins',
-                                         **{
-                                             'title': '%s%s' % (self.event_data['reason'], desc),
-                                             'backCount': u'金币:%s' % backMoney,
-                                             'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-                                         })
-
-                        self.notify_charging_finished(user.managerialOpenId if user else '')
-
-                    elif portInfo.has_key('consumeRcdId'):
-                        consumeMoney, descFee = smartBox.calc_consume_money(duration, consumeElec)
-                        backMoney = RMB(portInfo['coins']) - consumeMoney
-                        if backMoney < RMB(0):
-                            backMoney = RMB(0)
-
-                        desc = u'您本次充电使用%s号端口,共计:%s分钟,收费标准为:%s,共计花费:%s元,您预支了:%s元,退回:%s元到您的个人中心中。' % \
-                               (port, duration, descFee, consumeMoney, portInfo['coins'], backMoney)
-
-                        consumeDict = {'reason': self.event_data['reason'], 'duration': duration,
-                                       'feeType': descFee, 'chargeIndex': port}
-                        ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
-                                                                        {'open_id': portInfo['openId'], 'port': port,
-                                                                         'device_imei': self.device['devNo'],
-                                                                         'isFinished': False},
-                                                                        consumeDict)
-
-                        # 退额度
-                        try:
-                            vCardId = portInfo['vCardId']
-                            vCard = UserVirtualCard.objects.get(id = vCardId)
-                        except DoesNotExist, e:
-                            logger.info('can not find the vCard id = %s' % vCardId)
-                            return
-
-                        self.notify_user(self.get_managerialOpenId_by_openId(portInfo['openId']) if vCard else '',
-                                         'refund_coins',
-                                         **{
-                                             'title': '%s%s' % (self.event_data['reason'], desc),
-                                             'backCount': u'金币:%s' % backMoney,
-                                             'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-                                         })
-
-                        consumeRcdId = portInfo.get('consumeRcdId', None)
-                        if consumeRcdId is None:
-                            logger.info('can not find consume rcd id')
-                            return
-                        try:
-                            vCardConsumeRcd = VCardConsumeRecord.objects.get(id = consumeRcdId)
-                        except DoesNotExist, e:
-                            logger.info('can not find the consume rcd id = %s' % consumeRcdId)
-                            return
-
-                        vCard.refund_quota(vCardConsumeRcd, duration, consumeElec, backMoney.mongo_amount)
-
-                    elif portInfo.has_key('cardNo'):
-                        card = self.update_card_dealer_and_type(portInfo['cardNo'], 'ID')
-                        consumeMoney, descFee = smartBox.calc_consume_money(duration, consumeElec)
-                        self.consume_money_for_card(card, consumeMoney)
-
-                        desc = u'您本次充电使用%s号端口,共计:%s分钟,收费标准为:%s,共计花费:%s元' % \
-                               (port, duration, descFee, consumeMoney)
-
-                        consumeDict = {'reason': self.event_data['reason'], 'duration': duration,
-                                       'feeType': descFee, 'spendMoney': str(consumeMoney),
-                                       'chargeIndex': port}
-
-                        self.record_consume_for_card(card, consumeMoney,
-                                                     desc = u'充电时间:%s分钟' % duration,
-                                                     servicedInfo = consumeDict)
-
-                        ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
-                                                                        {'cardId': str(card.id), 'port': port,
-                                                                         'device_imei': self.device['devNo'],
-                                                                         'isFinished': False},
-                                                                        consumeDict, False)
-
-                        self.notify_balance_has_consume_for_card(card, consumeMoney, desc)
-                        self.notify_charging_finished(card.managerialOpenId)
-            finally:
-                Device.clear_port_control_cache(self.device['devNo'], str(port))
-                notify_event_to_north(self.dealer, self.device, level = Const.EVENT_NORMAL,
-                                      desc = self.event_data['reason'])

+ 3 - 0
apps/web/superadmin/tasks.py

@@ -3,6 +3,7 @@
 
 
 import datetime
 import datetime
 import os
 import os
+import time
 from collections import OrderedDict
 from collections import OrderedDict
 
 
 import pandas
 import pandas
@@ -17,6 +18,8 @@ from apps.thirdparties.dingding import DingDingRobot
 from apps.web.agent.define import AgentConst
 from apps.web.agent.define import AgentConst
 from apps.web.agent.models import Agent
 from apps.web.agent.models import Agent
 from apps.web.constant import Const, ComplaintResponseTemplate
 from apps.web.constant import Const, ComplaintResponseTemplate
+from apps.web.core.bridge.wechat import MyWechatClientV3
+from apps.web.core.models import WechatChannelApp
 from apps.web.core.payment import WithdrawGateway
 from apps.web.core.payment import WithdrawGateway
 from apps.web.core.utils import generate_excel_report
 from apps.web.core.utils import generate_excel_report
 from apps.web.dealer.define import DealerConst
 from apps.web.dealer.define import DealerConst

+ 2 - 1
apps/web/superadmin/views.py

@@ -28,6 +28,7 @@ from apps.web.common.models import AddressType, FAQ, WithdrawBankCard, WithdrawB
 from apps.web.common.models import Feature
 from apps.web.common.models import Feature
 from apps.web.constant import Const, SimStatus
 from apps.web.constant import Const, SimStatus
 from apps.web.core import ROLE
 from apps.web.core import ROLE
+from apps.web.core.bridge.wechat import WechatClientProxy
 from apps.web.core.exceptions import InvalidFileSize, InvalidFileName, \
 from apps.web.core.exceptions import InvalidFileSize, InvalidFileName, \
     ManagerServiceTimeOutException, ManagerServiceSerialException, ServiceException, RentDeviceError
     ManagerServiceTimeOutException, ManagerServiceSerialException, ServiceException, RentDeviceError
 from apps.web.core.file import AliOssFileUploader
 from apps.web.core.file import AliOssFileUploader
@@ -51,7 +52,7 @@ from apps.web.superadmin.models import SuperManager, WebLog
 from apps.web.user.models import RechargeRecord, ConsumeRecord
 from apps.web.user.models import RechargeRecord, ConsumeRecord
 from apps.web.user.transaction_deprecated import refund_cash
 from apps.web.user.transaction_deprecated import refund_cash
 from apps.web.utils import permission_required, error_tolerate, super_manager_login, trace_call
 from apps.web.utils import permission_required, error_tolerate, super_manager_login, trace_call
-from apps.web.validation import SaveWithdrawBankCardSchema, SavePublicWithdrawBankCardExtraSchema, \
+from apps.web.validation import SavePublicWithdrawBankCardExtraSchema, \
     SaveWithdrawBankCardSchemaForSuper
     SaveWithdrawBankCardSchemaForSuper
 from library.qiben import SimManager
 from library.qiben import SimManager
 from taskmanager.mediator import task_caller
 from taskmanager.mediator import task_caller

+ 1 - 1
apps/web/user/models.py

@@ -52,7 +52,7 @@ from apps.web.constant import (Const,
                                DEVICE_INCOME_STRATEGY, support_policy_device, support_policy_weifule,
                                DEVICE_INCOME_STRATEGY, support_policy_device, support_policy_weifule,
                                PARTITION_ROLE)
                                PARTITION_ROLE)
 from apps.web.core import PayAppType, ROLE
 from apps.web.core import PayAppType, ROLE
-from apps.web.core.bridge import WechatClientProxy
+from apps.web.core.bridge.wechat import WechatClientProxy
 from apps.web.core.db import Searchable, MonetaryField, VirtualCoinField, RoleBaseDocument, BooleanIntField
 from apps.web.core.db import Searchable, MonetaryField, VirtualCoinField, RoleBaseDocument, BooleanIntField
 from apps.web.core.exceptions import InsufficientFundsError, ServiceException, ImproperlyOperatedBalance
 from apps.web.core.exceptions import InsufficientFundsError, ServiceException, ImproperlyOperatedBalance
 from apps.web.core.models import BoundOpenInfo
 from apps.web.core.models import BoundOpenInfo

+ 1 - 1
apps/web/user/tasks.py

@@ -13,7 +13,7 @@ from apps.web.agent.models import Agent
 from apps.web.common.transaction.pay import PayManager
 from apps.web.common.transaction.pay import PayManager
 from apps.web.common.transaction.refund import RefundManager
 from apps.web.common.transaction.refund import RefundManager
 from apps.web.constant import Const
 from apps.web.constant import Const
-from apps.web.core.bridge import WechatClientProxy
+from apps.web.core.bridge.wechat import WechatClientProxy
 from apps.web.core.helpers import ActionDeviceBuilder
 from apps.web.core.helpers import ActionDeviceBuilder
 from apps.web.core.models import WechatUserManagerApp, WechatUserSubscribeManagerApp
 from apps.web.core.models import WechatUserManagerApp, WechatUserSubscribeManagerApp
 from apps.web.core.payment import PaymentGateway
 from apps.web.core.payment import PaymentGateway

+ 8 - 14
apps/web/user/utils.py

@@ -5,13 +5,9 @@ import datetime
 import hashlib
 import hashlib
 import json
 import json
 import logging
 import logging
-import os
-import string
 import time
 import time
 import traceback
 import traceback
-import urllib
-import urlparse
-from collections import defaultdict, OrderedDict
+from collections import defaultdict
 from decimal import Decimal
 from decimal import Decimal
 from functools import wraps, partial
 from functools import wraps, partial
 
 
@@ -20,25 +16,23 @@ from aliyunsdkcore.http.method_type import GET
 from django.conf import settings
 from django.conf import settings
 from django.core.cache import cache
 from django.core.cache import cache
 from django.utils.module_loading import import_string
 from django.utils.module_loading import import_string
-from mongoengine import NotUniqueError, DoesNotExist, MultipleObjectsReturned, Q
-from requests.exceptions import ConnectTimeout
-from typing import TYPE_CHECKING, Optional, Union, Dict
+from mongoengine import NotUniqueError, DoesNotExist, Q
+from typing import TYPE_CHECKING, Optional, Dict
 
 
 from apilib.monetary import VirtualCoin, RMB, Ratio
 from apilib.monetary import VirtualCoin, RMB, Ratio
 from apilib.utils import fix_dict
 from apilib.utils import fix_dict
 from apilib.utils_json import JsonResponse
 from apilib.utils_json import JsonResponse
-from apilib.utils_string import cn, get_random_str
+from apilib.utils_string import cn
 from apilib.utils_url import before_frag_add_query
 from apilib.utils_url import before_frag_add_query
 from apps import serviceCache
 from apps import serviceCache
 from apps.web.agent.models import Agent, MoniApp
 from apps.web.agent.models import Agent, MoniApp
-from apps.web.common.models import ExceptionLog, MonthlyPackageTemp
-from apps.web.common.proxy import ClientConsumeModelProxy
+from apps.web.common.models import ExceptionLog
 from apps.web.common.transaction import OrderNoMaker, OrderMainType, UserPaySubType
 from apps.web.common.transaction import OrderNoMaker, OrderMainType, UserPaySubType
 from apps.web.constant import Const, ErrorCode, USER_RECHARGE_TYPE, APP_TYPE, AppPlatformType
 from apps.web.constant import Const, ErrorCode, USER_RECHARGE_TYPE, APP_TYPE, AppPlatformType
 from apps.web.core import PayAppType, ROLE
 from apps.web.core import PayAppType, ROLE
 from apps.web.core.accounting import Accounting
 from apps.web.core.accounting import Accounting
 from apps.web.core.auth.wechat import WechatAuthBridge
 from apps.web.core.auth.wechat import WechatAuthBridge
-from apps.web.core.bridge import WechatClientProxy
+from apps.web.core.bridge.wechat import WechatClientProxy
 from apps.web.core.exceptions import ServiceException, InvalidParameter, InterceptException
 from apps.web.core.exceptions import ServiceException, InvalidParameter, InterceptException
 from apps.web.core.helpers import ActionDeviceBuilder
 from apps.web.core.helpers import ActionDeviceBuilder
 from apps.web.core.models import WechatPayApp, WechatAuthApp
 from apps.web.core.models import WechatPayApp, WechatAuthApp
@@ -47,12 +41,12 @@ from apps.web.device.define import DeviceChannelType
 from apps.web.device.models import Device, Group
 from apps.web.device.models import Device, Group
 from apps.web.exceptions import UserServerException
 from apps.web.exceptions import UserServerException
 from apps.web.helpers import get_wechat_auth_bridge, get_wechat_user_manager_mp_proxy, get_app, get_user_manager_agent, \
 from apps.web.helpers import get_wechat_auth_bridge, get_wechat_user_manager_mp_proxy, get_app, get_user_manager_agent, \
-    DealerCustomizedBrandVisitor, AgentCustomizedBrandVisitor, get_platform_promotion_pay_gateway
+    AgentCustomizedBrandVisitor, get_platform_promotion_pay_gateway
 from apps.web.report.ledger import Ledger
 from apps.web.report.ledger import Ledger
 from apps.web.user import Cookies, UserAuthState
 from apps.web.user import Cookies, UserAuthState
 from apps.web.user.conf import USER_AUTH_REDIRECT_URL
 from apps.web.user.conf import USER_AUTH_REDIRECT_URL
 from apps.web.user.models import MyUser, Card, RechargeRecord, UserVirtualCard, \
 from apps.web.user.models import MyUser, Card, RechargeRecord, UserVirtualCard, \
-    ServiceProgress, ConsumeRecord, MoniUser, BlackListUsers, Redpack, MyUserDetail
+    ConsumeRecord, MoniUser, BlackListUsers, Redpack, MyUserDetail
 from apps.web.user.payments import gen_quick_pay_purchase_subject, gen_recharge_purchase_subject
 from apps.web.user.payments import gen_quick_pay_purchase_subject, gen_recharge_purchase_subject
 from apps.web.user.utils2 import ConsumeOrderStateEngine
 from apps.web.user.utils2 import ConsumeOrderStateEngine
 from apps.web.utils import supported_app, detect_wechat_client, detect_alipay_client, detect_jdpay_client, \
 from apps.web.utils import supported_app, detect_wechat_client, detect_alipay_client, detect_jdpay_client, \

+ 15 - 1
library/jdpsi/client.py

@@ -4,6 +4,8 @@
 import base64
 import base64
 import datetime
 import datetime
 import hashlib
 import hashlib
+from decimal import Decimal
+
 import simplejson as json
 import simplejson as json
 import logging
 import logging
 import random
 import random
@@ -15,7 +17,8 @@ from urlparse import urljoin
 import requests
 import requests
 from Crypto.Cipher import DES3
 from Crypto.Cipher import DES3
 
 
-from apilib.monetary import JDMerchantPermillage
+from apilib.monetary import Permillage
+from apilib.numerics import quantize
 from library.jdbase.exceptions import JDNetworkException
 from library.jdbase.exceptions import JDNetworkException
 from library.jdpsi.constants import JdPsiErrorCode
 from library.jdpsi.constants import JdPsiErrorCode
 from library.jdpsi.exceptions import JdPsiException
 from library.jdpsi.exceptions import JdPsiException
@@ -23,6 +26,17 @@ from library.jdpsi.exceptions import JdPsiException
 logger = logging.getLogger(__name__)
 logger = logging.getLogger(__name__)
 
 
 
 
+class JDMerchantPermillage(Permillage):
+
+    def to_jd_params(self):
+        """
+        打印出来的是百分之多少 比如设定的是JDMerchantPermillage(6) 表示是千分之6
+        则使用str之后 显示的是 0.60
+        :return:
+        """
+        return u'{amount:.2f}'.format(amount=quantize((self * Decimal('0.1'))._amount, places='0.01'))
+
+
 class MyEncoder(json.JSONEncoder):
 class MyEncoder(json.JSONEncoder):
 
 
     def default(self, obj):
     def default(self, obj):