import React, { useContext, useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { Button, Input, Radio, Modal, Checkbox, Row, Col, Tree, ConfigProvider, message, Tooltip } from 'antd'; import Empty from '@wisdom-components/empty'; import { UnorderedListOutlined, ExclamationCircleFilled, SearchOutlined, CloseOutlined, InfoCircleOutlined } from '@ant-design/icons'; import './index.less'; import { getQuataList, updateMonitorConf } from './apis'; const { TreeNode } = Tree; const QuotaSelect = ({ buttonProps, deviceList, confList, onSelect, pointType, width, title, cancelText, okText, onModalOk, onModalClose, onModalCancel, searchPrefix, placeholder, maximum, user, treeProps, defaultSelect, disabledList, isCommonTag, }) => { const { getPrefixCls } = useContext(ConfigProvider.ConfigContext); const prefixCls = getPrefixCls('ec-quota-select'); const [visible, setVisible] = useState(false); const [targetValue, setTargetValue] = useState(defaultSelect); const [allQuotaList, setAllQuotaList] = useState([]); const [quotaList, setQuotaList] = useState([]); const [groupQuotaList, setGroupQuotaList] = useState([]); const [selectDevice, setSelectDevice] = useState({}); // 选中的设备 const [selectData, setSelectData] = useState([]); // 选中的指标数据 const [confParams, setConfParams] = useState({}); const [search, setSearch] = useState(''); const fetchData = (item = {}) => { console.log(1221, item); // 请求指标列表 getQuataList({ accountName: item.deviceType, // addrSchemeID: item.pointAddressID, isCommonTag: isCommonTag, }).then((res) => { if (res.code === 0) { const data = res.data.length > 0 ? res.data.map((child) => ({ ...child, checked: item.confList.includes(child.sensorName), title: child.sensorName, key: child.sensorName, })) : []; let k = data.find(function (a) { return a.isShow == 1; }); setTargetValue(k ? 'emphasis' : 'all'); setAllQuotaList(data); setSelectData(data.filter((child) => child.checked)); } else { message.error(res.msg); } }); }; // 更新设备配置 const updateDeviceConf = () => { const params = { ...confParams, loginName: user, type: '用户', }; const curSelectList = JSON.parse(JSON.stringify(selectData)); const curSelectKey = curSelectList.map((child) => child.key); params[pointType] = curSelectKey.join(','); updateMonitorConf(params).then((response) => { if (response.code === 0) { message.success('保存成功'); } else { message.error(response.msg); } }); }; // 处理指标分组 const handleGroupData = (data) => { const groupData = []; const groupQuotaData = []; data.forEach((item) => { if (!groupData.includes(item.groupName)) { groupData.push(item.groupName); } }); groupData.forEach((group) => { const list = []; data.forEach((child) => { if (child.groupName === group) { list.push(child); } }); groupQuotaData.push({ groupName: group || '未分组指标', quotaList: list, }); }); setGroupQuotaList(groupQuotaData); }; useEffect(() => { handleGroupData(quotaList); }, [quotaList]); useEffect(() => { if (targetValue === 'emphasis') { filterEmphasisQuota(); } else { let newQuotaList = allQuotaList.filter((item) => item.sensorName.indexOf(search) >= 0); setQuotaList(newQuotaList); } }, [allQuotaList]); useEffect(() => { let data = JSON.parse(JSON.stringify(allQuotaList)); data.forEach((item) => { item.checked = false; if (selectData.length > 0) { selectData.forEach((child) => { if (child.key === item.key) { item.checked = true; } }); } }); setAllQuotaList(data); }, [selectData]); // 过滤重点指标 const filterEmphasisQuota = () => { let newQuotaList = [...allQuotaList]; newQuotaList = newQuotaList.filter( (item) => item.isShow === 1 && item.sensorName.indexOf(search) >= 0, ); setQuotaList(newQuotaList); }; // 展示模态框 const showModal = (item) => { setVisible(true); setSelectDevice(item); fetchData(item); }; useEffect(() => { let param = confList.filter((child) => child.deviceType === selectDevice.deviceType)[0]; if (!param) param = { deviceType: selectDevice.deviceType, }; setConfParams({ ...param }); }, [selectDevice]); // 关闭模态框 const handleCancel = (e) => { if (e.target.innerHTML === cancelText) { setSelectData([]); onModalCancel && onModalCancel(); } else { onModalClose && onModalClose(); setQuotaList([]); setGroupQuotaList([]); setVisible(false); } }; const onOk = () => { onModalOk && onModalOk(); handleOk(); setQuotaList([]); setGroupQuotaList([]); setVisible(false); }; const handleOk = () => { const curSelectList = JSON.parse(JSON.stringify(selectData)); const curSelectKey = curSelectList.map((child) => child.key); onSelect({ device: selectDevice, selectKey: curSelectKey, selectList: curSelectList, }); }; // 切换重点与全部 const onRadioChange = (e) => { if (e.target.value === 'all') { let newQuotaList = allQuotaList.filter((item) => item.sensorName.indexOf(search) >= 0); setQuotaList(newQuotaList); } else { filterEmphasisQuota(); } setTargetValue(e.target.value); }; // 搜索指标 const onSearch = (e) => { if (e.type === 'keydown' || e.target.value === '') { setSearch(e.target.value); if (e.target.value !== '') { let newQuotaList = []; quotaList.forEach((item) => { if (!item.sensorName) return; if (item.sensorName.indexOf(e.target.value) > -1) newQuotaList.push(item); }); setQuotaList(newQuotaList); } else { if (targetValue === 'all') { setQuotaList(allQuotaList); } else { filterEmphasisQuota(); } } } }; // 处理复选框点击事件 const handleCheckboxChange = (e, item) => { let curSelectList = JSON.parse(JSON.stringify(selectData)); if (item.checked) { curSelectList = curSelectList.filter((child) => child.title !== item.title); } else { curSelectList.push({ ...item, checked: !item.checked }); } setSelectData(curSelectList); }; // 处理取消选择按钮点击事件 const handleCancelSelect = ({ title }) => { let data = [...selectData]; data = data.filter((item) => item.title !== title); setSelectData(data); }; // 拖动选中树节点 const handleDrop = (info) => { const dropKey = info.node.key; const dragKey = info.dragNode.key; const dropPos = info.node.pos.split('-'); const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]); const loop = (data, key, callback) => { for (let i = 0; i < data.length; i++) { if (data[i].key === key) { return callback(data[i], i, data); } if (data[i].children) { loop(data[i].children, key, callback); } } }; const data = [...selectData]; let dragObj; loop(data, dragKey, (item, index, arr) => { arr.splice(index, 1); dragObj = item; }); if (!info.dropToGap) { loop(data, dropKey, (item) => { item.children = item.children || []; item.children.unshift(dragObj); }); } else if ( (info.node.props.children || []).length > 0 && // Has children info.node.props.expanded && // Is expanded dropPosition === 1 // On the bottom gap ) { loop(data, dropKey, (item) => { item.children = item.children || []; item.children.unshift(dragObj); }); } else { let ar; let i; loop(data, dropKey, (item, index, arr) => { ar = arr; i = index; }); if (dropPosition === -1) { ar.splice(i, 0, dragObj); } else { ar.splice(i + 1, 0, dragObj); } } setSelectData(data); }; return ( <div className={classNames(prefixCls)}> <div className={classNames(`${prefixCls}-btn-wrap`)}> {!!deviceList.length && deviceList.map((item, index) => ( <Button key={index} icon={<UnorderedListOutlined />} {...buttonProps} onClick={() => showModal(item)} > {buttonProps.children ? buttonProps.children : `${item.deviceName}(${item.confList ? item.confList.length : 0})`} </Button> ))} </div> {visible && ( <Modal centered width={width} title={title} cancelText={cancelText} okText={okText} visible={true} onCancel={handleCancel} onOk={onOk} className={classNames(`${prefixCls}-modal`)} footer={[ user ? ( <Button style={{ float: 'left' }} key="save" type="primary" onClick={() => { updateDeviceConf(); onOk(); }} > 保存修改 </Button> ) : null, <Button key="cancel" onClick={handleCancel}> 取消选择 </Button>, <Button key="ok" type="primary" onClick={onOk}> 确定 </Button>, ]} > <div className={classNames(`${prefixCls}-modal-wrap`)}> <div className={classNames(`${prefixCls}-modal-left`)}> <div className={classNames(`${prefixCls}-modal-select-wrap`)}> <Input className={classNames(`${prefixCls}-modal-search`)} placeholder={placeholder} bordered={false} prefix={searchPrefix} onChange={onSearch} onPressEnter={onSearch} /> <div className={classNames(`${prefixCls}-modal-target`)}> <div>指标:</div> <Radio.Group onChange={onRadioChange} value={targetValue}> <Radio.Button value="emphasis">重点指标</Radio.Button> <Radio.Button value="all">全部</Radio.Button> </Radio.Group> </div> <div className={classNames(`${prefixCls}-modal-select`, { warning: !(selectData.length < maximum), })} > {selectData.length < maximum ? ( <> <ExclamationCircleFilled /> <div>已选择 {selectData.length} 个指标</div> </> ) : ( <> <ExclamationCircleFilled /> <div>已达上限,最多选择 {maximum} 个指标</div> </> )} </div> </div> <div className={classNames(`${prefixCls}-modal-option-wrap`)}> {!quotaList.length && <Empty />} {!!quotaList.length && groupQuotaList.map((group, index) => ( <div key={index}> <div className={classNames(`${prefixCls}-modal-class-title`)}> {group.groupName} </div> <Row gutter={[0, 6]}> {group.quotaList.map((item) => ( <Col span={8} key={item.key}> <Checkbox value={item.title} checked={item.checked} disabled={ ((selectData.length > maximum || selectData.length === maximum) && !item.checked) || disabledList.includes(item.title) } onChange={(e) => handleCheckboxChange(e, item)} > {item.title} {item.notInFVersion && <Tooltip placement="bottom" title={`${item.notInFVersion} 版本不存在当前指标`}><InfoCircleOutlined className={classNames(`${prefixCls}-modal-class-mark`)}/></Tooltip>} </Checkbox> </Col> ))} </Row> </div> ))} </div> </div> <div className={classNames(`${prefixCls}-modal-right`)}> <div className={classNames(`${prefixCls}-modal-number`)}> 已选:{selectData.length}/{maximum} </div> <div className={classNames(`${prefixCls}-modal-tree`)}> <Tree draggable={true} onDrop={handleDrop} {...treeProps}> {selectData.map((item) => ( <TreeNode key={item.key} title={ <div className={classNames(`${prefixCls}-modal-tree-title`)}> <div>{item.title}</div> <CloseOutlined onClick={() => handleCancelSelect(item)} /> </div> } /> ))} </Tree> </div> </div> </div> </Modal> )} </div> ); }; QuotaSelect.defaultProps = { buttonProps: {}, width: 900, title: '选择显示字段', cancelText: '取消选择', okText: '确定', placeholder: '搜索关键词', searchPrefix: <SearchOutlined />, maximum: 0, user: null, pointType: 'cardPoints', deviceList: [], confList: [], treeProps: {}, onSelect: () => {}, onModalCancel: () => {}, onModalOk: () => {}, onModalClose: () => {}, defaultSelect: 'emphasis', disabledList: [], isCommonTag: false, }; QuotaSelect.propTypes = { buttonProps: PropTypes.object, width: PropTypes.number, title: PropTypes.string, cancelText: PropTypes.string, okText: PropTypes.string, placeholder: PropTypes.string, searchPrefix: PropTypes.node, maximum: PropTypes.number, user: PropTypes.string, pointType: PropTypes.string, deviceList: PropTypes.array, confList: PropTypes.array, treeProps: PropTypes.object, onSelect: PropTypes.func, onModalCancel: PropTypes.func, onModalOk: PropTypes.func, onModalClose: PropTypes.func, defaultSelect: PropTypes.string, disabledList: PropTypes.array, isCommonTag: PropTypes.bool, }; export default QuotaSelect;