Commit 84294082 authored by tianfen's avatar tianfen

perf: 站点管理

parent bfc22498
Pipeline #21486 skipped with stages
...@@ -10,14 +10,14 @@ import { ...@@ -10,14 +10,14 @@ import {
Spin, Spin,
List, List,
Space, Space,
Collapse,
Checkbox,
Select
} from 'antd'; } from 'antd';
import { DoubleLeftOutlined, DoubleRightOutlined } from '@ant-design/icons'; import lodash from 'lodash';
import { DoubleLeftOutlined, DoubleRightOutlined,DownOutlined,UpOutlined } from '@ant-design/icons';
import PageContainer from '@/components/BasePageContainer'; import PageContainer from '@/components/BasePageContainer';
import { import {getWebModuleTree,chooseUserToStation,getAllGroup,getStationUserList} from '@/services/userCenter/siteManage/api';
getWebModuleTree,
chooseUserToStation,
getUserByStation,
} from '@/services/userCenter/siteManage/api';
import ListCard, { import ListCard, {
checkChildrenByCondition, checkChildrenByCondition,
getId, getId,
...@@ -32,26 +32,30 @@ import EditModal from './EditModal'; ...@@ -32,26 +32,30 @@ import EditModal from './EditModal';
import userStyles from '@/pages/userCenter/userManage/UserManage.less'; import userStyles from '@/pages/userCenter/userManage/UserManage.less';
const { Search } = Input; const { Search } = Input;
const placeholder = '请输入人员姓名'; const { Option } = Select;
const placeholder = '请输入机构名称';
const SiteManage = props => { const SiteManage = props => {
const { userMode } = props; const { userMode } = props;
const [treeData, setTreeData] = useState([]); // 树结构数据 const [treeData, setTreeData] = useState([]); // 树结构数据
const [currentStation, setCurrentStation] = useState({}); // 当前选中站点 const [currentStation, setCurrentStation] = useState({}); // 当前选中站点
const [searchWord, setSearchWord] = useState(''); // 关键字 const [searchWord, setSearchWord] = useState(''); // 关键字
const [modalVisible, setModalVisible] = useState(false); // 新增弹窗 const [visibleParams,setvisibleParams]=useState({
modalVisible:false,//新增弹窗
delVisible:false,//删除弹窗
editVisible:false,//修改弹窗
spinLoading:false,//加载弹窗
btnLoading:false,
loading:false,
checkBoxLoading:false
})
const [flag, setFlag] = useState(1); const [flag, setFlag] = useState(1);
const [delVisible, setDelVisible] = useState(false); // 删除弹窗
const [editVisible, setEditVisible] = useState(false); // 修改弹窗
const [subList, setSubList] = useState([]); // 选中的数组
const [spinLoading, setSpinLoading] = useState(false);
const [btnLoading, setBtnLoading] = useState(false);
const [valueList, setValueList] = useState([]);
const [dataList, setdataList] = useState([]); const [dataList, setdataList] = useState([]);
const [loading, setLoading] = useState(true);
const [mulu, setMulu] = useState(true); const [mulu, setMulu] = useState(true);
const [optionsList,setOptionsList]=useState([])
//侧边栏站点
useEffect(() => { useEffect(() => {
setSpinLoading(true); handleShowModal('spinLoading',true)
getWebModuleTree({ getWebModuleTree({
userMode: userMode || 'super', userMode: userMode || 'super',
select: '', select: '',
...@@ -60,7 +64,7 @@ const SiteManage = props => { ...@@ -60,7 +64,7 @@ const SiteManage = props => {
node: -2, node: -2,
}) })
.then(res => { .then(res => {
setSpinLoading(false); handleShowModal('spinLoading',false)
let arr = []; let arr = [];
if (res) { if (res) {
arr.push(res.find(item => item.id === 'Web4StationRoot')); arr.push(res.find(item => item.id === 'Web4StationRoot'));
...@@ -79,115 +83,138 @@ const SiteManage = props => { ...@@ -79,115 +83,138 @@ const SiteManage = props => {
} }
}) })
.catch(err => { .catch(err => {
setSpinLoading(false); handleShowModal('spinLoading',false)
console.error(err); console.error(err);
}); });
}, [flag]); }, [flag]);
//右边对应的机构
useEffect(() => { useEffect(() => {
if (!currentStation.stationID) return; if (!currentStation.stationID) return;
setLoading(true); handleShowModal('loading',true)
const defaultConfig = {}; getAllGroup({stationId: currentStation.stationID,}).then(res=>{
getUserByStation({ if(res.code===0){
stationID: currentStation.stationID, let data=res.data;
_version: 9999, // for(let i=0;i<2000;i++){
_dc: new Date().getTime(), // data.push({
// GroupId:i+10000,
// GroupName:`测试${i}`
// })
// }
handleShowModal('loading',false)
setdataList(data)
setOptionsList(data)
}
}) })
.then(res => {
const list = [];
// eslint-disable-next-line no-unused-expressions
res &&
res.forEach(item => {
list.push({ ...defaultConfig, ...item });
});
const finalList = buildMap(list);
setdataList(finalList);
setValueList(
finalList
.map(l =>
checkChildrenByCondition(
l,
it => (it.isChecked ? [getId(it)] : []),
true,
'map',
).flat(Infinity),
)
.flat(Infinity)
.filter(Boolean),
);
setLoading(false);
})
.catch(err => {
setLoading(false);
});
}, [currentStation]); }, [currentStation]);
const buildMap = list => { //弹出模态框
const obj = { const handleShowModal=(key,value)=>{
type: 'widgetGroup', setvisibleParams({...visibleParams,[key]:value});
searchWord, }
children: '',
text: '',
itemid: '',
};
let arr = list.map(item => {
item.id = item.OUID * 10000;
item.text = item.OUName;
item.isChecked = false;
item.type = 'widgetGroup';
item.children = item.userList.map(u => ({
...u,
text: u.userName,
type: 'widgetChild',
}));
return item;
});
console.log(arr);
return arr.filter(item => item.userList.length > 0);
};
// 新增站点
const handleAdd = e => {
console.log(e);
setModalVisible(true);
};
// 站点删除
const handleDel = e => {
setDelVisible(true);
};
// 编辑站点
const handleEdit = e => {
setEditVisible(true);
};
// 获取搜索框的值 // 获取搜索框的值
const handleSearch = value => { const handleSearch = value => {
setSearchWord(value); if(value){
dataList.forEach(item=>{
item.color=item.GroupName.indexOf(value)>-1?'#f00':'#333'
})
setdataList(lodash.cloneDeep(dataList))
setSearchWord(value);
}
}; };
const handleChange = e => { //搜索框点击进行锚点链接跳转
const { value } = e.target; const handleChange = value => {
setSearchWord(value); if(value){
let index=dataList.findIndex(item=>item.GroupId===value)
dataList.forEach(item=>{
item.color='#333'
})
dataList[index].color='#f00'
setdataList(lodash.cloneDeep(dataList))
let anchorElement = document.getElementById(`siteId${value}`);
anchorElement.scrollIntoView()
}
}; };
const confirmModal = e => { const confirmModal = e => {
setModalVisible(false); handleShowModal('modalVisible',false)
setFlag(flag + 1); setFlag(flag + 1);
}; };
const delModal = () => { const delModal = () => {
setDelVisible(false); handleShowModal('delVisible',false)
setFlag(flag + 1); setFlag(flag + 1);
}; };
const editModal = () => { const editModal = () => {
setEditVisible(false); handleShowModal('editVisible',false)
setFlag(flag + 1); setFlag(flag + 1);
}; };
const valueCallback = valueObj => { const handleHide = () => {
setSubList(valueObj); setMulu(!mulu);
}; };
const handleCommit = results => { const renderListItem = items =>
setBtnLoading(true); items.map(t => (
<List.Item
onClick={() => {
setCurrentStation(t);
}}
key={t.id}
className={classnames({
[styles.listItem]: true,
[styles.selected]: currentStation.id === t.id,
})}
>
{t.text}
</List.Item>
));
const handleChangeCollpase=(groupId,isShow)=>{
let index=dataList.findIndex(item=>item.GroupId==groupId)
dataList[index].isShow=!isShow
if(dataList[index].children&&dataList[index].children.length>0){
setdataList(lodash.cloneDeep(dataList))
return;
}
handleShowModal('loading',true)
getStationUserList({stationID:currentStation.stationID,groupId}).then(res=>{
if(res.code===0&&res.data){
handleShowModal('loading',false)
dataList[index].children=res.data;
setdataList(lodash.cloneDeep(dataList))
}
})
}
//每组全选全不选
const handleChangeAll=(e,index)=>{
dataList[index].isChecked=e.target.checked
dataList[index].selectList=e.target.checked?dataList[index].userList:[]
dataList[index].children&&dataList[index].children.forEach(item=>{
item.isChecked=e.target.checked
})
setdataList(lodash.cloneDeep(dataList))
}
//单个选择checkbox
const handleChangeSignel=(e,index,vIndex)=>{
dataList[index].children[vIndex].isChecked=e.target.checked;
let checked=dataList[index].children.filter(item=>item.isChecked).length==dataList[index].children.length
dataList[index].isChecked=checked
let selectArray=dataList[index].children.filter(item=>item.isChecked)
dataList[index].selectList=selectArray
setdataList(lodash.cloneDeep(dataList))
}
//提交
const handleCommitBtn=()=>{
handleShowModal('btnLoading',true)
let result=[]
//数据处理成后台需要的格式
dataList.forEach(item=>{
if(item.selectList&&item.selectList.length>0){
let idArr=item.selectList.map(v=>v.userID)
item.isChecked&&idArr.push(item.id)
result.push(...idArr)
}
})
chooseUserToStation( chooseUserToStation(
qs.stringify({ qs.stringify({
// userList: String(arr.flat()), userList: String(result.flat()),
userList: String(results.flat()),
stationID: currentStation.stationID, stationID: currentStation.stationID,
}), }),
{ {
...@@ -197,7 +224,8 @@ const SiteManage = props => { ...@@ -197,7 +224,8 @@ const SiteManage = props => {
}, },
) )
.then(res => { .then(res => {
setBtnLoading(false); handleShowModal('btnLoading',false)
if (res.success) { if (res.success) {
notification.success({ notification.success({
message: '提示', message: '提示',
...@@ -213,29 +241,10 @@ const SiteManage = props => { ...@@ -213,29 +241,10 @@ const SiteManage = props => {
} }
}) })
.catch(err => { .catch(err => {
setBtnLoading(false); handleShowModal('btnLoading',false)
console.log(err); console.log(err);
}); });
}; }
const handleHide = () => {
setMulu(!mulu);
};
const renderListItem = items =>
items.map(t => (
<List.Item
onClick={() => {
setCurrentStation(t);
}}
key={t.id}
className={classnames({
[styles.listItem]: true,
[styles.selected]: currentStation.id === t.id,
})}
>
{t.text}
</List.Item>
));
return ( return (
<PageContainer> <PageContainer>
{/* <Row> {/* <Row>
...@@ -249,7 +258,7 @@ const SiteManage = props => { ...@@ -249,7 +258,7 @@ const SiteManage = props => {
> >
<Spin <Spin
tip="loading...." tip="loading...."
spinning={spinLoading} spinning={visibleParams.spinLoading}
style={{ marginTop: '20px' }} style={{ marginTop: '20px' }}
> >
<div className={userStyles.siteTitle}> <div className={userStyles.siteTitle}>
...@@ -258,20 +267,20 @@ const SiteManage = props => { ...@@ -258,20 +267,20 @@ const SiteManage = props => {
<List>{renderListItem(treeData)}</List> <List>{renderListItem(treeData)}</List>
</Spin> </Spin>
<AddModal <AddModal
visible={modalVisible} visible={visibleParams.modalVisible}
onCancel={() => setModalVisible(false)} onCancel={()=>handleShowModal('modalVisible',false)}
confirmModal={confirmModal} confirmModal={confirmModal}
/> />
<DelModal <DelModal
visible={delVisible} visible={visibleParams.delVisible}
stationId={currentStation.stationID} stationId={currentStation.stationID}
onCancel={() => setDelVisible(false)} onCancel={()=>handleShowModal('delVisible',false)}
confirmModal={delModal} confirmModal={delModal}
/> />
<EditModal <EditModal
visible={editVisible} visible={visibleParams.editVisible}
stationObj={currentStation} stationObj={currentStation}
onCancel={() => setEditVisible(false)} onCancel={()=>handleShowModal('editVisible',false)}
confirmModal={editModal} confirmModal={editModal}
/> />
<div> <div>
...@@ -328,21 +337,28 @@ const SiteManage = props => { ...@@ -328,21 +337,28 @@ const SiteManage = props => {
<Row align="middle"> <Row align="middle">
<Col span={1}>搜索</Col> <Col span={1}>搜索</Col>
<Col span={8}> <Col span={8}>
<Search <Select
allowClear style={{width:'100%'}}
showSearch
placeholder={placeholder} placeholder={placeholder}
onSearch={handleSearch} onSearch={handleSearch}
onChange={handleChange} onSelect={handleChange}
enterButton filterOption={(input, option) =>
/> option.children.indexOf(input) >= 0
}
>
{optionsList.map(item=>{
return <Option key={item.GroupId} value={item.GroupId}>{item.GroupName}</Option>
})}
</Select>
</Col> </Col>
<Col span={3} /> {/* <Col span={3} /> */}
<Col span={8}> <Col span={15} style={{textAlign:'right'}}>
<Space size="large"> <Space size="small">
<Button <Button
type="primary" type="primary"
onClick={() => { onClick={() => {
handleAdd(); handleShowModal('modalVisible',true);
}} }}
> >
新增 新增
...@@ -350,9 +366,9 @@ const SiteManage = props => { ...@@ -350,9 +366,9 @@ const SiteManage = props => {
<Button <Button
type="primary" type="primary"
onClick={() => { onClick={() => {
handleEdit(); handleShowModal('editVisible',true);
}} }}
disabled={!currentStation.stationID || spinLoading} disabled={!currentStation.stationID || visibleParams.spinLoading}
> >
编辑 编辑
</Button> </Button>
...@@ -360,9 +376,9 @@ const SiteManage = props => { ...@@ -360,9 +376,9 @@ const SiteManage = props => {
danger danger
type="primary" type="primary"
onClick={() => { onClick={() => {
handleDel(currentStation.stationID); handleShowModal('delVisible',true);
}} }}
disabled={!currentStation.stationID || spinLoading} disabled={!currentStation.stationID || visibleParams.spinLoading}
> >
删除 删除
</Button> </Button>
...@@ -370,23 +386,22 @@ const SiteManage = props => { ...@@ -370,23 +386,22 @@ const SiteManage = props => {
</Col> </Col>
</Row> </Row>
</Card> </Card>
<Card <Card className={classnames({ [styles.boxH]: mulu, [styles.cardBoxR]: true, })}>
className={classnames({ {/* <Checkbox className={styles.siteAll}>全选/反选</Checkbox> */}
[styles.boxH]: mulu, <Spin spinning={visibleParams.loading}>
[styles.cardBoxR]: true, {dataList.map((item,index)=>{
})} return <Panels {...item}
> index={index}
{currentStation.stationID && ( key={item.GroupId}
<ListCard handleChangeCollpase={handleChangeCollpase}
loading={loading} handleChangeAll={handleChangeAll}
checkList={valueList} handleChangeSignel={handleChangeSignel}
dataList={dataList} />
searchWord={searchWord} })}
onCommit={handleCommit} </Spin>
btnLoading={btnLoading} {dataList.length?<Button type='primary' className={styles.siteCommit} onClick={handleCommitBtn}>提交</Button>:null}
/>
)}
</Card> </Card>
</div> </div>
</div> </div>
{/* </Col> {/* </Col>
...@@ -395,4 +410,28 @@ const SiteManage = props => { ...@@ -395,4 +410,28 @@ const SiteManage = props => {
); );
}; };
export default appConnector(SiteManage);
const Panels=React.memo((props)=>{
let {index,GroupId,GroupName,children,isChecked,isShow,color}=props;
return <div className={styles.sitePanel} key={GroupId} id={`siteId${GroupId}`}>
<div className={styles.sitePanelHead} onClick={()=>props.handleChangeCollpase(GroupId,isShow)}>
{isShow?<UpOutlined className={styles.siteIcon}/>:<DownOutlined className={styles.siteIcon}/>}
<p style={{color:color}}>{GroupName}</p>
</div>
{isShow?
<div className={styles.sitePanelCon}>
<Checkbox key={'0'} className={styles.siteList} checked={isChecked} onClick={(e)=>props.handleChangeAll(e,index)}>全选</Checkbox>
{children&&children.map((v,vIndex)=>{
return <CheckBoxRow {...v} index={index} vIndex={vIndex} key={v.userID} handleChangeSignel={props.handleChangeSignel}/>
})}
</div>:null
}
</div>
})
const CheckBoxRow=React.memo((props)=>{
let {vIndex,index,isChecked,userName}=props;
return <Checkbox className={styles.siteList} checked={isChecked} onClick={(e)=>props.handleChangeSignel(e,index,vIndex)}>{userName}</Checkbox>
})
export default React.memo(appConnector(SiteManage));
...@@ -97,4 +97,47 @@ ...@@ -97,4 +97,47 @@
width: 100%; width: 100%;
position: relative; position: relative;
transition: width 2s; transition: width 2s;
}
.siteCheckbox .ant-collapse-content > .ant-collapse-content-box{
padding: 16px 16px 0;
}
.siteList{
width:199px;
margin:0 0 15px 0
}
.sitePanel{
margin: 0 0 10px 0;
}
.sitePanelHead{
background-color: #f5f5f5;
padding:8px 10px;
cursor: pointer;
display: flex;
flex-direction: row;
}
.sitePanelHead p{
margin: 0;
}
.sitePanelCon{
border:1px solid #f5f5f5;
padding:20px;
padding-bottom: 0;
border-top:0
}
.sitePanel .ant-checkbox-wrapper + .ant-checkbox-wrapper{
margin:0
}
.siteIcon{
color:#ccc;
margin:4px 10px 0 0;
}
.siteAll{
margin:0 0 10px 0;
}
.siteColor{
color:#f00
}
.siteCommit{
} }
\ No newline at end of file
import { get, post, CITY_SERVICE } from '@/services/index'; import { get, post, CITY_SERVICE,PUBLISH_SERVICE } from '@/services/index';
/* /*
** params ** params
...@@ -30,3 +30,12 @@ export const chooseUserToStation = (params, options) => ...@@ -30,3 +30,12 @@ export const chooseUserToStation = (params, options) =>
// 获取人员 // 获取人员
export const getUserByStation = params => export const getUserByStation = params =>
get(`${CITY_SERVICE}/OMS.svc/P_GetUserByStation`, params); get(`${CITY_SERVICE}/OMS.svc/P_GetUserByStation`, params);
//获取站点一级列表
export const getAllGroup = params =>
get(`${PUBLISH_SERVICE}/UserCenter/GetAllGroup`, params);
//获取站点二级列表
export const getStationUserList = params =>
get(`${PUBLISH_SERVICE}/UserCenter/GetStationUserList`, params);
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