巴林闲侠
2 years ago
5 changed files with 409 additions and 229 deletions
@ -0,0 +1,132 @@ |
|||
'use strict'; |
|||
|
|||
async function overtimeStatistic (ctx) { |
|||
try { |
|||
const { models } = ctx.fs.dc; |
|||
const { clickHouse } = ctx.app.fs |
|||
const { judgeHoliday, memberList } = 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 |
|||
}) |
|||
|
|||
let returnD = [] |
|||
let pepUserIds = [] |
|||
userRes.rows.forEach(u => { |
|||
let existUser = returnD.find(r => r.pepUserId == u.pepUserId) |
|||
if (existUser) { |
|||
if (u.depId && !existUser.departmrnt.some(d => d.id == u.depId)) { |
|||
existUser.departmrnt.push({ |
|||
id: u.depId, |
|||
name: u.depName |
|||
}) |
|||
} |
|||
if (u.roleId && !existUser.role.some(r => r.id == u.roleId)) { |
|||
existUser.role.push({ |
|||
id: u.roleId, |
|||
name: u.roleName |
|||
}) |
|||
} |
|||
} else { |
|||
let obj = {} |
|||
for (let k in u) { |
|||
let nextKey = k.replace('hrMember.', '') |
|||
.replace('member.', '') |
|||
if (nextKey.includes('_')) { |
|||
nextKey = nextKey.toLowerCase() |
|||
.replace( |
|||
/(_)[a-z]/g, |
|||
(L) => L.toUpperCase() |
|||
) |
|||
.replace(/_/g, '') |
|||
} |
|||
obj[nextKey] = u[k] |
|||
} |
|||
pepUserIds.push(u.pepUserId) |
|||
returnD.push({ |
|||
...obj, |
|||
departmrnt: u.depId ? [{ |
|||
id: u.depId, |
|||
name: u.depName |
|||
}] : [], |
|||
role: u.roleId ? [{ |
|||
id: u.roleId, |
|||
name: u.roleName |
|||
}] : [], |
|||
del: undefined, |
|||
pepuserid: undefined, |
|||
"vacateStartTime": undefined, |
|||
"vacateEndTime": undefined, |
|||
"overtimeStartTime": undefined, |
|||
"overtimeEndTime": undefined, |
|||
}) |
|||
} |
|||
}) |
|||
|
|||
// 查加班总数
|
|||
const countRes = await clickHouse.hr.query(` |
|||
SELECT |
|||
overtime.pep_user_id AS pepUserId, |
|||
count(pep_process_story_id) AS count |
|||
FROM overtime |
|||
WHERE overtime.pep_user_id IN (${pepUserIds.join(',')}) |
|||
${startDate ? ` |
|||
AND overtime.start_time >= '${moment(startDate).format('YYYY-MM-DD')}' |
|||
`: ''}
|
|||
${endDate ? ` |
|||
AND overtime.start_time <= '${moment(endDate).format('YYYY-MM-DD')}' |
|||
` : ''}
|
|||
GROUP BY overtime.pep_user_id |
|||
`).toPromise()
|
|||
|
|||
const sumRes = await clickHouse.hr.query(` |
|||
SELECT |
|||
overtime.pep_user_id AS pepUserId, |
|||
holiday.type AS dayType, |
|||
overtime.compensate AS compensate, |
|||
sum(overtime_day.duration) AS duration |
|||
FROM overtime_day |
|||
INNER JOIN overtime |
|||
ON overtime.id = overtime_day.overtime_id |
|||
AND overtime.pep_user_id IN (${pepUserIds.join(',')}) |
|||
LEFT JOIN holiday |
|||
ON holiday.day = overtime_day.day |
|||
WHERE overtime.pep_user_id IN (${pepUserIds.join(',')}) |
|||
${startDate ? ` |
|||
AND overtime_day.day >= '${moment(startDate).format('YYYY-MM-DD')}' |
|||
`: ''}
|
|||
${endDate ? ` |
|||
AND overtime_day.day <= '${moment(endDate).format('YYYY-MM-DD')}' |
|||
` : ''}
|
|||
GROUP BY holiday.type, overtime.compensate, overtime.pep_user_id |
|||
`).toPromise()
|
|||
|
|||
returnD.forEach(u => { |
|||
u.overtimeCount = (countRes.find(c => c.pepUserId == u.pepUserId) || {}).count || 0 |
|||
|
|||
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 |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
overtimeStatistic, |
|||
}; |
@ -0,0 +1,8 @@ |
|||
'use strict'; |
|||
|
|||
const attendance = require('../../controllers/attendance'); |
|||
|
|||
module.exports = function (app, router, opts) { |
|||
app.fs.api.logAttr['GET/attendance/overtime'] = { content: '加班统计', visible: true }; |
|||
router.get('/attendance/overtime', attendance.overtimeStatistic); |
|||
}; |
Loading…
Reference in new issue