// ==UserScript== // @name 一键生成 GitLab 周报汇总 // @namespace https://github.com/kiccer // @version 2.2 // @description 一键生成 GitLab 周报汇总,生成自定义时间段的汇报。 // @author kiccer<1072907338@qq.com> // @supportURL https://github.com/kiccer/TampermonkeyScripts/issues // @license MIT // @match http://192.168.1.128:8088/* // @icon https://gd-hbimg.huaban.com/690fe61ca630eaffd3e052c73d3aa7d66d45d95a6101-gORZdx_fw658/format/webp // @require https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js // @require https://cdn.bootcdn.net/ajax/libs/bootstrap-daterangepicker/3.1/moment.min.js // @require https://cdn.bootcdn.net/ajax/libs/bootstrap-daterangepicker/3.1/daterangepicker.min.js // @require https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.11/clipboard.min.js // @require https://cdn.bootcdn.net/ajax/libs/toastr.js/latest/toastr.min.js // @resource toastr_css https://cdn.bootcdn.net/ajax/libs/toastr.js/latest/toastr.min.css // @resource daterangepicker_css https://cdn.bootcdn.net/ajax/libs/bootstrap-daterangepicker/3.1/daterangepicker.min.css // @grant GM_addStyle // @grant GM_getResourceText // @grant GM_xmlhttpRequest // @noframes // @downloadURL none // ==/UserScript== /* globals $ GM_addStyle GM_getResourceText GM_xmlhttpRequest moment ClipboardJS toastr */ $(() => { 'use strict' const targetPath = $('.header-user-dropdown-toggle').attr('href') const currentPath = location.pathname // 判断是否是目标地址 if (targetPath !== currentPath) return // 加载 CSS GM_addStyle(GM_getResourceText('toastr_css')) GM_addStyle(GM_getResourceText('daterangepicker_css')) GM_addStyle(` .kiccer-daterange-input { visibility: hidden; width: 0; height: 32px; border: 0; padding: 0; margin: 0; position: absolute; } `) // 按钮容器 const btnContainer = $('.cover-controls') // 日报 const copyBtn = $('') copyBtn.addClass('btn btn-gray') copyBtn.html('生成日报') copyBtn.appendTo(btnContainer) copyBtn.on('click', async e => { const startTime = moment().format('YYYY-MM-DD 00:00:00') const endTime = moment().format('YYYY-MM-DD 23:59:59') const summaryList = await getSummary(startTime, endTime) const text = getTextBySummary(startTime, endTime, summaryList) copy(text) toastr.success('复制成功!') }) // 智能生成周报 const smartBtn = $('') smartBtn.addClass('btn btn-gray') smartBtn.attr('title', '获取过去最近的工作周,自动判断法定节假日。') smartBtn.html('智能周报') smartBtn.appendTo(btnContainer) smartBtn.on('click', async e => { const end = await findDate(moment(), [0]) const start = await findDate(end.subtract(1, 'day'), [1, 2]) const startTime = start.add(1, 'day').format('YYYY-MM-DD 00:00:00') const endTime = end.format('YYYY-MM-DD 23:59:59') const summaryList = await getSummary(startTime, endTime) const text = getTextBySummary(startTime, endTime, summaryList) copy(text) toastr.success('复制成功!') }) // 自定义汇总时间范围 const customBtn = $('') customBtn.addClass('btn btn-gray') customBtn.html('自定义时间') customBtn.appendTo(btnContainer) customBtn.on('click', e => { dateRange.click() }) // 日期选择期 (https://github.com/dangrossman/daterangepicker) const dateRange = $('') customBtn.append(dateRange) dateRange.on('click', e => { e.stopPropagation() }) $('input[name="daterange"]').daterangepicker({ opens: 'left', locale: { format: 'YYYY-MM-DD', separator: ' - ', applyLabel: '确定', cancelLabel: '取消', fromLabel: '从', toLabel: '至', customRangeLabel: '自定义', weekLabel: '周', daysOfWeek: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], firstDay: 1 } }, (start, end, label) => { // daterange changed. }).on('apply.daterangepicker', async (ev, picker) => { customBtn.attr('disabled', true) const startTime = picker.startDate.format('YYYY-MM-DD 00:00:00') const endTime = picker.endDate.format('YYYY-MM-DD 23:59:59') const summaryList = await getSummary(startTime, endTime) const text = getTextBySummary(startTime, endTime, summaryList) copy(text) toastr.success('复制成功!') customBtn.attr('disabled', false) }) // 向前寻找日期,工作日0 周末1 法定节假日2,例:findDate(今天, 0) 从今天开始往前找,返回最近的一个工作日日期。 function findDate (start, type = [0]) { return new Promise((resolve, reject) => { const loop = (time) => { // 节假日万年历API: http://www.free-api.com/doc/562 GM_xmlhttpRequest({ url: `https://www.mxnzp.com/api/holiday/single/${time}?ignoreHoliday=false&app_id=rgihdrm0kslojqvm&app_secret=WnhrK251TWlUUThqaVFWbG5OeGQwdz09`, onload: res => { const { data } = JSON.parse(res.response) output(`${moment(time).format('YYYY-MM-DD')} 是 ${['工作日', '周末', '法定节假日'][data.type]}`) // console.log(data) if (type.includes(data.type)) { resolve(moment(time)) } else { loop(moment(time).subtract(1, 'day').format('YYYYMMDD')) } } }) } loop(moment(start).format('YYYYMMDD')) }) } // 控制台输出 function output (msg) { console.log(`%c[${moment().format('HH:mm:ss')}'${String(Date.now() % 1000).padStart(3, '0')}] %c${msg}`, 'color: red', 'color: blue') } // 加载页面 (v2.2 改为接口请求,然后放到一个隐藏元素内,兼容 gitlab 多版本) const hideList = $('