/* eslint-disable no-restricted-syntax */ 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 { ManOutlined } from '@ant-design/icons'; import { RoleGroupList } from '@/services/messagemanage/messagemanage'; import { useTheme } from 'bizcharts'; import styles from './VisibleRoleModal.less'; 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, selectValue, tree, leafs, visible, onCancel, } = props; useEffect(() => { console.log(tree); console.log(leafs); // eslint-disable-next-line no-shadow if (selectValue) { setSelectRole(selectValue); } setDataTree(tree); setDataLeafs(leafs); }, [visible]); const handleCancel = () => { onCancel(); }; const handleOk = () => { // eslint-disable-next-line no-unused-expressions console.log(selectValues); onSubmit && onSubmit(selectValues); }; // const handleClick = () => { // setPreviewVisible(true); // }; const onChange2 = value => { console.log(value); const strArr = []; // eslint-disable-next-line no-restricted-syntax 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 value={selectRole} /> <div className={styles.select_btn} onClick={handleClick}> {title || '选择角色'} </div> </div> )} */} <SiteModal {...props} title={ title && Object.prototype.toString.call(title) !== '[object Object]' ? `选择${title}` : '关联角色' } bodyStyle={{ width: '100%', minHeight: '100px' }} style={{ top: 200, borderRadius: '20px' }} width="800px" destroyOnClose cancelText="取消" okText="确认" onOk={() => handleOk()} confirmLoading={loading} visible={visible} onCancel={handleCancel} > <div className={styles.list_card}> <ListCard {...props} onChange2={onChange2} data={dataTree} dataLeafs={dataLeafs} initValues={initValues} selectValue={selectValue} /> </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, selectValue } = props; const [changedItem, setChangedItem] = useState({ item: {} }); const [indeterminateAll, setIndeterminateAll] = useState(false); const [checkValue, setCheckValue] = useState(false); const [valueList, setValueList] = useState([]); const checkAll = e => { setIndeterminateAll(false); if (e.target.checked) { setCheckValue(true); const result = data.map(item => getAllID(item)).flat(Infinity); console.log(result); setValueList(result); // eslint-disable-next-line no-unused-expressions const fliterResult = filterChildren(result); const strArr = []; // eslint-disable-next-line no-restricted-syntax for (const item of fliterResult) { strArr.push(item.name); } // eslint-disable-next-line no-unused-expressions onChange && onChange(strArr.toString()); // eslint-disable-next-line no-unused-expressions onChange2 && onChange2(fliterResult); } else { setCheckValue(false); setValueList([]); // eslint-disable-next-line no-unused-expressions const fliterResult = filterChildren(result); // eslint-disable-next-line no-unused-expressions onChange && onChange(fliterResult); // eslint-disable-next-line no-unused-expressions 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)); console.log(result); 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 = []; // eslint-disable-next-line no-restricted-syntax for (const item of fliterResult) { strArr.push(item.name); } // eslint-disable-next-line no-unused-expressions onChange && onChange(strArr.toString()); // eslint-disable-next-line no-unused-expressions onChange2 && onChange2(fliterResult); console.log(fliterResult); console.log(strArr.toString()); }; useEffect(() => { // eslint-disable-next-line no-unused-expressions initValues && setValueList(initValues); }, []); useEffect(() => { console.log(initValues); console.log(initValues.length); let dataaa = []; data.map(i => { i.children.map(j => { dataaa.push(j); }); }); console.log(dataaa); if (initValues.length === 0) { setIndeterminateAll(false); setCheckValue(false); } else if (initValues.length < dataaa.length) { setIndeterminateAll(true); setCheckValue(false); } else { setIndeterminateAll(false); setCheckValue(true); } }, [selectValue]); return ( <div> <Checkbox onChange={checkAll} indeterminate={indeterminateAll} checked={checkValue}> 全选/全不选 </Checkbox> {data.map((item, i) => ( <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 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;