'use strict'; const moment = require('moment') const fs = require('fs'); async function overtimeStatistic (ctx) { try { const { models } = ctx.fs.dc; const { clickHouse } = ctx.app.fs const { memberList, packageUserData, overtimeStatisticListDayType } = ctx.app.fs.utils const { keywordTarget, keyword, limit, page, orderBy, orderDirection, startDate, endDate, } = ctx.query const userRes = await memberList({ keywordTarget, keyword, limit, page, orderBy, orderDirection, overtimeDayStatisticStartDate: startDate, overtimeDayStatisticendDate: endDate, overtimeCountStatistic: true, overtimeCountStatisticStartDate: startDate, overtimeCountStatisticendDate: endDate, }) let { packageUser: returnD, pepUserIds } = await packageUserData(userRes) const sumRes = await overtimeStatisticListDayType({ startDate, endDate, pepUserIds }) returnD.forEach(u => { u.overtimeStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId) }) ctx.status = 200; ctx.body = { count: userRes.count, rows: returnD } } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function exportOvertimeStatistic (ctx) { try { const { models } = ctx.fs.dc; const { clickHouse } = ctx.app.fs const { memberList, packageUserData, overtimeStatisticListDayType, simpleExcelDown, dayType, overtimeType } = ctx.app.fs.utils const { keywordTarget, keyword, limit, page, orderBy, orderDirection, startDate, endDate, } = ctx.query const userRes = await memberList({ keywordTarget, keyword, limit, page, orderBy, orderDirection, overtimeDayStatisticStartDate: startDate, overtimeDayStatisticendDate: endDate, overtimeCountStatistic: true, overtimeCountStatisticStartDate: startDate, overtimeCountStatisticendDate: endDate, }) let { packageUser: returnD, pepUserIds } = await packageUserData(userRes) const sumRes = await overtimeStatisticListDayType({ startDate, endDate, pepUserIds }) returnD.forEach(d => { d.departmrnt = d.departmrnt.map(dep => dep.name).join('、') d.role = d.role.map(r => r.name).join('、') let overtimeStatistic = sumRes.filter(s => s.pepUserId == d.pepUserId) for (let dayTypeKey in dayType) { for (let overtimeTypeKey in overtimeType) { let corOverTimeSta = overtimeStatistic.find(o => o.compensate == overtimeTypeKey && o.dayType == dayTypeKey) if (corOverTimeSta) { d[overtimeTypeKey + dayTypeKey] = (corOverTimeSta.duration / 3600) // .toFixed(1) } } } for (let overtimeTypeKey in overtimeType) { d['sum' + overtimeTypeKey] = overtimeStatistic.reduce((sum, o) => { if (o.compensate == overtimeTypeKey) { sum += o.duration / 3600 } return sum }, 0) } }) let overtimeTypeHeader = [] let sumOvertimeTypeHeader = [] for (let overtimeTypeKey in overtimeType) { sumOvertimeTypeHeader.push({ title: `合计${overtimeType[overtimeTypeKey]}加班时长(小时)`, key: 'sum' + overtimeTypeKey, defaultValue: 0 }) for (let dayTypeKey in dayType) { overtimeTypeHeader.push({ title: dayType[dayTypeKey] + '-' + overtimeType[overtimeTypeKey], key: overtimeTypeKey + dayTypeKey, defaultValue: 0 }) } } const header = [{ title: '员工编号', key: 'userCode', }, { title: '姓名', key: 'userName', }, { title: '所属部门', key: 'departmrnt', }, { title: '职位', key: 'role', }, { title: '加班次数(次)', key: 'overtimeCount', },] .concat(overtimeTypeHeader) .concat(sumOvertimeTypeHeader) const fileName = `加班统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}-${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}_${moment().format('YYYYMMDDHHmmss')}` + '.csv' const filePath = await simpleExcelDown({ data: returnD, header, fileName: fileName }) const fileData = fs.readFileSync(filePath); ctx.status = 200; ctx.set('Content-Type', 'application/x-xls'); ctx.set('Content-disposition', 'attachment; filename=' + encodeURI(fileName)); ctx.body = fileData; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: error`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function vacateStatistic (ctx) { try { const { models } = ctx.fs.dc; const { clickHouse } = ctx.app.fs const { judgeHoliday, memberList, packageUserData, vacateStatisticListDayType } = ctx.app.fs.utils const { keywordTarget, keyword, limit, page, orderBy, orderDirection, startDate, endDate, } = ctx.query const userRes = await memberList({ keywordTarget, keyword, limit, page, orderBy, orderDirection, vacateDayStatisticStartDate: startDate, vacateDayStatisticendDate: endDate, vacateDurationStatistic: true, vacateCountStatistic: true, vacateCountStatisticStartDate: startDate, vacateCountStatisticendDate: endDate, }) let { packageUser: returnD, pepUserIds } = await packageUserData(userRes) const sumRes = await vacateStatisticListDayType({ startDate, endDate, pepUserIds }) returnD.forEach(u => { u.vacateStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId) }) ctx.status = 200; ctx.body = { count: userRes.count, rows: returnD } } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function exportVacateStatistic (ctx) { try { const { models } = ctx.fs.dc; const { clickHouse } = ctx.app.fs const { memberList, packageUserData, vacateStatisticListDayType, overtimeStatisticListDayType, simpleExcelDown, dayType, overtimeType } = ctx.app.fs.utils const { keywordTarget, keyword, limit, page, orderBy, orderDirection, startDate, endDate, } = ctx.query const vacateTypeRes = await clickHouse.hr.query(` SELECT type FROM vacate GROUP BY type ORDER BY type DESC `).toPromise() const userRes = await memberList({ keywordTarget, keyword, limit, page, orderBy, orderDirection, vacateDayStatisticStartDate: startDate, vacateDayStatisticendDate: endDate, vacateDurationStatistic: true, vacateCountStatistic: true, vacateCountStatisticStartDate: startDate, vacateCountStatisticendDate: endDate, }) let { packageUser: returnD, pepUserIds } = await packageUserData(userRes) const sumRes = await vacateStatisticListDayType({ startDate, endDate, pepUserIds }) returnD.forEach(u => { u.departmrnt = u.departmrnt.map(dep => dep.name).join('、') u.role = u.role.map(r => r.name).join('、') let vacateStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId) for (let { type } of vacateTypeRes) { u[type] = vacateStatistic.reduce((sum, v) => { if (v.type == type) { sum += v.duration / 3600 } return sum }, 0) } u.vacateDayStatisticDuration = (u.vacateDayStatisticDuration || 0) / 3600 }) const header = [{ title: '员工编号', key: 'userCode', }, { title: '姓名', key: 'userName', }, { title: '所属部门', key: 'departmrnt', }, { title: '职位', key: 'role', },] .concat(vacateTypeRes.map(v => { return { title: `${v.type}请假时长(小时)`, key: v.type, defaultValue: '0', } })) .concat( [{ title: '合计请假次数(次)', key: 'vacateCount', defaultValue: '0', }, { title: '合计请假时长(小时)', key: 'vacateDayStatisticDuration', defaultValue: '0', }] ) const fileName = `请假统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}-${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}_${moment().format('YYYYMMDDHHmmss')}` + '.csv' const filePath = await simpleExcelDown({ data: returnD, header, fileName: fileName }) const fileData = fs.readFileSync(filePath); ctx.status = 200; ctx.set('Content-Type', 'application/x-xls'); ctx.set('Content-disposition', 'attachment; filename=' + encodeURI(fileName)); ctx.body = fileData; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: error`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } module.exports = { overtimeStatistic, exportOvertimeStatistic, vacateStatistic, exportVacateStatistic, };