import React, { useEffect, useState } from 'react' import SiteModal from '@/components/Modal/SiteModa'; import { Checkbox, Input, Button, Modal } from 'antd' //import { data } from '../Mock' import _ from 'lodash'; import classnames from 'classnames'; import styles from './VisibleRoleModal.less' import { ManOutlined } from '@ant-design/icons'; import { RoleGroupList } from '@/services/platform/messagemanage' import { useTheme } from 'bizcharts'; const checkIsGroup = node => node.children?.length > 0; const getId = item => item.userID || item.roleID || item.stationID || item.id; const VisibleRoleModal = props => { const [loading, setLoading] = useState(false); const [previewVisible, setPreviewVisible] = useState(false) const [selectRole, setSelectRole] = useState([]) const [dataTree, setDataTree] = useState([]) const [dataLeafs, setDataLeafs] = useState([]) const [selectValues, setSelectValues] = useState([]) const { onSubmit, title, operate,initValues } = props const GetRoleGroupList = () => { RoleGroupList().then( res => { //数据转换 let tree = [] let leafs = [] res.data.roleList.map((item, index) => { tree.push({ name: item.visibleTitle, id: index, children: item.roleList.map((roleItem) => { leafs.push({ name: roleItem.roleName, id: roleItem.roleID, }) const leafNode = { name: roleItem.roleName, id: roleItem.roleID, children: [] } // for (const id of initValues) { // if(id == roleItem.roleID){ // leafNode.checked = true // } // } return leafNode }) }) }) setDataTree(tree) setDataLeafs(leafs) } ) } useEffect(() => { setSelectRole(props.value) GetRoleGroupList() }, [props]) const handleCancel = () => { setPreviewVisible(false) } const handleOk = () => { setPreviewVisible(false) onSubmit && onSubmit(selectValues) } const handleClick = () => { setPreviewVisible(true) } const onChange2 = (value) => { console.log(value) const strArr = [] for (const item of value) { strArr.push(item.name) } setSelectRole(strArr.toString()) setSelectValues(value) } return ( <div className={styles.role_container}> { operate ? ( <div onClick={handleClick}> { operate } </div> ) : ( <div style={{ display: "flex", flexDirection: "row", width: "100%" }}> <Input disabled={true} value={selectRole} /> <div className={styles.select_btn} onClick={handleClick}>{title ? title : "选择角色"}</div> </div> ) } <SiteModal {...props} title={title ? `选择${title}` : 关联角色} bodyStyle={{ width: '100%', minHeight: '100px' }} style={{ top: 200, borderRadius: '20px' }} width="800px" destroyOnClose cancelText="取消" okText="确认" onOk={() => handleOk()} confirmLoading={loading} visible={previewVisible} onCancel={handleCancel} > <div className={styles.list_card}> <ListCard {...props} onChange2={onChange2} data={dataTree} dataLeafs={dataLeafs} initValues={initValues}/> </div> </SiteModal> </div> ) } const checkChildrenByCondition = ( item, fn, withGroup = true, method = 'every', ) => { if (item.children && item.children.length > 0) { return fn(item); } const childrenResults = item.children[method](t => checkChildrenByCondition(t, fn, withGroup, method), ); return withGroup ? [fn(item), ...childrenResults] : [...childrenResults]; }; const ListCard = props => { const { onChange, onChange2, data, dataLeafs,initValues } = props const [changedItem, setChangedItem] = useState({ item: {} }); const [valueList, setValueList] = useState([]); const checkAll = e => { if (e.target.checked) { const result = data.map(item => getAllID(item)).flat(Infinity); setValueList(result); // eslint-disable-next-line no-unused-expressions const fliterResult = filterChildren(result) const strArr = [] for (const item of fliterResult) { strArr.push(item.name) } onChange && onChange(strArr.toString()) onChange2 && onChange2(fliterResult) } else { setValueList([]); // eslint-disable-next-line no-unused-expressions const fliterResult = filterChildren(result) onChange && onChange(fliterResult) onChange2 && onChange2(fliterResult) } }; const getAllID = item => { let result = []; const haveChildren = Array.isArray(item.children) && item.children.length > 0; // 统一使用 getId result.push(getId(item)); if (haveChildren) { // 每次递归result被置空,所以要另外保存 result = [...item.children.map(i => getAllID(i)), ...result]; } return result; }; const filterChildren = (select) => { let selectLeafs = [] for (const leaf of dataLeafs) { for (const id of select) { if (id == leaf.id) { selectLeafs.push(leaf) } } } return selectLeafs } const updateValueList = (checkedKeys, childrenKeys, sourceItem) => { const removekeys = _.difference(childrenKeys, checkedKeys); let result = _.uniq(_.union(checkedKeys, valueList)); _.remove(result, v => removekeys.includes(v)); setValueList(result); if (sourceItem) setChangedItem(sourceItem); // eslint-disable-next-line no-unused-expressions // onChange && onChange(result); // onChange2 && onChange2(result); const fliterResult = filterChildren(result) const strArr = [] for (const item of fliterResult) { strArr.push(item.name) } onChange && onChange(strArr.toString()) onChange2 && onChange2(fliterResult) } useEffect(() => { initValues&&setValueList(initValues) }, []) return ( <div> <Checkbox onChange={checkAll}>全选/全不选</Checkbox> { data.map((item, i) => { return <ListCardItem key={i} item={item} updateValueList={updateValueList} valueList={valueList} changedItem={changedItem} {...props} /> }) } </div> ) } const ListCardItem = props => { const { item, valueList, updateValueList, changedItem } = props; const id = item.id; // 当前组件是否是分组id const isGroup = item.children && item.children.length > 0; const [indeterminate, setIndeterminate] = useState(!isGroup); const [childrenKeys, setChildrenKeys] = useState([]); useEffect(() => { if (isGroup) { const keys = item.children .map(child => checkChildrenByCondition(child, c => c.id, true, 'map'), ) .flat(Infinity); setChildrenKeys(keys); } else { // } }, [item]); useEffect(() => { // 子节点勾选状态变化时 if ( isGroup && changedItem.item !== item && !checkIsGroup(changedItem.item) && childrenKeys.includes(getId(changedItem.item)) ) { if (changedItem.value && childrenKeys.every(c => valueList.includes(c))) { // 全选 updateValueList([id], [id]); setIndeterminate(false); } else if (childrenKeys.some(c => valueList.includes(c))) { // 半选 // eslint-disable-next-line no-unused-expressions valueList.includes(id) && updateValueList([], [id]); setIndeterminate(true); } else { // 零选 // eslint-disable-next-line no-unused-expressions valueList.includes(id) && updateValueList([], [id]); setIndeterminate(false); } } }, [changedItem.item, changedItem.value]); const handleChecked = e => { const { checked: v } = e.target; if (isGroup) { const result = [...childrenKeys, id]; updateValueList(v ? result : [], result, { item, value: v }); setIndeterminate(false); } else { updateValueList(v ? [id] : [], [id], { item, value: v }); } } const renderChild = () => item.children && item.children.map((c, i) => ( <ListCardItem item={c} key={`item${i}key`} updateValueList={updateValueList} valueList={valueList} changedItem={changedItem} /> )); return ( <div className={classnames({ [styles.divBox]: isGroup, [styles.divSingle]: !isGroup, })}> <div className={styles.topCheckbox}> <Checkbox indeterminate={isGroup ? indeterminate : false} checked={valueList.includes(id)} onChange={handleChecked} > {item.name} </Checkbox> <div style={{ width: '100%' }} className={styles.checkdiv}> { renderChild() } </div> </div> </div> ) } export default VisibleRoleModal