deartibers 2 years ago
parent
commit
2217ed1e30
  1. BIN
      web/client/assets/images/hrImg/defaultAvatar.png
  2. 3
      web/client/src/sections/auth/containers/login.jsx
  3. 58
      web/client/src/sections/humanAffairs/actions/personnelFiles.js
  4. 360
      web/client/src/sections/humanAffairs/components/city.json
  5. 117
      web/client/src/sections/humanAffairs/components/deleteModal.jsx
  6. 152
      web/client/src/sections/humanAffairs/components/personnelModal.jsx
  7. 15
      web/client/src/sections/humanAffairs/components/style.less
  8. 73
      web/client/src/sections/humanAffairs/containers/personnelFiles.jsx
  9. 67
      web/client/src/sections/humanAffairs/containers/personnelFilesDetail.jsx
  10. 6
      web/client/src/utils/webapi.js

BIN
web/client/assets/images/hrImg/defaultAvatar.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

3
web/client/src/sections/auth/containers/login.jsx

@ -59,13 +59,14 @@ const Login = props => {
width: 388,
marginTop: "18.33%"
}}>
<div style={{ fontSize: 31, color: '#000000',marginBottom:90 }}>
<div style={{ fontSize: 31, color: '#000000', marginBottom: 90 }}>
FS-CRM企业信息管理系统
</div>
<Form
onSubmit={values => {
dispatch(login(values.username, values.password)).then(res => {
const data = res.payload.user
localStorage.setItem('word', JSON.stringify(values.password))
dispatch(actions.layout.initWebSocket({ ioUrl: apiRoot, token: data.token, hrUserId: data.hrUserInfo.id }))
})
}}

58
web/client/src/sections/humanAffairs/actions/personnelFiles.js

@ -23,4 +23,60 @@ export function membersBulkAdd(values) {
data: values,
msg: { option: '导入员工信息' },
});
}
}
export function postMember (data) {//添加/编辑成员
let msg = ''
if (data) {
msg = data.msg
}
return (dispatch) =>
basicAction({
type: "post",
dispatch: dispatch,
data,
actionType: "POST_MEMBER",
url: `${ApiTable.postMember}`,
msg: { option: msg }, //添加/编辑成员
reducer: { name: "" },
});
}
export function getMemberList(query) {//查询人员列表
return (dispatch) => basicAction({
type: "get",
dispatch: dispatch,
actionType: "GET_MENBERLIST",
query: query,
url: `${ApiTable.getMemberList}`,
msg: { option: "查询人员列表" },
reducer: { name: "MemberList", params: { noClear: true } },
});
}
export function delMember (data) {//删除人员信息
let msg = ''
if (data) {
msg = data.msg
}
return (dispatch) =>
basicAction({
type: "del",
query:data,
dispatch: dispatch,
actionType: "DEL_MEMBER",
url: `${ApiTable.delMember}`,
msg: { option: msg }, //删除人员信息
reducer: {},
});
}
export function getMemberOvertime(query) {//查询单个人员加班统计数据
return (dispatch) => basicAction({
type: "get",
dispatch: dispatch,
actionType: "GET_MemberOVERTIME",
query: query,
url: `${ApiTable.getMemberOvertime}`,
msg: { option: "查询人员加班统计数据" },
reducer: { name: "MemberOvertime", params: { noClear: true } },
});
}

360
web/client/src/sections/humanAffairs/components/city.json

@ -1,143 +1,11 @@
[
{
"code": "11",
"name": "北京市",
"children": [
{
"code": "110101",
"name": "东城区"
},
{
"code": "110102",
"name": "西城区"
},
{
"code": "110105",
"name": "朝阳区"
},
{
"code": "110106",
"name": "丰台区"
},
{
"code": "110107",
"name": "石景山区"
},
{
"code": "110108",
"name": "海淀区"
},
{
"code": "110109",
"name": "门头沟区"
},
{
"code": "110111",
"name": "房山区"
},
{
"code": "110112",
"name": "通州区"
},
{
"code": "110113",
"name": "顺义区"
},
{
"code": "110114",
"name": "昌平区"
},
{
"code": "110115",
"name": "大兴区"
},
{
"code": "110116",
"name": "怀柔区"
},
{
"code": "110117",
"name": "平谷区"
},
{
"code": "110118",
"name": "密云区"
},
{
"code": "110119",
"name": "延庆区"
}
]
"name": "北京市"
},
{
"code": "12",
"name": "天津市",
"children": [
{
"code": "120101",
"name": "和平区"
},
{
"code": "120102",
"name": "河东区"
},
{
"code": "120103",
"name": "河西区"
},
{
"code": "120104",
"name": "南开区"
},
{
"code": "120105",
"name": "河北区"
},
{
"code": "120106",
"name": "红桥区"
},
{
"code": "120110",
"name": "东丽区"
},
{
"code": "120111",
"name": "西青区"
},
{
"code": "120112",
"name": "津南区"
},
{
"code": "120113",
"name": "北辰区"
},
{
"code": "120114",
"name": "武清区"
},
{
"code": "120115",
"name": "宝坻区"
},
{
"code": "120116",
"name": "滨海新区"
},
{
"code": "120117",
"name": "宁河区"
},
{
"code": "120118",
"name": "静海区"
},
{
"code": "120119",
"name": "蓟州区"
}
]
"name": "天津市"
},
{
"code": "13",
@ -457,73 +325,7 @@
},
{
"code": "31",
"name": "上海市",
"children": [
{
"code": "310101",
"name": "黄浦区"
},
{
"code": "310104",
"name": "徐汇区"
},
{
"code": "310105",
"name": "长宁区"
},
{
"code": "310106",
"name": "静安区"
},
{
"code": "310107",
"name": "普陀区"
},
{
"code": "310109",
"name": "虹口区"
},
{
"code": "310110",
"name": "杨浦区"
},
{
"code": "310112",
"name": "闵行区"
},
{
"code": "310113",
"name": "宝山区"
},
{
"code": "310114",
"name": "嘉定区"
},
{
"code": "310115",
"name": "浦东新区"
},
{
"code": "310116",
"name": "金山区"
},
{
"code": "310117",
"name": "松江区"
},
{
"code": "310118",
"name": "青浦区"
},
{
"code": "310120",
"name": "奉贤区"
},
{
"code": "310151",
"name": "崇明区"
}
]
"name": "上海市"
},
{
"code": "32",
@ -1315,161 +1117,7 @@
},
{
"code": "50",
"name": "重庆市",
"children": [
{
"code": "500101",
"name": "万州区"
},
{
"code": "500102",
"name": "涪陵区"
},
{
"code": "500103",
"name": "渝中区"
},
{
"code": "500104",
"name": "大渡口区"
},
{
"code": "500105",
"name": "江北区"
},
{
"code": "500106",
"name": "沙坪坝区"
},
{
"code": "500107",
"name": "九龙坡区"
},
{
"code": "500108",
"name": "南岸区"
},
{
"code": "500109",
"name": "北碚区"
},
{
"code": "500110",
"name": "綦江区"
},
{
"code": "500111",
"name": "大足区"
},
{
"code": "500112",
"name": "渝北区"
},
{
"code": "500113",
"name": "巴南区"
},
{
"code": "500114",
"name": "黔江区"
},
{
"code": "500115",
"name": "长寿区"
},
{
"code": "500116",
"name": "江津区"
},
{
"code": "500117",
"name": "合川区"
},
{
"code": "500118",
"name": "永川区"
},
{
"code": "500119",
"name": "南川区"
},
{
"code": "500120",
"name": "璧山区"
},
{
"code": "500151",
"name": "铜梁区"
},
{
"code": "500152",
"name": "潼南区"
},
{
"code": "500153",
"name": "荣昌区"
},
{
"code": "500154",
"name": "开州区"
},
{
"code": "500155",
"name": "梁平区"
},
{
"code": "500156",
"name": "武隆区"
},
{
"code": "500229",
"name": "城口县"
},
{
"code": "500230",
"name": "丰都县"
},
{
"code": "500231",
"name": "垫江县"
},
{
"code": "500233",
"name": "忠县"
},
{
"code": "500235",
"name": "云阳县"
},
{
"code": "500236",
"name": "奉节县"
},
{
"code": "500237",
"name": "巫山县"
},
{
"code": "500238",
"name": "巫溪县"
},
{
"code": "500240",
"name": "石柱土家族自治县"
},
{
"code": "500241",
"name": "秀山土家族苗族自治县"
},
{
"code": "500242",
"name": "酉阳土家族苗族自治县"
},
{
"code": "500243",
"name": "彭水苗族土家族自治县"
}
]
"name": "重庆市"
},
{
"code": "51",

117
web/client/src/sections/humanAffairs/components/deleteModal.jsx

@ -0,0 +1,117 @@
import React, { useState, useRef, useEffect } from "react";
import { connect } from "react-redux";
import { Modal, Form, Button, Upload, Toast } from "@douyinfe/semi-ui";
import { IconAlertCircle } from '@douyinfe/semi-icons';
import cityData from './city.json';
import PerfectScrollbar from "perfect-scrollbar";
import './style.less'
let Scrollbar;
function deleteModal (props) {
const {
close,
cancel,
visible,
dispatch,
actions,
pepUserId
} = props;
const { humanAffairs } = actions;
const form = useRef();//
const [idPhoto, setIdPhoto] = useState(); //
const [word, setWord] = useState(); //
//
useEffect(() => {
setWord(JSON.parse(localStorage.getItem('word')))
}, []);
useEffect(() => {
const Project = document.getElementById("myForm");
if (Project) {
if (Project && Scrollbar) {
Scrollbar.update();
}
Scrollbar = new PerfectScrollbar("#myForm", {
suppressScrollX: true,
});
}
});
function handleOk () {
//
form.current
.validate()
.then((values) => {
if (word == values.word) {
dispatch(humanAffairs.delMember({ pepUserId: pepUserId, msg: '删除档案' })).then((res) => {//(PEP)
if (res.success) {
close();
}
})
}
else {
Toast.error('密码错误');
form.current.setValue('word', '')
}
})
}
function handleCancel () {
cancel();
//
}
return (
<>
<Modal
title={'警告'}
okText="确认删除"
cancelText="取消"
visible={visible}
onOk={handleOk}
width={500}
onCancel={handleCancel}
>
<div style={{ borderBottom: '1px solid #DCDEE0', margin: '0px -24px' }}></div>
<Form
// allowEmpty
labelPosition="left"
labelAlign="right"
labelWidth="116px"
onValueChange={(values, field) => {
console.log('values', values);
}}
getFormApi={(formApi) => (form.current = formApi)}
>
<div style={{ padding: '20px 0px' }}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div>
<Form.Input
field="word"
label='我的登录密码:'
style={{ width: 334 }}
initValue={'' || ""}
placeholder="请输入登录密码"
mode="password"
showClear
rules={[{ required: true, message: "请输入登录密码" }]}
/>
</div>
</div>
</div>
</Form>
</Modal >
</>
);
}
function mapStateToProps (state) {
const { auth, global, members } = state;
return {
// loading: members.isRequesting,
user: auth.user,
actions: global.actions,
apiRoot: global.apiRoot,
// members: members.data,
};
}
export default connect(mapStateToProps)(deleteModal);

152
web/client/src/sections/humanAffairs/components/personnelModal.jsx

@ -4,7 +4,7 @@ import { Modal, Form, Button, Upload } from "@douyinfe/semi-ui";
import { IconAlertCircle } from '@douyinfe/semi-icons';
import cityData from './city.json';
import PerfectScrollbar from "perfect-scrollbar";
import './style.less'
let Scrollbar;
function pushModal (props) {
const {
@ -16,7 +16,8 @@ function pushModal (props) {
actions,
adminEdit,//
editObj,
user
user,
apiRoot,
} = props;
const { humanAffairs } = actions;
const form = useRef();//
@ -26,16 +27,24 @@ function pushModal (props) {
const [peoplePro, setPeoplePro] = useState({}); //
const [usecityData, setUsecityData] = useState(); //id
const [idPhoto, setIdPhoto] = useState(); //
const [idPhotoBtn, setIdPhotoBtn] = useState(true); //
const [vitae, setVitae] = useState(); //
const [vitaeBtn, setVitaeBtn] = useState(true); //
//
useEffect(() => {
let mycityData = JSON.parse(JSON.stringify(cityData));
for (let i = 0; i < mycityData.length; i++) {
mycityData[i].value = mycityData[i].name
mycityData[i].label = mycityData[i].name
for (let j = 0; j < mycityData[i].children.length; j++) {
mycityData[i].children[j].value = mycityData[i].children[j].name
mycityData[i].children[j].label = mycityData[i].children[j].name
if (mycityData[i].children) {
for (let j = 0; j < mycityData[i].children.length; j++) {
mycityData[i].children[j].value = mycityData[i].children[j].name
mycityData[i].children[j].label = mycityData[i].children[j].name
}
}
}
setUsecityData(mycityData)
@ -64,24 +73,64 @@ function pushModal (props) {
});
}
});
function memberSeach (id) {
function memberSeach (id) {//
dispatch(humanAffairs.getMemberSearch({ keyword: id })).then((res) => {//
if (res.success) {
console.log('res.payload.data', res.payload.data);
setPeoplePro(res.payload.data[0])
}
})
}
function uploadOnChange (fileList, currentFile, event) {//
if (fileList.currentFile.status == "success") {
setIdPhoto(fileList.currentFile.response.key)
setIdPhotoBtn(false)
}
if (fileList.fileList.length == 0) {
setIdPhotoBtn(true);
setIdPhoto('');
}
}
function uploadPdfOnChange (fileList, currentFile, event) {//
if (fileList.currentFile.status == "success") {
setVitae(fileList.currentFile.response.key)
setVitaeBtn(false)
}
if (fileList.fileList.length == 0) {
setVitaeBtn(true);
setVitae('');
}
}
function handleOk () {
//
form.current
.validate()
.then((values) => {
let obj = values
if (values.nativePlace) {
if (values.nativePlace.length > 1) {
obj.nativePlace = values.nativePlace.join('-')
}
else {
obj.nativePlace = values.nativePlace[0]
}
}
if (values.workPlace) {
if (values.workPlace.length > 1) {
obj.workPlace = values.workPlace.join('-')
}
else {
obj.workPlace = values.workPlace[0]
}
}
if (adminEdit) {
}
else {
dispatch(humanAffairs.postMember({ idPhoto: idPhoto, vitae: vitae, msg: '新增档案', ...obj })).then((res) => {//(PEP)
if (res.success) {
close();
}
})
}
})
}
@ -103,7 +152,7 @@ function pushModal (props) {
<div style={{ borderBottom: '1px solid #DCDEE0', margin: '0px -24px' }}></div>
<div id="myForm" style={{ margin: "0px 26px", height: 546 }}>
<Form
allowEmpty
// allowEmpty
labelPosition="left"
labelAlign="right"
labelWidth="98px"
@ -236,22 +285,24 @@ function pushModal (props) {
/>
</div>
{/* idPhoto */}
<div style={{ height: 32, margin: '12px 0px 12px 40px', display: 'flex', alignItems: 'center' }}>
<div style={{ margin: '12px 0px 12px 40px', display: 'flex', alignItems: 'center' }} className='upload'>
<div style={{ color: 'rgba(0, 0, 0, 0.65)', fontWeight: 600, width: 98, paddingRight: 16, textAlign: 'end' }}>
上传照片:
</div>
<div>
<Upload action={'_api/attachments/idPhoto?token=' + user.token} limit='1' accept="image/*" maxSize={10240}
<Upload action={apiRoot + '/attachments/idPhoto?token=' + user.token} limit={1} accept="image/*" maxSize={10240}
onSizeError={(file, fileList) => Toast.error(`${file.name} 超过10M`)}
onChange={uploadOnChange}
>
<Button theme='solid' type='primary' style={{ width: 89, borderRadius: 3, height: 32, background: '#005ABD', color: '#FFFFFF' }}>请上传照片</Button>
{
!idPhotoBtn ? '' : (<Button theme='solid' type='primary' style={{ width: 89, borderRadius: 3, height: 32, background: '#005ABD', color: '#FFFFFF' }}>请上传照片</Button>)
}
</Upload>
</div>
</div>
</div>
<div style={{ color: '#1890FF', fontSize: 12, textAlign: 'end' }}>
请上传照片不超过10m支持pngjpgbmp格式
请上传照片不超过10M支持pngjpgbmp格式
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div>
@ -277,7 +328,8 @@ function pushModal (props) {
label='出生年月:'
placeholder="请选择出生年月"
style={{ width: 184 }}
initValue={new Date()} />
// initValue={new Date()}
/>
</div>
<div>
<Form.Cascader
@ -332,6 +384,28 @@ function pushModal (props) {
</Form.Cascader>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div>
<Form.Select
label="婚育状态:"
field="marital"
placeholder="请选择婚育状态"
style={{ width: 122 }}
initValue={'' || ""}
showClear
>
<Form.Select.Option value='已婚已育'>
已婚已育
</Form.Select.Option>
<Form.Select.Option value='已婚'>
已婚
</Form.Select.Option>
<Form.Select.Option value='未婚'>
未婚
</Form.Select.Option>
</Form.Select>
</div>
</div>
</div>
</div>
{/* 学历信息 */}
@ -404,7 +478,8 @@ function pushModal (props) {
label='毕业时间:'
placeholder="请选择毕业时间"
style={{ width: 300 }}
initValue={new Date()} />
// initValue={new Date()}
/>
</div>
</div>
</div>
@ -423,7 +498,8 @@ function pushModal (props) {
label='入职时间:'
placeholder="请选择入职时间"
style={{ width: 288 }}
initValue={new Date()} />
// initValue={new Date()} .
/>
</div>
<div>
<Form.DatePicker
@ -432,7 +508,8 @@ function pushModal (props) {
placeholder="请选择转试用期时间"
labelWidth="110px"
style={{ width: 288 }}
initValue={new Date()} />
// initValue={new Date()}
/>
</div>
</div>
@ -446,7 +523,8 @@ function pushModal (props) {
label='转正时间:'
placeholder="请选择转正时间"
style={{ width: 288 }}
initValue={new Date()} />
// initValue={new Date()}
/>
</div>
<div>
<Form.DatePicker
@ -455,7 +533,8 @@ function pushModal (props) {
placeholder="请选择离职时间"
style={{ width: 288 }}
labelWidth="110px"
initValue={new Date()} />
// initValue={new Date()}
/>
</div>
</div>
</div>
@ -481,18 +560,30 @@ function pushModal (props) {
/>
</div>
{/* vitae */}
<div style={{ height: 32, width: 386, margin: '12px 0px', display: 'flex', alignItems: 'center' }}>
<div style={{ width: 386, margin: '12px 0px', display: 'flex', alignItems: 'center' }} className='vitae'>
<div style={{ color: 'rgba(0, 0, 0, 0.65)', fontWeight: 600, width: 98, paddingRight: 16, textAlign: 'end' }}>
上传简历:
</div>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '5px 12px', background: 'rgba(0,90,189,0.07)', width: 288, height: 32, cursor: "pointer" }}>
<div style={{ color: '#005ABD', fontSize: 13 }}>
请上传简历.pdf
</div>
<div style={{ width: 11, height: 11, display: 'flex', alignItems: 'center', }}>
<img src="/assets/images/hrImg/upload.png" alt="" style={{ width: '100%', height: '100%' }} />
</div>
</div>
<Upload action={apiRoot + '/attachments/vitae?token=' + user.token} limit={1} accept=".pdf" maxSize={10240}
onSizeError={(file, fileList) => Toast.error(`${file.name} 超过10M`)}
onChange={uploadPdfOnChange}
>
{
!vitaeBtn ? '' : (
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '5px 12px', background: 'rgba(0,90,189,0.07)', width: 288, height: 32, cursor: "pointer" }}>
<div style={{ color: '#005ABD', fontSize: 13 }}>
请上传简历.pdf
</div>
<div style={{ width: 11, height: 11, display: 'flex', alignItems: 'center', }}>
<img src="/assets/images/hrImg/upload.png" alt="" style={{ width: '100%', height: '100%' }} />
</div>
</div>
)
}
</Upload>
</div>
<div style={{ color: '#1890FF', fontSize: 12, textAlign: 'end' }}>
请上传简历不超过10M支持pdf格式
</div>
</div>
<div>
@ -507,7 +598,7 @@ function pushModal (props) {
</div>
</Form>
</div>
</Modal>
</Modal >
</>
);
}
@ -517,6 +608,7 @@ function mapStateToProps (state) {
// loading: members.isRequesting,
user: auth.user,
actions: global.actions,
apiRoot: global.apiRoot,
// members: members.data,
};
}

15
web/client/src/sections/humanAffairs/components/style.less

@ -0,0 +1,15 @@
.upload{
.semi-upload-file-card{
width:182px;
}
}
.vitae{
.semi-upload-file-card{
width:288px;
height: 32px;
.semi-upload-file-card-preview{
height: 30px;
width: 30px;
}
}
}

73
web/client/src/sections/humanAffairs/containers/personnelFiles.jsx

@ -1,10 +1,11 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Select, Input, Button, CheckboxGroup } from '@douyinfe/semi-ui';
import { Select, Input, Button, CheckboxGroup, Tooltip } from '@douyinfe/semi-ui';
import { IconSearch } from '@douyinfe/semi-icons';
import PersonnelModal from '../components/personnelModal';
import ExportMembersModal from './import-members-modal'
import '../style.less'
import moment from 'moment'
const Rest = (props) => {
const { dispatch, actions, history, user, loading, socket } = props
@ -12,7 +13,7 @@ const Rest = (props) => {
const { humanAffairs } = actions;
let [departmentValue, setDepartmentValue] = useState('');
let [archivesList, setArchivesList] = useState(['', '', '', '', '', '', '', '', '', '']);
let [archivesList, setArchivesList] = useState([]);
const [personnelModal, setPersonnelModal] = useState(false);//
const [exportModalVs, setExportModalVs] = useState(false);
const options = [
@ -29,9 +30,11 @@ const Rest = (props) => {
getMemberSearchList()
}, [])
function getMemberSearchList() {//
dispatch(humanAffairs.getMemberSearch()).then((res) => {//
function getMemberSearchList () {//
dispatch(humanAffairs.getMemberList()).then((res) => {//
if (res.success) {
console.log('res.success', res.payload.data);
setArchivesList(res.payload.data)
// let mytableData = JSON.parse(JSON.stringify(res.payload.data.rows));
// let mytableKey = []
// for (let index = 0; index < mytableData.length; index++) {
@ -46,11 +49,11 @@ const Rest = (props) => {
})
}
function typeOnChange(e) {//
function typeOnChange (e) {//
console.log('e.target.value', e.target.value);
setTypeChoose(e.target.value);
}
function seachValueChange() {
function seachValueChange () {
}
return (
@ -146,19 +149,40 @@ const Rest = (props) => {
return (
<div key={index} style={{ display: 'flex', width: 368, border: '1px solid #F9F9F9', boxShadow: '0px 0px 4px 1px rgba(0,0,0,0.08)', padding: 10, marginRight: 40, marginBottom: 20 }}>
<div style={{ width: 128, height: 192 }}>
<img src="/assets/images/hrImg/mc.png" alt="" style={{ width: '100%', height: '100%' }} />
<img src={item.idPhoto ? '/_file-server/' + item.idPhoto : '/assets/images/hrImg/defaultAvatar.png'} alt="" style={{ width: '100%', height: '100%' }} />
</div>
<div style={{ marginLeft: 4 }}>
<div style={{ display: 'flex' }}>
<div style={{ color: '#005ABD', fontSize: 14, marginRight: 6 }}>
0012
{item.pepUserId}
</div>
<div style={{ padding: '0px 4px 1px 4px ', color: '#FFFFFF', fontSize: 12, background: 'rgba(0,90,189,0.8)', borderRadius: 2 }}>
行业服务部
</div>
{/* <div>
{
item.departmrnt.map((ite, idx) => {
let departmentsArr = []
for (let i = 0; i < item.departmrnt.length; i++) {
departmentsArr.push(item.departmrnt[i].name)
}
return (
<div key={idx} style={{ display: 'flex' }}>
{idx == 0 ?
(<div style={{ padding: '0px 4px 1px 4px ', color: '#FFFFFF', fontSize: 12, background: 'rgba(0,90,189,0.8)', borderRadius: 2, marginRight: 4 }}>
{ite.name}
</div>) : ('')
</div> */}
}
{
item.departmrnt.length > 1 && idx == 1 ? (
<Tooltip content={departmentsArr.join(',')} trigger="click" style={{ lineHeight: 2 }}>
<div style={{ padding: '0px 4px 1px 4px ', color: '#FFFFFF', fontSize: 12, background: 'rgba(0,90,189,0.8)', borderRadius: 2, marginRight: 4, cursor: "pointer", }}>
...
</div>
</Tooltip>
) : ('')
}
</div>
)
})
}
</div>
<div style={{ marginTop: 16, display: 'flex', marginLeft: 4 }}>
<div style={{ display: 'flex', width: 159 }}>
@ -166,27 +190,27 @@ const Rest = (props) => {
<img src="/assets/images/hrImg/mc.png" alt="" style={{ width: '100%', height: '100%' }} />
</div>
<div style={{ fontSize: 14, color: '#282828', marginLeft: 12, marginRight: 9 }}>
刘昊然
{item.userName}
</div>
<div style={{ background: '#FFFBE3', padding: '2px 6px 1px', color: '#D3A000', fontSize: 12, borderRadius: '8px 0px 8px 0px' }}>
请假中
</div>
</div>
<div style={{ color: 'rgba(0,0,0,0.65)', fontSize: 12 }}>
23
{item.birthday ? moment(new Date()).diff(item.birthday, 'years') + '岁' : '暂无'}
</div>
</div>
<div style={{ marginTop: 16, display: 'flex', marginLeft: 4 }}>
<div style={{ display: 'flex', width: 159 }}>
<div style={{ width: 20, height: 20 }}>
<img src="/assets/images/hrImg/man.png" alt="" style={{ width: '100%', height: '100%' }} />
<img src={item.gender == '女' ? "/assets/images/hrImg/woman.png" : "/assets/images/hrImg/man.png"} alt="" style={{ width: '100%', height: '100%' }} />
</div>
<div style={{ fontSize: 14, color: '#282828', marginLeft: 12, marginRight: 9 }}>
{item.gender || '暂无'}
</div>
</div>
<div style={{ color: 'rgba(0,0,0,0.65)', fontSize: 12 }}>
未婚
{item.marital || '暂无'}
</div>
</div>
<div style={{ marginTop: 16, display: 'flex', marginLeft: 4 }}>
@ -195,11 +219,11 @@ const Rest = (props) => {
<img src="/assets/images/hrImg/post.png" alt="" style={{ width: '100%', height: '100%' }} />
</div>
<div style={{ fontSize: 14, color: '#282828', marginLeft: 12, marginRight: 9 }}>
人力资源部副部长
{item.roleName || '暂无'}
</div>
</div>
<div style={{ color: 'rgba(0,0,0,0.65)', fontSize: 12 }}>
9年经验
{item.experienceYear ? item.experienceYear + '年经验' : '暂无'}
</div>
</div>
<div style={{ marginTop: 16, display: 'flex', marginLeft: 4 }}>
@ -208,17 +232,17 @@ const Rest = (props) => {
<img src="/assets/images/hrImg/year.png" alt="" style={{ width: '100%', height: '100%' }} />
</div>
<div style={{ fontSize: 14, color: '#282828', marginLeft: 12, marginRight: 9 }}>
入职3
{item.hiredate ? '入职' + moment(new Date()).diff(item.hiredate, 'years') + '' : '暂无'}
</div>
</div>
<div style={{ color: 'rgba(0,0,0,0.65)', fontSize: 12 }}>
本科
{item.educationBackground || '暂无'}
</div>
</div>
<div style={{ marginTop: 16, marginLeft: 4 }}>
<Button theme='solid' type='primary' style={{ width: 212, borderRadius: 17, height: 28 }}
onClick={() => {
history.push(`/personnelFilesDetail`);
history.push(`/personnelFilesDetail?${item.pepUserId}`);
}}>详情</Button>
</div>
</div>
@ -242,6 +266,7 @@ const Rest = (props) => {
// anxincloudArr={anxincloudArr}
cancel={() => {
setPersonnelModal(false);
getMemberSearchList()
}}
close={() => {
setPersonnelModal(false);
@ -257,7 +282,7 @@ const Rest = (props) => {
)
}
function mapStateToProps(state) {
function mapStateToProps (state) {
const { auth, global, members, webSocket } = state;
return {
// loading: members.isRequesting,

67
web/client/src/sections/humanAffairs/containers/personnelFilesDetail.jsx

@ -4,17 +4,21 @@ import { Select, Input, Button, CheckboxGroup, DatePicker, Table } from '@douyin
import { IconSearch } from '@douyinfe/semi-icons';
import ReactECharts from 'echarts-for-react';
import * as echarts from 'echarts';
import DeleteModal from '../components/deleteModal';
import '../style.less'
const Rest = (props) => {
const { dispatch, actions, user, loading, socket } = props
const { dispatch, actions, user, loading, socket, history } = props
const { humanAffairs } = actions;
const [option, setOption] = useState({});
const [leaveoption, setLeaveOption] = useState({});
const [tableData, setTableData] = useState([{}, {}, {}, {}, {}, {}, {}]) //
const [leaveData, setLeaveData] = useState([{}, {}, {}, {}, {}, {}, {}]) //
const [deleteModal, setDeleteModal] = useState(false) //
const [columns, setColumns] = useState([//
{
title: "实例号",
@ -119,14 +123,41 @@ const Rest = (props) => {
},
},
])
const [pepUserId, setPepUserId] = useState('');
const scroll = useMemo(() => ({ y: 248 }), []);
useEffect(() => {
getMemberSearchList()
getWorkOption()
getLeaveOption()
getWorkOption()//
getLeaveOption()//
setPepUserId(history?.location?.search.slice(1))
peopleDetail()
}, [])
function peopleDetail () {
dispatch(humanAffairs.getMemberList({keywordTarget:'number',keyword:history?.location?.search.slice(1)})).then((res) => {//
if (res.success) {
console.log('res.success', res.payload.data);
// setArchivesList(res.payload.data)
// let mytableData = JSON.parse(JSON.stringify(res.payload.data.rows));
// let mytableKey = []
// for (let index = 0; index < mytableData.length; index++) {
// mytableData[index].key = mytableData[index].id
// mytableKey.push(mytableData[index].id)
// }
// setTableKey(mytableKey)
// setTableData(mytableData)
// setLimits(res.payload.data.count)
// mylimits.current = res.payload.data.rows.length
}
})
}
function getWorkOption () {//线
dispatch(humanAffairs.getMemberOvertime({pepUserId:history?.location?.search.slice(1),startDate:'',endDate:''})).then((res) => {//
if (res.success) {
console.log('res.success', res.payload.data);
}
})
var date = [];
date.push([2017, 6, 1].join("/"));
date.push([2017, 6, 2].join("/"));
@ -309,7 +340,9 @@ const Rest = (props) => {
<div style={{ background: '#FFFFFF', boxShadow: '0px 0px 12px 2px rgba(220,222,224,0.2)', borderRadius: 2, padding: '20px 0px 20px 19px ', marginTop: 12 }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<div style={{ display: 'flex', alignItems: 'baseline' }}>
<div style={{ width: 20, height: 20, marginRight: 10, cursor: "pointer" }}>
<div style={{ width: 20, height: 20, marginRight: 10, cursor: "pointer" }} onClick={() => {
history.goBack();
}}>
<img src="/assets/images/hrImg/back.png" alt="" style={{ width: '100%', height: '100%' }} />
</div>
<div style={{ width: 0, height: 20, borderLeft: '3px solid #0F7EFB', borderTop: '3px solid transparent', borderBottom: '3px solid transparent' }}></div>
@ -319,7 +352,9 @@ const Rest = (props) => {
<div style={{ padding: '6px 20px', background: '#0F7EFB', color: '#FFFFFF', fontSize: 14, cursor: "pointer" }}>
编辑档案
</div>
<div style={{ padding: '6px 20px', background: '#FF5254', color: '#FFFFFF', fontSize: 14, cursor: "pointer", marginLeft: 20 }}>
<div style={{ padding: '6px 20px', background: '#FF5254', color: '#FFFFFF', fontSize: 14, cursor: "pointer", marginLeft: 20 }}
onClick={() => { setDeleteModal(true) }}
>
删除档案
</div>
</div>
@ -734,6 +769,28 @@ const Rest = (props) => {
</div>
</div>
</div>
{//
deleteModal ?
<DeleteModal
visible={true}
pepUserId={pepUserId}
// pepList={pepList}
// memberEdit={memberEdit}
// editObj={editObj}
// pomsList={pomsList}
// anxinDelete={anxinDelete}
// anxincloudArr={anxincloudArr}
cancel={() => {
setDeleteModal(false);
// getMemberSearchList()
}}
close={() => {
setDeleteModal(false);
// getUserList()
history.goBack()
}} >
</DeleteModal> : ''
}
</>
)
}

6
web/client/src/utils/webapi.js

@ -18,7 +18,11 @@ export const ApiTable = {
//人事管理-人员档案
getMemberSearch: 'member/search',//搜索项企用户
addMembersBulk: 'add/members/bulk'
addMembersBulk: 'add/members/bulk',
postMember: 'member',//添加人员信息
getMemberList: 'member/list',//查询人员列表
delMember: 'member',//删除人员信息
getMemberOvertime: 'member/overtime',//查询单个人员加班统计数据
};
export const RouteTable = {

Loading…
Cancel
Save