'use strict'; const moment = require('moment') async function add (ctx) { try { const { models } = ctx.fs.dc; const { pepUserId, idNumber, idPhoto, gender, birthday, nativePlace, marital, politicsStatus, phoneNumber, workPlace, graduatedFrom, educationBackground, specialty, graduationDate, hiredate, turnProbationPeriod, regularDate, dimissionDate, experienceYear, occupationalHistory, vitae } = ctx.request.body const existMemberRes = await models.Member.findOne({ where: { pepUserId } }) if (existMemberRes && !existMemberRes.del) { throw '当前人员信息已存在' } let storageData = { pepUserId, idNumber, idPhoto, gender, birthday, nativePlace, marital, politicsStatus, phoneNumber, workPlace, graduatedFrom, educationBackground, specialty, graduationDate, hiredate, turnProbationPeriod, regularDate, dimissionDate, experienceYear, occupationalHistory, vitae, del: false } if (existMemberRes && existMemberRes.del) { await models.Member.update(storageData, { where: { pepUserId, } }) } else { await models.Member.create(storageData) } ctx.status = 204; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: error`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function edit (ctx) { try { const { models } = ctx.fs.dc; const { pepUserId, idNumber, idPhoto, gender, birthday, nativePlace, marital, politicsStatus, phoneNumber, workPlace, graduatedFrom, educationBackground, specialty, graduationDate, hiredate, turnProbationPeriod, regularDate, dimissionDate, experienceYear, occupationalHistory, vitae } = ctx.request.body const existMemberRes = await models.Member.findOne({ where: { pepUserId } }) if (!existMemberRes) { throw '当前人员信息不存在' } let storageData = { pepUserId, idNumber, idPhoto, gender, birthday, nativePlace, marital, politicsStatus, phoneNumber, workPlace, graduatedFrom, educationBackground, specialty, graduationDate, hiredate, turnProbationPeriod, regularDate, dimissionDate, experienceYear, occupationalHistory, vitae, del: false } await models.Member.update(storageData, { where: { pepUserId: pepUserId } }) ctx.status = 204; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: error`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function searchPepMember (ctx) { try { const { models } = ctx.fs.dc; const { clickHouse } = ctx.app.fs const { keyword } = ctx.query let whereOption = [] if (keyword) { whereOption.push(`user.id = ${keyword}`) whereOption.push(`user.name LIKE '${keyword}'`) } const userRes = await clickHouse.pepEmis.query(` SELECT user.id AS pepUserId, user.name AS userName, role.name AS roleName, role.id AS roleId, department.name AS depName, department.id AS depId FROM user LEFT JOIN user_role ON user_role.user = user.id LEFT JOIN role ON role.id = user_role.role LEFT JOIN department_user ON department_user.user = user.id LEFT JOIN department ON department.id = department_user.department ${whereOption.length ? `WHERE ${whereOption.join(' OR ')}` : ''} `).toPromise() let returnD = [] userRes.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 { returnD.push({ pepUserId: u.pepUserId, name: u.userName, departmrnt: u.depId ? [{ id: u.depId, name: u.depName }] : [], role: u.roleId ? [{ id: u.roleId, name: u.roleName }] : [], }) } }) ctx.status = 200; ctx.body = 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 del (ctx) { try { const { models } = ctx.fs.dc; const { pepUserId } = ctx.query await models.Member.update({ del: true, }, { where: { pepUserId, } }) ctx.status = 204; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: error`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function list (ctx) { try { const { models } = ctx.fs.dc; const { judgeHoliday, memberList } = ctx.app.fs.utils const { keywordTarget, keyword, limit, page, state } = ctx.query const userRes = await memberList({ keywordTarget, keyword, limit, page, state }) let returnD = [] userRes.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] } 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 }) } }) ctx.status = 200; ctx.body = 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 overTimeStatistics (ctx) { try { const { models } = ctx.fs.dc; const { clickHouse } = ctx.app.fs const { database: pepEmis } = clickHouse.pepEmis.opts.config const { startDate, endDate, pepUserId } = ctx.query const timeOption = [] if (startDate && endDate) { timeOption.push( `wpStory.create_at <= '${moment(endDate).format('YYYY-MM-DD HH:mm:ss')}' AND wpStory.create_at > '${moment(startDate).format('YYYY-MM-DD HH:mm:ss')}'` ) } const dataRes = await clickHouse.hr.query(` SELECT compensate, create_at AS createTime, start_time AS startTime, end_time AS endTime, pay_dayoff AS payDayoff, pay_festivals AS payFestivals, pay_workday AS payWorkday, reason, take_rest_dayoff AS takeRestDayoff, take_rest_festivals AS takeRestFestivals, take_rest_workday AS takeRestWorkday, wpStory.id AS storyId FROM overtime INNER JOIN ${pepEmis}.workflow_process_history AS wpStory ON wpStory.id = overtime.pep_process_story_id ${timeOption.length ? `AND ${timeOption.join(' AND ')}` : ''} WHERE overtime.pep_user_id = ${pepUserId} `).toPromise() const statisticRes = await clickHouse.hr.query(` SELECT count(overtime.id) AS overTimeCount, sum(pay_dayoff) AS sumPayDayoff, sum(pay_festivals) AS sumPayFestivals, sum(pay_workday) AS sumPayWorkday, sum(take_rest_dayoff) AS sumTakeRestDayoff, sum(take_rest_festivals) AS sumTakeRestFestivals, sum(take_rest_workday) AS sumTakeRestWorkday FROM overtime INNER JOIN ${pepEmis}.workflow_process_history AS wpStory ON wpStory.id = overtime.pep_process_story_id ${timeOption.length ? `AND ${timeOption.join(' AND ')}` : ''} WHERE overtime.pep_user_id = ${pepUserId} GROUP BY overtime.pep_user_id `).toPromise() let returnD = { ...(statisticRes.length ? statisticRes[0] : {}), data: dataRes } ctx.status = 200; ctx.body = 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 vacateStatistics (ctx) { try { const { models } = ctx.fs.dc; const { clickHouse } = ctx.app.fs const { database: pepEmis } = clickHouse.pepEmis.opts.config const { startDate, endDate, pepUserId } = ctx.query const timeOption = [] if (startDate && endDate) { timeOption.push( `wpStory.create_at <= '${moment(endDate).format('YYYY-MM-DD HH:mm:ss')}' AND wpStory.create_at > '${moment(startDate).format('YYYY-MM-DD HH:mm:ss')}'` ) } const dataRes = await clickHouse.hr.query(` SELECT type, create_at AS createTime, start_time AS startTime, end_time AS endTime, duration, reason, wpStory.id AS storyId FROM vacate INNER JOIN ${pepEmis}.workflow_process_history AS wpStory ON wpStory.id = vacate.pep_process_story_id ${timeOption.length ? `AND ${timeOption.join(' AND ')}` : ''} WHERE vacate.pep_user_id = ${pepUserId} `).toPromise() const statisticRes = await clickHouse.hr.query(` SELECT type, count(vacate.id) AS count, sum(duration) AS sumDuration FROM vacate INNER JOIN ${pepEmis}.workflow_process_history AS wpStory ON wpStory.id = vacate.pep_process_story_id ${timeOption.length ? `AND ${timeOption.join(' AND ')}` : ''} WHERE vacate.pep_user_id = ${pepUserId} GROUP BY type `).toPromise() let returnD = { statistic: statisticRes, data: dataRes } ctx.status = 200; ctx.body = 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 exportData (ctx) { try { const { models } = ctx.fs.dc; const { judgeHoliday, memberList } = ctx.app.fs.utils const { keywordTarget, keyword, limit, page, state } = ctx.query const userRes = await memberList({ keywordTarget, keyword, limit, page, state }) const tableAttributes = models['Member'].tableAttributes ctx.status = 200; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: error`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function addMembersBulk (ctx) { let errorMsg = { message: '批量添加员工信息失败' }; const transaction = await ctx.fs.dc.orm.transaction(); try { const models = ctx.fs.dc.models; const data = ctx.request.body; let addMembers = []; let editMembers = []; let memberList = await models.Member.findAll({ attributes: ['pepUserId'] }); data.map(d => { let exist = memberList.find(d => d.pepUserId == d.number);//项企的人员编号字段还没有 if (exist) { editMembers.push(d); } else { addMembers.push(d); } }) //处理新增的 if (addMembers.length) { await models.Member.bulkCreate(addMembers); } //处理编辑的 if (editMembers.length) { for (let i in editMembers) { let { pepUserId, name, idNumber, gender, birthday, nativePlace, marital, politicsStatus, phoneNumber, workPlace, graduatedFrom, educationBackground, specialty, graduationDate, hiredate, turnProbationPeriod, regularDate, dimissionDate, experienceYear, occupationalHistory } = editMembers[i]; let dataToUpdate = { name, idNumber, gender, birthday, nativePlace, marital, politicsStatus, phoneNumber, workPlace, graduatedFrom, educationBackground, specialty, graduationDate, hiredate, turnProbationPeriod, regularDate, dimissionDate, experienceYear, occupationalHistory } await models.Member.update(dataToUpdate, { where: { pepUserId: pepUserId } }); } } await transaction.commit(); ctx.status = 204; } catch (error) { await transaction.rollback(); ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = errorMsg; } } module.exports = { add, edit, del, searchPepMember, list, overTimeStatistics, vacateStatistics, exportData, addMembersBulk }