計算累計時數
// ==UserScript==
// @name 計算時數小工具
// @namespace amltbXlfd3U=
// @version 0.9
// @description 計算累計時數
// @author Jimmy
// @match https://cy.iwerp.net/portal/page/new_home.xhtml
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// @run-at document-idle
// @license MIT
// ==/UserScript==
(function () {
'use strict';
function main() {
removeMachine();
const tableContainer = document.querySelector('#formTemplate\\:attend_rec_datatable');
if (tableContainer) {
const panelContainer = document.querySelector('#formTemplate\\:attend_rec_panel_content');
const container = document.createElement('div');
container.setAttribute('id', 'formTemplate:result');
container.style.paddingTop = '25px';
container.style.textAlign = 'center';
if (!document.querySelector('#formTemplate\\:result')) {
panelContainer.appendChild(container);
}
const table = tableContainer.querySelector('table[role="grid"]')
const tableObj = tableToObj(table);
const signInTime = tableObj[0].簽到.match(/\b\d{2}:\d{2}\b/);
const result = calculateWorkSchedule(signInTime);
let message = result.message;
if (result.lateMinutes > 0) {
message += `<br>遲到時間: ${result.lateMinutes} 分鐘`;
if (result.requiredLeave) {
message += `<br>應請假從 ${result.requiredLeave.start} 到 ${result.requiredLeave.end}`;
} else {
message += "<br>無需請假";
}
}
document.querySelector('#formTemplate\\:result').innerHTML = message;
}
}
function tableToObj(table) {
var rows = table.rows;
var propCells = rows[0].cells;
var propNames = [];
var results = [];
var obj, row, cells;
for (var i = 0, iLen = propCells.length; i < iLen; i++) {
propNames.push(propCells[i].textContent || propCells[i].innerText);
}
for (var j = 1, jLen = rows.length; j < jLen; j++) {
cells = rows[j].cells;
obj = {};
for (var k = 0; k < iLen; k++) {
obj[propNames[k]] = cells[k].textContent || cells[k].innerText;
}
results.push(obj)
}
return results;
}
function debounce(fn, delay) {
var timeout = null;
return function () {
if (timeout) {
return;
} else {
timeout = setTimeout(function () {
fn();
timeout = null;
}, delay);
}
}
}
function calculateWorkSchedule(checkInTime) {
const workSchedules = [
{ start: "08:00", end: "17:00", bufferEnd: "08:15" },
{ start: "08:30", end: "17:30", bufferEnd: "08:45" },
{ start: "09:00", end: "18:00", bufferEnd: "09:15" },
{ start: "09:30", end: "18:30", bufferEnd: "09:45" }
];
const checkIn = new Date(`1970-01-01T${checkInTime}:00`);
let schedule = workSchedules[3];
for (const ws of workSchedules) {
if (checkIn <= new Date(`1970-01-01T${ws.bufferEnd}:00`)) {
schedule = ws;
break;
}
}
const startWorkTime = new Date(`1970-01-01T${schedule.start}:00`);
const endWorkTime = new Date(`1970-01-01T${schedule.end}:00`);
const bufferTime = new Date(startWorkTime.getTime() + 15 * 60000);
let lateMinutes = 0;
let leaveStart = null;
let leaveEnd = null;
if (checkIn > bufferTime) {
const fixedStartWorkTime = new Date(`1970-01-01T09:30:00`);
const fixedEndWorkTime = new Date(`1970-01-01T18:30:00`);
const fixedBufferTime = new Date(fixedStartWorkTime.getTime() + 15 * 60000);
lateMinutes = Math.ceil((checkIn - fixedStartWorkTime) / 60000);
const leaveDuration = Math.max(60, Math.ceil(lateMinutes / 30) * 30); // 最少請假1小時,每30分鐘遞增
leaveStart = fixedStartWorkTime;
leaveEnd = new Date(fixedStartWorkTime.getTime() + leaveDuration * 60000);
return {
message: `您的下班時間是${fixedEndWorkTime.toTimeString().substr(0, 5)}`,
lateMinutes: lateMinutes,
requiredLeave: {
start: leaveStart.toTimeString().substr(0, 5),
end: leaveEnd.toTimeString().substr(0, 5)
}
};
}
return {
message: `您的下班時間是${schedule.end}`,
lateMinutes: lateMinutes,
requiredLeave: null
};
}
function removeMachine() {
var cells = document.querySelectorAll('td');
cells.forEach(function (cell) {
var regex = /(\d{2}:\d{2})\((.*?)\)/;
var match = regex.exec(cell.textContent);
if (match !== null) {
var time = match[1];
var removedContent = match[2];
cell.dataset.removedContent = removedContent;
cell.textContent = time;
cell.addEventListener('mouseover', function () {
cell.textContent = time + ' (' + removedContent + ')';
});
cell.addEventListener('mouseout', function () {
cell.textContent = time;
});
}
});
}
main();
var el = document.documentElement;
el.addEventListener('DOMSubtreeModified', debounce(main, 2000));
})();