#!/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] # 使用游戏货币支付的订单类型
class ValueObj():
def __init__(self):
return
def getCTGOKSumInfo(argvDict):
## 统计所有玩家充值累加
startDate = argvDict.get("startDate", "")
endDate = argvDict.get("endDate", "")
# 查询中心备份的
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 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()