/* eslint-disable no-shadow */ /* eslint-disable react/jsx-boolean-value */ import React, { useState, useEffect } from 'react'; import { Form, Modal, Space, Table, Button, Popconfirm, Spin, notification, Tooltip, TreeSelect, Empty, Checkbox, Switch, Tag, } from 'antd'; import { EditOutlined, DeleteOutlined, SortDescendingOutlined, PlusSquareOutlined, RollbackOutlined, ConsoleSqlOutlined, EyeOutlined, } from '@ant-design/icons'; import { reloadTableFields, removeFields, loadUnattachedTables, LoadLedgers, } from '@/services/tablemanager/tablemanager'; import { useHistory } from 'react-router-dom'; import FieldEditor from './fieldEditor'; import AffiliateAdd from '../components/Field/affiliateAdd'; import LoadGroup from '../components/Field/loadGroupNew'; import styles from './index.less'; import PerviewPrase from './PerviewPrase'; import { LayerSetting } from '@/services/gis/gis'; const AddModal = props => { const history = useHistory(); const [allData, setAllData] = useState([]); const [treeData, setTreeData] = useState([]); const [keepTreeFirst, setKeepTreeFirst] = useState([]); const [tableList, setTableList] = useState([]); const [tableData, setTableData] = useState([]); const [treeLoading, setTreeLoading] = useState(false); const [formObj, setFormObj] = useState(''); const [flag, setFlag] = useState(0); // 弹窗类型 const [isVisible, setIsVisible] = useState(false); // 弹窗 const [isType, setIsType] = useState(''); // 弹窗类型 const [itemData, setItemData] = useState({}); const [select, setSelect] = useState([]); const [selectTableName, setSelectTableName] = useState({}); const [pramFormObj, setPramFormObj] = useState({}); const [visible, setVisible] = useState(false); // 弹窗 const [type, setType] = useState(''); // 弹窗类型 const [chooseLine, setChooseLine] = useState(''); const { TreeNode } = TreeSelect; const [treeSelectValue, setTreeSelectValue] = useState(undefined); const [selectTreeData, setSelectTreeData] = useState([]); const [selectDataFirst, setSelectDataFirst] = useState([]); const [multiOperate, setMultiOperate] = useState(true); // 是否禁用用户批量操作 const [selectedRowKeys, setSelectedRowKeys] = useState([]); // 已选字段配置数,机构改变时重置 const [deleteUserVisible, setDeleteUserVisible] = useState(false); // 批量删除 const [checkStrictly, setCheckStrictly] = useState(false); const [selectGroup, setSelectGroup] = useState([]); const [keepStandingBook, setKeepStandingBook] = useState([]); const [keepTreeData, setKeepTreeData] = useState([]); const [keepTree, setKeepTree] = useState([]); // 保存树字段名称 const [perviewPrase, setPerViewPrase] = useState(false); const [tablesSchema, setTablesSchema] = useState(null); // 存储parseForm组件需要的数据格式 const editor = record => { console.log(record); if (!record.children) { setIsType('edit'); setIsVisible(true); setItemData(record); } }; const Submit = prop => { setIsVisible(false); setFlag(flag + 1); }; const getField = () => { loadUnattachedTables().then(res => { if (res.data.root && res.data.root.length) { setTableList(res.data.root); } }); }; // 处理表格特殊样式 const styleConfig = record => { if (record.Type === 1) { return 'red'; } if (record.Type === 2) { return 'grey'; } return '000000D9'; }; const setRowClassName = record => Object.entries(record).toString() === Object.entries(selectTableName).toString() ? styles.clickRowStyle : ''; const columns = [ { title: '字段名', dataIndex: 'name', key: 'name', align: 'left', width: 300, onCell: () => ({ style: { maxWidth: 300, overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis', cursor: 'pointer', }, }), render: (text, record) => { let aa = ( <div style={{ fontWeight: 'bold' }}> <span style={{ color: 'rgb(63 163 255)' }}> {text}(共{allData[text] ? allData[text].length : ''}条) </span> </div> ); let bb = ( <Tooltip title={text}> <div style={{ color: styleConfig(record) }}>{text}</div> </Tooltip> ); const obj = { children: record.children ? aa : bb, props: {}, }; obj.props.colSpan = record.children ? 8 : 1; return obj; }, }, { title: '别名', dataIndex: 'alias', key: 'alias', align: 'center', width: 300, onCell: () => ({ style: { maxWidth: 300, overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis', cursor: 'pointer', }, }), render: (text, record) => { const obj = { children: ( <Tooltip placement="topLeft" title={text}> <span style={{ color: styleConfig(record) }}>{text} </span> </Tooltip> ), props: {}, }; obj.props.colSpan = record.children ? 0 : 1; return obj; }, }, { title: '字段类型', dataIndex: 'storeType', key: 'storeType', align: 'center', width: 150, render: (text, record) => { const obj = { children: <span style={{ color: styleConfig(record) }}>{text} </span>, props: {}, }; obj.props.colSpan = record.children ? 0 : 1; return obj; }, }, { title: '形态', dataIndex: 'shape', key: 'shape', align: 'center', width: 150, render: (text, record) => { const obj = { children: <span style={{ color: styleConfig(record) }}>{text} </span>, props: {}, }; obj.props.colSpan = record.children ? 0 : 1; return obj; }, }, { title: '配置', dataIndex: 'config', key: 'config', align: 'center', width: 250, onCell: () => ({ style: { maxWidth: 250, overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis', cursor: 'pointer', }, }), render: (text, record) => { const obj = { children: ( <Tooltip placement="topLeft" title={text}> <span style={{ color: styleConfig(record) }}>{text} </span> </Tooltip> ), props: {}, }; obj.props.colSpan = record.children ? 0 : 1; return obj; }, }, { title: '只读', dataIndex: 'readOnly', key: 'readOnly', align: 'center', width: 100, render: (text, record) => { const obj = { children: ( <span style={{ color: styleConfig(record) }}> <Tag color={text === 1 ? 'success' : 'processing'}>{text === 1 ? '是' : '否'}</Tag> </span> ), props: {}, }; obj.props.colSpan = record.children ? 0 : 1; return obj; }, }, { title: '同步', dataIndex: 'syncEvent', key: 'syncEvent', align: 'center', width: 100, render: (text, record) => { const obj = { children: ( <span style={{ color: styleConfig(record) }}> <Tag color={text === '否' ? 'processing' : 'success'}> {text === '否' ? '否' : '是'} </Tag> </span> ), props: {}, }; obj.props.colSpan = record.children ? 0 : 1; return obj; }, }, { title: '操作', ellipsis: true, align: 'center', render: (text, record) => { const obj = { children: ( <Space> {record.children ? ( <span /> ) : ( <> {/* <Tooltip title="修改"> <EditOutlined style={{ fontSize: '16px', color: '#1890FF' }} onClick={() => { editor(record); }} > 编辑 </EditOutlined> </Tooltip> */} <div onClick={e => e.stopPropagation()}> <Popconfirm title="是否删除该字段?" okText="确认" cancelText="取消" onConfirm={() => { deleteChart(record); }} > <Tooltip title="删除"> <DeleteOutlined style={{ fontSize: '16px', color: '#e86060' }}> 删除 </DeleteOutlined> </Tooltip> </Popconfirm> </div> </> )} </Space> ), props: {}, }; obj.props.colSpan = record.children ? 0 : 1; return obj; }, }, ]; useEffect(() => { LoadLedgers().then(res => { if (res.code === 0) { let data = []; res.data.root.map(i => { data.push(i.name); }); setKeepStandingBook(res.data.root); } }); LayerSetting({ client: 'sandbox' }).then(res => { let dataArea = res.data.find(i => i.layerType == 'PipenetLayer'); console.log(res.data[0]); let ss = { layers: [dataArea], }; let depart = { OID: 1017, code: '1-1016-1017', name: '管理员' }; let userInfo = { OID: 1, fullName: '总经理', loginName: 'admin', depart }; window.globalConfig = { ...window.globalConfig, mapsettings: ss, userInfo, }; }); }, []); useEffect(() => { if (props.location.state.id) { setSelectTreeData(props.location.state.keepTreeSelect); setSelectDataFirst(props.location.state.keepTreeFirst); if (treeSelectValue) { let ss = treeSelectValue.substring(0, treeSelectValue.lastIndexOf('@')); setFormObj(treeSelectValue.substring(0, treeSelectValue.lastIndexOf('@'))); reloadTableFields({ tableName: treeSelectValue.substring(0, treeSelectValue.lastIndexOf('@')), }).then(res => { setTreeLoading(false); if (res.msg === 'Ok') { console.log(res.data.root); let arrlist = []; let data = {}; let listArr = []; res.data.root.map(i => { arrlist.push(i.name); }); console.log(arrlist); setKeepTree(arrlist); data.TableFieldNames = arrlist; data.TableName = treeSelectValue.substring(0, treeSelectValue.lastIndexOf('@')); listArr.push(data); setKeepTreeData(listArr); let arr = formateArrDataA(res.data.root, 'group'); let newArr = []; Object.keys(arr).map((item, index) => { newArr.push({ type: item, key: index, id: index }); }); setAllData(arr); let aa = []; let bb = []; let list = {}; let arrdata = []; let flowNodeMeta = {}; Object.keys(arr).forEach((item, index) => { console.log(arr[item]); arr[item].map(i => { i.fieldName = i.name; i.configInfo = i.config; i.presetValue = i.preset == '(无)' ? '' : i.preset; i.showCss = props.location.state.template.tableStyle; i.tableName = ss; i.uiGroup = item; i.readOnly = i.readOnly == '是' ? 1 : 0; i.type = '文本'; i.visible = 1; i.colSpan = i.rowSpan; }); aa.push({ name: item, key: index, ID: index, children: arr[item] }); arrdata.push({ groupName: item, schema: arr[item], visible: 1 }); bb.push(item); }); flowNodeMeta.groups = arrdata; list.flowNodeMeta = flowNodeMeta; list.showCss = props.location.state.template.tableStyle; console.log(list); let tablesSchema = { child: {}, groups: list.flowNodeMeta.groups, values: [], modules: [], relationForm: {}, }; setTablesSchema(tablesSchema); console.log(arr); console.log(newArr); setKeepTreeFirst(bb); setTreeData(aa); setSelectGroup(newArr); setTableData(newArr); setSelect(newArr); } }); } else { let ss = props.location.state.id; setFormObj(props.location.state.id); reloadTableFields({ tableName: props.location.state.id, }).then(res => { setTreeLoading(false); if (res.msg === 'Ok') { console.log(res.data.root); let result = {}; // result. let arrlist = []; let data = {}; let listArr = []; res.data.root.map(i => { arrlist.push(i.name); }); console.log(arrlist); setKeepTree(arrlist); data.TableFieldNames = arrlist; data.TableName = props.location.state.id; listArr.push(data); setKeepTreeData(listArr); let arr = formateArrDataA(res.data.root, 'group'); let newArr = []; Object.keys(arr).map((item, index) => { newArr.push({ type: item, key: index, id: index }); }); setAllData(arr); let aa = []; let bb = []; let list = {}; let arrdata = []; let flowNodeMeta = {}; Object.keys(arr).forEach((item, index) => { console.log(arr[item]); arr[item].map(i => { i.fieldName = i.name; i.configInfo = i.config; i.presetValue = i.preset == '(无)' ? '' : i.preset; i.showCss = props.location.state.template.tableStyle; i.tableName = ss; i.uiGroup = item; i.readOnly = i.readOnly == '是' ? 1 : 0; i.type = '文本'; i.visible = 1; i.colSpan = i.rowSpan; }); aa.push({ name: item, key: index, ID: index, children: arr[item] }); arrdata.push({ groupName: item, schema: arr[item], visible: 1 }); bb.push(item); }); flowNodeMeta.groups = arrdata; list.flowNodeMeta = flowNodeMeta; list.showCss = props.location.state.template.tableStyle; console.log(list); let tablesSchema = { child: {}, groups: list.flowNodeMeta.groups, values: [], modules: [], relationForm: {}, }; setTablesSchema(tablesSchema); console.log(aa, 'aaaaaaaaaaaaa'); console.log(arr); console.log(newArr); setSelectGroup(newArr); setKeepTreeFirst(bb); setTreeData(aa); setTableData(newArr); setSelect(newArr); } }); } setTreeLoading(true); getField(); } }, [flag]); const formateArrDataA = (initialArr, name) => { // 判定传参是否符合规则 if (!(initialArr instanceof Array)) { return '请传入正确格式的数组'; } if (!name) { return '请传入对象属性'; } // 先获取一下这个数组中有多少个"name" let nameArr = []; // eslint-disable-next-line no-restricted-syntax for (let i in initialArr) { if (nameArr.indexOf(initialArr[i][`${name}`]) === -1) { nameArr.push(initialArr[i][`${name}`]); } } // 新建一个包含多个list的结果对象 let tempObj = {}; // 根据不同的"name"生成多个数组 for (let k in nameArr) { for (let j in initialArr) { if (initialArr[j][`${name}`] == nameArr[k]) { // 每次外循环时新建一个对应"name"的数组, 内循环时当前数组不变 tempObj[nameArr[k]] = tempObj[nameArr[k]] || []; tempObj[nameArr[k]].push(initialArr[j]); } } } for (let keys in tempObj) { let arr = []; tempObj[keys].map((item, index) => { tempObj[keys] = arr; item.key = index; arr.push(item); }); } return tempObj; }; // 删除字段配置 const deleteChart = record => { removeFields({ fieldIDs: record.ID }).then(res => { if (res.msg === 'Ok' || res.msg === '') { notification.success({ message: '提示', duration: 3, description: '删除成功', }); setFlag(flag + 1); } else { notification.error({ message: '提示', duration: 3, description: res.msg, }); } }); }; // 批量删除字段配置 const multiDeleteChart = () => { console.log(selectedRowKeys.toString()); removeFields({ fieldIDs: selectedRowKeys.toString() }).then(res => { setDeleteUserVisible(false); if (res.msg === 'Ok' || res.msg === '') { setMultiOperate(true); notification.success({ message: '提示', duration: 3, description: '删除成功', }); setSelectedRowKeys([]); setFlag(flag + 1); } else { notification.error({ message: '提示', duration: 3, description: res.msg, }); } }); }; // 返回上一级 const back = () => { console.log(props.location.state); let { template, tableScroll, keepValue, pickIndex, groupArr, searchValue, select, } = props.location.state; console.log(keepValue); console.log(pickIndex, groupArr, 'back'); history.push({ pathname: '/biz/account/table', query: { template, tableScroll, backIndex: pickIndex, group: groupArr, keepValue, searchV: searchValue, selectValue: select, }, }); }; const onUnfold = (expanded, record) => { if (record.children) { const data = [...selectGroup]; // let index = selectGroup.find(i => i.type || i.name == record.name); if (expanded) { data.push(record); setSelectGroup(data); } else { let aa = []; data.map(i => { if (i.name && i.name != record.name) { aa.push(i); } else if (i.type && i.type != record.name) { aa.push(i); } }); setSelectGroup(aa); } } }; // 附加 const add = record => { if (treeSelectValue) { selectTreeData.map(i => { i.children.map(j => { if (j.tableName == treeSelectValue.substring(0, treeSelectValue.lastIndexOf('@'))) { setPramFormObj(j); } }); }); } else { setPramFormObj(props.location.state.template); } setType('affiliateAdd'); setVisible(true); }; // 分组与排序 const sort = record => { if (treeSelectValue) { selectTreeData.map(i => { i.children.map(j => { if (j.tableName == treeSelectValue.substring(0, treeSelectValue.lastIndexOf('@'))) { setPramFormObj(j); } }); }); } else { setPramFormObj(props.location.state.template); } setType('sort'); setVisible(true); }; const onSubmit = prop => { setVisible(false); setFlag(flag + 1); }; const treeSelectOnchange = e => { console.log(e); if (e) { setTreeLoading(true); console.log('切换'); setSelectedRowKeys([]); setMultiOperate(true); setTreeSelectValue(e); console.log(e.substring(0, e.lastIndexOf('@'))); let ss = e.substring(0, e.lastIndexOf('@')); setFormObj(e.substring(0, e.lastIndexOf('@'))); reloadTableFields({ tableName: e.substring(0, e.lastIndexOf('@')), }).then(res => { setTreeLoading(false); if (res.msg === 'Ok') { let arrlist = []; let data = {}; let listArr = []; res.data.root.map(i => { arrlist.push(i.name); }); console.log(arrlist); setKeepTree(arrlist); data.TableFieldNames = arrlist; data.TableName = e.substring(0, e.lastIndexOf('@')); listArr.push(data); setKeepTreeData(listArr); console.log(res.data.root); let arr = formateArrDataA(res.data.root, 'group'); let newArr = []; Object.keys(arr).map((item, index) => { newArr.push({ type: item, key: index, id: index }); }); setAllData(arr); setSelectGroup(newArr); setTableData(newArr); let aa = []; let bb = []; let list = {}; let arrdata = []; let flowNodeMeta = {}; Object.keys(arr).forEach((item, index) => { arr[item].map(i => { i.fieldName = i.name; i.configInfo = i.config; i.presetValue = i.preset == '(无)' ? '' : i.preset; i.showCss = props.location.state.template.tableStyle; i.tableName = ss; i.uiGroup = item; i.readOnly = i.readOnly == '是' ? 1 : 0; i.type = '文本'; i.visible = 1; i.colSpan = i.rowSpan; }); aa.push({ name: item, key: index, ID: index, children: arr[item] }); arrdata.push({ groupName: item, schema: arr[item], visible: 1 }); bb.push(item); }); flowNodeMeta.groups = arrdata; list.flowNodeMeta = flowNodeMeta; list.showCss = props.location.state.template.tableStyle; console.log(list); let tablesSchema = { child: {}, groups: list.flowNodeMeta.groups, values: [], modules: [], relationForm: {}, }; setTablesSchema(tablesSchema); setKeepTreeFirst(bb); setTreeData(aa); setSelect(newArr); } }); } else { setTreeSelectValue(''); } }; const mapTree = org => { const haveChildren = Array.isArray(org.children) && org.children.length > 0; return haveChildren ? ( <TreeNode value={org.name} title={org.name} disabled> {org.children.map(item => mapTree(item))} </TreeNode> ) : ( <TreeNode value={`${org.tableName}@${org.groupName}`} title={org.tableName} key={`${org.tableName}@${org.groupName}`} /> ); }; // 复选框 const rowSelection = { selectedRowKeys, onChange: (selectedRowKeys, selectedRows) => { let aa = []; selectedRowKeys.map(i => { if (typeof i !== 'number') { aa.push(i); } }); setSelectedRowKeys(aa); if (selectedRows.length > 0) { setMultiOperate(false); } else { setMultiOperate(true); } }, }; const multiDelete = () => { setDeleteUserVisible(true); }; const preview = () => { setPerViewPrase(true); }; return ( <> <Spin tip="loading..." spinning={treeLoading}> <div className={styles.containerBox}> <div className={styles.config}> <div className={styles.title}> 字段配置 【{formObj}】</div> <div style={{ display: 'flex', justifyContent: 'flex-end' }}> <div style={{ lineHeight: '32px', marginRight: '5px' }}>快速切换表:</div> <div style={{ width: '350px', marginRight: '10px' }}> <TreeSelect showSearch style={{ width: '100%' }} value={treeSelectValue} dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} placeholder="请选择表名 " allowClear treeDefaultExpandAll showCheckedStrategy onChange={treeSelectOnchange} > {selectTreeData ? ( selectTreeData.map(i => mapTree(i)) ) : ( <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> )} </TreeSelect> </div> <div style={{ marginRight: '10px' }}> <Button type="primary" disabled={multiOperate} onClick={multiDelete}> <DeleteOutlined /> 批量删除 </Button> </div> <div className={styles.btn}> <Button type="primary" icon={<EyeOutlined />} onClick={preview}> 预览 </Button> <Button type="primary" icon={<PlusSquareOutlined />} onClick={add}> 附加 </Button> <Button type="primary" icon={<SortDescendingOutlined />} onClick={sort}> 分组排序 </Button> <Button type="primary" icon={<RollbackOutlined />} onClick={back}> 返回 </Button> </div> </div> </div> {/* <Table rowSelection={{ ...rowSelection }} columns={columns} dataSource={treeData} // // expandable={{ expandedRowRender }} size="small" rowKey={record => record.ID} // defaultExpandAllRows={true} // expandedRowKeys={chooseLine} // 展开的行 // defaultExpandedRowKeys={select.map(item => item.key)} // 展开的行 // expandedRowKeys={select.map(item => item.key)} // 展开的行 // // defaultExpandedRowKeys={0} expandRowByClick pagination={false} scroll={{ y: 'calc(100vh - 186px)' }} // onExpand={onUnfold} /> */} <Table columns={columns} size="small" rowKey={record => record.ID} rowSelection={{ ...rowSelection, checkStrictly, selectedRowKeys }} dataSource={treeData} pagination={false} bordered expandedRowKeys={selectGroup.map(item => item.key)} expandRowByClick scroll={{ y: 'calc(100% - 70px)' }} onRow={record => ({ onDoubleClick: event => { event.stopPropagation(); editor(record); }, onClick: event => { event.stopPropagation(); setSelectTableName(record); }, // 点击行 })} rowClassName={setRowClassName} onExpand={onUnfold} /> </div> </Spin> {/* 多选删除用户 */} <Modal title="确认删除字段" visible={deleteUserVisible} onOk={multiDeleteChart} onCancel={() => { setDeleteUserVisible(false); }} okText="确认" cancelText="取消" > <p>将删除多个配置字段, 是否确认删除?</p> </Modal> <FieldEditor isVisible={isVisible} keepTree={keepTree} keepTreeData={keepTreeData} isType={isType} itemData={itemData} formObj1={formObj} onCancel={() => setIsVisible(false)} treeData={treeData} keepTreeFirst={keepTreeFirst} callBackSubmit={Submit} keepStandingBook={keepStandingBook} /> {visible && type === 'affiliateAdd' && ( <AffiliateAdd visible={visible} tableList={tableList} type={type} onCancel={() => setVisible(false)} callBackSubmit={onSubmit} formObj={pramFormObj} /> )} {visible && type === 'sort' && ( <LoadGroup visible={visible} type={type} formObj={pramFormObj} onCancel={() => setVisible(false)} callBackSubmit={onSubmit} /> )} <PerviewPrase visible={perviewPrase} tablesSchema={tablesSchema} onCancel={() => setPerViewPrase(false)} /> </> ); }; export default AddModal;