zmh
1 year ago
3 changed files with 406 additions and 351 deletions
@ -1,371 +1,403 @@ |
|||
'use strict'; |
|||
const moment = require('moment') |
|||
const fs = require('fs'); |
|||
const { getDataRange } = require('../auth/index') |
|||
|
|||
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 => { |
|||
let overtimeStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId) |
|||
u.overtimeDuration = overtimeStatistic.reduce((sum, os) => sum + os.duration, 0) |
|||
u.overtimeStatistic = overtimeStatistic |
|||
}) |
|||
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 |
|||
} |
|||
} |
|||
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 |
|||
|
|||
let dataRange = await getDataRange(ctx); |
|||
if (dataRange.userIds && dataRange.userIds.length === 0) { |
|||
ctx.status = 200; |
|||
ctx.body = { |
|||
count: 0, |
|||
rows: [] |
|||
} |
|||
} else { |
|||
const userRes = await memberList({ |
|||
keywordTarget, keyword, limit, page, |
|||
orderBy, orderDirection, |
|||
overtimeDayStatisticStartDate: startDate, |
|||
overtimeDayStatisticendDate: endDate, |
|||
overtimeCountStatistic: true, |
|||
overtimeCountStatisticStartDate: startDate, |
|||
overtimeCountStatisticendDate: endDate, |
|||
userIds: dataRange.userIds |
|||
}) |
|||
|
|||
let { packageUser: returnD, pepUserIds } = await packageUserData(userRes) |
|||
|
|||
const sumRes = await overtimeStatisticListDayType({ |
|||
startDate, endDate, pepUserIds |
|||
}) |
|||
|
|||
returnD.forEach(u => { |
|||
let overtimeStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId) |
|||
u.overtimeDuration = overtimeStatistic.reduce((sum, os) => sum + os.duration, 0) |
|||
u.overtimeStatistic = overtimeStatistic |
|||
}) |
|||
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) |
|||
let totalDuration = 0 |
|||
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)
|
|||
totalDuration += corOverTimeSta.duration / 3600 |
|||
} |
|||
} |
|||
} |
|||
for (let overtimeTypeKey in overtimeType) { |
|||
d['sum' + overtimeTypeKey] = overtimeStatistic.reduce((sum, o) => { |
|||
if (o.compensate == overtimeTypeKey) { |
|||
sum += o.duration / 3600 |
|||
// totalDuration += o.duration / 3600
|
|||
} |
|||
return sum |
|||
}, 0) |
|||
} |
|||
d.totalDuration = totalDuration |
|||
}) |
|||
|
|||
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' |
|||
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 |
|||
let returnD = null; |
|||
let dataRange = await getDataRange(ctx); |
|||
if (dataRange.userIds && dataRange.userIds.length === 0) { |
|||
returnD = []; |
|||
} else { |
|||
const userRes = await memberList({ |
|||
keywordTarget, keyword, limit, page, |
|||
orderBy, orderDirection, |
|||
overtimeDayStatisticStartDate: startDate, |
|||
overtimeDayStatisticendDate: endDate, |
|||
overtimeCountStatistic: true, |
|||
overtimeCountStatisticStartDate: startDate, |
|||
overtimeCountStatisticendDate: endDate, |
|||
userIds: dataRange.userIds |
|||
}) |
|||
|
|||
let { packageUser, pepUserIds } = await packageUserData(userRes) |
|||
returnD = packageUser; |
|||
const sumRes = await overtimeStatisticListDayType({ |
|||
startDate, endDate, pepUserIds |
|||
}) |
|||
} |
|||
} |
|||
|
|||
const header = [{ |
|||
title: '员工编号', |
|||
key: 'userCode', |
|||
}, { |
|||
title: '姓名', |
|||
key: 'userName', |
|||
}, { |
|||
title: '所属部门', |
|||
key: 'departmrnt', |
|||
}, { |
|||
title: '职位', |
|||
key: 'role', |
|||
}, { |
|||
title: '加班次数(次)', |
|||
key: 'overtimeCount', |
|||
},] |
|||
.concat(overtimeTypeHeader) |
|||
.concat(sumOvertimeTypeHeader) |
|||
.concat([{ |
|||
title: '合计加班时长(小时)', |
|||
key: 'totalDuration', |
|||
defaultValue: '0' |
|||
}]) |
|||
|
|||
const fileName = `加班统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}${startDate && endDate ? '-' : ''}${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}${startDate || endDate ? '_' : ''}${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 |
|||
} |
|||
} |
|||
|
|||
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) |
|||
let totalDuration = 0 |
|||
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)
|
|||
totalDuration += corOverTimeSta.duration / 3600 |
|||
} |
|||
} |
|||
} |
|||
for (let overtimeTypeKey in overtimeType) { |
|||
d['sum' + overtimeTypeKey] = overtimeStatistic((sum, o) => { |
|||
if (o.compensate == overtimeTypeKey) { |
|||
sum += o.duration / 3600 |
|||
// totalDuration += o.duration / 3600
|
|||
} |
|||
return sum |
|||
}, 0) |
|||
} |
|||
d.totalDuration = totalDuration |
|||
}) |
|||
} |
|||
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) |
|||
.concat([{ |
|||
title: '合计加班时长(小时)', |
|||
key: 'totalDuration', |
|||
defaultValue: '0' |
|||
}]) |
|||
|
|||
const fileName = `加班统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}${startDate && endDate ? '-' : ''}${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}${startDate || endDate ? '_' : ''}${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 vacateType(ctx) { |
|||
try { |
|||
const { models } = ctx.fs.dc; |
|||
const { clickHouse } = ctx.app.fs |
|||
try { |
|||
const { models } = ctx.fs.dc; |
|||
const { clickHouse } = ctx.app.fs |
|||
|
|||
const vacateTypeRes = await clickHouse.hr.query(` |
|||
const vacateTypeRes = await clickHouse.hr.query(` |
|||
SELECT type FROM vacate GROUP BY type ORDER BY type DESC |
|||
`).toPromise()
|
|||
|
|||
ctx.status = 200; |
|||
ctx.body = vacateTypeRes |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: error`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
message: typeof error == 'string' ? error : undefined |
|||
} |
|||
} |
|||
ctx.status = 200; |
|||
ctx.body = vacateTypeRes |
|||
} 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 |
|||
}) |
|||
|
|||
const remarkList = await models.VacateRemark.findAll({}); //查询备注
|
|||
|
|||
returnD.forEach(u => { |
|||
let vacateStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId) |
|||
let remarkData = remarkList.filter(e => e.pepUserId == u.pepUserId) |
|||
u.vacateDuration = vacateStatistic.reduce((sum, vs) => sum + vs.duration, 0) |
|||
u.vacateStatistic = vacateStatistic |
|||
u.remark = remarkData.length ? remarkData[0].remark : null |
|||
}) |
|||
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 |
|||
} |
|||
} |
|||
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 |
|||
|
|||
let dataRange = await getDataRange(ctx); |
|||
if (dataRange.userIds && dataRange.userIds.length === 0) { |
|||
ctx.status = 200; |
|||
ctx.body = { |
|||
count: 0, |
|||
rows: [] |
|||
} |
|||
} else { |
|||
const userRes = await memberList({ |
|||
keywordTarget, keyword, limit, page, |
|||
orderBy, orderDirection, |
|||
vacateDayStatisticStartDate: startDate, |
|||
vacateDayStatisticendDate: endDate, |
|||
vacateDurationStatistic: true, |
|||
vacateCountStatistic: true, |
|||
vacateCountStatisticStartDate: startDate, |
|||
vacateCountStatisticendDate: endDate, |
|||
userIds: dataRange.userIds |
|||
}) |
|||
|
|||
let { packageUser: returnD, pepUserIds } = await packageUserData(userRes) |
|||
|
|||
const sumRes = await vacateStatisticListDayType({ |
|||
startDate, endDate, pepUserIds |
|||
}) |
|||
|
|||
const remarkList = await models.VacateRemark.findAll({}); //查询备注
|
|||
|
|||
returnD.forEach(u => { |
|||
let vacateStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId) |
|||
let remarkData = remarkList.filter(e => e.pepUserId == u.pepUserId) |
|||
u.vacateDuration = vacateStatistic.reduce((sum, vs) => sum + vs.duration, 0) |
|||
u.vacateStatistic = vacateStatistic |
|||
u.remark = remarkData.length ? remarkData[0].remark : null |
|||
}) |
|||
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(` |
|||
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()
|
|||
let returnD = null; |
|||
let dataRange = await getDataRange(ctx); |
|||
if (dataRange.userIds && dataRange.userIds.length === 0) { |
|||
returnD = []; |
|||
} else { |
|||
const userRes = await memberList({ |
|||
keywordTarget, keyword, limit, page, |
|||
orderBy, orderDirection, |
|||
vacateDayStatisticStartDate: startDate, |
|||
vacateDayStatisticendDate: endDate, |
|||
vacateDurationStatistic: true, |
|||
vacateCountStatistic: true, |
|||
vacateCountStatisticStartDate: startDate, |
|||
vacateCountStatisticendDate: endDate, |
|||
userIds: dataRange.userIds |
|||
}) |
|||
|
|||
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 |
|||
}) |
|||
|
|||
const remarkList = await models.VacateRemark.findAll({}); //查询备注
|
|||
|
|||
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 |
|||
u.userActiveStatus = u.userActiveStatus == 1 ? '在职' : u.userActiveStatus == 2 ? '离职' : '特殊状态-特殊账号' |
|||
let remarkData = remarkList.filter(e => e.pepUserId == u.pepUserId) |
|||
u.remark = remarkData.length ? (remarkData[0].remark == '' ? '无' : remarkData[0].remark) : '无' |
|||
}) |
|||
|
|||
const header = [{ |
|||
title: '员工编号', |
|||
key: 'userCode', |
|||
}, { |
|||
title: '姓名', |
|||
key: 'userName', |
|||
}, { |
|||
title: '所属部门', |
|||
key: 'departmrnt', |
|||
}, { |
|||
title: '职位', |
|||
key: 'role', |
|||
}, { |
|||
title: '在职状态', |
|||
key: 'userActiveStatus', |
|||
},] |
|||
.concat(vacateTypeRes.map(v => { |
|||
return { |
|||
title: `${v.type}请假时长(小时)`, |
|||
key: v.type, |
|||
defaultValue: '0', |
|||
} |
|||
})) |
|||
.concat( |
|||
[{ |
|||
title: '合计请假次数(次)', |
|||
key: 'vacateCount', |
|||
defaultValue: '0', |
|||
}, { |
|||
title: '合计请假时长(小时)', |
|||
key: 'vacateDayStatisticDuration', |
|||
defaultValue: '0', |
|||
}] |
|||
) |
|||
.concat( |
|||
[{ |
|||
title: '备注', |
|||
key: 'remark', |
|||
}] |
|||
) |
|||
|
|||
const fileName = `请假统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}${startDate && endDate ? '-' : ''}${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}${startDate || endDate ? '_' : ''}${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 |
|||
} |
|||
} |
|||
let { packageUser, pepUserIds } = await packageUserData(userRes) |
|||
returnD = packageUser; |
|||
const sumRes = await vacateStatisticListDayType({ |
|||
startDate, endDate, pepUserIds |
|||
}) |
|||
|
|||
const remarkList = await models.VacateRemark.findAll({}); //查询备注
|
|||
|
|||
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 |
|||
u.userActiveStatus = u.userActiveStatus == 1 ? '在职' : u.userActiveStatus == 2 ? '离职' : '特殊状态-特殊账号' |
|||
let remarkData = remarkList.filter(e => e.pepUserId == u.pepUserId) |
|||
u.remark = remarkData.length ? (remarkData[0].remark == '' ? '无' : remarkData[0].remark) : '无' |
|||
}) |
|||
} |
|||
const header = [{ |
|||
title: '员工编号', |
|||
key: 'userCode', |
|||
}, { |
|||
title: '姓名', |
|||
key: 'userName', |
|||
}, { |
|||
title: '所属部门', |
|||
key: 'departmrnt', |
|||
}, { |
|||
title: '职位', |
|||
key: 'role', |
|||
}, { |
|||
title: '在职状态', |
|||
key: 'userActiveStatus', |
|||
},] |
|||
.concat(vacateTypeRes.map(v => { |
|||
return { |
|||
title: `${v.type}请假时长(小时)`, |
|||
key: v.type, |
|||
defaultValue: '0', |
|||
} |
|||
})) |
|||
.concat( |
|||
[{ |
|||
title: '合计请假次数(次)', |
|||
key: 'vacateCount', |
|||
defaultValue: '0', |
|||
}, { |
|||
title: '合计请假时长(小时)', |
|||
key: 'vacateDayStatisticDuration', |
|||
defaultValue: '0', |
|||
}] |
|||
) |
|||
.concat( |
|||
[{ |
|||
title: '备注', |
|||
key: 'remark', |
|||
}] |
|||
) |
|||
|
|||
const fileName = `请假统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}${startDate && endDate ? '-' : ''}${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}${startDate || endDate ? '_' : ''}${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 vacateRemark(ctx) { |
|||
try { |
|||
const { models } = ctx.fs.dc; |
|||
const { remark, pepUserId } = ctx.query; |
|||
let oldData = await models.VacateRemark.findOne({ where: { pepUserId: pepUserId } }); |
|||
if (oldData) { |
|||
await models.VacateRemark.update({ remark, pepUserId }, { where: { pepUserId: pepUserId } }); |
|||
} else { |
|||
await models.VacateRemark.create({ remark, pepUserId }); |
|||
} |
|||
|
|||
ctx.status = 200; |
|||
ctx.body = '添加备注成功'; |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
"message": "添加备注失败" |
|||
} |
|||
} |
|||
try { |
|||
const { models } = ctx.fs.dc; |
|||
const { remark, pepUserId } = ctx.query; |
|||
let oldData = await models.VacateRemark.findOne({ where: { pepUserId: pepUserId } }); |
|||
if (oldData) { |
|||
await models.VacateRemark.update({ remark, pepUserId }, { where: { pepUserId: pepUserId } }); |
|||
} else { |
|||
await models.VacateRemark.create({ remark, pepUserId }); |
|||
} |
|||
|
|||
ctx.status = 200; |
|||
ctx.body = '添加备注成功'; |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
"message": "添加备注失败" |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
overtimeStatistic, |
|||
exportOvertimeStatistic, |
|||
vacateType, |
|||
vacateStatistic, |
|||
exportVacateStatistic, |
|||
vacateRemark |
|||
overtimeStatistic, |
|||
exportOvertimeStatistic, |
|||
vacateType, |
|||
vacateStatistic, |
|||
exportVacateStatistic, |
|||
vacateRemark |
|||
}; |
Loading…
Reference in new issue