From b305766ad31d7772c79487f935789bae85b1862a Mon Sep 17 00:00:00 2001 From: zhouxin Date: Tue, 27 Dec 2022 17:35:01 +0800 Subject: [PATCH] =?UTF-8?q?(*)=E5=B2=97=E4=BD=8D=E8=AF=84=E7=BA=A7?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E3=80=81=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/member/index.js | 71 ++++++++++++++++++- api/app/lib/routes/member/index.js | 8 ++- .../actions/employeeInformation.js | 25 ++++++- .../components/importPositionRating.jsx | 15 ++-- .../containers/positionRating.jsx | 60 ++++++++++------ web/client/src/utils/webapi.js | 2 + 6 files changed, 144 insertions(+), 37 deletions(-) diff --git a/api/app/lib/controllers/member/index.js b/api/app/lib/controllers/member/index.js index 3d1a661..6fad724 100644 --- a/api/app/lib/controllers/member/index.js +++ b/api/app/lib/controllers/member/index.js @@ -746,9 +746,12 @@ async function getPositionRating(ctx) { const userInfo = userRes && userRes.filter(u => item.pepUserId == u.userId); item.dataValues.department = userInfo.map(u => { return { depName: u.depName, depId: u.depId } }); item.dataValues.userName = userInfo.length && userInfo[0].userName; - item.d + const { theoryPassed, totalRatingPassed, ratingTime, ...rest } = item.dataValues rslt.push({ - ...item.dataValues, + ...rest, + theoryPassed: theoryPassed ? '是' : '否', + totalRatingPassed: totalRatingPassed ? '是' : '否', + ratingTime: moment(ratingTime).format('YYYY-MM-DD'), department: userInfo.map(u => { return { depName: u.depName, depId: u.depId } }), userName: userInfo.length && userInfo[0].userName, userPost: userInfo.length && userInfo[0].userPost @@ -772,6 +775,66 @@ async function getPositionRating(ctx) { } } } +//新增岗位评级 +async function postPositionRating(ctx) { + let errorMsg = { message: '导入岗位绩效失败' }; + const transaction = await ctx.fs.dc.orm.transaction(); + + try { + const models = ctx.fs.dc.models; + const data = ctx.request.body; + + //处理新增的 + if (data) { + if (data.length) { + const dataToSave = []; + const dataToUpdate = []; + data.map((item) => { + const { pepUserId, technicalGrade } = item; + dataToUpdate.push({ pepUserId, technicalGrade }); + }) + await models.PositionRating.bulkCreate(data, { transaction }); + for (let item in dataToUpdate) { + await models.Member.update({ technicalGrade: dataToUpdate[item].technicalGrade }, + { where: { pepUserId: dataToUpdate[item].pepUserId }, transaction }); + } + } + else { + await models.PositionRating.create(data, { transaction }); + await models.Member.update({ technicalGrade: data.technicalGrade }, + { where: { pepUserId: data.pepUserId }, transaction }); + } + //更新member表字段 + } + + 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; + } +} +async function delPositionRating(ctx) { + try { + const { models } = ctx.fs.dc; + const { id } = ctx.params; + + const oldData = await models.PositionRating.findOne({ where: { id: id } }); + if (oldData) { + //todo 更新memeber技术等级字段 + await models.PositionRating.destory({ where: { id: id }, transaction }); + } + 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 + } + } +} module.exports = { add, edit, @@ -785,5 +848,7 @@ module.exports = { nativePlaceList, workPlaceList, maritalList, - getPositionRating + getPositionRating, + postPositionRating, + delPositionRating } \ 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 6208ba5..bcb3c36 100644 --- a/api/app/lib/routes/member/index.js +++ b/api/app/lib/routes/member/index.js @@ -39,6 +39,12 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/members/export'] = { content: '导出员工信息', visible: true }; router.get('/members/export', member.exportData); - app.fs.api.logAttr['GET/members/position_rating'] = { content: '查询岗位评级信息', visible: true }; + app.fs.api.logAttr['GET/members/position_rating'] = { content: '查询岗位评级信息', visible: false }; router.get('/members/position_rating', member.getPositionRating); + + app.fs.api.logAttr['POST/members/position_rating'] = { content: '新增岗位评级信息', visible: true }; + router.post('/members/position_rating', member.postPositionRating); + + app.fs.api.logAttr['DEL/members/position_rating/:id'] = { content: '删除岗位评级信息', visible: true }; + router.del('/members/position_rating/:id', member.delPositionRating); }; \ No newline at end of file diff --git a/web/client/src/sections/humanAffairs/actions/employeeInformation.js b/web/client/src/sections/humanAffairs/actions/employeeInformation.js index b0b0b4d..e89f205 100644 --- a/web/client/src/sections/humanAffairs/actions/employeeInformation.js +++ b/web/client/src/sections/humanAffairs/actions/employeeInformation.js @@ -57,7 +57,7 @@ export function getAttendanceOvertime(query) {//加班统计 reducer: { name: "AttendanceOvertime", params: { noClear: true } }, }); } -export function getPositionRating(query){//岗位评级 +export function getPositionRating(query) {//岗位评级 return (dispatch) => basicAction({ type: "get", dispatch: dispatch, @@ -67,4 +67,27 @@ export function getPositionRating(query){//岗位评级 msg: { option: "岗位评级" }, reducer: { name: "positionRating", params: { noClear: true } }, }); +} + +export function postPositionRating(data) { + return (dispatch) => + basicAction({ + type: "post", + dispatch: dispatch, + data, + actionType: "POST_POSITION_RATING", + url: `${ApiTable.postPositionRating}`, + msg: { option: "导入岗位评级" } + }) +} + +export function delPositionRating(id) { + return (dispatch) => + basicAction({ + type: "del", + dispatch: dispatch, + actionType: "DEL_POSITIONRATING", + url: `${ApiTable.delPositionRating.replace("{id}", id)}`, + msg: { option: "删除岗位评级" } + }); } \ No newline at end of file diff --git a/web/client/src/sections/humanAffairs/components/importPositionRating.jsx b/web/client/src/sections/humanAffairs/components/importPositionRating.jsx index 0c5dba7..3adcc5d 100644 --- a/web/client/src/sections/humanAffairs/components/importPositionRating.jsx +++ b/web/client/src/sections/humanAffairs/components/importPositionRating.jsx @@ -16,23 +16,16 @@ const IMPORT_FIELD = { const SHEETNAME = "岗位评级"; const ImportPositionRatingModal = props => { - const { onCancel, user, memberList } = props; + const { onCancel, onOk, user, memberList } = props; const [msg, setMsg] = useState(''); const [loading, setLoading] = useState(''); const [postData, setPostData] = useState([]); const fileLimit = '.xlsx'; - //初始化 const confirm = () => { if (postData.length) { - setLoading(true) - // dispatch(postAllPersonalTrainRecord(postData)).then(res => { - // if (res.success) { - // onCancel() - // dispatch(getPersonalTrainRecord(query)) - // } - // setLoading(false) - // }) + setLoading(true); + onOk(postData); } else { Notification.warning({ content: '没有数据可以提交,请上传数据文件', duration: 2 }) } @@ -170,6 +163,8 @@ const ImportPositionRatingModal = props => { if (!["是", "否"].includes(obj[item])) { errmsg = `第${i + 2}行【${IMPORT_FIELD[item].label}】不合法,请修改`; break; + } else { + obj[item] = "是" == obj[item] ? true : false; } } else if ("ratingTime" == item) { diff --git a/web/client/src/sections/humanAffairs/containers/positionRating.jsx b/web/client/src/sections/humanAffairs/containers/positionRating.jsx index 6e6519f..c24c828 100644 --- a/web/client/src/sections/humanAffairs/containers/positionRating.jsx +++ b/web/client/src/sections/humanAffairs/containers/positionRating.jsx @@ -1,17 +1,13 @@ import React, { useEffect, useState, useRef, useMemo } from 'react'; import { connect } from 'react-redux'; -import moment from 'moment' -import { Table, Button, Pagination, Skeleton, Form, Tooltip } from '@douyinfe/semi-ui'; -import { IconSearch } from '@douyinfe/semi-icons'; +import { Table, Button, Pagination, Skeleton, Popconfirm, Tooltip } from '@douyinfe/semi-ui'; import { SkeletonScreen, Setup } from "$components"; -import { UserAttribute } from '$utils'; import ImportPositionRatingModal from '../components/importPositionRating'; import '../style.less'; const PositionRating = (props) => { - const { dispatch, actions, memberList, history, user, loading, socket, xqMembers } = props - const { humanAffairs } = actions; - const { getMemberList, getPositionRating } = actions.humanAffairs; + const { dispatch, actions, memberList } = props + const { getMemberList, getPositionRating, postPositionRating, delPositionRating } = actions.humanAffairs; const form = useRef();//表单 let [archivesList, setArchivesList] = useState([]);//人员列表 @@ -25,8 +21,8 @@ const PositionRating = (props) => { getMainList() }, [query]) - function getMainList() { - dispatch(getPositionRating(query)).then((res) => { + function getMainList(queryObj) { + dispatch(getPositionRating(queryObj || query)).then((res) => { if (res.success) { setArchivesList(res.payload?.data?.rows) setLimits(res.payload?.data?.count) @@ -103,45 +99,50 @@ const PositionRating = (props) => { width: 120, dataIndex: "userPost", key: "userPost", - render: (_, r, index) => { - return r.userPost || '-'; - }, }, { title: '评级时间', - width: 100, + width: 120, dataIndex: "ratingTime", key: "ratingTime", - render: (_, r, index) => -, }, { title: '理论基础测评成绩', width: 150, dataIndex: "theoryBasicScore", key: "theoryBasicScore", - render: (_, r, index) => -, }, { title: '理论基础测评是否通过(≥60)', - width: 150, + width: 130, dataIndex: "theoryPassed", key: "theoryPassed", - render: (_, r, index) => -, }, { title: '评级总成绩', - width: 150, + width: 100, dataIndex: "totalScore", key: "totalScore", - render: (_, r, index) => -, }, { title: '评级总成绩是否通过(K≥60)', - width: 150, + width: 130, dataIndex: "totalRatingPassed", key: "totalRatingPassed", - render: (_, r, index) => -, }, { title: '技术职级等级', width: 150, dataIndex: "technicalGrade", key: "technicalGrade", - render: (_, r, index) => -, + }, { + title: '操作', + width: 100, + dataIndex: "action", + key: "action", + render: (text, record) =>
{ handleDel(record.id) }} + position={"leftBottom"} + > + 删除 +
}]; function handleRow(record, index) {//斑马条纹 @@ -162,6 +163,20 @@ const PositionRating = (props) => { } setImportModal(true); } + + const handleImportOk = (dataToSave) => { + dispatch(postPositionRating(dataToSave)).then(res => { + setImportModal(false); + setQuery({ limit: 10, page: 0 }); + getMainList({ limit: 10, page: 0 }); + }) + } + const handleDel = (id) => { + dispatch(delPositionRating(id)).then(res => { + setQuery({ limit: 10, page: 0 }); + getMainList({ limit: 10, page: 0 }); + }) + } const scroll = useMemo(() => ({}), []); return ( <> @@ -266,6 +281,7 @@ const PositionRating = (props) => { {importModal ? { setImportModal(false) }} /> : ''} diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js index 8ff83a8..1dee153 100644 --- a/web/client/src/utils/webapi.js +++ b/web/client/src/utils/webapi.js @@ -38,6 +38,8 @@ export const ApiTable = { delSalesMember: 'sales/member/del', addSalesMemberBulk: 'add/sales/members/bulk', getPositionRating: 'members/position_rating', + postPositionRating: 'members/position_rating', + delPositionRating: 'members/position_rating/{id}', //部门培训记录 getDepartmentTrainRecord: 'department/train/record/list',