人力资源
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

338 lines
10 KiB

'use strict';
const moment = require('moment')
const fs = require('fs');
async function salesList(ctx) {
try {
const { memberList, packageUserData } = ctx.app.fs.utils
const {
keywordTarget, keyword, limit, page, state,
hiredateStart, hiredateEnd, marital, native, workPlace,
orderBy, orderDirection, placeSearch,userActiveStatus
} = ctx.query
const userRes = await memberList({
keywordTarget, keyword, limit: '', page: '', state,
hiredateStart, hiredateEnd, marital, native, workPlace,
orderBy, orderDirection,
nowAttendanceTime: true
})
let { packageUser: members } = await packageUserData(userRes, {
state: true,
})
const { models } = ctx.fs.dc;
let mIds = members.map(m => m.pepUserId);
let where = {
del: false,
pepUserId: { $in: mIds }
}
if (placeSearch) {
where.$or = [{
provinces: { $like: `%${placeSearch}%` }
}, {
cities: { $like: `%${placeSearch}%` }
}]
}
let res = await models.SalesDistribution.findAndCountAll({
where: where,
offset: Number(page) * Number(limit),
limit: Number(limit),
order: [['id', 'DESC']]
})
let rslt = []
res.rows.map(d => {
let info = members.find(m => m.pepUserId == d.dataValues.pepUserId);
let item = {
name: info.userName,
userCode: info.userCode,
post: info.userPost,
department: info.departmrnt,
hireDate: info.hiredate,//入职时间
regularDate: info.regularDate,//转正时间
userActiveStatus:info.userActiveStatus,
...d.dataValues
}
rslt.push(item);
})
rslt= rslt.filter(e=>e.userActiveStatus == userActiveStatus)
ctx.status = 200;
ctx.body = {
count: res.count,
rows: rslt
};
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function add(ctx) {
try {
const { models } = ctx.fs.dc;
const { pepUserId, provinces, cities, businessLines } = ctx.request.body
const existRes = await models.SalesDistribution.findOne({
where: { pepUserId }
})
if (existRes && !existRes.del) {
throw '当前销售人员信息已存在'
}
let storageData = { pepUserId, provinces, cities, businessLines, del: false }
if (existRes && existRes.del) {
await models.SalesDistribution.update(storageData, {
where: { pepUserId }
})
} else {
await models.SalesDistribution.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, provinces, cities, businessLines } = ctx.request.body
const existRes = await models.SalesDistribution.findOne({
where: { pepUserId }
})
if (!existRes) {
throw '当前销售人员信息不存在'
}
let storageData = { pepUserId, provinces, cities, businessLines, del: false }
await models.SalesDistribution.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 del(ctx) {
try {
const { models } = ctx.fs.dc;
const { pepUserId } = ctx.query
await models.SalesDistribution.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 exportData(ctx) {
// try {
// const { models } = ctx.fs.dc;
// const { clickHouse, opts: { qiniu } } = ctx.app.fs
// const { simpleExcelDown, memberList, packageUserData } = ctx.app.fs.utils
// const {
// keywordTarget, keyword, limit, page, state, keys = '',
// hiredateStart, hiredateEnd, marital, native, workPlace,
// orderBy, orderDirection,
// } = ctx.query
// const userRes = await memberList({
// keywordTarget, keyword, limit, page, state,
// hiredateStart, hiredateEnd, marital, native, workPlace,
// orderBy, orderDirection,
// nowAttendanceTime: true
// })
// const tableAttributes = models['Member'].tableAttributes
// const optionKeys = keys.split(',')
// let { packageUser: exportD, pepUserIds } = await packageUserData(userRes)
// let preHeader = [{
// title: '员工编号',
// key: 'userCode',
// }, {
// title: '姓名',
// key: 'userName',
// }]
// let header = [].concat(preHeader)
// for (let k in tableAttributes) {
// const comment = tableAttributes[k].comment
// if (k != 'id' && k != 'pepUserId' && comment) {
// if ([].includes(k)) {
// // 截住不想导出的字段
// continue
// }
// header.push({
// title: comment || '-',
// key: k,
// // index: tableAttributes[k].index,
// })
// }
// }
// if (optionKeys.includes('overtimeStatistic')) {
// header = header.concat([{
// title: '累计加班次数',
// key: 'overTimeCount',
// }, {
// title: '累计加班总时长 / h',
// key: 'overTimeDuration',
// },])
// }
// if (optionKeys.includes('vacateStatistic')) {
// header = header.concat([{
// title: '累计请假次数',
// key: 'vacateCount',
// }, {
// title: '累计请假总时长 / h',
// key: 'vacateDuration',
// },])
// }
// // 查询累计加班次数及总时长
// const statisticOvertimeRes = await clickHouse.hr.query(`
// SELECT
// pep_user_id AS pepUserId,
// count(id) AS count,
// sum(duration) AS duration
// FROM
// overtime
// WHERE pep_user_id IN (${pepUserIds.join(',')})
// GROUP BY pep_user_id
// `).toPromise()
// const statisticVacateRes = await clickHouse.hr.query(`
// SELECT
// pep_user_id AS pepUserId,
// count(id) AS count,
// sum(duration) AS duration
// FROM
// vacate
// WHERE pep_user_id IN (${pepUserIds.join(',')})
// GROUP BY pep_user_id
// `).toPromise()
// exportD.forEach(d => {
// d.departmrnt = d.departmrnt.map(dep => dep.name).join('、')
// d.role = d.role.map(r => r.name).join('、')
// d.idPhoto ? d.idPhoto = qiniu.domain + '/' + d.idPhoto : ''
// d.vitae ? d.vitae = qiniu.domain + '/' + d.vitae : ''
// const corOverTime = statisticOvertimeRes.find(so => so.pepUserId == d.pepUserId)
// d.overTimeCount = corOverTime ? corOverTime.count : 0
// d.overTimeDuration = corOverTime ? (corOverTime.duration / 3600).toFixed(1) : 0
// const corVacate = statisticVacateRes.find(so => so.pepUserId == d.pepUserId)
// d.vacateCount = corVacate ? corVacate.count : 0
// d.vacateDuration = corVacate ? (corVacate.duration / 3600).toFixed(1) : 0
// })
// const fileName = `人员信息_${moment().format('YYYYMMDDHHmmss')}` + '.csv'
// const filePath = await simpleExcelDown({ data: exportD, 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 addSalesMemberBulk(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 addArr = [];
let editArr = [];
let list = await models.SalesDistribution.findAll({
attributes: ['pepUserId']
});
data.map(d => {
let exist = list.find(m => m.pepUserId == d.pepUserId);//项企的人员编号字段还没有
if (exist) {
editArr.push(d);
} else {
addArr.push(d);
}
})
//处理新增的
if (addArr.length) {
await models.SalesDistribution.bulkCreate(addArr);
}
//处理编辑的
if (editArr.length) {
for (let i in editArr) {
let { pepUserId, provinces, cities, businessLines, del = false } = editArr[i];
let dataToUpdate = {
provinces,
cities,
businessLines,
del
}
await models.SalesDistribution.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 = {
salesList,
add,
edit,
del,
//exportData,
addSalesMemberBulk,
}