巴林闲侠
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