| #!/usr/bin/python  | 
| # -*- coding: utf-8 -*-  | 
| #  | 
| ##@package  | 
| #  | 
| # @todo: 激活码  | 
| #  | 
| # @author: Alee  | 
| # @date 2018-5-4 22:10:51  | 
| # @version 1.0  | 
| #  | 
| # @note: 中文必须传utf8,收到的为urlencode内容  .decode('gbk').encode('utf8')  | 
| # 1.生成礼包批次  | 
| # 2.查询礼包批次  | 
| # 3.删除礼包批次  | 
| # 4.下载礼包批次  | 
| # 5.查询礼包卡号/使用礼包卡号  | 
| #---------------------------------------------------------------------  | 
|   | 
| from bottle import Bottle, request, static_file  | 
| import random  | 
| import time  | 
| import md5  | 
| import CouponDB  | 
| import datetime  | 
| from lib import ReadConfig  | 
| import json  | 
| import urllib2  | 
| import urllib  | 
| from lib import mylog, CommFunc  | 
| import os.path  | 
| import zipfile  | 
|   | 
| # get: request.query.username request.GET.get('username','')  | 
| # post: request.forms.get('username')  request.POST.get('username')  | 
| #===============================================================================  | 
| # @myapp.route('/cool/kk/:name3/:count#\\d+#')  | 
| # def maybe(name3, count):  | 
| # client_ip = request.environ.get('REMOTE_ADDR')  | 
| # client_ip = request.environ.get('HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR')  | 
| #===============================================================================  | 
|   | 
| ConfigIO = ReadConfig.ReadConfig(os.getcwd() + "\\config.ini")  | 
|   | 
| # 应用端口  | 
| CenterPort = ConfigIO.GetValue("Coupon", "CenterPort")  | 
| #mobiletest.173on.com:55000  | 
| Def_ExportUrl = ConfigIO.GetValue("Coupon", "exporturl") + "/Coupon/CouponLoad.php?couponid=%s&channel=%s"  | 
|   | 
| # GM端口  | 
| PushPort = ConfigIO.GetValue("Coupon", "PushPort")  | 
| PushKey = ConfigIO.GetValue("Coupon", "PushKey")  | 
| CommonCards = eval(ConfigIO.GetValue("Coupon", "CommonCards"))  | 
|                   | 
|           | 
| Def_CardMsg = {  | 
|                0:"CodeRewardSys2", #  兑换码无效  | 
|                1: "CodeRewardSys1", #   兑换卡奖励已发至邮件  | 
|                2:"CodeRewardSys3", #  兑换码已使用过  | 
|                3:"CodeRewardSys4",  # 同类型兑换码只能使用一次  | 
|          }  | 
|                   | 
|                   | 
|                   | 
| myapp = Bottle()  | 
|   | 
| #申请礼包卡批次  | 
| @myapp.route('/Coupon/CouponBatch.php', method='POST')  | 
| def CouponBatch():  | 
|     dataDict = request.POST  | 
|     for key, value in dataDict.items():  | 
|         mylog.debug("key:%s  value:%s"%(key, value))  | 
|   | 
|     appid = dataDict.get("channel", "")     # 运营提供的APPID,即渠道  | 
|     if not appid:  | 
|         mylog.debug("no appid")  | 
|         return json.dumps({"error":"param appid"}, ensure_ascii=False)  | 
|     couponType = dataDict.get("coupontype", "")    # 礼包卡类型  | 
|     if not couponType:  | 
|         mylog.debug("no couponType")  | 
|         return json.dumps({"error":"param couponType"}, ensure_ascii=False)  | 
|       | 
|     if not ConfigIO.HasSection(couponType):  | 
|         return json.dumps({"error":"no couponType"}, ensure_ascii=False)  | 
|       | 
|     minSNo = CommFunc.ToIntDef(dataDict.get("minserverno", 0), 0)   # 若只选中一个则代表只有单服使用  | 
|     maxSNo = CommFunc.ToIntDef(dataDict.get("maxserverno", 0), 0)  | 
|     amount = int(dataDict.get("amount", 0))     # 礼包数量  | 
|     expireTime = dataDict.get("expiretime", "") # 过期时间  | 
|       | 
|     # 不可重复即可  生成卡号批次标志,随机  | 
|     coupon_id = md5.md5("%s%s%s%s"%(appid, random.randint(1, 10000), time.time(), couponType)).hexdigest()  | 
|       | 
|     dbController = CouponDB.GetDBEventCon()  | 
|     if not dbController:  | 
|         # 无法获取数据库  | 
|         mylog.debug("no dbController")  | 
|         return json.dumps({"error":"db"}, ensure_ascii=False)  | 
|       | 
|     tmpDict = {}  | 
|     #新增  | 
|     tmpDict['createtime'] = str(datetime.datetime.today()).split(".")[0]   #创建时间  | 
|     tmpDict['exportUrl'] = Def_ExportUrl%(coupon_id, appid)  # 卡批次下载地址 提供给运营商获取  | 
|     tmpDict['couponid'] = coupon_id  # 卡批次,用于控制这一批次卡的使用权限和下载依据  | 
|       | 
|     # 若只选中一个则代表只有单服使用,0则不限制使用范围  | 
|     if minSNo == 0 or maxSNo == 0:  | 
|         minSNo = max(minSNo, maxSNo)  | 
|         maxSNo = minSNo  | 
|     tmpDict["minserverno"] = minSNo  #  使用区服限制  | 
|     tmpDict["maxserverno"] = maxSNo  | 
|     tmpDict["amount"] = amount  #此批次卡的总数量  | 
|     tmpDict["coupontype"] = couponType  # 卡类型 开头字母做标识如 g代表此卡只能使用一次 h卡可以重复使用  | 
|     tmpDict["expiretime"] = expireTime  # 结束时间 ""空为无限制,具体时间格式为2018-06-07     | 
|     tmpDict["channel"] = appid  | 
|     tmpDict["status"] = 0   # 0正常 1不可用  | 
|       | 
|     # 插入表1批次清单,表2为具体卡号  | 
|     result = dbController.insert(CouponDB.CouponBatchColName, tmpDict)  | 
|     if not result:  | 
|         mylog.debug("insert error-%s"%(dbController.lastError))  | 
|         mylog.debug("insert error-%s-%s"%(coupon_id, tmpDict))  | 
|         return json.dumps({"error":"insert couponid"}, ensure_ascii=False)  | 
|       | 
|     #===========================================================================  | 
|     # { "_id" : ObjectId("5b1a3e474eb1001100f7ad55"), "status" : 0, "code" : "m069cafd  | 
|     # 8ea1b30ajn", "coupontype" : "3", "couponid" : "0300229afaa52bbce59e7e6c104f307  | 
|     # e", "createtime" : "2018-06-08 16:28:55", "channel" : "asd" }  | 
|     #===========================================================================  | 
|     #批量插入卡号,暂且一次性插入十万  | 
|     tmpCodeList = []  | 
|     for i in xrange(amount):  | 
|         tmpCodeDoc = {}  | 
|         # 前3位为类型标识  | 
|         tmpCodeDoc['code'] = tmpDict["coupontype"][0] + md5.md5(tmpDict['channel'] + str(tmpDict['createtime']) + str(i) + \  | 
|                                      str(random.randint(1000, 2000000))).hexdigest()[2:14] + \  | 
|                                      random.choice('1234567890abcdefghijklmnopqrstuvwxyz') +\  | 
|                                      random.choice('1234567890abcdefghijklmnopqrstuvwxyz')   | 
|         tmpCodeDoc['coupontype'] = tmpDict['coupontype']  | 
|         tmpCodeDoc['couponid'] = tmpDict['couponid']  | 
|           | 
|         tmpCodeDoc['channel'] = tmpDict['channel']  | 
|         tmpCodeDoc['status'] = 0  | 
|         tmpCodeDoc['usetime'] = ""  | 
|         tmpCodeDoc['accid'] = ""  | 
|         tmpCodeList.append(tmpCodeDoc)  | 
|   | 
|     result = dbController.insert(CouponDB.CouponCodeColName + "_" + tmpDict['channel'], tmpCodeList)  | 
|     if not result:  | 
|         return json.dumps({"error":"insert card"}, ensure_ascii=False)  | 
|     if "_id" in tmpDict:  | 
|         del tmpDict["_id"]  | 
|   | 
|     mylog.debug("插入成功%s"%json.dumps(tmpDict, ensure_ascii=False))  | 
|           | 
|     return json.dumps(tmpDict, ensure_ascii=False)  | 
|   | 
| # 查询此平台礼包批次或者指定礼包批次查询  | 
| @myapp.route('/Coupon/CouponQuery.php')  | 
| def QueryCouponBatch():  | 
|     dataDict = request.GET  | 
|     appid = dataDict.get("channel", "")     # 运营提供的APPID,即渠道  | 
|     if not appid:  | 
|         mylog.debug("no appid")  | 
|         return json.dumps({"error":"param channel"}, ensure_ascii=False)  | 
|     couponid = dataDict.get("couponid", "")  | 
|     # 单查  | 
|     dbController = CouponDB.GetDBEventCon()  | 
|     if not dbController:  | 
|         # 无法获取数据库  | 
|         mylog.debug("no dbController")  | 
|         return json.dumps({"error":"db"}, ensure_ascii=False)  | 
|     if couponid:  | 
|         result, findList = dbController.find(CouponDB.CouponBatchColName, {'channel':appid, 'couponid':couponid})  | 
|     else:  | 
|         result, findList = dbController.find(CouponDB.CouponBatchColName, {'channel':appid})  | 
|       | 
|     if not findList:  | 
|         return json.dumps({"error":"no couponid"}, ensure_ascii=False)  | 
|       | 
|     return json.dumps(findList, ensure_ascii=False)  | 
|   | 
|   | 
| # 更新指定礼包批次 0:正常  其他异常  | 
| @myapp.route('/Coupon/CouponUpdate.php')  | 
| def UpdateCouponBatch():  | 
|     dataDict = request.GET  | 
|     appid = dataDict.get("channel", "")     # 运营提供的APPID,即渠道  | 
|     if not appid:  | 
|         mylog.debug("no appid")  | 
|         return json.dumps({"error":"param appid"}, ensure_ascii=False)  | 
|     couponid = dataDict.get("couponid", "")  | 
|     if not couponid:  | 
|         return json.dumps({"error":"param couponid"}, ensure_ascii=False)  | 
|       | 
|     status = CommFunc.ToIntDef(dataDict.get("status", 0), 0)  | 
|       | 
|     dbController = CouponDB.GetDBEventCon()  | 
|     if not dbController:  | 
|         # 无法获取数据库  | 
|         mylog.debug("no dbController")  | 
|         return json.dumps({"error":"db"}, ensure_ascii=False)  | 
|       | 
|     result, data = dbController.find_one(CouponDB.CouponBatchColName, {'channel':appid, 'couponid':couponid})  | 
|     if not data:  | 
|         return json.dumps({"error":"no couponid"}, ensure_ascii=False)  | 
|       | 
|     data['status'] = status  | 
|     dbController.update(CouponDB.CouponBatchColName, {'channel':appid, 'couponid':couponid}, data)  | 
|       | 
|       | 
|     return json.dumps({"success":couponid}, ensure_ascii=False)  | 
|   | 
|   | 
| # 查询卡使用情况  | 
| @myapp.route('/Coupon/QueryCouponCode.php')  | 
| def QueryCouponCode():  | 
|     dataDict = request.GET  | 
|     appid = dataDict.get("channel", "")     # 运营提供的APPID,即渠道  | 
|     if not appid:  | 
|         mylog.debug("no appid")  | 
|         return json.dumps({"error":"param appid"}, ensure_ascii=False)  | 
|     codeStr = dataDict.get("code", "")  | 
|     if not codeStr:  | 
|         return json.dumps({"error":"param code"}, ensure_ascii=False)  | 
|       | 
|     dbController = CouponDB.GetDBEventCon()  | 
|     if not dbController:  | 
|         # 无法获取数据库  | 
|         mylog.debug("no dbController")  | 
|         return json.dumps({"error":"db"}, ensure_ascii=False)  | 
|     result, data = dbController.find(CouponDB.CouponCodeColName + "_" + appid, {'channel':appid, 'code':codeStr})  | 
|     if not data:  | 
|         return json.dumps({"error":"no code"}, ensure_ascii=False)  | 
|       | 
|     return json.dumps(data, ensure_ascii=False)  | 
|   | 
|       | 
| def GetDateTimeByStr(timeStr, timeFomat="%Y-%m-%d"):  | 
|     try:  | 
|         return datetime.datetime.strptime(timeStr, timeFomat)  | 
|       | 
|     except:  | 
|         mylog.debug("GetDateTimeByStr error %s"%timeStr)  | 
|       | 
|     return  | 
|       | 
|   | 
|   | 
| #=================游戏服务器记录==========================================================  | 
| # $arrayInsert=array( '_id'=>$orderID, 'ServerID'=>$getServer_id,   | 
| #                    'AccID'=>$qid, 'OrderAmount'=>$nOrderAmount,   | 
| #                    'OrderID'=>$orderID, 'Sign'=>$recvSign,   | 
| #                    'BeginOrderTime'=>date("Y-m-d H:i:s"), 'EndOrderTime'=>0,   | 
| #                    'IsProcess'=>0, "OrderInfo"=>$DataArray['OrderInfo']);  | 
| #===========================================================================  | 
|   | 
| #=================后台数据记录==========================================================  | 
| # appid    是    string    微信商城用户选择的平台appid  | 
| # regionid    是    string    区服ID:  s8001  | 
| # orderid    是    string    微信商城订单号不能与充值订单重复  | 
| # passport    是    string    玩家游戏帐号  | 
| # roleid    是    string    角色名称  | 
| # ordertitle    是    string    订单标题,例如:  128元礼包  | 
| # orderinfo    是    string    订单信息, 例如:  snxxz.18  | 
| # money    是    float    付款数保留两位小数  | 
| # ip    是    string    玩家IP,可空值  | 
| # level    是    string    等级  | 
| # viplevel    是    string    VIP等级  | 
| # time    是    string    充值时间戳 例如: 1539447585  | 
| # sign    是    string    签名  | 
| #===========================================================================  | 
|   | 
| #http://center.2460web.com:53002/Coupon/CouponWXBill.php  | 
| #微信商城 参数 ordertitle orderinfo orderid count money(保留两位小数)sign ip time(补发不更新时间)  | 
| @myapp.route('/Coupon/CouponWXBill.php', method='POST')  | 
| def CouponWXBill():  | 
|     dataDict = request.POST  | 
|     for key, value in dataDict.items():  | 
|         mylog.debug("key:%s  value:%s"%(key, value))  | 
|   | 
|     channel = "zyxh"  # 需支持多个appid,一个订单一个激活码  | 
|     orderID = dataDict.get("orderid", "")    # 订单,根据数量分支出多个订单对应一个激活码  | 
|     if not orderID:  | 
|         return json.dumps({"error":"param orderid"}, ensure_ascii=False)  | 
|       | 
|     orderInfo = dataDict.get("orderinfo", "")    # 商品编号  | 
|     if not orderInfo:  | 
|         return json.dumps({"error":"param orderInfo"}, ensure_ascii=False)  | 
|       | 
|     count = int(dataDict.get("count", 0))     # 礼包数量  | 
|     if count <= 0:  | 
|         return json.dumps({"error":"param count"}, ensure_ascii=False)  | 
|       | 
|     money = float(dataDict.get("money", 0))     # 价格  | 
|     if money <= 0:  | 
|         return json.dumps({"error":"param money"}, ensure_ascii=False)  | 
|       | 
|       | 
|     timeStr = dataDict.get("time", "")     # 充值时间,补发不更新时间  | 
|     if not timeStr:  | 
|         return json.dumps({"error":"param time"}, ensure_ascii=False)  | 
|       | 
|     sign = dataDict.get("sign", "")     # 充值时间,补发不更新时间  | 
|     if not sign:  | 
|         return json.dumps({"error":"param sign"}, ensure_ascii=False)  | 
|       | 
|     key = ConfigIO.GetValue("Coupon", channel + "_wxkey")  | 
|     calcSign = md5.md5(str(count) + orderID + timeStr + key).hexdigest()  | 
|     if calcSign != sign:  | 
|         mylog.debug("error sign=%s"%calcSign)  | 
|         return json.dumps({"error":"sign"}, ensure_ascii=False)  | 
|       | 
|       | 
|     dbController = CouponDB.GetDBEventCon()  | 
|     if not dbController:  | 
|         # 无法获取数据库  | 
|         mylog.debug("no dbController")  | 
|         return json.dumps({"error":"db"}, ensure_ascii=False)  | 
|       | 
|     # 验证是否重复订单  | 
|     result = dbController.find(CouponDB.CouponWXColName, {"realorderid":orderID})  | 
|     if result[1]:  | 
|         codeList = []  | 
|         for cardInfo in result[1]:  | 
|             codeList.append(cardInfo['code'])  | 
|         #return json.dumps({"error":"orderid repeat"}, ensure_ascii=False)  | 
|         mylog.debug("orderid repeat")  | 
|         return json.dumps({orderID:codeList}, ensure_ascii=False)  | 
|       | 
|     #批量插入卡号  | 
|     tmpCodeList = []    # 卡信息  | 
|     codeList = []   # 卡号  | 
|     for i in xrange(count):  | 
|         tmpCodeDoc = {}  | 
|         # 前3位为类型标识  | 
|         tmpCodeDoc['code'] = "wx" + md5.md5( channel + str(i) + orderID + timeStr + str(i) + \  | 
|                                      str(random.randint(1000, 2000000))).hexdigest()[5:17] + \  | 
|                                      random.choice('1234567890abcdefghijklmnopqrstuvwxyz') +\  | 
|                                      random.choice('1234567890abcdefghijklmnopqrstuvwxyz')   | 
|         tmpCodeDoc['operateid'] = channel   # appid组合标识 一家运营商可能有多个appid  | 
|         tmpCodeDoc['status'] = 0  | 
|         tmpCodeDoc['usetime'] = ""  | 
|           | 
|         tmpCodeDoc['count'] = count  | 
|           | 
|         tmpCodeDoc['appid'] = ""    # 记录用  | 
|         tmpCodeDoc['serverid'] = ""    # 记录用  | 
|         tmpCodeDoc['realorderid'] = orderID    # 购物的orderID,会根据数量拆解  | 
|         tmpCodeDoc['orderid'] = orderID + "_" + str(i+1)    # 拆解的orderID,会根据数量拆解  | 
|         tmpCodeDoc['accid'] = ""  | 
|         tmpCodeDoc['roleid'] = ""  | 
|         tmpCodeDoc['ordertitle'] = dataDict.get("ordertitle", "")  | 
|         tmpCodeDoc['orderinfo'] = orderInfo  | 
|         tmpCodeDoc['money'] = money  | 
|         tmpCodeDoc['ip'] = dataDict.get("ip", "")  | 
|         tmpCodeDoc['level'] = ""  | 
|         tmpCodeDoc['viplevel'] = ""  | 
|         tmpCodeDoc['createtime'] = timeStr  | 
|           | 
|         tmpCodeList.append(tmpCodeDoc)  | 
|         codeList.append(tmpCodeDoc['code'])  | 
|           | 
|           | 
|     result = dbController.insert(CouponDB.CouponWXColName, tmpCodeList)  | 
|     if not result:  | 
|         return json.dumps({"error":"insert card"}, ensure_ascii=False)  | 
|   | 
|     mylog.debug("插入成功%s条订单"%len(tmpCodeList))  | 
|      | 
|     return json.dumps({orderID:codeList}, ensure_ascii=False)  |