mopybird před 2 roky
rodič
revize
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.core import PayAppType, APP_KEY_DELIMITER, ROLE
 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.models import WechatManagerApp, WechatAuthApp, BoundOpenInfo, AliApp, WechatPayApp, \
     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.core.exceptions import InsufficientFundsError
 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.sysparas import SysParas
 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.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.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.models import Device, DeviceType, Group, MajorDeviceType, DeviceCommand, Cell, ManagerInputDev, \
+    SwapGroup, FaultRecord
 from apps.web.device.timescale import OfflineCoinsManager
 from apps.web.device.validation import equipGroupSchema
 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.user.models import MyUser, Card
 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
 )
 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 os
+import time
 from collections import OrderedDict
 
 import pandas
@@ -17,6 +18,8 @@ from apps.thirdparties.dingding import DingDingRobot
 from apps.web.agent.define import AgentConst
 from apps.web.agent.models import Agent
 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.utils import generate_excel_report
 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.constant import Const, SimStatus
 from apps.web.core import ROLE
+from apps.web.core.bridge.wechat import WechatClientProxy
 from apps.web.core.exceptions import InvalidFileSize, InvalidFileName, \
     ManagerServiceTimeOutException, ManagerServiceSerialException, ServiceException, RentDeviceError
 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.transaction_deprecated import refund_cash
 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
 from library.qiben import SimManager
 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,
                                PARTITION_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.exceptions import InsufficientFundsError, ServiceException, ImproperlyOperatedBalance
 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.refund import RefundManager
 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.models import WechatUserManagerApp, WechatUserSubscribeManagerApp
 from apps.web.core.payment import PaymentGateway

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

@@ -5,13 +5,9 @@ import datetime
 import hashlib
 import json
 import logging
-import os
-import string
 import time
 import traceback
-import urllib
-import urlparse
-from collections import defaultdict, OrderedDict
+from collections import defaultdict
 from decimal import Decimal
 from functools import wraps, partial
 
@@ -20,25 +16,23 @@ from aliyunsdkcore.http.method_type import GET
 from django.conf import settings
 from django.core.cache import cache
 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.utils import fix_dict
 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 apps import serviceCache
 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.constant import Const, ErrorCode, USER_RECHARGE_TYPE, APP_TYPE, AppPlatformType
 from apps.web.core import PayAppType, ROLE
 from apps.web.core.accounting import Accounting
 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.helpers import ActionDeviceBuilder
 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.exceptions import UserServerException
 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.user import Cookies, UserAuthState
 from apps.web.user.conf import USER_AUTH_REDIRECT_URL
 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.utils2 import ConsumeOrderStateEngine
 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 datetime
 import hashlib
+from decimal import Decimal
+
 import simplejson as json
 import logging
 import random
@@ -15,7 +17,8 @@ from urlparse import urljoin
 import requests
 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.jdpsi.constants import JdPsiErrorCode
 from library.jdpsi.exceptions import JdPsiException
@@ -23,6 +26,17 @@ from library.jdpsi.exceptions import JdPsiException
 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):
 
     def default(self, obj):