// ==UserScript==
// @name 亿赛通oa工时自动计算
// @namespace http://tampermonkey.net/
// @version 0.5.1
// @description 亿赛通oa工时自动计算脚本 http://jsrun.net/2wsKp.js
// @author hangj
// @match http://192.168.0.26:8080/*
// @match https://oa.esafenet.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=0.26
// @grant none
// ==/UserScript==
(function () {
'use strict'
// 计算平均值
function average(nums) {
return nums.length === 0 ? 0 : (nums.reduce((a, b) => a + b) / nums.length).toFixed(2)
}
// 计算总值
function sum(nums) {
return nums.length === 0 ? 0 : nums.reduce((a, b) => a + b).toFixed(2)
}
// 计算百分比
function percentage(num, total) {
return (num === 0 || total === 0) ? 0 : Math.round(num / total * 10000) / 100.00
}
function isHoliday(date, week) {
const holidaySetArray = ['2022-12-31', '2023-01-01', '2023-01-18', '2023-01-19', '2023-01-20', '2023-01-21', '2023-01-22', '2023-01-23', '2023-01-24', '2023-01-25', '2023-01-26', '2023-01-27', '2023-01-28', '2023-01-29', '2023-04-05', '2023-04-29', '2023-04-30', '2023-05-01', '2023-05-02', '2023-05-03', '2023-06-22', '2023-06-23', '2023-06-24', '2023-09-29', '2023-09-30', '2023-10-01', '2023-10-02', '2023-10-03', '2023-10-04', '2023-10-05', '2023-10-06', '2023-01-31', '2023-01-31', '2023-01-31', '2023-01-31',]
const fuckHolidaySetArray = ['2023-04-23', '2023-05-06', '2023-06-25', '2023-10-07', '2023-10-08']
const holidaySet = new Set(holidaySetArray)
const fuckHolidaySetSet = new Set(fuckHolidaySetArray)
if (holidaySet.has(date)) {
return true
} else if (fuckHolidaySetSet.has(date)) {
return false
} else if (week === 0 || week === 6) {
return true
}
return false
}
// spans 解析读取转data
function spansToData(tr, dataArrayIds) {
const spans = tr.querySelectorAll('span.wea-url')
const data = {}
data.date = spans[2].innerText
data.week = spans[3].innerText
data.dept = spans[0].innerText
data.name = spans[1].innerText
data.er = spans[6].innerText
data.startTime = new Date(data.date + ' ' + spans[4].innerText)
data.endTime = new Date(data.date + ' ' + spans[5].innerText)
if (data.er !== '') {
data.endTime.setTime(data.endTime.getTime() + 1000 * 60 * 60 * 24)
}
data.hour = parseInt(data.endTime - data.startTime + '') / 1000 / 60 / 60
const isHolidayFlag = isHoliday(data.date, data.startTime.getDay())
let endTime = new Date(data.startTime.getTime() + 1000 * 60 * 60 * (isHolidayFlag ? 8 : 9.5))
if (new Date() > endTime) {
if (!isHolidayFlag && data.hour < 9.5) {
spans[6].innerText = spans[6].innerText + '(' + data.hour.toFixed(2) + 'h)'
tr.style['background-color'] = 'red'
tr.style['font-size'] = 'larger'
}
} else {
spans[6].innerText = spans[6].innerText + '(' + endTime.getHours() + ':' + endTime.getMinutes() + ':' + endTime.getSeconds() + ')'
spans[6].style.color = 'red'
}
if (dataArrayIds.has(data.date)) {
return null
}
return data
}
// 显示名称、所有数据、true 本月 false 上月 undefined 所有
function createHtml(name, value, moreMonth) {
const dayStartDate = new Date(new Date().toLocaleDateString())
const dayStartTime = dayStartDate.getTime()
dayStartDate.setDate(1)
const monthStartTime = dayStartDate.getTime()
const filterValue = value.filter(o => {
const time = o.startTime.getTime()
let monthFlag = true
if (moreMonth !== undefined) {
monthFlag = moreMonth ? (time >= monthStartTime) : (time < monthStartTime)
}
return monthFlag && time < dayStartTime && !isHoliday(o.date, o.week) && o.hour > 1
}).map(o => o.hour)
const val = average(filterValue)
return sum(filterValue) + '小时,' + filterValue.length + '天,' + name + ':' + val + '(' + percentage(val, 9.5) + '%)\n'
}
let isSelfChange = false
let mainTime = new Date().getTime()
function mainWhile() {
let main = document.querySelector('#themeLayoutRoute')
if (main == null) {
setTimeout(mainWhile, 1000)
} else {
listenerMainWhile()
// 页面加载完成后,监听主页面变动,修改主页面更新时间
main.addEventListener('DOMNodeInserted', () => {
const times = new Date().getTime() - mainTime
mainTime = new Date().getTime()
if (times > 3000) {
listenerMainWhile()
}
}, false)
}
}
function listenerMainWhile() {
if (new Date().getTime() - mainTime < 2000) {
setTimeout(listenerMainWhile, 1000)
} else {
if (isSelfChange == false) {
isSelfChange = true
tbodyWhile()
} else {
return
}
}
}
function tbodyWhile() {
const title = document.querySelector('.wea-new-top-title-breadcrumb')
const tbody = document.querySelector('.ant-table-tbody')
const trs = document.querySelectorAll('table > tbody > tr')
if (title == null || trs.length === 0) {
setTimeout(tbodyWhile, 1000)
} else {
(() => {
new Promise((resolve, reject) => {
if (title.innerText.startsWith('个人考勤查询')) {
doEst(title, tbody, trs)
resolve('解析成功')
} else {
resolve('非考勤页面,结束')
}
})
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => { isSelfChange = false })
})()
}
}
const dataArray = []
const dataArrayIds = new Set()
function doEst(title, tbody, trs) {
title.innerText = '个人考勤查询^_^ by jackkke'
trs.forEach(tr => {
const data = spansToData(tr, dataArrayIds)
if (data != null) {
dataArray.push(data)
dataArrayIds.add(data.date)
}
})
title.title = createHtml('月平均', dataArray, true) + createHtml('总平均', dataArray, undefined)
}
mainWhile()
})()