gqz / 工时计算器

// ==UserScript==
// @name         工时计算器
// @namespace    https://cloud.italent.cn/attendance#/indexPage?metaObjName=Attendance.AttendanceStatistics&app=Attendance&viewName=Attendance.AttendanceDataRecordNavView
// @version      0.1.8
// @description  EHR加班工时计算
// @icon         https://www.ztn.cn/img/new/favicon.ico
// @author       GQZ
// @match        https://www.italent.cn/portal/convoy/attendance*
// @match        https://cloud.italent.cn/attendance*
// @connect      cloud.italent.cn
// @grant        GM_log
// @grant        GM_xmlhttpRequest
// @require      https://cdn.bootcdn.net/ajax/libs/jquery/2.1.4/jquery.min.js
// @license      MIT
// @updateURL https://openuserjs.org/meta/gqz/工时计算器.meta.js
// @downloadURL https://openuserjs.org/install/gqz/工时计算器.user.js
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    function getStorage(key){
        return window.sessionStorage.getItem(key)
    }

    function getTimestamp() {
        return new Date().getTime();
    }

    function request(method, url, data = {}) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                url: url,
                method: method,
                headers: {
                },
                onload: function (xhr) {
                    resolve(JSON.parse(xhr.responseText))
                },
                onerror: function (err) {
                    console.log('error', err)
                    reject(err)
                }
            });
        })
    }

    async function get(url) {
        return await request('get', url)
    }

    async function post(url, data) {
        return new Promise((resolve, reject) => {
            let dataStr = JSON.stringify(data);
            GM_xmlhttpRequest({
                url: url,
                method: 'POST',
                responseType: "json",
                data: dataStr,
                headers: {
                    "Content-Type": "application/json"
                },
                onload: function (xhr) {
                    resolve(JSON.parse(xhr.responseText))
                },
                onerror: function (err) {
                    console.log('error', err)
                    reject(err)
                }
            });
        })
    }

    function checkUrl() {
        let temp1 = ''
        if(window.location.host !== 'cloud.italent.cn'){
            let url = new URL(window.location.href);
            temp1 = url.searchParams.get('_restoreHref');
            if (!temp1) {
                return false;
            }
        }else{
            temp1 = window.location.href;
        }
        var vars = temp1.split("?");
        return (new URLSearchParams('?' + vars[1])).get('viewName') == 'Attendance.AttendanceDataRecordNavView'
    }

    function addDom() {
        if (!jQuery('#ViewListLayer #totalHLD').length) {
            jQuery('#ViewListLayer').append('<div id="totalHLD" class="">加班时长 <i style="background: #000000;padding: 2px 8px;border-radius: 10px;">--</i> 分钟</div>')
        }
    }

    async function getSearchParms(){
        let pageParam = await get('https://cloud.italent.cn/api/v2/UI/IndexPage?metaObjName=Attendance.AttendanceStatistics&app=Attendance&viewName=Attendance.AttendanceDataRecordNavView&shadow_context=%7BappModel%3A%22italent%22%2Cuppid%3A%221%22%7D&_k=imr9ec&PaaS-SourceApp=Attendance&excludeDataSource=true&PaaS-CurrentView=Attendance.AttendanceDataRecordNavView&time=' + getTimestamp());
        return pageParam.sub_cmps.active_view.sub_cmps.search_form.biz_data;
    }

   function doCalc() {
        console.log('检查网址', checkUrl())
        if (!checkUrl()) {
            return;
        }
        setTimeout(() => {
            jQuery('.isFocusableButton').on('click', () => {
                jQuery('#totalHLD i').css('color', '#000').text('--')
                setTimeout(() => {
                    caleNum()
                }, 1000);
            })
        }, 3000);
        setTimeout(() => {
            addDom();
        }, 1000);
        caleNum();
    }

    async function caleNum() {
        try {
            let totalMin = 0;

            //let pageParam = await get('https://cloud.italent.cn/api/v2/UI/IndexPage?metaObjName=Attendance.AttendanceStatistics&app=Attendance&viewName=Attendance.AttendanceDataRecordNavView&shadow_context=%7BappModel%3A%22italent%22%2Cuppid%3A%221%22%7D&_k=imr9ec&PaaS-SourceApp=Attendance&excludeDataSource=true&PaaS-CurrentView=Attendance.AttendanceDataRecordNavView&time=' + getTimestamp());
            //let paramBizData = pageParam.sub_cmps.active_view.sub_cmps.search_form.biz_data;
            postParam.search_data.items=[];
            let localStorage = getStorage(storageKey)
            let paramBizData = []
            if(localStorage){
                 paramBizData =  JSON.parse(localStorage)
            }else{
                paramBizData = await getSearchParms()
            }

            for (let key in paramBizData) {
                postParam.search_data.items.push(Object.assign({}, paramItem, paramBizData[key]))
            }
            console.log('search_data',postParam.search_data.items)
            let data = await post('https://cloud.italent.cn/api/v2/UI/TableList?viewName=Attendance.SingleObjectListView.EmpAttendanceDataList&metaObjName=Attendance.AttendanceStatistics&app=Attendance&PaaS-SourceApp=Attendance&PaaS-CurrentView=Attendance.AttendanceDataRecordNavView&shadow_context=%7BappModel%3A%22italent%22%2Cuppid%3A%221%22%7D', postParam);

            for (const key in data.biz_data) {
                let durationStr = parseFloat(data.biz_data[key].WorkPeriod.value);
                if (durationStr < 9) {
                    continue;
                }
                let tempMin = durationStr - 9;
                totalMin += tempMin;
            }
            let totalMins = totalMin * 60
            let color = 'red';
            if (totalMins > 1500) {
                color = '#FF8000';
            }
            if (totalMins > 2000) {
                color = '#ffd700';
            }
            if (totalMins > 2500) {
                color = '#00C957';
            }
            addDom();
            jQuery('#totalHLD i').css('color', color).text(parseInt(totalMins.toFixed(2)))

        } catch (error) {
            console.log('err', error)
        }

    }

    let paramItem = { "name": "", "text": "", "value": "", "num": "", "metaObjName": "", "metaFieldRelationIDPath": "", "queryAreaSubNodes": false }
    let postParam = { "table_data": { "advance": { "cmp_render": { "viewPath": "MyAttendanceStatisticsTable", "status": "enable" } }, "hasCheckColumn": true, "ext_data": { "ListViewLabel": "我的考勤列表" }, "isEnableGlobleCheck": false, "hasRowHandler": true, "paging": { "total": 0, "capacity": 100, "page": 0, "capacityList": [15, 30, 60, 100] }, "isAvatars": true, "viewName": "Attendance.SingleObjectListView.EmpAttendanceDataList", "operateColumWidth": 140, "extendsParam": "", "isSyncRowHandler": true, "isFrozenOperationColumnHandler": false, "isCustomListViewExisted": false, "getTreeNodeUrl": null, "sort_fields": [{ "sort_column": "SwipingCardDate", "sort_dir": "desc" }], "description": "员工出勤列表", "metaObjName": "Attendance.AttendanceStatistics", "isCustomListView": false, "navViewIsCustom": false, "navViewName": "Attendance.AttendanceDataRecordNavView", "navViewVersion": "20211130154400588" }, "search_data": { "metaObjName": "Attendance.AttendanceStatistics", "searchView": "Attendance.EmpAttendanceDataSearch", "items": [], "searchFormFilterJson": null } };

    let storageKey = 'BEISEN_CLOUD_SSN____active_searchid_7b546bbd-3be2-4338-9de6-51b8cceb2750__1';

    (async function () {
        setTimeout(() => {
            doCalc();
        }, 2000);
        window.onhashchange = () => {
            doCalc()
        };
    })();

})();