hxp
2024-12-16 3bc897685e16d0855fec1aebaee3c90466fa851b
10162 后台优化(增加全服等级分布查询)
4个文件已修改
1个文件已添加
283 ■■■■■ 已修改文件
Account/User.php 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Common/CommFunc.php 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
index.php 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
js/common.js 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
serverrep/allplayerlv.php 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Account/User.php
@@ -27,7 +27,8 @@
                    Permission::P_REP_KeepLogin => array("Name" => \Lang\gettext("全服留存")),
                    Permission::P_REP_LTV => array("Name" => \Lang\gettext("全服LTV")),
                    Permission::P_REP_FirstLoginFirstPayCnt => array("Name" => \Lang\gettext("首登首充人数")),
                    Permission::P_REP_XPayPaycnt => array("Name" => \Lang\gettext("购买X礼包再付人数")),
                    Permission::P_REP_XPayPaycnt => array("Name" => \Lang\gettext("购买X礼包再次付费人数")),
                    Permission::P_All_PlayerLV => array("Name" => \Lang\gettext("全服等级分布")),
                )
            ),
            array(
@@ -219,6 +220,7 @@
    const P_REP_LTV = "P_REP_LTV";
    const P_REP_FirstLoginFirstPayCnt = "P_REP_FirstLoginFirstPayCnt";
    const P_REP_XPayPaycnt = "P_REP_XPayPaycnt";
    const P_All_PlayerLV = "P_All_PlayerLV";
    //服务器
    const P_Online = "P_Online";
Common/CommFunc.php
@@ -1447,3 +1447,50 @@
{
    return json_decode(GetFileContents(dirname(__FILE__) . "/mailtypes.json", "[]"), true);
}
// 组合服务器ID查询条件,搭配 common.js AddServerIDCondition 使用
function MatchServerIDCond(&$find, &$serverIDCondArray)
{
    if (!isset($serverIDCondArray)) {
        $serverIDCondArray = array();
    }
    $serverIDCondNumMax = 20;
    $serverIDCondIn = array();
    $serverIDCondFind = array();
    for ($i = 1; $i < $serverIDCondNumMax + 1; $i++) {
        if (!array_key_exists("ServerIDGTE" . $i, $_POST)) {
            continue;
        }
        $eValue = intval($_POST["ServerIDE" . $i]);
        $gteValue = intval($_POST["ServerIDGTE" . $i]);
        $lteValue = intval($_POST["ServerIDLTE" . $i]);
        // \Logging\LogInfo("serverIDCond." . $i . " : eValue:" . $eValue . " gteValue:" . $gteValue . " lteValue:" . $lteValue);
        if ($eValue <= 0 && $gteValue <= 0 && $lteValue <= 0) {
            continue;
        }
        if ($gteValue > 0 && $lteValue > 0 && $gteValue > $lteValue) {
            continue;
        }
        if ($eValue > 0) {
            array_push($serverIDCondIn, $eValue);
        }
        $cond = array();
        if ($gteValue > 0) {
            $cond['$gte'] = $gteValue;
        }
        if ($lteValue > 0) {
            $cond['$lte'] = $lteValue;
        }
        if (count($cond)) {
            array_push($serverIDCondFind, array("ServerID" => $cond));
        }
        array_push($serverIDCondArray, array($eValue, $gteValue, $lteValue));
    }
    if (count($serverIDCondIn) > 0) {
        array_push($serverIDCondFind, array("ServerID" => array('$in' => $serverIDCondIn)));
    }
    if (count($serverIDCondFind) > 0) {
        $find['$or'] = $serverIDCondFind;
    }
    // \Logging\LogInfo("find:" . json_encode($find));
}
index.php
@@ -44,7 +44,8 @@
        array(\User\Permission::P_REP_KeepLogin, "serverrep/keeplogin.php", \Lang\gettext("全服留存")),
        array(\User\Permission::P_REP_LTV, "serverrep/ltv.php", \Lang\gettext("全服LTV")),
        array(\User\Permission::P_REP_FirstLoginFirstPayCnt, "serverrep/firstLoginFirstPayCnt.php", \Lang\gettext("首登首充人数")),
        array(\User\Permission::P_REP_FirstLoginFirstPayCnt, "serverrep/xpaypaycnt.php", \Lang\gettext("购买X礼包再付人数")),
        array(\User\Permission::P_REP_FirstLoginFirstPayCnt, "serverrep/xpaypaycnt.php", \Lang\gettext("购买X礼包再次付费人数")),
        array(\User\Permission::P_All_PlayerLV, "serverrep/allplayerlv.php", \Lang\gettext("全服等级分布")),
    ),
    \Lang\gettext("服务器") => array(
js/common.js
@@ -122,7 +122,7 @@
    }
}
function doSubmit(to, p, method='GET') { // to:提交动作(action),p:参数
function doSubmit(to, p, method = 'GET') { // to:提交动作(action),p:参数
    var myForm = document.createElement("form");
    myForm.method = method;
    myForm.action = to;
@@ -152,6 +152,63 @@
    return true;
}
// 服务器ID条件,搭配 \CommFunc\MatchServerIDCond 使用
var serverIDCondNum = 0; // 服务器ID条件编号
function LoadServerIDCondition(serverIDCondArray) {
    var serverIDCondList = JSON.parse(serverIDCondArray);
    if (!serverIDCondList) {
        return;
    }
    for (let index = 0; index < serverIDCondList.length; index++) {
        const cond = serverIDCondList[index];
        const eValue = cond[0] > 0 ? cond[0] : "";
        const gteValue = cond[1] > 0 ? cond[1] : "";
        const lteValue = cond[2] > 0 ? cond[2] : "";
        AddServerIDCondition(eValue, gteValue, lteValue);
    }
}
function AddServerIDCondition(eValue, gteValue, lteValue) {
    var serverIDCondNumMax = 20; // 最大条件数
    if (serverIDCondNum >= serverIDCondNumMax) {
        alert("服务器ID条件超过最大个数: " + serverIDCondNumMax);
        return;
    }
    serverIDCondNum += 1;
    var serverIDCondition = "<div id=\"ServerIDCond" + serverIDCondNum + "\">" +
        "服务器ID条件" + (serverIDCondNum < 10 ? "&nbsp;&nbsp;" + serverIDCondNum : serverIDCondNum) + " => " +
        "&nbsp;&nbsp;等于: " + "<input type=\"number\" name=\"ServerIDE" + serverIDCondNum + "\"" +
        " id=\"ServerIDE" + serverIDCondNum + "\" value=\"" + eValue + "\" min=\"0\" style=\"width: 60px\" />" +
        "&nbsp;&nbsp;大于等于: " + "<input type=\"number\" name=\"ServerIDGTE" + serverIDCondNum + "\"" +
        " id=\"ServerIDGTE" + serverIDCondNum + "\" value=\"" + gteValue + "\" min=\"0\" style=\"width: 60px\" />" +
        "&nbsp;&nbsp;小于等于: " + "<input type=\"number\" name=\"ServerIDLTE" + serverIDCondNum + "\"" +
        " id=\"ServerIDLTE" + serverIDCondNum + "\" value=\"" + lteValue + "\" min=\"0\" style=\"width: 60px\" />" +
        "&nbsp;&nbsp;<a href=\"javascript:DelServerIDCondition(" + serverIDCondNum + ")\">删除</a>";
    "</div>";
    document.getElementById("ServerIDCondition").insertAdjacentHTML("beforeEnd", serverIDCondition);
}
function DelServerIDCondition(delNum) {
    document.getElementById("ServerIDCondition").removeChild(document.getElementById("ServerIDCond" + delNum));
}
function ResetServerIDCondition() {
    document.getElementById("ServerIDCondition").innerHTML = "";
    serverIDCondNum = 0;
}
/**复制 */
function copyToClipboard(text) {
    var textarea = document.createElement('textarea');
    textarea.style.position = 'fixed';
    textarea.style.opacity = 0;
    textarea.value = text;
    document.body.appendChild(textarea);
    textarea.select();
    document.execCommand('copy');
    document.body.removeChild(textarea);
}
/**
 * 绘制曲线图
 * @param {*} chartID 图表ID,关联html中的元素ID
@@ -162,7 +219,7 @@
 * @param {*} datasetDataList 数据表数据列表,即每条线的数据,线的数据长度必须与x轴刻度文本列表长度一致
 * @param {*} datasetLabList 数据表标题列表,即每条线的标题,有几条线的数据即有几个标题
 */
 function drawChart_Line(chartID, chartText, xText, yText, labels, datasetDataList, datasetLabList = []) {
function drawChart_Line(chartID, chartText, xText, yText, labels, datasetDataList, datasetLabList = []) {
    var backgroundColors = [
        'rgba(79, 66, 255, 0.2)',
        'rgba(255, 99, 132, 0.2)',
serverrep/allplayerlv.php
New file
@@ -0,0 +1,168 @@
<?php
include_once "/Common/Logging.php";
include_once "/Account/User.php";
include_once "/language/lang.php";
include_once "/serverrep/report.php";
\Logging\CreateLogging("rep.allplayerlv.php");
$Permission = \User\Permission::P_All_PlayerLV;
$alertMsg = "";
$channel = $_SESSION['spid'];
$UserAccount = $_SESSION['UserAccount'];
$user = new \User\User($UserAccount);
if (!$user->HavePermission($Permission)) {
    exit;
}
// $startDate = array_key_exists("startDate", $_POST) ? $_POST["startDate"] : date("Y-m-d", strtotime("-7 days"));
// $endDate = array_key_exists("endDate", $_POST) ? $_POST["endDate"] : date("Y-m-d");
$match = array("Channel" => $channel);
\CommFunc\MatchServerIDCond($match, $serverIDCondArray);
\Logging\LogInfo("match:" . print_r($match, true));
$showByServerID = $_POST["showByServerID"];
$_id = array('LV' => '$LV');
if ($showByServerID) {
    $_id = array('ServerID' => '$ServerID', 'LV' => '$LV');
}
$ret = \DBOper\Aggregate("ServerRoles", array(
    array(
        '$match' => $match,
    ),
    array(
        '$group' => array(
            '_id' => $_id,
            'count' => array('$sum' => 1),
        )
    )
), $retInfo);
// \Logging\LogInfo("retInfo:" . print_r($retInfo, true));
$serverLVCountInfo = array();
foreach ($retInfo as $info) {
    $_idInfo = $info["_id"];
    $key = $showByServerID ? $_idInfo["ServerID"] . "" : "0";
    $LV = $_idInfo["LV"];
    $count = $info["count"];
    if (!$serverLVCountInfo[$key]) {
        $serverLVCountInfo[$key] = array();
    }
    $lvCountInfo = $serverLVCountInfo[$key];
    $lvCountInfo[$LV . ""] = $count;
    $serverLVCountInfo[$key] = $lvCountInfo;
}
// \Logging\LogInfo("serverLVCountInfo:" . print_r($serverLVCountInfo, true));
?>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title><?php echo \Lang\gettext("全服等级分布"); ?></title>
    <link rel="gettext" type="application/x-po" href="../language/<?php echo \Lang\getLang(); ?>/LC_MESSAGES/<?php echo \Lang\getjspodomain(); ?>.po" />
</head>
<body>
    <center>
        <p><b><?php echo \Lang\gettext("全服等级分布"); ?></b></P>
    </center>
    <form method="post">
        &nbsp;&nbsp;<input type="button" value="添加服务器ID条件" onclick="AddServerIDCondition('', '', '')" />
        &nbsp;&nbsp;<input type="button" value="重置条件" onclick="ResetServerIDCondition()" />
        &nbsp;&nbsp;
        <input type="checkbox" name="showByServerID" id="showByServerID" <?php echo $showByServerID == "on" ? "checked" : ""; ?> />区服独立显示
        &nbsp;&nbsp;<input type="submit" value="<?php echo \Lang\gettext("查询"); ?>" />
        &nbsp;&nbsp;<input type="button" value="<?php echo \Lang\gettext("复制数据"); ?>" onclick="onCopyData()" />
        <div id="ServerIDCondition"></div>
        <hr />
        <div id="MyChart"></div>
    </form>
</body>
<script type='text/javascript' src='/language/gettext.js'></script>
<script type='text/javascript' src="/js/calendar.js"></script>
<script type='text/javascript' src="/js/common.js"></script>
<script type='text/javascript' src="/js/chart.min.js"></script>
<script type="text/javascript">
    var copydata = "";
    window.onload = function() {
        LoadServerIDCondition('<?php echo json_encode($serverIDCondArray); ?>');
        var showByServerID = <?php echo json_encode($showByServerID); ?>;
        var serverLVCountInfo = JSON.parse('<?php echo json_encode($serverLVCountInfo); ?>');
        // console.log("showByServerID", showByServerID);
        // console.log("serverLVCountInfo", serverLVCountInfo);
        var serverIDList = [];
        for (const serverID in serverLVCountInfo) {
            serverIDList.push(parseInt(serverID));
        }
        serverIDList.sort((a, b) => a - b); // 按区服顺序展示
        // console.log("serverIDList", serverIDList);
        copydata += "<table><tr>";
        for (let index = 0; index < serverIDList.length; index++) {
            const serverID = serverIDList[index];
            const lvCountInfo = serverLVCountInfo[serverID + ""];
            // console.log("serverID", serverID, lvCountInfo);
            let xLabels = [];
            let yDatas = [];
            let totalCnt = 0;
            for (const lv in lvCountInfo) {
                const lvCnt = lvCountInfo[lv];
                xLabels.push(lv);
                yDatas.push(lvCnt);
                totalCnt += lvCnt;
            }
            let datas = {
                "人数": yDatas
            };
            let chartID = "myChart" + serverID; // 图表ID,关联html中的元素ID
            let insHtml = "";
            insHtml += "<canvas id=\"" + chartID + "\" ></canvas>"; // 插入画布
            insHtml += "<hr />";
            document.getElementById("MyChart").insertAdjacentHTML("beforeEnd", insHtml);
            let chartText = serverID == 0 ? "全服" : "s" + serverID; // 图表总标题
            chartText += " 总人数: " + totalCnt;
            let xText = "等级"; // x轴文本, 如等级
            let yText = "人数"; // y轴文本, 如人数
            // (图标ID, 图标标题, x轴文本, y轴文本, x轴刻度文本列表, y轴数据列表, y轴数据标题列表)
            drawChart_Line(chartID, chartText, xText, yText, xLabels, Object.values(datas), Object.keys(datas));
            // 复制数据
            copydata += "<td>";
            copydata += "<table>";
            copydata += "<tr><td>服务器: " + chartText + "</td></tr>";
            copydata += "<tr><td>等级</td><td>人数</td></tr>";
            for (let index = 0; index < xLabels.length; index++) {
                const lv = xLabels[index];
                const playerCount = yDatas[index];
                copydata += "<tr><td>" + lv + "</td><td>" + playerCount + "</td></tr>";
            }
            copydata += "<tr></tr>";
            copydata += "</table>";
            copydata += "</td>";
        }
        copydata += "</tr></table>";
    }
    function onCopyData() {
        if (!copydata) {
            alert("没有数据");
            return
        }
        copyToClipboard(copydata);
        alert("表格复制成功,可直接粘贴到Excel工作表!");
    }
</script>
</html>