#!/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)