Selon le règlement de l'entreprise, huit heures par mois, système de travail flexible. Donc, généralement, tout le monde n'arrive pas à l'heure. Si quelque chose arrive, ils rentrent tôt après avoir quitté le travail. Il n'y a donc peut-être pas assez d'heures de travail dans un mois, mais le calendrier de présence de l'entreprise est le suivant :
Sauf les congés et les jours fériés, les autres styles d'affichage sont les mêmes. Il est très gênant d'estimer les heures de travail approximatives de ce mois une par une à chaque fois. Plus tard, j'ai vu que quelqu'un dans l'entreprise utilisait une extension Chrome capable de calculer les heures de travail sur un mois, mais j'ai senti que je ne voyais toujours pas ce que je voulais voir, car en plus des heures de travail accumulées par mois, Je voulais aussi voir : la durée moyenne du travail par jour, la durée du travail par jour, le nombre de jours après 20h (ceux qui quittent le travail après 20h peuvent se faire rembourser le dîner, haha...), le nombre de jours où ils quittent le travail après 22 heures (le prix du taxi est remboursé)... J'ai donc décidé d'en écrire un moi-même.
Dans la première étape, j'ai écrit une méthode JS, puis je l'ai copiée et collée via la console de l'outil de développement F12 pour l'exécuter.
Le système OA utilisé par l'entreprise ne référence pas la bibliothèque jQuery, mon idée initiale était donc de référencer dynamiquement la bibliothèque de classes jQuery, comme suit :
Mais nous avons rencontré des problèmes : l'un est que $ est occupé, et l'autre est que le système RH utilise l'imbrication iframe, et il y a aussi l'imbrication de cadres, et la structure est très compliquée. Le code exécuté par la console est exécuté au niveau supérieur et le dernier plug-in d'extension Chrome est exécuté dans le cadre interne. Peut-être que le JS ici ne peut pas être utilisé directement. Bien que le problème de l'occupation de $ puisse être résolu par jQuery.noConflict();, il existe un problème d'ordre d'appel entre la bibliothèque jquery et la bibliothèque JS du système d'origine, et l'objet jQuery n'est pas accessible dans le cadre interne. Finalement, j'ai décidé d'abandonner jQuery et d'utiliser du JavaScript natif.
Le code JS est le suivant :
/* * author:清明雨上 * date:2016-1-5 */ var mydate = function() { //time2-time1 function getTimeDiff(time1, time2) { var st1 = time1.split(':'); var st2 = time2.split(':'); return ((st2[0] | 0) * 60 + (st2[1] | 0)) - ((st1[0] | 0) * 60 + (st1[1] | 0) * 1); } var timeList = []; var mymain = window.parent.frames['Main'].document.getElementById('ctl00_cphMain_CalendarAC'); var listAC = mymain.getElementsByClassName('listAC'); for (var i = 0; i < listAC.length; i++) { var item = listAC[i]; var t = {}; t.timeSpan = item.getElementsByTagName('td')[1].innerText; t.remark = item.getElementsByTagName('td')[2].innerText; timeList.push(t); }; var totalMin = 0; var noworkDays = 0; //请假天数 var workDays = 0; //实际上班天数 var workHourEveryday = []; var no8h = 0; //未满8小时天数 var over20 = 0; //20点以后下班天数 var over21 = 0; //21点以后下班天数 var over22 = 0; //22点以后下班天数 var over23 = 0; //23点以后下班天数 for (var i = 0; i < timeList.length; i++) { var time = timeList[i]; if (time.remark != '无') { noworkDays++; continue; } if (time.timeSpan == '无刷卡记录') continue; var splitTime = time.timeSpan.split('~'); if (splitTime.length == 2) { //正常上下班 var begin = splitTime[0]; var end = splitTime[1]; var thisMin = getTimeDiff(begin, end); totalMin += thisMin; workDays++; if (thisMin / 60 < 8) { workHourEveryday.push('<font color="red"><b style="font-size:15px">' + parseInt(thisMin / 60) + '</b>.' + thisMin % 60 + '</font>'); no8h++; } else { workHourEveryday.push('<b style="font-size:15px">' + parseInt(thisMin / 60) + '</b>.' + thisMin % 60); var offworkHour = parseInt(end.split(':')[0]); if (offworkHour >= 20) { over20++; } if (offworkHour >= 21) { over21++; } if (offworkHour >= 22) { over22++; } if (offworkHour >= 23) { over23++; } } } }; var myHour = parseInt(totalMin / 60); //本月工作累计小时数 var otherMin = totalMin % 60; //本月工作出小时部分外的分钟数 var avgHourOneDay = workDays == 0 ? '0.0' : '<b style="font-size:15px">'+(parseInt(myHour / workDays) + '</b>.' + (parseInt((myHour % workDays) * 60 / workDays) + parseInt(otherMin / workDays))); //平均每天工作时长 var html = '<div class="alectest" style="background: #cbebfb;padding:7px;">\ <div>出勤时间:<b style="font-size:15px;color:red">' + myHour + '</b>小时<font color="red">' + otherMin + '</font>分钟(平均<font color="red">' + avgHourOneDay + '</font>小时/天)</div>\ <div>参考时间:' + workDays * 8 + '小时【' + workDays + '天】(除去请假和节假日,实际有打卡记录的天数)</div>\ <div>请假/外出天数:' + noworkDays + '天</div>\ <div>每天工作时间(格式:小时.分钟):' + workHourEveryday.join(',') + '</div>\ <div>未满8小时天数:<b style="font-size:15px">' + no8h + '</b>天</div>\ <div>20点以后下班天数:<b style="font-size:15px">' + over20 + '</b>天</div>\ <div>21点以后下班天数:<b style="font-size:15px">' + over21 + '</b>天</div>\ <div>22点以后下班天数:<b style="font-size:15px">' + over22 + '</b>天</div>\ <div>23点以后下班天数:<b style="font-size:15px">' + over23 + '</b>天</div>\ </div>' var alectest = mymain.parentNode.getElementsByClassName('alectest'); if (alectest.length > 0) { // mymain.parentNode.removeChild(alectest[0]); alectest[0].innerHTML = html; } else { var div = document.createElement("div"); div.innerHTML = html; var fragement = document.createDocumentFragment(); while (div.childNodes[0]) { fragement.appendChild(div.childNodes[0]); } mymain.parentNode.insertBefore(fragement, mymain); } bindBtnClick(); } var bindBtnClick = function() { window.parent.frames['Main'].document.getElementById('ctl00_cphTop_BtnQuery').addEventListener('click', function() { var inter = setInterval(function() { if (window.parent.frames['Main'].document.getElementById('ctl00_cphMain_CalendarAC') && window.parent.frames['Main'].document.getElementById('ctl00_UpMaster').style.display == 'none') { clearInterval(inter); mydate(); } }, 500); }, false); } bindBtnClick();
Description du code : écoutez l'événement de clic du bouton de requête de présence. Une fois les informations de présence chargées, exécutez ma méthode JS.
La deuxième étape consiste à développer une extension Chrome
Documents de référence : http://open.chrome.360.cn/extension_dev/content_scripts.html (Interrogez la description de chaque attribut du nœud content_scripts de manifest.json)
Manifest.json est requis, le contenu final est le suivant :
{ "manifest_version":2, "name": "Extension Name", "version": "0.1.0", "description": "插件描述", "icons": { "48": "icon.png" }, "content_scripts": [ { "all_frames" : true, "matches": ["http://*"], "js": ["haha.js"], "run_at": "document_end" } ] }
De plus, placez une image icon.png dans le même répertoire. À ce stade, tous les fichiers sont prêts. Le répertoire est le suivant :
.Ouvrez le mode développeur de la liste d'extensions de Chrome "Extension de package volumineux..." et entrez le répertoire parent où se trouvent les trois fichiers ci-dessus dans le répertoire racine de l'extension.
Cliquez sur [Extension du package].
Remarque : si le fait de cliquer sur le bouton ne se reflète pas pendant une longue période, il se peut que votre Chrome n'autorise pas les extensions tierces non certifiées. La solution consiste à cliquer avec le bouton droit sur le raccourci Chrome > Propriétés > ajouter "activer". " après la zone de saisie cible -easy-off-store-extension-install", faites attention à l'espace précédent.
Ensuite, réessayez les étapes ci-dessus.
Étape 3 : empêcher Chrome de bloquer les paramètres des extensions non officielles
Chrome vous demandera de suspendre les extensions non officielles. L'invite apparaîtra à chaque démarrage, ce qui est très ennuyeux.
Rechercher des informations : http://www.itechzero.com/prevent-chrome-shielding-unofficial-extensions-tutorial.html (Tutoriel pour empêcher Chrome de bloquer les extensions non officielles)
Selon les informations ci-dessus, ce problème peut être facilement résolu.
À ce stade, le programme évolutif est terminé, et le résultat est le suivant :