import React from "react";
|
import { Link } from "react-router-dom";
|
import { Card, Row, Col, Icon, Form, Input, Button, Table, DatePicker, message, Breadcrumb, Tree, Modal, Layout, Popconfirm, Select, Cascader, Spin, Alert, Tooltip, Empty, Statistic, Dropdown, Menu, Tag } from "antd";
|
import moment from "moment";
|
import SearchTree from '../../components/common/Tree';
|
import fetch from '../../api/request';
|
// import SearchTree from "../component/tree/index";
|
// import Fetch from "../fetch";
|
import JobDetail from "./JobDetail";
|
// import {
|
// getUnitByAssociate,
|
// getUserOfPost,
|
// jobCount,
|
// postSet,
|
// getPostDetail,
|
// savePost
|
// } from "../fetch/api";
|
|
const FormItem = Form.Item;
|
const confirm = Modal.confirm;
|
const TreeNode = Tree.TreeNode;
|
const Search = Input.Search;
|
|
class JobManage extends React.Component {
|
constructor(props) {
|
super(props);
|
this.state = {
|
options: [],
|
selectOptionId: "",
|
spinning: false,
|
dataSet: {},
|
jobCount: {},
|
user: {},
|
|
jobData: [],
|
selectUser: {}, //右边选中的user
|
selectUserLeft: {}, //左边选中的user
|
visible: false,
|
tsData: {}, //临时数据
|
|
// unitId: '' //单位编号
|
showUnder: false,
|
modify: false, //是否切换详情
|
params: {
|
postId: "", //岗位id
|
unitId: "", //所选的单位id
|
depts: [] //单位下的部门所有信息
|
},
|
|
detailData: {}, //详情数据,
|
getUnitByAssociate: null,//部门下的岗位分配情况
|
searchCode: '',//模糊查询字符串
|
|
currentSelectUnMatchUsers: null,//当前所选未配岗人员
|
|
};
|
}
|
componentDidMount() {
|
this.getAllUnits();
|
}
|
|
//获取所有的单位树形结构
|
getAllUnits = () => {
|
fetch({
|
url: 'api/unit/getAllUnitsByCascade'
|
}).then(res => {
|
if (res) {
|
this.setState({ options: res })
|
}
|
})
|
}
|
|
//级联框onChange事件
|
onChange = (value, selectedOptions) => {
|
this.setState({
|
selectOptionId: selectedOptions.length && selectedOptions[selectedOptions.length - 1].id,
|
}, () => {
|
if (this.state.selectOptionId) { this.loadJobData() }
|
else { this.setState({ showUnder: false }) }
|
});
|
};
|
|
// 加载关于岗位的相关接口
|
loadJobData = () => {
|
this.setState({
|
spinning: true
|
});
|
let p = [this.jobCount(), this.getUnitByAssociate(), this.getUserOfPost()]
|
Promise.all(p).then(res => {
|
this.setState({ spinning: false });
|
if (res.length == p.length) {
|
this.setState({
|
showUnder: true,
|
jobCount: res[0],
|
getUnitByAssociate: res[1],
|
getUserOfPost: res[2]
|
})
|
}
|
})
|
};
|
|
// 获取单位相关数据(包含单位下的部门,部门下的岗位)
|
getUnitByAssociate = () => {
|
let { selectOptionId } = this.state;//单位id
|
return new Promise((resolve, reject) => {
|
fetch({
|
url: `api/unit/getUnitByAssociate`,
|
params: { id: selectOptionId }
|
}).then(res => {
|
if (res) {
|
resolve(res);
|
}
|
})
|
})
|
}
|
|
//获取配岗用户
|
getUserOfPost = () => {
|
return new Promise((resolve, reject) => {
|
fetch({
|
url: `api/user/getUserOfPost`
|
}).then(res => {
|
if (res) {
|
resolve(res);
|
}
|
})
|
})
|
}
|
|
// 获取岗位统计数
|
jobCount = () => {
|
let { selectOptionId } = this.state;//单位id
|
return new Promise((resolve, reject) => {
|
fetch({
|
url: `api/post/count`,
|
params: { unitId: selectOptionId }
|
}).then(res => {
|
if (res) {
|
resolve(res);
|
}
|
})
|
})
|
}
|
|
//从左侧选择员工(兼岗、调岗、撤岗)
|
selectLeft = e => {
|
document.querySelector("body").style.cursor = "crosshair";
|
};
|
|
|
cancelFun = () => {
|
this.setState({
|
modify: false
|
});
|
};
|
|
//兼岗
|
setJG = () => {
|
let { dgOrjgData, currentSelectUnMatchUsers } = this.state;
|
fetch({
|
url: `api/post/set`,
|
method: 'POST',
|
data: {
|
operateType: 2,
|
userId: currentSelectUnMatchUsers.id,//员工id
|
sourcePostId: dgOrjgData.id//岗位id
|
}
|
}).then(res => {
|
if (res) {
|
message.success('设置兼岗成功');
|
this.setState({ visible: false, currentSelectUnMatchUsers: null })
|
this.loadJobData();
|
}
|
})
|
};
|
|
//调岗
|
setDG = () => {
|
let { dgOrjgData, currentSelectUnMatchUsers } = this.state;
|
fetch({
|
url: `api/post/set`,
|
method: 'POST',
|
data: {
|
operateType: 3,
|
userId: currentSelectUnMatchUsers.id,
|
sourcePostId: currentSelectUnMatchUsers.postId,
|
targetPostId: dgOrjgData.id
|
}
|
}).then(res => {
|
if (res) {
|
message.success('设置调岗成功');
|
this.setState({ visible: false, currentSelectUnMatchUsers: null })
|
this.loadJobData();
|
}
|
})
|
};
|
|
//撤岗
|
setCG = (data) => {
|
let _this = this;
|
let { currentSelectUnMatchUsers } = _this.state;
|
confirm({
|
title: `你确定要对员工(${data.userTrueName})撤岗吗?`,
|
onOk() {
|
fetch({
|
url: `api/post/set`,
|
method: 'POST',
|
data: {
|
operateType: 4,
|
userId: data.userId,//员工id
|
sourcePostId: data.id//岗位id
|
}
|
}).then(res => {
|
if (res) {
|
message.success('撤岗成功');
|
_this.loadJobData();
|
if (currentSelectUnMatchUsers && currentSelectUnMatchUsers.id == data.userId) {
|
_this.setState({ currentSelectUnMatchUsers: null })//取消其高亮显示
|
}
|
}
|
})
|
},
|
onCancel() { },
|
});
|
};
|
|
//右侧选中员工,进行配岗操作
|
setPG = (post) => {
|
let _this = this;
|
let { currentSelectUnMatchUsers, getUnitByAssociate } = _this.state;
|
if (!currentSelectUnMatchUsers) {
|
return message.warning('请于右侧待配岗员工列表中选择待岗员工')
|
}
|
|
if (getUnitByAssociate && getUnitByAssociate.depts.reduce((p, n) => (
|
n.posts ? p.concat(n.posts) : p
|
), []).findIndex(({ userId }) => userId == currentSelectUnMatchUsers.id) !== -1) {
|
// 此处触发调岗、兼岗操作
|
return _this.setState({ visible: true, dgOrjgData: post });
|
}
|
confirm({
|
title: `已选择员工(${currentSelectUnMatchUsers.trueName}), 您确定要对该员工配岗吗?`,
|
onOk() {
|
fetch({
|
url: `api/post/set`,
|
method: 'POST',
|
data: {
|
operateType: 1, //设置主岗
|
sourcePostId: post.id,
|
userId: currentSelectUnMatchUsers.id,
|
userTrueName: currentSelectUnMatchUsers.trueName
|
}
|
}).then(res => {
|
if (res) {
|
message.success('配岗成功');
|
_this.setState({ currentSelectUnMatchUsers: null });
|
_this.loadJobData();
|
}
|
})
|
|
},
|
onCancel() { },
|
});
|
}
|
|
// 员工的模糊搜索
|
onInputChange = (e) => {
|
this.setState({ searchCode: e.target.value })
|
}
|
|
onCancel = () => {
|
this.setState({
|
visible: false
|
});
|
};
|
|
// 岗位(新增 | 编辑)
|
modifyFun = (data) => {
|
let { getUnitByAssociate } = this.state;
|
let { id } = data;
|
this.setState({
|
modify: true,
|
params: {
|
...data,
|
depts: getUnitByAssociate.depts
|
}
|
});
|
if (id) {
|
this.setState({ spinning: true });
|
fetch({
|
url: `api/post/getById`,
|
params: { id }
|
}).then(res => {
|
if (res) {
|
this.setState({
|
detailData: res,
|
spinning: false,
|
})
|
}
|
})
|
} else {
|
this.setState({
|
detailData: {}//置空表单数据
|
})
|
}
|
};
|
|
//保存岗位
|
saveFun = data => {
|
this.setState({ spinning: true });
|
fetch({
|
url: `api/post/save`,
|
method: 'POST',
|
data
|
}).then(res => {
|
this.setState({ spinning: false });
|
if (res) {
|
message.success("保存岗位成功");
|
this.setState({ modify: false });
|
this.loadJobData();
|
}
|
})
|
};
|
|
//删除岗位
|
postDel = (data) => {
|
let _this = this;
|
let { id, name } = data;
|
confirm({
|
title: `您确定要删除岗位(${name})吗?`,
|
onOk() {
|
fetch({
|
url: `api/post/delete`,
|
params: { ids: id }
|
}).then(res => {
|
if (res) {
|
message.success('删除岗位成功');
|
_this.loadJobData();
|
}
|
})
|
},
|
onCancel() { },
|
});
|
}
|
|
// 选中当前待配岗人员
|
setCurrentSelectUnMatchUsers = (person) => {
|
let { currentSelectUnMatchUsers } = this.state;
|
currentSelectUnMatchUsers = currentSelectUnMatchUsers && person.id == currentSelectUnMatchUsers.id ? null : person;
|
if (currentSelectUnMatchUsers) {
|
message.success('已选中:' + currentSelectUnMatchUsers.trueName)
|
}
|
this.setState({
|
currentSelectUnMatchUsers
|
})
|
}
|
|
render() {
|
const { options, jobCount, visible, params, getUnitByAssociate, searchCode, getUserOfPost, currentSelectUnMatchUsers } = this.state;
|
|
const gridStyle = { width: '25%', padding: 8, boxShadow: 'none' };
|
|
return (
|
<React.Fragment>
|
<div
|
className="h-100 border padding bg-white"
|
style={{ display: !this.state.modify ? "flex" : "none" }}
|
>
|
<React.Fragment>
|
{visible && (
|
<Modal
|
onCancel={this.onCancel}
|
visible={true}
|
footer={
|
<div>
|
<Button onClick={this.setJG} type="primary">兼岗</Button>
|
<Button onClick={this.setDG} type="primary">调岗</Button>
|
<Button onClick={this.onCancel}>取消</Button>
|
</div>
|
}
|
>
|
<p>您已经对此员工进行配岗,你还可以对他进行</p>
|
</Modal>
|
)}
|
<div
|
style={{
|
width: '100%',
|
display: "flex",
|
flexDirection: "column",
|
overflowY: "auto"
|
}}
|
>
|
{/* 单位级联框 */}
|
<div className="padding-tb">
|
<Cascader
|
fieldNames={{
|
label: "name",
|
value: "name",
|
children: "children"
|
}}
|
options={options}
|
onChange={this.onChange}
|
placeholder="请选择单位"
|
style={{ width: "100%" }}
|
changeOnSelect
|
/>
|
</div>
|
|
<div className="flex-1">
|
<Spin spinning={this.state.spinning}>
|
{this.state.showUnder && (
|
<React.Fragment>
|
<Row style={{ height: "100%" }}>
|
<Col
|
span={15}
|
style={{ border: "1px solid #e8e8e8", display: 'flex', flexDirection: 'column', padding: 10 }}
|
className="h-100 treeNodeUnselectable"
|
>
|
{/* 当前单位的配岗信息 */}
|
<Row type="flex" justify="space-between" gutter={20}>
|
<Col>
|
<Row type="flex" gutter={30} style={{ marginBottom: 15 }}>
|
<Col>
|
<div className="flex-box align-center">
|
<a className="statistic-label">总岗位:</a>
|
<Statistic value={jobCount.totalNum || 0} valueStyle={{ fontSize: 16, fontWeight: 'bold' }} />
|
</div>
|
</Col>
|
<Col>
|
<div className="flex-box align-center">
|
<div className="statistic-label">实岗:</div>
|
<Statistic value={jobCount.fullNum || 0} valueStyle={{ fontSize: 16, fontWeight: 'bold' }} />
|
</div>
|
</Col>
|
<Col>
|
<div className="flex-box align-center">
|
<div className="statistic-label">空岗:</div>
|
<Statistic value={jobCount.emptyNum || 0} valueStyle={{ fontSize: 16, fontWeight: 'bold' }} />
|
</div>
|
</Col>
|
</Row>
|
</Col>
|
<Col>
|
<Button type='primary' size="small" onClick={() => { this.modifyFun({ id: '' }) }}>新增岗位</Button>
|
</Col>
|
</Row>
|
|
<div className="flex-1">
|
{
|
getUnitByAssociate && getUnitByAssociate.depts && getUnitByAssociate.depts.map(({ posts, name, id }, deptIndex) => (
|
<Card type="inner" title={'部门:' + name} style={{ marginBottom: 15 }} size="small" key={id}>
|
{
|
posts && posts.length > 0 ? posts.map((p, posIndex) => (
|
<Card.Grid style={gridStyle} hoverable={false} key={p.id}>
|
<Row type="flex" gutter={10}>
|
<Col style={{ height: 22 }}>
|
{/* 岗位名(编辑,删除) */}
|
<Dropdown overlay={<Menu>
|
<Menu.Item key="1" onClick={() => this.modifyFun(p)}>编辑岗位</Menu.Item>
|
<Menu.Item key="2" onClick={() => this.postDel(p)}>删除岗位</Menu.Item>
|
</Menu>} trigger={['contextMenu']}>
|
<div style={{ cursor: 'pointer' }} >{p.name}</div>
|
</Dropdown>
|
</Col>
|
{p.userTrueName &&
|
<Col style={{ height: 22 }}>
|
<Dropdown overlay={<Menu>
|
<Menu.Item key="1" onClick={() => this.setCG({ ...p, deptIndex, posIndex })}>撤岗</Menu.Item>
|
</Menu>} trigger={['contextMenu']}>
|
{/* <a>{p.userTrueName}</a> */}
|
{currentSelectUnMatchUsers && currentSelectUnMatchUsers.id == p.userId ?
|
<Tag style={{ cursor: 'pointer' }} color="#cc4e45" onDoubleClick={() => this.setCurrentSelectUnMatchUsers({ id: p.userId, trueName: p.userTrueName, postId: p.id })}>{p.userTrueName}</Tag> :
|
<a onDoubleClick={() => this.setCurrentSelectUnMatchUsers({ id: p.userId, trueName: p.userTrueName, postId: p.id })}>{p.userTrueName}</a>
|
}
|
</Dropdown>
|
</Col>}
|
{!p.userTrueName && <Col><a onClick={() => { this.setPG(p) }}>[ 请选择 ]</a></Col>}
|
</Row>
|
</Card.Grid>
|
)) : <Row type="flex" justify="center">
|
<Col>该 部 门 下 暂 无 岗 位</Col>
|
</Row>
|
}
|
</Card>
|
))
|
}
|
</div>
|
|
<Row>
|
<Alert message="您可以右键点击‘岗位’进行岗位编辑、删除,双击人员选中该人员,对该人员进行配岗操作" type="warning" />
|
</Row>
|
</Col>
|
<Col span={1} />
|
<Col
|
span={8}
|
style={{
|
border: "1px solid #e8e8e8",
|
display: "flex",
|
flexDirection: "column",
|
overflow: 'auto',
|
padding: 10
|
}}
|
className="h-100 treeNodeUnselectable"
|
>
|
<div style={{ fontSize: 16, fontWeight: 'bold', textAlign: 'center', paddingBottom: 10 }}>
|
待配岗人员
|
</div>
|
<Input
|
style={{ marginBottom: 1 }}
|
placeholder="请输入人员姓名"
|
onChange={this.onInputChange}
|
allowClear
|
prefix={<Icon type="search" />}
|
/>
|
<div className="flex-1">
|
<Card bordered={false} bodyStyle={{ padding: 10 }}>
|
{
|
getUserOfPost && getUserOfPost.unMatchUsers && getUserOfPost.unMatchUsers.length > 0 ?
|
getUserOfPost.unMatchUsers.filter(({ trueName }) => trueName.indexOf(searchCode) !== -1).map((person) => (
|
<Card.Grid style={{ ...gridStyle, width: '20%' }} key={person.id}>
|
{currentSelectUnMatchUsers && currentSelectUnMatchUsers.id == person.id ?
|
<Tag style={{ cursor: 'pointer' }} color="#cc4e45" onDoubleClick={() => this.setCurrentSelectUnMatchUsers(person)}>{person.trueName}</Tag> :
|
<Tag style={{ cursor: 'pointer' }} onDoubleClick={() => this.setCurrentSelectUnMatchUsers(person)}>{person.trueName}</Tag>
|
}
|
</Card.Grid>
|
)) : <Empty description={'暂无待配岗人员'} className="h-100 flex-box-column align-center justify-content" />
|
}
|
</Card>
|
|
</div>
|
<div style={{ marginTop: 10 }}>
|
<Row>
|
<Alert message="您可以双击人员选中未配岗人员,对该人员进行配岗操作" type="warning" />
|
</Row>
|
</div>
|
</Col>
|
</Row>
|
<Row />
|
</React.Fragment>
|
)}
|
|
{!this.state.showUnder && (
|
<Empty description={'暂无数据,请选择单位'} className="h-100 flex-box-column align-center justify-content" />
|
)}
|
</Spin>
|
</div>
|
</div>
|
</React.Fragment>
|
</div>
|
|
<div style={{ display: this.state.modify ? "block" : "none" }}>
|
<JobDetail
|
cancelFun={this.cancelFun}
|
params={params}
|
dataSet={this.state.detailData}
|
saveFun={this.saveFun}
|
spinning={this.state.spinning}
|
/>
|
</div>
|
</React.Fragment>
|
);
|
}
|
}
|
|
const JobManageList = Form.create()(JobManage);
|
export default JobManageList;
|