From bf7b9fe48021dd33f3365d38ad50ef0e4f6d51b1 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Tue, 18 Oct 2022 14:49:21 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E5=81=87=E5=8B=A4=E6=97=A5=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E9=97=B4=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/member/index.js | 50 ++++++++++++++++++++++--- api/app/lib/routes/member/index.js | 6 +++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/api/app/lib/controllers/member/index.js b/api/app/lib/controllers/member/index.js index 749e9f2..09edb9a 100644 --- a/api/app/lib/controllers/member/index.js +++ b/api/app/lib/controllers/member/index.js @@ -198,12 +198,39 @@ async function nativePlaceList (ctx) { const { models } = ctx.fs.dc; const nRes = await models.Member.findAll({ - attributes: [''], - group: '' + attributes: ['nativePlace'], + group: 'nativePlace', + where: { + nativePlace: { $ne: null } + } }) ctx.status = 200; - ctx.body = [] + ctx.body = nRes + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: error`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + +async function workPlaceList (ctx) { + // 获取已有的工作地列表 + try { + const { models } = ctx.fs.dc; + + const wRes = await models.Member.findAll({ + attributes: ['workPlace'], + group: 'workPlace', + where: { + workPlace: { $ne: null } + } + }) + + ctx.status = 200; + ctx.body = wRes } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: error`); ctx.status = 400; @@ -217,7 +244,10 @@ 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 { + keywordTarget, keyword, limit, page, state, + + } = ctx.query const curDay = moment().format('YYYY-MM-DD') const nowTime = moment() @@ -366,6 +396,10 @@ async function overTimeStatistics (ctx) { INNER JOIN overtime ON overtime.id = overtime_day.overtime_id AND overtime.pep_user_id = ${pepUserId} + ${startDate && endDate ? ` + WHERE overtime_day.day >= '${moment(startDate).format('YYYY-MM-DD')}' + AND overtime_day.day <= '${moment(endDate).format('YYYY-MM-DD')}' + ` : ''} GROUP BY overtime_day.day, overtime.compensate `).toPromise() @@ -436,6 +470,10 @@ async function vacateStatistics (ctx) { INNER JOIN vacate ON vacate.id = vacate_day.vacate_id AND vacate.pep_user_id = ${pepUserId} + ${startDate && endDate ? ` + WHERE vacate_day.day >= '${moment(startDate).format('YYYY-MM-DD')}' + AND vacate_day.day <= '${moment(endDate).format('YYYY-MM-DD')}' + ` : ''} GROUP BY vacate_day.day `).toPromise() @@ -679,5 +717,7 @@ module.exports = { overTimeStatistics, vacateStatistics, exportData, - addMembersBulk + addMembersBulk, + nativePlaceList, + workPlaceList, } \ No newline at end of file diff --git a/api/app/lib/routes/member/index.js b/api/app/lib/routes/member/index.js index 6bd9b0f..4d367d0 100644 --- a/api/app/lib/routes/member/index.js +++ b/api/app/lib/routes/member/index.js @@ -15,6 +15,12 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/member/search'] = { content: '搜索项企用户', visible: true }; router.get('/member/search', member.searchPepMember); + app.fs.api.logAttr['GET/member/native_place'] = { content: '查询籍贯列表', visible: true }; + router.get('/member/native_place', member.nativePlaceList); + + app.fs.api.logAttr['GET/member/work_place'] = { content: '查询工作地列表', visible: true }; + router.get('/member/work_place', member.workPlaceList); + app.fs.api.logAttr['GET/member/list'] = { content: '查询人员列表', visible: true }; router.get('/member/list', member.list); From 6d23f09e0899a93dd21170f38fc236b7d36de6d0 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Tue, 18 Oct 2022 15:00:22 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E5=81=87=E5=8B=A4=E6=97=A5=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E9=97=B4=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/member/index.js | 33 ++++++++++++++++--------- api/app/lib/utils/member.js | 11 ++++++++- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/api/app/lib/controllers/member/index.js b/api/app/lib/controllers/member/index.js index 09edb9a..9e654a5 100644 --- a/api/app/lib/controllers/member/index.js +++ b/api/app/lib/controllers/member/index.js @@ -246,7 +246,7 @@ async function list (ctx) { const { judgeHoliday, memberList } = ctx.app.fs.utils const { keywordTarget, keyword, limit, page, state, - + hiredateStart, hiredateEnd } = ctx.query const curDay = moment().format('YYYY-MM-DD') @@ -265,7 +265,10 @@ async function list (ctx) { dayoffTime = true } } - const userRes = await memberList({ keywordTarget, keyword, limit, page, state }) + const userRes = await memberList({ + keywordTarget, keyword, limit, page, state, + hiredateStart, hiredateEnd + }) let returnD = [] userRes.rows.forEach(u => { @@ -396,9 +399,11 @@ async function overTimeStatistics (ctx) { INNER JOIN overtime ON overtime.id = overtime_day.overtime_id AND overtime.pep_user_id = ${pepUserId} - ${startDate && endDate ? ` - WHERE overtime_day.day >= '${moment(startDate).format('YYYY-MM-DD')}' - AND overtime_day.day <= '${moment(endDate).format('YYYY-MM-DD')}' + ${startDate ? ` + AND overtime_day.day >= '${moment(startDate).format('YYYY-MM-DD')}' + `: ''} + ${endDate ? ` + AND overtime_day.day <= '${moment(endDate).format('YYYY-MM-DD')}' ` : ''} GROUP BY overtime_day.day, overtime.compensate `).toPromise() @@ -427,10 +432,14 @@ async function vacateStatistics (ctx) { const { startDate, endDate, pepUserId } = ctx.query const timeOption = [] - if (startDate && endDate) { + if (startDate) { 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')}'` + `wpStory.create_at > '${moment(startDate).format('YYYY-MM-DD HH:mm:ss')}'` + ) + } + if (endDate) { + timeOption.push( + `wpStory.create_at <= '${moment(endDate).format('YYYY-MM-DD HH:mm:ss')}'` ) } const dataRes = await clickHouse.hr.query(` @@ -470,9 +479,11 @@ async function vacateStatistics (ctx) { INNER JOIN vacate ON vacate.id = vacate_day.vacate_id AND vacate.pep_user_id = ${pepUserId} - ${startDate && endDate ? ` - WHERE vacate_day.day >= '${moment(startDate).format('YYYY-MM-DD')}' - AND vacate_day.day <= '${moment(endDate).format('YYYY-MM-DD')}' + ${startDate ? ` + AND vacate_day.day >= '${moment(startDate).format('YYYY-MM-DD')}' + `: ''} + ${endDate ? ` + AND vacate_day.day <= '${moment(endDate).format('YYYY-MM-DD')}' ` : ''} GROUP BY vacate_day.day `).toPromise() diff --git a/api/app/lib/utils/member.js b/api/app/lib/utils/member.js index a1d61b4..2629e8b 100644 --- a/api/app/lib/utils/member.js +++ b/api/app/lib/utils/member.js @@ -4,7 +4,10 @@ const request = require('superagent'); module.exports = function (app, opts) { - async function memberList ({ keywordTarget, keyword, limit, page, state }) { + async function memberList ({ + keywordTarget, keyword, limit, page, state, + hiredateStart, hiredateEnd + }) { const { judgeHoliday } = app.fs.utils const { clickHouse } = app.fs const { database: pepEmis } = clickHouse.pepEmis.opts.config @@ -114,6 +117,12 @@ module.exports = function (app, opts) { ${state == 'dimission' ? `AND member.dimission_date IS NOT null` : ''} ${state == 'onJob' ? `AND member.dimission_date IS null` : ''} ${whereFromSelectOption.length ? `AND ${whereFromSelectOption.join('AND')}` : ''} + ${hiredateStart ? ` + AND member.hiredate >= '${moment(hiredateStart).format('YYYY-MM-DD')}' + `: ''} + ${hiredateEnd ? ` + AND member.hiredate <= '${moment(hiredateEnd).format('YYYY-MM-DD')}' + ` : ''} ` const userRes = await clickHouse.hr.query(` From ace284e8d79b918f19bf3c8374734cb95a497ed8 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Tue, 18 Oct 2022 15:15:59 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=20API=5FHR=5FURL=20=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/member/index.js | 4 ++-- api/app/lib/utils/member.js | 11 ++++++++++- web/config.js | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/api/app/lib/controllers/member/index.js b/api/app/lib/controllers/member/index.js index 9e654a5..62a7da4 100644 --- a/api/app/lib/controllers/member/index.js +++ b/api/app/lib/controllers/member/index.js @@ -246,7 +246,7 @@ async function list (ctx) { const { judgeHoliday, memberList } = ctx.app.fs.utils const { keywordTarget, keyword, limit, page, state, - hiredateStart, hiredateEnd + hiredateStart, hiredateEnd, marital, native, workPlace } = ctx.query const curDay = moment().format('YYYY-MM-DD') @@ -267,7 +267,7 @@ async function list (ctx) { } const userRes = await memberList({ keywordTarget, keyword, limit, page, state, - hiredateStart, hiredateEnd + hiredateStart, hiredateEnd, marital, native, workPlace }) let returnD = [] diff --git a/api/app/lib/utils/member.js b/api/app/lib/utils/member.js index 2629e8b..589494b 100644 --- a/api/app/lib/utils/member.js +++ b/api/app/lib/utils/member.js @@ -6,7 +6,7 @@ module.exports = function (app, opts) { async function memberList ({ keywordTarget, keyword, limit, page, state, - hiredateStart, hiredateEnd + hiredateStart, hiredateEnd, marital, native, workPlace }) { const { judgeHoliday } = app.fs.utils const { clickHouse } = app.fs @@ -123,6 +123,15 @@ module.exports = function (app, opts) { ${hiredateEnd ? ` AND member.hiredate <= '${moment(hiredateEnd).format('YYYY-MM-DD')}' ` : ''} + ${marital ? ` + AND member.marital = '${marital}' + `: ''} + ${native ? ` + AND member.native_place = '${native}' + `: ''} + ${native ? ` + AND member.work_place = '${workPlace}' + `: ''} ` const userRes = await clickHouse.hr.query(` diff --git a/web/config.js b/web/config.js index bdb1a46..03989d4 100644 --- a/web/config.js +++ b/web/config.js @@ -34,6 +34,7 @@ const ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE = process.env.ANXINCLOUD_QINIU_DOMA if ( !API_URL + || !API_HR_URL || !ANXINCLOUD_QINIU_AK || !ANXINCLOUD_QINIU_SK || !ANXINCLOUD_QINIU_BUCKET_RESOURCE || !ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE ) { console.log('缺少启动参数,异常退出'); From 719567cf11fce5fac597490ca93acc4403db571f Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Tue, 18 Oct 2022 15:19:33 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=A9=9A=E8=82=B2?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/member/index.js | 25 +++++++++++++++++++++++++ api/app/lib/routes/member/index.js | 3 +++ api/app/lib/utils/member.js | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/api/app/lib/controllers/member/index.js b/api/app/lib/controllers/member/index.js index 62a7da4..de5d31f 100644 --- a/api/app/lib/controllers/member/index.js +++ b/api/app/lib/controllers/member/index.js @@ -240,6 +240,30 @@ async function workPlaceList (ctx) { } } +async function maritalList (ctx) { + // 获取已有的婚育状况列表 + try { + const { models } = ctx.fs.dc; + + const mRes = await models.Member.findAll({ + attributes: ['marital'], + group: 'marital', + where: { + marital: { $ne: null } + } + }) + + ctx.status = 200; + ctx.body = mRes + } 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; @@ -731,4 +755,5 @@ module.exports = { addMembersBulk, nativePlaceList, workPlaceList, + maritalList, } \ No newline at end of file diff --git a/api/app/lib/routes/member/index.js b/api/app/lib/routes/member/index.js index 4d367d0..9c7bb8a 100644 --- a/api/app/lib/routes/member/index.js +++ b/api/app/lib/routes/member/index.js @@ -18,6 +18,9 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/member/native_place'] = { content: '查询籍贯列表', visible: true }; router.get('/member/native_place', member.nativePlaceList); + app.fs.api.logAttr['GET/member/marital'] = { content: '查询婚育列表', visible: true }; + router.get('/member/marital', member.maritalList); + app.fs.api.logAttr['GET/member/work_place'] = { content: '查询工作地列表', visible: true }; router.get('/member/work_place', member.workPlaceList); diff --git a/api/app/lib/utils/member.js b/api/app/lib/utils/member.js index 589494b..85d353d 100644 --- a/api/app/lib/utils/member.js +++ b/api/app/lib/utils/member.js @@ -129,7 +129,7 @@ module.exports = function (app, opts) { ${native ? ` AND member.native_place = '${native}' `: ''} - ${native ? ` + ${workPlace ? ` AND member.work_place = '${workPlace}' `: ''} ` From 3b555ae9067f073f99db45e805ad8bfbc4bb2047 Mon Sep 17 00:00:00 2001 From: wuqun Date: Tue, 18 Oct 2022 16:06:13 +0800 Subject: [PATCH 5/6] =?UTF-8?q?5930=20=E4=BA=BA=E5=91=98=E6=A1=A3=E6=A1=88?= =?UTF-8?q?=E4=BA=BA=E5=91=98=E4=BF=A1=E6=81=AF=E5=AF=BC=E5=85=A5=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E4=B8=8B=E8=BD=BD=E5=BA=94=E8=AF=A5=E4=B8=BAcsv?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E6=A8=A1=E6=9D=BF=205932=20=E4=BA=BA?= =?UTF-8?q?=E5=91=98=E6=A1=A3=E6=A1=88=E4=BA=BA=E5=91=98=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E6=A0=BC=E5=BC=8F=E6=9C=AA=E5=81=9A=E9=99=90?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../containers/import-members-modal.js | 50 ++++++++++++------- .../containers/personnelFiles.jsx | 1 + 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/web/client/src/sections/humanAffairs/containers/import-members-modal.js b/web/client/src/sections/humanAffairs/containers/import-members-modal.js index cf9a00c..0cb6d48 100644 --- a/web/client/src/sections/humanAffairs/containers/import-members-modal.js +++ b/web/client/src/sections/humanAffairs/containers/import-members-modal.js @@ -31,8 +31,24 @@ const ImportMembersModal = props => { } } + const dldCsvMb = () => { + //表头 + let head = "人员编号,姓名,证件号,性别(男/女),出生年月日(例2022/02/01),籍贯,婚育状态(已婚/未婚/已婚已育),政治面貌,联系方式,工作地点,毕业院校,学历,专业,毕业时间,入职时间,转试用期时间,转正时间,离职日期,工作经验(年),历史工作经历与职务\n" + //数据 + //let data = 1 + ',' + 2 + ',' + 3 + ',' + 4 + ',' + 5 + let templateCsv = "data:text/csv;charset=utf-8,\ufeff" + head; + //创建一个a标签 + let link = document.createElement("a"); + //为a标签设置属性 + link.setAttribute("href", templateCsv); + link.setAttribute("download", "人资系统人员信息导入模板.csv"); + //点击a标签 + link.click(); + } + const download = () => { - dldTemplate(); + //dldTemplate(); + dldCsvMb(); let str = ""; rule.forEach((v, i) => { str += `${v}\r\n` @@ -40,21 +56,21 @@ const ImportMembersModal = props => { dldText("填写说明.txt", str); } - const dldTemplate = () => { - let dataTable = []; - let option = {}; - option.fileName = '人资系统人员信息导入模板'; - option.datas = [ - { - sheetData: dataTable, - sheetName: '人资系统人员信息导入模板', - sheetFilter: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'], //excel文件中需显示的列数据 - sheetHeader: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'], //excel文件中每列的表头名称 - } - ] - let toExcel = new ExportJsonExcel(option); //生成excel文件 - toExcel.saveExcel(); //下载excel文件 - } + // const dldTemplate = () => { + // let dataTable = []; + // let option = {}; + // option.fileName = '人资系统人员信息导入模板'; + // option.datas = [ + // { + // sheetData: dataTable, + // sheetName: '人资系统人员信息导入模板', + // sheetFilter: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'], //excel文件中需显示的列数据 + // sheetHeader: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'], //excel文件中每列的表头名称 + // } + // ] + // let toExcel = new ExportJsonExcel(option); //生成excel文件 + // toExcel.saveExcel(); //下载excel文件 + // } const dldText = (filename, text) => { var element = document.createElement('a'); @@ -68,7 +84,7 @@ const ImportMembersModal = props => { document.body.removeChild(element); } //const action = '/file/qiniu/upload?type=excel&token=' + user.token; - const fileLimit = '.xls,.xlsx,.csv'; + const fileLimit = '.csv'; const getFileBlob = (url) => { return new Promise((resolve, reject) => { diff --git a/web/client/src/sections/humanAffairs/containers/personnelFiles.jsx b/web/client/src/sections/humanAffairs/containers/personnelFiles.jsx index d87ea29..f45095e 100644 --- a/web/client/src/sections/humanAffairs/containers/personnelFiles.jsx +++ b/web/client/src/sections/humanAffairs/containers/personnelFiles.jsx @@ -32,6 +32,7 @@ const Rest = (props) => { }, [typeChoose]) function getMemberSearchList () {//搜索项企用户 + dispatch(humanAffairs.getMemberSearch()) dispatch(humanAffairs.getMemberList({ keywordTarget, keyword, state: typeChoose })).then((res) => {//搜索项企用户 if (res.success) { setArchivesList(res.payload?.data?.rows) From 64dc6b85e59ed431f52d5f6c1f45b22e1bf5798e Mon Sep 17 00:00:00 2001 From: wuqun Date: Tue, 18 Oct 2022 16:19:03 +0800 Subject: [PATCH 6/6] =?UTF-8?q?5936=20=E4=BA=BA=E5=91=98=E6=A1=A3=E6=A1=88?= =?UTF-8?q?=E4=BA=BA=E5=91=98=E4=BF=A1=E6=81=AF=E5=AF=BC=E5=85=A5=E5=BF=85?= =?UTF-8?q?=E5=A1=AB=E4=B8=94=E6=AD=A3=E7=A1=AE=E7=9A=84=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E7=BC=96=E5=8F=B7=E5=90=8E=E6=8F=90=E7=A4=BA=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/sections/humanAffairs/containers/import-members-modal.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web/client/src/sections/humanAffairs/containers/import-members-modal.js b/web/client/src/sections/humanAffairs/containers/import-members-modal.js index 0cb6d48..54332f9 100644 --- a/web/client/src/sections/humanAffairs/containers/import-members-modal.js +++ b/web/client/src/sections/humanAffairs/containers/import-members-modal.js @@ -104,6 +104,7 @@ const ImportMembersModal = props => { const workbook = XLSX.read(result, { type: "binary", cellDates: true,//设为true,将天数的时间戳转为时间格式 + codepage: 936 }); let data = []; // 存储获取到的数据 // 遍历每张工作表进行读取(这里默认只读取第一张表)