#!/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 = "<center><p>" + _(u"充值排行") + "</p></center>"
|
if startDate:
|
printStr += _(u"开始日期") + ": %s<br/>" % startDate;
|
if endDate:
|
printStr += _(u"结束日期") + ": %s<br/>" % endDate;
|
|
if argvDict.get("ItemCTG"):
|
printStr += _(u"包含道具充值") + "<br/>"
|
else:
|
printStr += _(u"不含道具充值") + "<br/>"
|
|
if argvDict.get("BuyOrderInfo"):
|
printStr += _(u"包含货币购买") + "<br/>"
|
else:
|
printStr += _(u"不含货币购买") + "<br/>"
|
|
if argvDict.get("GMCTG"):
|
printStr += _(u"包含后台充值") + "<br/>"
|
else:
|
printStr += _(u"不含后台充值") + "<br/>"
|
|
if argvDict.get("ExchangePayCoin"):
|
printStr += _(u"包含代币转换") + "<br/>"
|
else:
|
printStr += _(u"不含代币转换") + "<br/>"
|
|
# 表格输出
|
for payOrderType, vObjList in showSumInfoSortDict.items():
|
printStr += "<hr/>"
|
orderTypeName = CommFunc.getPayOrderTypeName(payOrderType)
|
printStr += "=== 【%s】支付%s ===<br/>" % (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"找不到该玩家") + "!<br/>%s<br/>" % 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 = "<center><p>" + _(u"充值记录") + "</p></center>"
|
printStr += _(u"玩家账号") + ": %s<br/>" % queryAccID;
|
if playerName:
|
printStr += _(u"玩家名称") + ": %s<br/>" % playerName;
|
|
if startDate:
|
printStr += _(u"开始日期") + ": %s<br/>" % startDate;
|
if endDate:
|
printStr += _(u"结束日期") + ": %s<br/>" % endDate;
|
|
if argvDict.get("ItemCTG"):
|
printStr += _(u"包含道具充值") + "<br/>"
|
else:
|
printStr += _(u"不含道具充值") + "<br/>"
|
|
if argvDict.get("BuyOrderInfo"):
|
printStr += _(u"包含货币购买") + "<br/>"
|
else:
|
printStr += _(u"不含货币购买") + "<br/>"
|
|
if argvDict.get("GMCTG"):
|
printStr += _(u"包含后台充值") + "<br/>"
|
else:
|
printStr += _(u"不含后台充值") + "<br/>"
|
|
if argvDict.get("ExchangePayCoin"):
|
printStr += _(u"包含代币转换") + "<br/>"
|
else:
|
printStr += _(u"不含代币转换") + "<br/>"
|
|
printStr += "coinType: %s" % _(u"0-直充;1-直购;6-代币转换;7-代币充值") + "<br/>"
|
|
# 表格输出
|
for payOrderType, showInfo in showErrOrderInfo.items():
|
if not showInfo:
|
continue
|
printStr += "<hr/>"
|
orderTypeName = CommFunc.getPayOrderTypeName(payOrderType)
|
orderValueTotal = showInfo["orderValueTotal"]
|
drList = showInfo["drList"]
|
|
printStr += "=== 【%s】%s ===<br/>" % (orderTypeName, _(u"充值失败到账记录"));
|
printStr += "%s: %s %s<br/>" % (_(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 += "<hr/>"
|
orderTypeName = CommFunc.getPayOrderTypeName(payOrderType)
|
printStr += "=== 【%s】支付%s ===<br/>" % (orderTypeName, _(u"充值成功到账记录"));
|
if not showInfo:
|
continue
|
orderValueTotal = showInfo["orderValueTotal"]
|
drList = showInfo["drList"]
|
printStr += "支付%s: %s %s<br/>" % (_(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()
|