hxp
2020-12-03 19e0109ec1e936204cb85362d2e3f705b8b9554c
Tool/WebCenter/CouponCode/webapp.py
@@ -24,6 +24,7 @@
from lib import mylog, CommFunc
import os.path
import zipfile
import time
# get: request.query.username request.GET.get('username','')
# post: request.forms.get('username')  request.POST.get('username')
@@ -58,6 +59,15 @@
                
myapp = Bottle()
# 防止短时间内的多次无效访问 accid:time
AccID_Cache_Dict = {}
def CleanAccID():
    global AccID_Cache_Dict
    if len(AccID_Cache_Dict) < 100:
        return
    AccID_Cache_Dict = {}
#/api/Coupon/index.php?couponBatchId=%s&agentName=%s"
@@ -98,11 +108,25 @@
    return static_file("%s.zip"%couponid, r".\download", download=True)
# 卡类型 开头字母做标识如 g1~999代表此卡只能使用一次 h1~999卡可以重复使用 z开头代表固定码
#================客户端请求参数===============================================================
# channel    是    string    Appid 如jsgameios
# code    是    string    兑换码
# accid    是    string    账号
# spid    是    string    运营商ID,研发自己配置的,如jisu代表极速平台
# sid    是    int    服务器ID 数字
# pushurl    是    string    域名链接s222.xxx.com
# roleid    是    string    玩家游戏名
# level    是    int    玩家等级
# viplevel    是    Int    玩家VIP等级
#===============================================================================
#2018.10.10 混服支持导致账号拼接逻辑变更需要spid
# 卡类型 开头字母做标识如 g1~999代表此卡只能使用一次 h1~999卡可以重复使用 z开头代表固定码 wx开头代表微信商店
# 玩家使用卡号 参数 平台 区服 账号 区服链接(GM用)卡号
# http://center.xxx.com:53003/Coupon/CouponCode.php?channel=appid&code=XXX&accid=YYY&sid=222&pushurl=s222.xxx.com
# http://center.xxx.com:53003/Coupon/CouponCode.php
@myapp.route('/Coupon/CouponCode.php')
def CouponCode():
    global AccID_Cache_Dict
    dataDict = request.GET
    
    for key, value in dataDict.items():
@@ -115,7 +139,10 @@
    codeStr = dataDict.get("code", "")
    if not codeStr:
        return
    codeStr = codeStr.strip()
    #只是用来拼接账号
    spID = dataDict.get("spid", "")
    accid = dataDict.get("accid", "")
    if not accid:
        return
@@ -128,7 +155,21 @@
        return
    
    # 转化为游戏账号 
    accid = "%s@%s@s%s"%(accid, agentName, sid)
    accid = "%s@%s@s%s"%(accid.lower(), spID, sid)
    try:
        CleanAccID()
        #mylog.debug("AccID_Cache_Dict : %s"%str(AccID_Cache_Dict))
        if accid not in AccID_Cache_Dict:
            AccID_Cache_Dict[accid] = int(time.time())
        elif time.time() - AccID_Cache_Dict[accid] < 2:
            mylog.debug("==========bad: fast click  %s"%accid)
            return
        AccID_Cache_Dict[accid] = int(time.time())
    except:
        pass
    
    dbController = CouponDB.GetDBEventCon()
    if not dbController:
@@ -140,7 +181,8 @@
    gmresult = {'accID':accid, 'sid':sid, 'channel':agentName}
    #-----------统一固定码处理----------------------
    if codeStr in CommonCards:
    CommonCardsList = CommonCards.get(agentName, [])
    if codeStr in CommonCardsList:
        # 不同固定码各自只能领一次
        result, commondata = dbController.find_one(CouponDB.CouponCodeColName + "_Common", {"code":codeStr, "accid":accid})
        if commondata:
@@ -157,6 +199,90 @@
        mylog.debug("common ok")
        return SendGm(gmresult, pushurl)
    #-----------微信商城----------------------
    if codeStr.startswith('wx'):
        operateID = GetOperateID(agentName)
        if not operateID:
            mylog.debug("wx no appid  = %s"%agentName)
            return
        result, wxdata = dbController.find_one(CouponDB.CouponWXColName, {"code":codeStr, "operateid":operateID})
        if not wxdata:
            return
        if int(wxdata['status']) == 1:
            gmresult['status'] = 2
            mylog.debug("wxcard used!")
            return SendGm(gmresult, pushurl)
        wxdata['status'] = 1
        wxdata['accid'] = dataDict.get("accid", "")     # 此处用原始账号
        wxdata['usetime'] = str(datetime.datetime.today()).split(".")[0]
        wxdata['appid'] = agentName
        wxdata['serverid'] = 's%s'%sid
        wxdata['roleid'] = dataDict.get("roleid", "")
        wxdata['level'] = dataDict.get("level", "")
        wxdata['viplevel'] = dataDict.get("viplevel", "")
        if SendWXBill(wxdata, pushurl):
            # 充值成功
            dbController.update(CouponDB.CouponWXColName, {"code":codeStr, "operateid":operateID}, wxdata)
            # 通知后台记录
            SendDataCollectorBillInfo(wxdata, pushurl, operateID)
        return
    #-----------批量兑换码处理,同类型可重复领取----------------------
    if codeStr.startswith('h'):
        result, data = dbController.find_one(CouponDB.CouponCodeColName + "_" + agentName, {"code":codeStr, "channel":agentName})
        if not data:
            #无此卡
            gmresult['status'] = 0
            mylog.debug("no card")
            return SendGm(gmresult, pushurl)
        if int(data['status']) == 1:
            #已使用,同卡号记录默认可用,避免断线发送失败的情况(未返回结果验证情况下)
            gmresult['status'] = 2
            mylog.debug("card used!")
            return SendGm(gmresult, pushurl)
        result, data2 = dbController.find_one(CouponDB.CouponBatchColName, {"couponid":data["couponid"]})
        if not data2:
            #此批次卡已删除
            gmresult['status'] = 0
            mylog.debug("no couponid")
            return SendGm(gmresult, pushurl)
        if int(data2['status']) == 1:
            #暂停使用该批次卡
            gmresult['status'] = 0
            mylog.debug("couponid frozed")
            return SendGm(gmresult, pushurl)
        if (data2["minserverno"] != 0 and data2["maxserverno"] != 0):
            if int(data2["minserverno"]) > sid or int(data2["maxserverno"]) < sid:
                #不在指定区
                gmresult['status'] = 0
                mylog.debug("no sid")
                return SendGm(gmresult, pushurl)
        if data2["expiretime"] != "" and datetime.datetime.today() > GetDateTimeByStr(data2["expiretime"]):
            #已过期
            gmresult['status'] = 0
            mylog.debug("time pass")
            return SendGm(gmresult, pushurl)
        #可重复领取则不验证同批次卡
        data['status'] = 1
        data['accid'] = accid
        data['usetime'] = str(datetime.datetime.today())
        dbController.update(CouponDB.CouponCodeColName + "_" + agentName, {"code":codeStr, "channel":agentName}, data)
        # 0 不可用,1.可用发放奖励 ,2.已使用 3.同类型卡不能使用两次
        gmresult['status'] = 1
        gmresult['code'] = codeStr
        gmresult['coupontype'] = data["coupontype"]
        mylog.debug("card ok!")
        return SendGm(gmresult, pushurl)
    #-----------批量兑换码处理,同类型只领取一次----------------------
    result, data = dbController.find_one(CouponDB.CouponCodeColName + "_" + agentName, {"code":codeStr, "channel":agentName})
    if not data:
@@ -268,7 +394,7 @@
        for itemList in Items:
            pack_data["ItemID%s"%i] = str(itemList[0])
            pack_data["ItemCnt%s"%i] = str(itemList[1])
            pack_data["IsBind%s"%i] = '1'
            pack_data["IsBind%s"%i] = str(itemList[2] if len(itemList) > 2 else 0)
            i += 1
            
        pack_data["pack_type"] = "GMT_AddPersonalCompensation"
@@ -283,9 +409,9 @@
        post = {}
        post['pack'] = pack_data_dict;
        post['sign'] = sign;
        result = urllib2.urlopen(gmurl, urllib.urlencode(post), 10)
        result = urllib2.urlopen(gmurl, urllib.urlencode(post), 3)
        content = result.read()
        #content = result.read()
        result.close()
        
        # 成功提示
@@ -306,7 +432,7 @@
        post['sign'] = sign;
        urllib2.urlopen(gmurl, urllib.urlencode(post), 3)
        
        return content
        return 0
    except Exception, e:
        mylog.debug("gm error %s"%e)
    return
@@ -321,3 +447,78 @@
    
    return
    
# 通过appid找到运营商
def GetOperateID(appid):
    appidDict = eval(ConfigIO.GetValue("Coupon", "appid_dict"))
    for key, value in appidDict.items():
        if appid in value:
            return key
    return ""
# 微信入口充值
def SendWXBill(wxdata, pushurl):
    try:
        billurl = "http://%s/api/exchange/index.php"%pushurl
        post = {}
        post['AccountID'] = wxdata['accid']
        post['RegionName'] = wxdata['serverid']
        post['OrderAmount'] = wxdata['money']
        post['BillNO'] = wxdata['orderid']
        post['OrderInfo'] = wxdata['orderinfo']
        post['OperatorID'] = wxdata['appid']
        key = ConfigIO.GetValue("Coupon", "key_%s"%post['OperatorID'])
        # $sign=md5($AccountID.$OrderAmount.$BillNO.$RegionName.$key)
        mylog.debug("appid = %s  key = %s"%(post['OperatorID'], key))
        sign = md5.md5(post['AccountID'] + str(post['OrderAmount']) + post['BillNO'] + post['RegionName'] + key).hexdigest()
        post['Sign'] = sign
        result = urllib2.urlopen(billurl, urllib.urlencode(post), 3)
        resultDict = json.loads(result.read())
        mylog.debug("resultDict = %s "%(resultDict))
        if int(resultDict["errorcode"]) > 0:
            return True
    except Exception, e:
        mylog.info("SendWXBill error %s"%e)
    return False
# 通知后台数据中心记录
def SendDataCollectorBillInfo(wxdata, pushurl, operateID):
    try:
        billurl = "http://recharge.game.2460web.com:12000/api/notify/swwx"
        post = {}
        post['appid'] = wxdata['appid']
        post['regionid'] = wxdata['serverid']
        post['orderid'] = wxdata['orderid']
        post['passport'] = wxdata['accid']
        post['roleid'] =  wxdata['roleid']
        post['ordertitle'] = wxdata['ordertitle'].encode("UTF8")
        post['orderinfo'] = wxdata['orderinfo']
        post['money'] = wxdata['money']
        post['ip'] = wxdata['ip']
        post['level'] = wxdata['level']
        post['viplevel'] = wxdata['viplevel']
        post['time'] = int(time.time())
        key = ConfigIO.GetValue("Coupon", "key_%s"%post['appid'])
        #md5(appid=$appid&regionid=$regionid&passport=$passport&&money=$money&time=$time$app_secret)
        signStr = "appid=%s&regionid=%s&passport=%s&money=%s&time=%s%s"%(\
                    post['appid'], post['regionid'], post['passport'], post['money'], post['time'], key)
        sign = md5.md5(signStr).hexdigest()
        #mylog.debug("SendDataCollectorBillInfo  %s-%s-%s-%s"%(signStr, sign, key, post))
        post['sign'] = sign
        result = urllib2.urlopen(billurl +"?" + urllib.urlencode(post), timeout =3)
        #mylog.debug("SendDataCollectorBillInfo result %s"%result.read())
    except Exception, e:
        mylog.debug("SendDataCollectorBillInfo error %s"%e)