生财有术志愿者后台打卡统计专用

https://i.shengcaiyoushu.com/volunteer/operation/activity/user?id=XXX 作为一个懒人,不想手动统计,干脆做个工具一目了然

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         生财有术志愿者后台打卡统计专用
// @namespace    http://www.heigoou.com
// @version      1.1
// @description  https://i.shengcaiyoushu.com/volunteer/operation/activity/user?id=XXX 作为一个懒人,不想手动统计,干脆做个工具一目了然
// @author       北封,jexxx
// @match        https://i.shengcaiyoushu.com/volunteer/operation/activity/user*
// @require      https://fastly.jsdelivr.net/npm/[email protected]/dist/echarts.min.js
// @icon         data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMzYwcHgiIGhlaWdodD0iMzYwcHgiIHZpZXdCb3g9IjAgMCAzNjAgMzYwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA2MC4xICg4ODEzMykgLSBodHRwczovL3NrZXRjaC5jb20gLS0+CiAgICA8dGl0bGU+57yW57uEPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+CiAgICAgICAgPHBvbHlnb24gaWQ9InBhdGgtMSIgcG9pbnRzPSIxLjEzMzQwMjI0ZS0wNSAwIDM1OS45OTk4NjMgMCAzNTkuOTk5ODYzIDM2MCAxLjEzMzQwMjI0ZS0wNSAzNjAiPjwvcG9seWdvbj4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSIxLjEt5by556qXIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0i57yW57uEIj4KICAgICAgICAgICAgPGc+CiAgICAgICAgICAgICAgICA8bWFzayBpZD0ibWFzay0yIiBmaWxsPSJ3aGl0ZSI+CiAgICAgICAgICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgIDwvbWFzaz4KICAgICAgICAgICAgICAgIDxnIGlkPSJDbGlwLTIiPjwvZz4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xOTAuMTU5NCwzMzUuMDA1MiBDOTYuNTE4NCwzNDAuOTk2MiAxOS4wMDA0LDI2My40NzgyIDI0Ljk5MzQsMTY5LjgzODIgQzI5Ljk0NjQsOTIuNDQ2MiA5Mi40NjE0LDI5LjkzNjIgMTY5Ljg1MjQsMjQuOTkxMiBDMjYzLjQ4MjQsMTkuMDA5MiAzNDAuOTg3NCw5Ni41MTMyIDMzNS4wMDg0LDE5MC4xNDQyIEMzMzAuMDYzNCwyNjcuNTM3MiAyNjcuNTUzNCwzMzAuMDUzMiAxOTAuMTU5NCwzMzUuMDA1MiBNMTg4LjQ0ODQsMC4xOTQyIEM4Mi41NDE0LC00LjY3MzggLTQuNjczNiw4Mi41NDIyIDAuMTk0NCwxODguNDQ3MiBDNC40Mzg0LDI4MC43ODMyIDc5LjIxNjQsMzU1LjU2MTIgMTcxLjU1MjQsMzU5LjgwNjIgQzI3Ny40NTc0LDM2NC42NzQyIDM2NC42NzQ0LDI3Ny40NTkyIDM1OS44MDU0LDE3MS41NTIyIEMzNTUuNTU4NCw3OS4yMTYyIDI4MC43ODM0LDQuNDQxMiAxODguNDQ4NCwwLjE5NDIiIGlkPSJGaWxsLTEiIGZpbGw9IiMwQTVENEYiIG1hc2s9InVybCgjbWFzay0yKSI+PC9wYXRoPgogICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNjYuMzQ5OCwyMDguOTY4MSBMMTY2LjM0OTgsMjIxLjc4OTEgTDE0OC43MjM4LDIyMS43ODkxIEMxNDguMDYxOCwyMjEuNzg5MSAxNDcuODA3OCwyMjAuOTI0MSAxNDguMzYzOCwyMjAuNTY0MSBMMTY2LjM0OTgsMjA4Ljk2ODEgWiBNMTkzLjY0ODgsMTYxLjQ5MTEgTDE5My42NDg4LDE0OS4wMTAxIEwyMTAuNTk4OCwxNDkuMDEwMSBDMjExLjMzNjgsMTQ5LjAxMDEgMjExLjYyMDgsMTQ5Ljk3NTEgMjEwLjk5NzgsMTUwLjM3MzEgTDE5My42NDg4LDE2MS40OTExIFogTTI0Ny40NjY4LDIyMS43ODkxIEwxOTMuODc3OCwyMjEuNzg5MSBMMTkzLjY1MDgsMjE5LjU5MjEgTDE5My42NDg4LDE5MS40NzkxIEwyNDguMTM1OCwxNTYuNzY4MSBDMjUzLjQ2MzgsMTUzLjM3MzEgMjU2Ljc0NTgsMTQ1LjM5ODEgMjU0LjIwMzgsMTM2Ljg1NTEgQzI1MS43ODI4LDEyOS4yNzIxIDI0NC43MzM4LDEyNC4xMjQxIDIzNi43NzI4LDEyNC4xMjQxIEwxOTMuNjQ4OCwxMjQuMTI0MSBMMTkzLjY0ODgsODcuOTcyMSBDMTkzLjY0ODgsODQuMTYzMSAxOTAuNTYwOCw4MS4wNzYxIDE4Ni43NTE4LDgxLjA3NjEgTDE3My4yNDI4LDgxLjA3NjEgQzE2OS40MzU4LDgxLjA3NjEgMTY2LjM0OTgsODQuMTYyMSAxNjYuMzQ5OCw4Ny45NjkxIEwxNjYuMzQ5OCwxMjQuMTI0MSBMMTEyLjc0NjgsMTI0LjEyNDEgQzEwNy45Nzk4LDEyNC4xMjQxIDEwNC4xMTI4LDEyNy45ODkxIDEwNC4xMTI4LDEzMi43NTkxIEwxMDQuMTEyOCwxNDAuMjA5MSBDMTA0LjExMjgsMTQ1LjA3MTEgMTA4LjA1MzgsMTQ5LjAxMDEgMTEyLjkxMjgsMTQ5LjAxMDEgTDE2Ni4zNDk4LDE0OS4wMTAxIEwxNjYuMzQ5OCwxNzkuMDEzMSBMMTEyLjczMjgsMjEzLjQxODEgQzEwNi44Njg4LDIxNy4xODgxIDEwMy4yMjM4LDIyNS44MTIxIDEwNS40OTQ4LDIzMy41NzIxIEMxMDcuODUwOCwyNDEuMjM5MSAxMTQuOTMzOCwyNDYuNDc0MSAxMjIuOTU2OCwyNDYuNDc0MSBMMTY2LjM0OTgsMjQ2LjQ3NDEgTDE2Ni4zNDk4LDI3NS41NDQxIEMxNjYuMzQ5OCwyNzkuMzU0MSAxNjkuNDM3OCwyODIuNDQwMSAxNzMuMjQ1OCwyODIuNDQwMSBMMTg2Ljc2MDgsMjgyLjQ0MDEgQzE5MC41NjQ4LDI4Mi40NDAxIDE5My42NDg4LDI3OS4zNTgxIDE5My42NDg4LDI3NS41NTMxIEwxOTMuNjQ4OCwyNDYuNDc0MSBMMjQ3LjU2MDgsMjQ2LjQ3NDEgQzI1Mi4xNTY4LDI0Ni40NzQxIDI1NS44ODM4LDI0Mi43NDYxIDI1NS44ODM4LDIzOC4xNTAxIEwyNTUuODgzOCwyMzAuMjA0MSBDMjU1Ljg4MzgsMjI1LjU1NzEgMjUyLjExNjgsMjIxLjc4OTEgMjQ3LjQ2NjgsMjIxLjc4OTEgTDI0Ny40NjY4LDIyMS43ODkxIFoiIGlkPSJGaWxsLTMiIGZpbGw9IiMwQTVENEYiPjwvcGF0aD4KICAgICAgICAgICAgPHBhdGggZD0iTTIyOC45Mjg5LDEwNi42NjQ0IEwyNDEuMTM0OSwxMDYuNjY0NCBDMjQ1LjI0NTksMTA2LjY2NDQgMjQ4LjU3ODksMTAzLjMzMTQgMjQ4LjU3ODksOTkuMjIxNCBMMjQ4LjU3ODksODguNTIzNCBDMjQ4LjU3ODksODQuNDExNCAyNDUuMjQzOSw4MS4wNzY0IDI0MS4xMzE5LDgxLjA3NjQgTDIyOC45Mjg5LDgxLjA3NjQgQzIyNC44MTg5LDgxLjA3NjQgMjIxLjQ4NTksODQuNDA5NCAyMjEuNDg1OSw4OC41MTk0IEwyMjEuNDg1OSw5OS4yMjE0IEMyMjEuNDg1OSwxMDMuMzMxNCAyMjQuODE4OSwxMDYuNjY0NCAyMjguOTI4OSwxMDYuNjY0NCIgaWQ9IkZpbGwtNSIgZmlsbD0iIzBBNUQ0RiI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+
// @grant        none
// @license GPLv3
// @run-at document-end

// ==/UserScript==

(function () {

    'use strict';
    let baseData = data;
    let stage = baseData.stage;
    let xData = [];
    let dayInfo = {};

    for (let d = 0; d < stage.length; d++) {
        let dayItem = stage[d];

        let time = dayItem.gmt_start * 1000;
        if (time > new Date().getTime()) {
            // 还没到的时间,就不统计了
            break;
        }

        let date = new Date(time);
        let year = date.getFullYear();
        let month = date.getMonth() + 1; // 月份
        let day = date.getDate(); // 日
        let dayStr = year + '-' + month + '-' + day;

        let dayData = {
            id: dayItem.id,
            idx: dayItem.idx,
            name: dayItem.name,
            dayStr: dayStr,
        };
        dayInfo[dayData.id] = dayData;
        xData.push(dayData.name + '\r\n' + dayData.dayStr);
    }
    $('.cxd-Panel--form').after('<div id="bf-container" style="width: 100%;height: 400px"></div>');
    $('#bf-container').after('<div id="pf-container" style="width: 100%;height: 400px"></div>');
    $('#pf-container').after('<div id="text-container" style="width: 90%;margin-left:auto;"></div>')
    $.post(window.location.href.replace('user', 'user/ajax'), function (response) {
        var items = response.data.items
        var result = {};
        // let totalPeople = Object.keys(response.data.extra.user).length;
        let yDaKaDataObject = {};
        const days = Object.keys(dayInfo);
        const highPoints = []; // 重点关注对象
        let wxids = new Set();
        for (let dd = 0; dd < days.length; dd++) {
            const dInfo = dayInfo[days[dd]];
            for (var k = 0; k < items.length; k++) {
                const item = items[k];
                if (item.identity) {
                    // identity: "志愿者" 领队 教练角色不统计
                    continue;
                }
                wxids.add(item.info['微信号(微信ID)']);
                yDaKaDataObject[dInfo['id']] = yDaKaDataObject[dInfo['id']] || {};


                var cnt = item.project_cnt;
                if (!result[cnt]) {
                    result[cnt] = [];
                }
                var name = response.data.extra.user[item.xq_group_number]['name'];
                var wx_name = response.data.extra.user[item.xq_group_number]['wx_name'];
                if (name != wx_name) {
                    name = name + '(' + wx_name + ')';
                }
                var user = name;
                var project_left_cnt = item.project_left_cnt;
                if (dd === 0) highPoints.push({ user, cnt, project_left_cnt });
                if (!result[cnt].includes(user)) {
                    result[cnt].push(user);
                }
                const project = item.project;
                yDaKaDataObject[dInfo['id']]['n'] = yDaKaDataObject[dInfo['id']]['n'] || [];
                yDaKaDataObject[dInfo['id']]['y'] = yDaKaDataObject[dInfo['id']]['y'] || [];

                if (project) {
                    if (project[dInfo['id']]) {
                        yDaKaDataObject[dInfo['id']]['y'].push(user);

                    } else {
                        yDaKaDataObject[dInfo['id']]['n'].push(user);
                    }


                } else {
                    if (!yDaKaDataObject[dInfo['id']]['n'].includes(user)) {
                        yDaKaDataObject[dInfo['id']]['n'].push(user);
                    }
                }


            }


        }

        let yNoDaKaData = [];
        let yDaKaData = [];

        for (let da = 0; da < days.length; da++) {
            const dayDaka = yDaKaDataObject[days[da]];
            const dayStep = dayInfo[days[da]];
            let daKaData = {
                value: dayDaka['y'].length,
                names: dayDaka['y'],
                percent: (Math.round((dayDaka['y'].length / (dayDaka['y'].length+dayDaka['n'].length)) * 100) / 100),
            };
            yDaKaData.push(daKaData);
            let ndaKaData = {
                value: dayDaka['n'].length,
                names: dayDaka['n'],
                percent: (Math.round((dayDaka['n'].length / (dayDaka['y'].length+dayDaka['n'].length)) * 100) / 100),
            };
            yNoDaKaData.push(ndaKaData)

        }

        var text = '';
        var keys = Object.keys(result);
        var step = 0;
        var _highPoints = highPoints.sort(function (a, b) {
            return Number(a.cnt) - Number(b.cnt);
        });
        for (var j = 0; j < keys.length; j++) {
            var day = keys[j];
            var people = result[day];
            step = step + people.length;
            text += '完成打卡 ' + day + ' 天的有 ' + people.length + ' 人,他们是:' + people + '<br>';
        }
        // console.log(text);
        // console.log(yNoDaKaData[yNoDaKaData.length-1].names);
        text += '-------------------------华丽的分割线-------------------------------------<br>'
        text += '今日未打卡人员>>>' + yNoDaKaData[yNoDaKaData.length - 1].names+'<br><br>';
        text += '微信ID:';
        for(let wId of wxids){
            text += wId+' , ';
        }
        $('#text-container').html(text)
        var dom = document.getElementById('bf-container');
        var pdom = document.getElementById('pf-container');
        var myChart = echarts.init(dom, null, { renderer: 'canvas', useDirtyRect: false });
        var myChart2 = echarts.init(pdom, null, { renderer: 'canvas', useDirtyRect: false });

        var option;

        option = {
            tooltip: {
                trigger: 'axis',
                backgroundColor: '#FFFFFF',
                borderColor: '#EEF1F7',
                borderWidth: 1,
                textStyle: {
                    width: 160,
                    height: 250,
                    lineHeight: 24,
                    color: '#666666',
                    fontSize: '14',
                    fontFamily: 'SourceHanSansCN-Normal'
                },
                formatter: params => {
                    // 获取xAxis data中的数据
                    let dataStr = `<div><p style="font-weight:bold;margin:0 8px 15px;">${params[0].axisValue} 打卡统计</p></div>`
                    params.forEach(item => {
                        dataStr += `<div>
          <div style="margin: 0 8px;">
            <span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:${item.color};"></span>
            <span>${item.seriesName} ${item.data.percent}:</span>
            <span style="float:right;color:#000000;margin-left:20px;">${item.data.value}人</span>`;
                        let names = item.data.names;
                        names.forEach(name => {
                            dataStr += `${name} `
                        });

                        //
                        //
                        dataStr +=
                            `</div>
        </div>`
                    })
                    return dataStr
                }
            },

            legend: {
            },
            // grid: {
            //   left: '3%',
            //   right: '4%',
            //   bottom: '3%',
            //   containLabel: true
            // },
            xAxis: {
                type: 'category',
                data: xData
            },
            yAxis: [
                {
                    type: 'value',
                    name: '积极打卡',
                },
                {
                    type: 'value',
                    name: '偷懒了~',
                },
            ],
            series: [
                {
                    name: '积极打卡',
                    type: 'bar',
                    stack: 'total',
                    label: {
                        show: true
                    },
                    emphasis: {
                        focus: 'series'
                    },
                    data: yDaKaData,

                },
                {
                    name: '偷懒了~',
                    type: 'bar',
                    stack: 'total',
                    label: {
                        show: true
                    },
                    emphasis: {
                        focus: 'series'
                    },
                    data: yNoDaKaData
                },
            ]
        };

        var option2 = {

            xAxis: {
                type: 'category',
                data: _highPoints.map(item => item.user),
                axisLabel: {
                    show: true,
                    interval: 0,
                    rotate: 40,
                    textStyle: {
                        color: '#333'
                    }
                },
            },
            yAxis: [
                {
                    type: 'value',
                    name: '打卡',
                },
            ],
            series: [
                {
                    name: '打卡',
                    type: 'bar',
                    stack: 'total',
                    label: {
                        show: true
                    },
                    emphasis: {
                        focus: 'series'
                    },
                    data: _highPoints.map(item => item.cnt),

                },
            ]
        };

        if (option && typeof option === 'object') {
            myChart.setOption(option);
        }

        if (option2 && typeof option2 === 'object') {
            myChart2.setOption(option2);
        }

        window.addEventListener('resize', () => {
            myChart.resize();
            myChart2.resize();
        });
    });
})();