#!/usr/bin/python # -*- coding: utf-8 -*- # @todo: CTGOK排行 import CommFunc import ConfigParser import DBOperate import operator import logging import mylog #==================== 配置 ==================== cfg = ConfigParser.ConfigParser() cfg.read("../../InterfaceConfig.php") ServerPath = cfg.get("ServerInfo", "ServerPath") # 获取字段key列表, [[key, 是否累加], ...], 最终的内容会按照配置的字段值导出, 如果空则全部导出 KeyList = [["AccID", False], ["PlayerID", False], ["orderCoin", True], ["orderMoneyType", False], ["orderMoneyValue", True]] # 根据什么字段名统计累加 PKKey = "AccID" # 过滤设定, {过滤key:[过滤值列表], ...}, 即会过滤掉对应key为某些值的内容 Filter_Set = {"eventName":[1003, "GMTCTG"]} # 匹配设定, {匹配key:[匹配值列表], ...}, 即只会匹配对应key为指定值的内容 # coinType: 0-直充;1-直购;2-道具;4-现金点;6-代币转换;7-代币充值 Match_Set = {"coinType":[0, 1, 7]} #==================== 配置 ==================== # 支付订单支持类型 1-人民币;2-美元;3-越南盾;4-soha币; 5-使用订单价值对应货币支付 DefaultOrderType = 1 # 默认人民币 PayByMoneyOrderTypeList = [5] # 使用游戏货币支付的订单类型 OnlyServerID = 0 class ValueObj(): def __init__(self): return def getCTGOKSumInfo(argvDict): ## 统计所有玩家充值累加 global OnlyServerID startDate = argvDict.get("startDate", "") endDate = argvDict.get("endDate", "") OnlyServerID = CommFunc.toInt(argvDict.get("OnlyServerID", "0")) logging.info("OnlyServerID:%s" % OnlyServerID) # 查询中心备份的 if CommFunc.isQueryCenterbak(argvDict): getCTGOKSumInfo_Centerbak(startDate, endDate, argvDict) return showSumInfoDict = getShowSumInfoDict(argvDict) needQueryCenterbak = CommFunc.loopMainServerDR(cfg, startDate, endDate, argvDict, checkDrFileNeedParseFunc_CtgOKSum, parseLineFunc_CtgOKSum, showSumInfoDict, argvDict) if needQueryCenterbak: showSumInfoDictBak = CommFunc.queryBackupCenterDR(cfg, argvDict) if showSumInfoDictBak == None: return for payOrderTypeStr, sumInfoDictBak in showSumInfoDictBak.items(): sumInfoDict = showSumInfoDict[int(payOrderTypeStr)] for pkValue, bakData in sumInfoDictBak.items(): if pkValue not in sumInfoDict: sumInfoDict[pkValue] = ValueObj() vObj = sumInfoDict[pkValue] for key, isSum in KeyList: if isSum: value = getattr(vObj, key, 0) + bakData.get(key, 0) else: value = bakData.get(key, "") setattr(vObj, key, value) maxOrder = CommFunc.toInt(argvDict.get("maxOrder"), 10) # 排序 accIDList = [] showSumInfoSortDict = {} for payOrderType, sumInfoDict in showSumInfoDict.items(): sortList = sumInfoDict.values() if payOrderType in PayByMoneyOrderTypeList: sortList.sort(key=operator.attrgetter("orderMoneyValue"), reverse=True) else: sortList.sort(key=operator.attrgetter("orderCoin"), reverse=True) if maxOrder and len(sortList) > maxOrder: sortList = sortList[:maxOrder] for vObj in sortList: if payOrderType in PayByMoneyOrderTypeList: orderValue = getattr(vObj, "orderMoneyValue", 0) else: orderValue = CommFunc.coinToY(getattr(vObj, "orderCoin", 0), CommFunc.getPayOrderCoinRate(payOrderType)) setattr(vObj, "orderValue", orderValue) accID = getattr(vObj, PKKey) if accID not in accIDList: accIDList.append(accID) showSumInfoSortDict[payOrderType] = sortList if accIDList: dboper = DBOperate.DBOper(ServerPath) findDBRet = dboper.findPlayerInfoByAccID(accIDList) dboper.close() dbPlayerInfo = {} for dbPlayer in findDBRet: accID = dbPlayer["AccID"] dbPlayerInfo[accID] = dbPlayer for vObjList in showSumInfoSortDict.values(): for vObj in vObjList: accID = getattr(vObj, PKKey) if accID not in dbPlayerInfo: continue dbPlayer = dbPlayerInfo[accID] setattr(vObj, "PlayerID", dbPlayer["PlayerID"]) setattr(vObj, "PlayerName", dbPlayer["PlayerName"]) printStr = "

" + _(u"充值排行") + "

" if startDate: printStr += _(u"开始日期") + ": %s
" % startDate; if endDate: printStr += _(u"结束日期") + ": %s
" % endDate; if argvDict.get("ItemCTG"): printStr += _(u"包含道具充值") + "
" else: printStr += _(u"不含道具充值") + "
" if argvDict.get("BuyOrderInfo"): printStr += _(u"包含货币购买") + "
" else: printStr += _(u"不含货币购买") + "
" if argvDict.get("GMCTG"): printStr += _(u"包含后台充值") + "
" else: printStr += _(u"不含后台充值") + "
" if argvDict.get("ExchangePayCoin"): printStr += _(u"包含代币转换") + "
" else: printStr += _(u"不含代币转换") + "
" # 表格输出 for payOrderType, vObjList in showSumInfoSortDict.items(): printStr += "
" orderTypeName = CommFunc.getPayOrderTypeName(payOrderType) printStr += "=== 【%s】支付%s ===
" % (orderTypeName, _(u"充值排行")) if not vObjList: continue printStr += CommFunc.editTableHtml(vObjList, ["AccID", "PlayerID", "PlayerName", "orderValue"], _(u"排名"), styleInfo={"AccID":{"align":"left", "title":_(u"账号")}, "PlayerID":{"align":"left", "title":_(u"玩家ID")}, "PlayerName":{"align":"left", "title":_(u"玩家名")}, "orderValue":{"align":"right", "title":orderTypeName}, }) # 只会返回最后一个print的内容 print printStr return def getShowSumInfoDict(argvDict): showSumInfoDict = {} # {payOrderType:{accID:obj, ...}} for payOrderType in range(1, 10): if "payOrderType%s" % payOrderType in argvDict: showSumInfoDict[payOrderType] = {} if not showSumInfoDict: showSumInfoDict[DefaultOrderType] = {} # 默认只显示人民币 return showSumInfoDict def getCTGOKSumInfo_Centerbak(startDate, endDate, argvDict): ## 查询中心服务器备份充值信息 showSumInfoDict = getShowSumInfoDict(argvDict) if not CommFunc.loopCenterbakRarDR(cfg, startDate, endDate, argvDict, checkDrFileNeedParseFunc_CtgOKSum, parseLineFunc_CtgOKSum, showSumInfoDict, argvDict): return return CommFunc.queryBackupCenterOK(showSumInfoDict) def checkDrFileNeedParseFunc_CtgOKSum(drFileName, *parseArgs, **kv): ''' 检查流向是否需要处理 @param drFileName: 流向文件名 xxx_日期.txt @param *parseArgs: 自定义参数 @return: isNeed, checkNeedParseRetInfo ''' isNeed = drFileName.startswith("CTGOK_") return isNeed, None def parseLineFunc_CtgOKSum(drName, dateStr, checkNeedParseRetInfo, line, *parseArgs, **kv): ''' 解析流向行内容 @param drName: 流向名 @param dateStr: 对应日期字符串 @param checkNeedParseRetInfo: checkDrFileNeedParseFunc 返回的内容 @param line: 本行内容 @param *parseArgs: 自定义参数 ''' showSumInfoDict, argvDict = parseArgs drDict = eval(line) if not checkDRNeed(drDict, argvDict): return if PKKey not in drDict: return payOrderType = drDict.get("payOrderType", DefaultOrderType) if payOrderType not in showSumInfoDict: return sumInfoDict = showSumInfoDict[payOrderType] pkValue = drDict[PKKey] if OnlyServerID: serverID = CommFunc.getServerID(pkValue) if CommFunc.getServerID(pkValue) != OnlyServerID: # logging.info("OnlyServerID:%s, 不统计 %s" % (OnlyServerID, pkValue)) return if pkValue not in sumInfoDict: sumInfoDict[pkValue] = ValueObj() vObj = sumInfoDict[pkValue] for key, isSum in KeyList: if key not in drDict: continue if isSum: value = getattr(vObj, key, 0) + drDict.get(key, 0) else: value = drDict.get(key, "") setattr(vObj, key, value) return ##================================================================================================= def checkDRNeed(drDict, argvDict): ## 通用检查该流向是否需要 noCheckRealCTGPayTypeList = [5, 6] # 5-金票支付 6-代币支付 payOrderType = drDict.get("payOrderType", DefaultOrderType) matchSet, filterSet = {}, {} if not argvDict.get("ItemCTG") and not argvDict.get("GMCTG") and not argvDict.get("BuyOrderInfo"): if payOrderType not in noCheckRealCTGPayTypeList and not IsRealCTG(drDict): return coinTypeList = [0, 1, 7] # 0-直充;1-直购;2-道具;4-现金点;6-代币转换;7-代币充值 if argvDict.get("ItemCTG"): coinTypeList.append(2) if argvDict.get("BuyOrderInfo"): coinTypeList.append(4) if argvDict.get("ExchangePayCoin"): coinTypeList.append(6) matchSet["coinType"] = coinTypeList if not argvDict.get("GMCTG"): if drDict["coinType"] in [0, 1, 7] and payOrderType not in noCheckRealCTGPayTypeList and not IsRealCTG(drDict): return filterSet["eventName"] = [1003, "GMTCTG"] # 排除GM充值的事件类型 if not CommFunc.matchDr(drDict, matchSet, filterSet): return return True def queryAccIDCTGInfo(argvDict): ## 查询个人充值记录 startDate = argvDict.get("startDate", "") endDate = argvDict.get("endDate", "") queryType = argvDict.get("queryType", "") playerFind = argvDict.get("playerFind", "") # 查询中心备份的 if CommFunc.isQueryCenterbak(argvDict): queryAccIDCTGInfo_Centerbak(startDate, endDate, argvDict) return playerName = "" queryAccID = playerFind if queryType == "playerName": # 根据玩家名查找的,以db为准,找到对应的账号进行匹配,不然玩家改名将导致匹配结果错误 dboper = DBOperate.DBOper(ServerPath) findDBRet = dboper.findPlayerInfoByName([playerFind]) dboper.close() if not findDBRet or findDBRet.count() == 0: print _(u"找不到该玩家") + "!
%s
" % playerFind return dbPlayer = findDBRet[0] queryAccID = CommFunc.encode(dbPlayer["AccID"]) playerName = CommFunc.encode(dbPlayer["PlayerName"]) ctgOKList = [] ctgErrorList = [] needQueryCenterbak = CommFunc.loopMainServerDR(cfg, startDate, endDate, argvDict, checkDrFileNeedParseFunc_AccIDCTGInfo, parseLineFunc_AccIDCTGInfo, queryAccID, ctgOKList, ctgErrorList, argvDict) if needQueryCenterbak: argvDict["queryAccID"] = queryAccID bakDataList = CommFunc.queryBackupCenterDR(cfg, argvDict) if bakDataList == None: return ctgOKList = bakDataList[0] + ctgOKList ctgErrorList = bakDataList[1] + ctgErrorList showOKOrderInfo, showErrOrderInfo = {}, {} for payOrderType in range(1, 10): if "payOrderType%s" % payOrderType in argvDict: showOKOrderInfo[payOrderType] = {} showErrOrderInfo[payOrderType] = {} if not showOKOrderInfo: showOKOrderInfo[DefaultOrderType] = {} # 默认只显示人民币 showErrOrderInfo[DefaultOrderType] = {} # 默认只显示人民币 # 成功订单 for drDict in ctgOKList: # {"orderCoin":orderCoin, "payOrderType":payOrderType, "orderMoneyType":orderMoneyType, "orderMoneyValue":orderMoneyValue} payOrderType = drDict.get("payOrderType", DefaultOrderType) if payOrderType not in showOKOrderInfo: continue showInfo = showOKOrderInfo[payOrderType] if payOrderType in PayByMoneyOrderTypeList: orderValue = drDict["orderMoneyValue"] drDict["orderValue"] = orderValue else: orderValue = drDict["orderCoin"] drDict["orderValue"] = CommFunc.coinToY(orderValue, CommFunc.getPayOrderCoinRate(payOrderType)) drList = showInfo.get("drList", []) drList.append(drDict) showInfo["drList"] = drList showInfo["orderValueTotal"] = showInfo.get("orderValueTotal", 0) + orderValue for payOrderType, showInfo in showOKOrderInfo.items(): if showInfo and payOrderType not in PayByMoneyOrderTypeList: showInfo["orderValueTotal"] = CommFunc.coinToY(showInfo["orderValueTotal"], CommFunc.getPayOrderCoinRate(payOrderType)) # 失败订单 for drDict in ctgErrorList: payOrderType = drDict.get("payOrderType", DefaultOrderType) if payOrderType not in showErrOrderInfo: continue showInfo = showErrOrderInfo[payOrderType] if payOrderType in PayByMoneyOrderTypeList: orderValue = drDict["orderMoneyValue"] drDict["orderValue"] = orderValue else: orderValue = drDict["orderCoin"] drDict["orderValue"] = CommFunc.coinToY(orderValue, CommFunc.getPayOrderCoinRate(payOrderType)) drList = showInfo.get("drList", []) drList.append(drDict) showInfo["drList"] = drList showInfo["orderValueTotal"] = showInfo.get("orderValueTotal", 0) + orderValue for payOrderType, showInfo in showErrOrderInfo.items(): if showInfo and payOrderType not in PayByMoneyOrderTypeList: showInfo["orderValueTotal"] = CommFunc.coinToY(showInfo["orderValueTotal"], CommFunc.getPayOrderCoinRate(payOrderType)) # 玩家名 if not playerName and ctgOKList: lastDict = ctgOKList[-1] playerName = lastDict.get("PlayerName", "") printStr = "

" + _(u"充值记录") + "

" printStr += _(u"玩家账号") + ": %s
" % queryAccID; if playerName: printStr += _(u"玩家名称") + ": %s
" % playerName; if startDate: printStr += _(u"开始日期") + ": %s
" % startDate; if endDate: printStr += _(u"结束日期") + ": %s
" % endDate; if argvDict.get("ItemCTG"): printStr += _(u"包含道具充值") + "
" else: printStr += _(u"不含道具充值") + "
" if argvDict.get("BuyOrderInfo"): printStr += _(u"包含货币购买") + "
" else: printStr += _(u"不含货币购买") + "
" if argvDict.get("GMCTG"): printStr += _(u"包含后台充值") + "
" else: printStr += _(u"不含后台充值") + "
" if argvDict.get("ExchangePayCoin"): printStr += _(u"包含代币转换") + "
" else: printStr += _(u"不含代币转换") + "
" printStr += "coinType: %s" % _(u"0-直充;1-直购;6-代币转换;7-代币充值") + "
" # 表格输出 for payOrderType, showInfo in showErrOrderInfo.items(): if not showInfo: continue printStr += "
" orderTypeName = CommFunc.getPayOrderTypeName(payOrderType) orderValueTotal = showInfo["orderValueTotal"] drList = showInfo["drList"] printStr += "=== 【%s】%s ===
" % (orderTypeName, _(u"充值失败到账记录")); printStr += "%s: %s %s
" % (_(u"充值失败到账总额度"), orderValueTotal, orderTypeName); printStr += CommFunc.editTableHtml(drList, ["appID", "orderInfo", "orderValue", "eventName", "ErrorInfo", "time", "orderID"], _(u"编号"), styleInfo={"orderInfo":{"align":"left", "title":_(u"商品编号")}, "orderValue":{"align":"right", "title":orderTypeName}, "ErrorInfo":{"align":"left", "title":_(u"错误信息")}, }) for payOrderType, showInfo in showOKOrderInfo.items(): printStr += "
" orderTypeName = CommFunc.getPayOrderTypeName(payOrderType) printStr += "=== 【%s】支付%s ===
" % (orderTypeName, _(u"充值成功到账记录")); if not showInfo: continue orderValueTotal = showInfo["orderValueTotal"] drList = showInfo["drList"] printStr += "支付%s: %s %s
" % (_(u"充值成功到账总额度"), orderValueTotal, orderTypeName); printStr += CommFunc.editTableHtml(drList, ["appID", "orderInfo", "orderValue", "eventName", "coinType", "time", "orderID", "ServerDay", "VIPLv"], _(u"编号"), styleInfo={"orderInfo":{"align":"left", "title":_(u"商品编号")}, "orderValue":{"align":"right", "title":orderTypeName}, "ServerDay":{"title":_(u"开服天")}, "VIPLv":{"title":_(u"VIP等级")}, }) # 只会返回最后一个print的内容 print printStr return def queryAccIDCTGInfo_Centerbak(startDate, endDate, argvDict): queryAccID = argvDict.get("queryAccID") if not queryAccID: return CommFunc.queryBackupCenterError("queryAccID is none") ctgOKList = [] ctgErrorList = [] if not CommFunc.loopCenterbakRarDR(cfg, startDate, endDate, argvDict, checkDrFileNeedParseFunc_AccIDCTGInfo, parseLineFunc_AccIDCTGInfo, queryAccID, ctgOKList, ctgErrorList, argvDict): return return CommFunc.queryBackupCenterOK([ctgOKList, ctgErrorList]) def checkDrFileNeedParseFunc_AccIDCTGInfo(drFileName, *parseArgs, **kv): ''' 检查流向是否需要处理 @param drFileName: 流向文件名 xxx_日期.txt @param *parseArgs: 自定义参数 @return: isNeed, checkNeedParseRetInfo ''' isNeed = (drFileName.startswith("CTGOK_") or drFileName.startswith("CTGError_")) return isNeed, None def parseLineFunc_AccIDCTGInfo(drName, dateStr, checkNeedParseRetInfo, line, *parseArgs, **kv): ''' 解析流向行内容 @param drName: 流向名 @param dateStr: 对应日期字符串 @param checkNeedParseRetInfo: checkDrFileNeedParseFunc 返回的内容 @param line: 本行内容 @param *parseArgs: 自定义参数 ''' queryAccID, ctgOKList, ctgErrorList, argvDict = parseArgs if queryAccID not in line: return drDict = eval(line) if queryAccID != drDict["AccID"]: return drKeyList = ["appID", "orderInfo", "orderCoin", "eventName", "coinType", "time", "orderID", "ServerDay", "VIPLv", "payOrderType", "orderMoneyType", "orderMoneyValue", "ErrorInfo", "PlayerName"] if drName.startswith("CTGError"): dDict = {} for key in drKeyList: if key in drDict: dDict[key] = drDict[key] ctgErrorList.append(dDict) return if not checkDRNeed(drDict, argvDict): return if drName.startswith("CTGOK"): dDict = {} for key in drKeyList: if key in drDict: dDict[key] = drDict[key] ctgOKList.append(dDict) return def IsRealCTG(drDict): ## 是否真实充值订单,真实充值订单一定有 orderID if not drDict.get('orderID'): return False return True def main(): CommFunc.setdefaultencoding() argvDict = CommFunc.parse_args() mylog.InitMyLog(argvDict.get("eventType", "")) CommFunc.gettextInstall(argvDict.get("lang", "")) playerFind = argvDict.get("playerFind", "") if playerFind != "": queryAccIDCTGInfo(argvDict) else: getCTGOKSumInfo(argvDict) return if __name__ == "__main__": try: main() except: CommFunc.printExceptionError()