禅道任务统计(自用)

统计禅道任务的工时

目前為 2023-06-08 提交的版本,檢視 最新版本

// ==UserScript==
// @name         禅道任务统计(自用)
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  统计禅道任务的工时
// @author       zyb
// @match        http://zentao.ngarihealth.com/index.php?m=my&f=task*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=ngarihealth.com
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    // Your code here...

    setTimeout(init, 2000)

    // 初始化函数
    function init() {

        // 数据处理
        let commonRequirementsList = [];
        let assignedRequirementsList = [];
        let trListDom = Array.from(document.querySelectorAll('#main #mainContent tbody tr')) || [];
        trListDom.forEach(itemDom => {
            // id
            const id = itemDom.querySelectorAll('.c-id')[0].querySelectorAll('.checkbox-primary input')[0].value;
            // 预计开始日期
            const dateStr = itemDom.querySelectorAll('td:nth-child(6)')[0].innerText;
            // 预计工时
            const estimateTime = +itemDom.querySelectorAll('td:nth-child(10)')[0].innerText;
            // 消耗工时
            const consumeTime = +itemDom.querySelectorAll('td:nth-child(11)')[0].innerText;

            if (dateStr) {
                // 平常的需求
                commonRequirementsList.push({ dateStr, estimateTime, consumeTime, id })
            } else {
                // 被分配的需求
                assignedRequirementsList.push({ dateStr, estimateTime, consumeTime, id })
            }
        })

        // 日期处理
        let nowMonth = new Date().getMonth() + 1;
        let previousMonth = (nowMonth === 1) ? 12 : (nowMonth - 1);
        // 处理完后存储的数据
        let dataForMonthObj = {
            // 本月的任务数据
            nowMonth: [],
            // 本月的月份
            nowMonthStr: '',
            // 本月预计工时
            estimateTime: 0,
            // 本月实际消耗工时
            consumeTime: 0,
            // 上个月的任务数据
            preMonth: [],
            // 上个月的月份
            preMonthStr: '',
            // 上个月预计工时
            preEstimateTime: 0,
            // 上个月实际消耗工时
            preConsumeTime: 0,
        };

        // 过滤平常任务的不同月份的数据
        commonRequirementsList.forEach(item => {
            if (!item.dateStr) {
                return;
            }

            // 当前数据的开始时间月份
            let month = new Date(item.dateStr).getMonth() + 1;

            // 如果是本月数据
            if (month === nowMonth) {
                dataForMonthObj.nowMonth.push(item);
                dataForMonthObj.nowMonthStr = month;
                dataForMonthObj.estimateTime += item.estimateTime;
                dataForMonthObj.consumeTime += item.consumeTime;
            }
            // 如果是上月数据
            if (month === previousMonth) {
                dataForMonthObj.preMonth.push(item);
                dataForMonthObj.preMonthStr = month;
                dataForMonthObj.preEstimateTime += item.estimateTime;
                dataForMonthObj.preConsumeTime += item.consumeTime;
            }
        });

        // 如果没有被分配的需求,则不需要后续调用接口操作
        if (!assignedRequirementsList.length) {
            setDivValueFuc(dataForMonthObj, true);
            return;
        }

        // 获取被分配的需求的日期
        const promiseList = assignedRequirementsList.map(async (item) => {
            // 设置请求的url
            let url = `http://zentao.ngarihealth.com/index.php?m=task&f=view&taskID=${item.id}`
            // 将异步请求转为同步,目的是减少服务器压力,以免被检测后封锁ip
            const resolve = await ajaxAsyncFuc({ url });

            return { data: resolve, object: item };
        });

        // 等待所有请求完成后,对不同月份的数据进行处理
        Promise.all(promiseList).then(res => {

            res.map(item => {
                // 创建一个div的Dom节点,将接口返回的HTML字符串转为Dom节点
                let div = document.createElement('div');
                div.innerHTML = item.data;
                const trDom = div.querySelectorAll('#legendLife tbody tr:nth-child(2)')[0];
                const value = trDom.querySelectorAll('td')[0].innerText;
                // 创建正则规则,匹配yyyy-MM-dd或yyyy/MM/dd时间格式
                const regex = /\d{4}[-/]\d{2}[-/]\d{2}/g;

                const obj = {
                    ...item.object,
                    // 截取符合正则规则的字符串,即任务日期
                    dateStr: value.match(regex)[0],
                };

                // 当前数据的开始时间月份
                let month = new Date(obj.dateStr).getMonth() + 1;

                // 如果是本月数据
                if (month === nowMonth) {
                    dataForMonthObj.nowMonth.push(obj);
                    dataForMonthObj.nowMonthStr = month;
                    dataForMonthObj.estimateTime += obj.estimateTime;
                    dataForMonthObj.consumeTime += obj.consumeTime;
                }
                // 如果是上月数据
                if (month === previousMonth) {
                    dataForMonthObj.preMonth.push(obj);
                    dataForMonthObj.preMonthStr = month;
                    dataForMonthObj.preEstimateTime += obj.estimateTime;
                    dataForMonthObj.preConsumeTime += obj.consumeTime;
                }

                return obj
            })
            setDivValueFuc(dataForMonthObj, false);
        });

    }

    // 将处理完的数据显示到页面上
    function setDivValueFuc(dataForMonthObj, tipsFlag) {
        let mainMenuDom = document.querySelectorAll('#mainMenu')[0];
        let divDom = document.createElement('div');
        divDom.style = 'height:33px;display:flex;align-items: center;padding:10px'
        divDom.innerHTML = `
		  <!--<span>${dataForMonthObj.nowMonthStr}月预计时间:<span style="color:red">${dataForMonthObj.estimateTime}</span>工时;</span>-->
		  <span>${dataForMonthObj.nowMonthStr}月消耗时间:<span style="color:red">${dataForMonthObj.consumeTime}</span>工时;</span>
		  <!--<span>${dataForMonthObj.preMonthStr}月预计时间:<span style="color:red">${dataForMonthObj.preEstimateTime}</span>工时;</span>-->
		  <span>${dataForMonthObj.preMonthStr}月消耗时间:<span style="color:red">${dataForMonthObj.preConsumeTime}</span>工时;</span>
          ${tipsFlag ? ('<span style="color:red">注意!未统计被分配的需求的工时</span>') : ('<span></span>')}
		`;
        mainMenuDom.appendChild(divDom);

        console.log('dataForMonthObj', dataForMonthObj)
        console.log('estimateTime', dataForMonthObj.estimateTime)
        console.log('consumeTime', dataForMonthObj.consumeTime)
        console.log('preEstimateTime', dataForMonthObj.preEstimateTime)
        console.log('preConsumeTime', dataForMonthObj.preConsumeTime)
    }

    // 发送ajax数据
    async function ajaxAsyncFuc(obj = {}) {
        return new Promise(function (resolve, reject) {
            // 发送数据
            const xhr = new XMLHttpRequest(); // 创建XMLHttpRequest对象
            const url = obj.url || ''; // 要访问的URL地址
            const contentType = obj.contentType || 'application/x-www-form-urlencoded'; // 设置请求头
            const type = obj.type || "GET"; // 定义请求方法
            const data = obj.data;

            xhr.open(type, url); // 定义请求方法和URL
            xhr.setRequestHeader('Content-type', contentType); // 设置请求头

            // 处理请求响应
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        // console.log(xhr.responseText); // 响应内容将会被打印到控制台
                        resolve(xhr.responseText);
                    } else {
                        reject();
                    }
                }
            }

            // 发送POST请求
            xhr.send(data); // 动态添加请求数据
        })
    }

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址