Commit 66f20aef authored by 邓超's avatar 邓超

fix: 重构工作流编辑器选择角色机构,默认承办人模块交互

parent d01f930e
Pipeline #43254 skipped with stages
......@@ -209,8 +209,13 @@ const FlowNode = () => {
dataIndex: 'extendRollbackNode',
align: 'center',
width: 80,
ellipsis: {
showTitle: true,
},
render: (text, record) => (
<span style={{ color: record.colorType === 2 ? 'red' : '#000000D9' }}>{text}</span>
<Tooltip placement="topLeft" title={text}>
<span style={{ color: record.colorType === 2 ? 'red' : '#000000D9' }}>{text}</span>
</Tooltip>
),
},
{
......
......@@ -15,13 +15,16 @@ import {
} from 'antd';
import { DeleteOutlined, EditTwoTone } from '@ant-design/icons';
import RoalChoose from './nodeModalComponents/RoalChoose';
import Undertaker from './nodeModalComponents/Undertaker';
const { Option } = Select;
const NodeModal = props => {
const { onSubumit, handleCancel, visible, modalType, editMsg } = props;
const [form] = Form.useForm();
const [showRoal, setShowRoal] = useState(false); // 是否显示选择角色用户弹窗
const [isEdit, setIsEdit] = useState(); // 是编辑角色还是添加角色
const [showUnderTaker, setShowUnderTaker] = useState(false); // 是否显示选择默认承办人弹窗
const [editIndex, setEditIndex] = useState(); // 当前编辑默认承办人索引
const [chooseUser, setChooseUser] = useState(); // 当前编辑角色或者机构的默认承办人
const [nodeMsg, setNodeMsg] = useState({
NodeName: '',
......@@ -59,44 +62,26 @@ const NodeModal = props => {
roleList.splice(index, 1);
setNodeMsg({ ...nodeMsg, roleList });
};
// 添加用户
const addUser = (obj, treeLength) => {
if (obj.roleId === '' || obj.roleName === '' || treeLength === 0) {
notification.error({
message: '提示',
duration: 3,
description: '请选择角色',
});
return;
}
// 如果已经有角色就提示
if (nodeMsg.roleList.some(item => item.roleId === obj.roleId) && isEdit === 'add') {
notification.error({
message: '提示',
duration: 3,
description: '机构(角色)已存在',
});
return;
}
// 编辑角色覆盖原有
let chooseIndex = nodeMsg.roleList.findIndex(item => item.roleId === obj.roleId);
let newList;
if (chooseIndex === -1) {
// 添加表格
setNodeMsg({ ...nodeMsg, roleList: [...nodeMsg.roleList, obj] });
} else {
newList = [...nodeMsg.roleList];
newList[chooseIndex] = obj;
// 修改表格
setNodeMsg({ ...nodeMsg, roleList: [...newList] });
}
// 添加角色或机构
const addUser = selectList => {
setNodeMsg({ ...nodeMsg, roleList: selectList });
setShowRoal(false);
};
// 添加默认承办人
const addUnderTaker = (userName, userId) => {
let list = JSON.parse(JSON.stringify(nodeMsg.roleList));
console.log(list, 'list');
console.log(editIndex, 'editIndex');
list[editIndex].defauletUserName = userName;
list[editIndex].defaultUserId = userId;
setNodeMsg({ ...nodeMsg, roleList: list });
setShowUnderTaker(false);
};
// 编辑默认承办人
const toEdit = record => {
setIsEdit('edit');
const toEdit = (record, index) => {
setEditIndex(index);
setChooseUser(record);
setShowRoal(true);
setShowUnderTaker(true);
};
// 定义表格
const columns = [
......@@ -133,9 +118,15 @@ const NodeModal = props => {
render: (text, record, index) => (
<>
<Space>
<Tooltip title="删除角色">
<Tooltip title="编辑默认承办人">
<EditTwoTone
onClick={() => toEdit(record, index)}
style={{ fontSize: '16px', color: '#1890FF' }}
/>
</Tooltip>
<Tooltip title="删除角色或机构">
<Popconfirm
title="是否删除该角色?"
title="是否删除该角色或机构?"
onConfirm={() => delUser(record, index)}
onCancel={() => message.error('取消删除')}
okText="是"
......@@ -144,12 +135,6 @@ const NodeModal = props => {
<DeleteOutlined style={{ fontSize: '16px', color: '#e86060' }} />
</Popconfirm>
</Tooltip>
<Tooltip title="修改默认承办人">
<EditTwoTone
onClick={() => toEdit(record)}
style={{ fontSize: '16px', color: '#1890FF' }}
/>
</Tooltip>
</Space>
</>
),
......@@ -163,6 +148,7 @@ const NodeModal = props => {
onClose={handleCancel}
visible={visible}
bodyStyle={{ paddingBottom: 20 }}
zIndex={10}
footer={
<Space>
<Button onClick={handleCancel}>取消</Button>
......@@ -226,11 +212,10 @@ const NodeModal = props => {
style={{ marginBottom: '10px' }}
onClick={() => {
setShowRoal(true);
setIsEdit('add');
}}
type="primary"
>
添加
请选择角色或机构
</Button>
<Table
dataSource={nodeMsg.roleList}
......@@ -239,21 +224,26 @@ const NodeModal = props => {
bordered
size="small"
scroll={{ y: 'calc(100vh - 550px)' }}
onRow={record => ({
onRow={(record, index) => ({
onDoubleClick: () => {
toEdit(record);
toEdit(record, index);
},
})}
pagination={false}
/>
</Drawer>
<RoalChoose
roleList={nodeMsg.roleList}
visible={showRoal}
modalType={isEdit}
chooseUser={chooseUser}
handleCancel={() => setShowRoal(false)}
onSubumit={addUser}
/>
<Undertaker
chooseUser={chooseUser}
visible={showUnderTaker}
handleCancel={() => setShowUnderTaker(false)}
onSubumit={addUnderTaker}
/>
</>
);
};
......
import React, { useEffect, useState } from 'react';
import { GetRoleUser } from '@/services/workflow/workflow';
import {
Form,
Modal,
Input,
Checkbox,
Button,
Pagination,
Spin,
Divider,
notification,
Empty,
Tabs,
} from 'antd';
import Tree from '@/components/ExpendableTree';
import { UserOutlined } from '@ant-design/icons';
import styles from '../../../workflow.less';
const CheckboxGroup = Checkbox.Group;
import { Modal, Input, Checkbox, Pagination, Spin, notification, Empty, Tabs, Tag } from 'antd';
import styles from './RoalChoose.less';
const { Search } = Input;
const { TabPane } = Tabs;
const RoalChoose = props => {
const { onSubumit, handleCancel, visible, modalType, chooseUser } = props;
const [form] = Form.useForm();
const [currentSelectId, setCurrentSelectId] = useState(''); // 当前选择节点Id
const [currentRoalName, setCurrentRoalName] = useState(''); // 当前选择节点名称
const [treeData, setTreeData] = useState([]); // 左侧树数据
const [checkedList, setCheckedList] = useState([]); // 选中的数据
const [plainOptions, setPlainOptions] = useState([]); // 默认的的数据
const [indeterminate, setIndeterminate] = useState(false); // 全选框的有选择但是没有全选的样式
const [checkAll, setCheckAll] = useState(false); // 全选框全选样式
const { onSubumit, handleCancel, visible, roleList } = props;
const [plainOptions, setPlainOptions] = useState([]); // 角色机构选择列表
const [total, setTotal] = useState(); // 角色人员条数
const [loading, setLoading] = useState(false); // 加载时的loading
const [userList, setUserList] = useState([]); // 编辑选中的用户信息
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [pageSize, setPageSize] = useState(33);
const [roleType, setRoleType] = useState('2'); // 角色类型
const [selected, setSelected] = useState(new Map()); // 已勾选角色列表
const [searchName, setSearchName] = useState(); // 搜索名称
const [delArr, setDelArr] = useState(new Map()); // 删除了的元素
// 初始化
useEffect(() => {
form.resetFields();
if (visible) {
setCurrentPage(1);
if (modalType === 'edit') {
console.log(chooseUser);
setRoleType(chooseUser.type.toString());
form.setFieldsValue({ roleName: chooseUser.roleName });
setUserList(chooseUser.defaultUserId);
getData('', 1, pageSize, chooseUser.roleId, chooseUser.type);
} else {
getData('', 1, pageSize, 0, 2);
setRoleType('2');
getData('', 1, pageSize, 0, 2);
setRoleType('2');
// 对已选的角色进行回显
if (roleList.length > 0) {
roleList.forEach(item => {
selected.set(item.roleId, {
roleName: item.roleName,
defauletUserName: item.defauletUserName,
defaultUserId: item.defaultUserId,
roleId: item.roleId,
type: item.type,
});
});
setSelected(selected);
}
} else {
setUserList([]);
setTreeData([]);
setPlainOptions([]);
setCheckedList([]);
setIndeterminate(false);
setCheckAll(false);
setSelected(new Map());
setDelArr(new Map());
}
}, [visible]);
// 默认选中第一个
useEffect(() => {
if (treeData.length > 0) {
setCurrentSelectId(treeData[0].id);
setCurrentRoalName(treeData[0].name);
let options = treeData[0].userList.map(item => ({
label: item.name,
value: item.id,
}));
setPlainOptions(options);
}
}, [treeData]);
// 对默认选中的进行处理
useEffect(() => {
if (userList.length > 0 && modalType === 'edit') {
onChange(userList);
} else {
setCheckedList([]);
setIndeterminate(false);
setCheckAll(false);
}
}, [plainOptions]);
// 获取左侧树回显
const getData = (roleName, pageIndex, pageSizes, roleId, Type) => {
......@@ -96,7 +54,13 @@ const RoalChoose = props => {
}).then(res => {
setLoading(false);
if (res.code === 0) {
setTreeData(res.data.data);
// 处理勾选角色或部门回显
res.data.data.forEach(item => {
if (selected.has(item.id)) {
item.isChecked = true;
}
});
setPlainOptions(res.data.data);
setTotal(res.data.count);
} else {
notification.error({
......@@ -108,68 +72,44 @@ const RoalChoose = props => {
});
};
// 查询角色
const onFinish = () => {
form.validateFields().then(validate => {
if (validate) {
setCurrentSelectId('');
setPlainOptions([]);
setCheckedList([]);
setIndeterminate(false);
setCheckAll(false);
setCurrentPage(1);
getData(validate.roleName, 1, pageSize, 0, roleType);
}
});
};
// 处理属性结构
const mapTree = item => {
const obj = { ...item };
return {
title: obj.name,
key: obj.id,
disabled: modalType === 'edit' && obj.name !== chooseUser.roleName,
userList: obj.userList,
};
};
// 选择树
const onSelect = (selectedKeys, e) => {
setCurrentRoalName(e.node.title);
if (selectedKeys[0]) {
// 选择后对复选框的用户进行重新赋值
let userLists = [...e.node.userList];
let options = userLists.map(item => ({
label: item.name,
value: item.id,
}));
setCurrentSelectId(selectedKeys[0]);
setPlainOptions(options);
}
const onSearch = value => {
setCurrentPage(1);
setSearchName(value);
getData(value, 1, pageSize, 0, roleType);
};
// 监听分页
const paginationChange = (page, pageSizes) => {
// 分页时清空复选框
setCurrentSelectId('');
setPlainOptions([]);
setCheckedList([]);
setIndeterminate(false);
setCheckAll(false);
setCurrentPage(page);
setPageSize(pageSizes);
let roleName = form.getFieldValue('roleName');
getData(roleName, page, pageSizes, 0, roleType);
};
// 复选框全选监听
const onCheckAllChange = e => {
let allOptions = plainOptions.map(item => item.value);
setCheckedList(e.target.checked ? allOptions : []);
setIndeterminate(false);
setCheckAll(e.target.checked);
getData(searchName, page, pageSizes, 0, roleType);
};
// 复选框监听事件
const onChange = list => {
setCheckedList(list);
setIndeterminate(!!list.length && list.length < plainOptions.length);
setCheckAll(list.length === plainOptions.length);
const selectChange = (e, index, value) => {
let list = JSON.parse(JSON.stringify(plainOptions));
list[index].isChecked = e.target.checked;
// 存储勾选角色或站点信息
if (e.target.checked) {
// 存储已选角色或站点的默认承办人
if (delArr.has(value.id)) {
selected.set(value.id, delArr.get(value.id));
delArr.delete(value.id);
} else {
selected.set(value.id, {
roleName: value.name,
type: value.type,
roleId: value.id,
defauletUserName: [],
defaultUserId: [],
});
}
} else {
delArr.set(value.id, selected.get(value.id));
selected.delete(value.id);
}
setDelArr(delArr);
setSelected(selected);
setPlainOptions(list);
};
// tab栏切换回调
const tabCallback = val => {
......@@ -177,133 +117,135 @@ const RoalChoose = props => {
return;
}
setRoleType(val);
setPlainOptions([]);
setCheckedList([]);
setIndeterminate(false);
setCheckAll(false);
setCurrentPage(1);
getData(form.getFieldValue('roleName'), 1, pageSize, 0, val);
getData(searchName, 1, pageSize, 0, val);
};
// 保存选择的角色列表
const onSave = () => {
// 默认承办人字符串拼接
let DeafaultUserName = '';
checkedList.forEach((item, index) => {
plainOptions.forEach(element => {
if (item === element.value) {
if (index === checkedList.length - 1) {
DeafaultUserName += `${element.label}`;
} else {
DeafaultUserName += `${element.label},`;
}
}
});
let selectData = [];
selected.forEach((val, key) => {
selectData.push(val);
});
onSubumit(selectData);
};
// 删除已选中列表
const delSelected = value => {
delArr.set(value, selected.get(value));
selected.delete(value);
setDelArr(delArr);
setSelected(selected);
let arr = JSON.parse(JSON.stringify(plainOptions));
arr.forEach(item => {
if (item.id === value) {
item.isChecked = false;
}
});
// 存入要插入的数据
let obj = {
roleName: currentRoalName,
roleId: currentSelectId,
defaultUserId: checkedList,
defauletUserName: DeafaultUserName,
type: Number(roleType),
};
onSubumit(obj, treeData.length);
setPlainOptions(arr);
};
// 角色列表样式
const roleDom = () =>
treeData.length > 0 ? (
<Tree
blockNode
autoExpandParent
onSelect={onSelect}
selectedKeys={[currentSelectId]}
treeData={treeData.map(item => mapTree(item))}
/>
) : (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="未有查找到角色" />
);
const roleDom = () => (
<>
<Spin spinning={loading}>
{plainOptions.length > 0 ? (
<div className={styles.checkContent}>
{plainOptions.map((item, index) => (
<div key={item.id} className={styles.check} title={item.name}>
<Checkbox
checked={item.isChecked}
onChange={e => {
selectChange(e, index, item);
}}
>
{item.name}
</Checkbox>
</div>
))}
</div>
) : (
<Empty
image={Empty.PRESENTED_IMAGE_SIMPLE}
description={`未有查找到${roleType === '2' ? '角色' : '机构'}`}
/>
)}
</Spin>
</>
);
return (
<Modal
title="角色用户列表"
visible={visible}
onOk={onSave}
width="860px"
onCancel={handleCancel}
maskClosable={false}
destroyOnClose
>
<div className={styles.pageContent}>
{/* 角色选择树 */}
<div className={styles.roleContent}>
{/* 角色搜索 */}
<div className={styles.header}>
<Form form={form} layout="inline" onFinish={onFinish}>
<Form.Item name="roleName">
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder="请输入机构或角色名称"
disabled={modalType === 'edit'}
allowClear
<div className={styles.modalContainer}>
<Modal
title="角色机构列表"
visible={visible}
onOk={onSave}
width="860px"
onCancel={handleCancel}
maskClosable={false}
destroyOnClose
getContainer={false}
zIndex={11}
>
<div className={styles.pageContent}>
{/* 可选列表 */}
<div className={styles.optionalList}>
<div className={styles.header}>
<Search
className={styles.searchInput}
allowClear
placeholder="请输入机构或角色"
onSearch={onSearch}
onChange={e => {
setSearchName(e.target.value);
}}
/>
<div className={styles.title}>可选列表</div>
<div className={styles.tabContent}>
<Tabs type="card" activeKey={roleType} onChange={tabCallback}>
<TabPane tab="角色" key="2">
{roleDom()}
</TabPane>
<TabPane tab="机构" key="1">
{roleDom()}
</TabPane>
</Tabs>
</div>
{/* 分页 */}
<div className={styles.footer}>
<Pagination
size="small"
total={total}
showSizeChanger
defaultCurrent={1}
current={currentPage}
onChange={paginationChange}
defaultPageSize={33}
pageSizeOptions={[33, 45, 60, 90]}
/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" disabled={modalType === 'edit'}>
搜索
</Button>
</Form.Item>
</Form>
</div>
{/* 角色树 */}
<Spin spinning={loading}>
<div className={styles.treeContent}>
<Tabs activeKey={roleType} onChange={tabCallback}>
<TabPane
tab="角色列表"
key="2"
disabled={modalType === 'edit' && chooseUser.type === 1}
>
{roleDom()}
</TabPane>
<TabPane
tab="机构列表"
key="1"
disabled={modalType === 'edit' && chooseUser.type === 2}
>
{roleDom()}
</TabPane>
</Tabs>
</div>
</div>
</Spin>
{/* 分页 */}
<div className={styles.footer}>
<Pagination
size="small"
total={total}
showSizeChanger
defaultCurrent={1}
current={currentPage}
onChange={paginationChange}
/>
</div>
</div>
{/* 用户列表 */}
<div className={styles.userContent}>
<div className={styles.userCheckBox}>
<Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
<span style={{ fontWeight: 700 }}>用户列表</span>
</Checkbox>
<Divider style={{ margin: '10px 0' }} />
<div className={styles.checkContent}>
{plainOptions.length > 0 ? (
<CheckboxGroup options={plainOptions} value={checkedList} onChange={onChange} />
{/* 已选列表 */}
<div className={styles.selectedList}>
<div className={styles.header}>
<div className={styles.title}>已选列表</div>
</div>
<div className={styles.selectBox}>
{[...selected].length > 0 ? (
<div className={styles.selectContent}>
{[...selected].map(item => (
<div className={styles.selectValue} key={item[0]}>
<Tag closable onClose={() => delSelected(item[0])}>
{item[1].roleName}
</Tag>
</div>
))}
</div>
) : (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="未有查找到用户" />
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="请选择角色或机构" />
)}
</div>
</div>
</div>
</div>
</Modal>
</Modal>
</div>
);
};
export default RoalChoose;
.modalContainer {
.ant-modal-body {
padding: 0;
}
.ant-modal-header {
padding: 28px 16px;
}
.pageContent {
display: flex;
height: 450px;
.optionalList {
position: relative;
width: 60%;
border-right: 1px solid #e7e7e7;
.title {
position: absolute;
left: 17px;
top: 10px;
font-weight: 700;
font-size: 14px;
z-index: 1;
color: #00070d;
}
.tabContent {
height: 430px;
.ant-tabs-content-holder {
height: 355px;
}
}
.searchInput {
position: absolute;
width: 200px;
z-index: 1;
top: 3px;
right: 40px;
.ant-input,
.ant-input-affix-wrapper {
border-top-left-radius: 20px;
border-bottom-left-radius: 20px;
}
.ant-input-group-addon {
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
.ant-input-search-button {
width: 40px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
}
.checkContent {
display: flex;
flex-wrap: wrap;
margin-left: 32px;
.check {
width: 150px;
margin-bottom: 10px;
margin-right: 6px;
.ant-checkbox-wrapper span {
max-width: 130px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.footer {
padding-left: 25px;
.ant-pagination {
border: none;
}
}
.ant-tabs-nav {
padding-left: 90px;
background-color: #f2f1f1;
}
.ant-tabs-tab {
background-color: #f2f1f1;
color: #666666;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.ant-tabs-tab-active {
background-color: #fff;
color: #1685ff;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
}
.selectedList {
position: relative;
width: 40%;
.header {
height: 40px;
width: 100%;
background-color: #f2f1f1;
.title {
position: absolute;
left: 17px;
top: 10px;
font-weight: 700;
font-size: 14px;
z-index: 1;
color: #00070d;
}
}
.selectBox {
height: 365px;
padding: 10px;
overflow-y: scroll;
.selectContent {
display: flex;
flex-wrap: wrap;
flex-direction: row;
.selectValue {
margin-bottom: 15px;
}
}
}
}
}
}
import React, { useEffect, useState } from 'react';
import { GetRoleUser } from '@/services/workflow/workflow';
import { Modal, Checkbox, notification, Empty, Divider } from 'antd';
const Undertaker = props => {
const { onSubumit, handleCancel, visible, chooseUser } = props;
const [checkedList, setCheckedList] = useState([]); // 选中的数据
const [plainOptions, setPlainOptions] = useState([]); // 默认的的数据
const [indeterminate, setIndeterminate] = useState(false); // 全选框的有选择但是没有全选的样式
const [checkAll, setCheckAll] = useState(false); // 全选框全选样式
const CheckboxGroup = Checkbox.Group;
useEffect(() => {
if (visible) {
getData();
} else {
setCheckedList([]);
setPlainOptions([]);
setCheckAll(false);
setIndeterminate(false);
}
}, [visible]);
useEffect(() => {
// 选中列表回显
if (chooseUser && plainOptions.length > 0) {
onChange(chooseUser.defaultUserId);
}
}, [plainOptions]);
// 获取可选默认承办人数据
const getData = () => {
GetRoleUser({
pageIndex: 1,
pageSize: 1,
roleId: chooseUser.roleId,
Type: Number(chooseUser.type),
}).then(res => {
if (res.code === 0) {
let data = res.data.data[0].userList.map(item => ({ value: item.id, label: item.name }));
setPlainOptions(data);
} else {
notification.error({
message: '提示',
duration: 3,
description: res.msg,
});
}
});
};
// 保存选择默认承办人
const onSave = () => {
let userName = [];
let mapList = new Map();
plainOptions.forEach(item => {
mapList.set(item.value, item.label);
});
checkedList.forEach(item => {
if (mapList.has(item)) {
userName.push(mapList.get(item));
}
});
onSubumit(userName.join(','), checkedList);
};
// 复选框全选监听
const onCheckAllChange = e => {
let allOptions = plainOptions.map(item => item.value);
setCheckedList(e.target.checked ? allOptions : []);
setIndeterminate(false);
setCheckAll(e.target.checked);
};
// 复选框监听事件
const onChange = list => {
setCheckedList(list);
setIndeterminate(!!list.length && list.length < plainOptions.length);
setCheckAll(list.length === plainOptions.length);
};
return (
<div>
<Modal
title="选择默认承办人"
visible={visible}
onOk={onSave}
width={400}
onCancel={handleCancel}
maskClosable={false}
destroyOnClose
>
<div>
<Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
<span style={{ fontWeight: 700 }}>用户列表</span>
</Checkbox>
<Divider style={{ margin: '10px 0' }} />
<div style={{ height: '380px', overflowY: 'scroll' }}>
{plainOptions.length > 0 ? (
<CheckboxGroup options={plainOptions} value={checkedList} onChange={onChange} />
) : (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="未有查找到用户" />
)}
</div>
</div>
</Modal>
</div>
);
};
export default Undertaker;
......@@ -108,7 +108,6 @@
.roleContent {
width: 50%;
margin-right: 10px;
.treeContent {
width: 100%;
height: 370px;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment