/* eslint-disable operator-assignment */ /* eslint-disable no-undef */ /* eslint-disable no-lonely-if */ /* eslint-disable prefer-template */ /* eslint-disable no-shadow */ /* * @Description: * @Author: leizhe * @Date: 2022-04-06 11:38:46 * @LastEditTime: 2022-08-18 16:40:36 * @LastEditors: dengchao 754083046@qq.com */ import React, { useState, useEffect } from 'react'; import { Button, Descriptions, Input, Card, Spin, Divider, Tabs, Table, Space, Tooltip, Modal, Image, Form, notification, message, Pagination, Dropdown, Menu, } from 'antd'; import { typeList, modelManageList, deleteByModel, DelModelType, DownLoadModelType, GetBasicInfo, DownLoadModelTypeSingle, Export, } from '@/services/drawBoardManage/api'; import { FormOutlined, DeleteOutlined, PlusOutlined, DownloadOutlined, UploadOutlined, SyncOutlined, PlusSquareFilled, ShareAltOutlined, DownOutlined, } from '@ant-design/icons'; import classnames from 'classnames'; import zhCN from 'antd/es/locale/zh_CN'; import styles from './DrawBoardManage.less'; import AddModal from './AddModal'; import EditModal from './EditModal'; import AddTemplate from './AddTemplate'; import ChildAddTemplate from './ChildAddTemplate'; import EditTemplate from './EditTemplate'; import ImportModal from './ImportModal'; import AssociationModel from './AssociationModel'; const { TabPane } = Tabs; const DrawBoardManage = () => { const [searchWord, setSearchWord] = useState(''); // 关键字 const [tableLoading, setTableLoading] = useState(false); const [treeLoading, setTreeLoading] = useState(false); const [tableData, setTableData] = useState([]); const [selectColor, setSelectColor] = useState({}); // 当前选中颜色,操作时设置 const [treeData, setTreeData] = useState([]); const [pickItem, setPickItem] = useState(''); const [rember1, setRember1] = useState(); const [hoverItemIndex, setHoverItemIndex] = useState(0); // hover流程索引 const [addModalVisible, setAddModalVisible] = useState(false); const [editModalVisible, setEditModalVisible] = useState(false); const [deleteModalVisible, setDeleteModalVisible] = useState(false); const [selectGroup, setSelectGroup] = useState([]); const [addTemplateVisible, setAddTemplateVisible] = useState(false); const [childAddTemplateVisible, setChildAddTemplateVisible] = useState(false); const [checkStrictly, setCheckStrictly] = useState(false); const [showSearchStyle, setShowSearchStyle] = useState(false); // 是否显示模糊查询样式 const [selectedRowKeys, setSelectedRowKeys] = useState([]); // 已选字段配置数,机构改变时重置 const [deleteVisible, setDeleteVisible] = useState(false); const [editVisible, setEditVisible] = useState(false); const [associationVisible, setAssociationVisible] = useState(false); const [multDeleteVisible, setMultDeleteVisible] = useState(false); const [changeObj, setChangeObj] = useState(''); const [obj, setObj] = useState(''); const [importVisible, setImportVisible] = useState(false); const { Search } = Input; const [keepId, setKeepId] = useState(''); const [totalData, setTotal] = useState(''); const [page, setPage] = useState(1); const [multiOperate, setMultiOperate] = useState(true); // 是否禁用用户批量操作 const [multiOperateButtonType, setMultiOperateButtonType] = useState(''); // 更改批量操作按钮样式 const [keepRow, setKeepRow] = useState([]); const setRowClassName = record => (record.ID === selectColor.ID ? styles.clickRowStyle : ''); useEffect(() => { setMultiOperate(true); if (pickItem) { updateTableData(pickItem.name, searchWord); } setPage(1); }, [pickItem]); useEffect(() => { updateTrees(); GetBasicInfo().then(res => { setKeepId(res.data); }); }, []); // 获取Tree数据 const updateTrees = e => { setTreeLoading(true); typeList().then(res => { setTreeLoading(false); if (res.code === 0) { if (e) { let aa = res.data.find(i => i.name === e); setPickItem(aa); updateTableData(e, searchWord); } else { console.log(pickItem); if (!pickItem) { updateTableData('', searchWord); } else { updateTableData(pickItem.name, searchWord); } } setTreeData(res.data); } }); }; const addBack = props => { console.log(props); updateTrees(props); }; const editBack = props => { console.log(props); updateTrees(props); }; // 获取表格数据 const updateTableData = (e, searchWord) => { setTableLoading(true); setSelectedRowKeys([]); modelManageList({ modelName: searchWord, modelType: e, }).then(res => { setTableLoading(false); if (res.code === 0) { if (searchWord != '') { setShowSearchStyle(true); } else { setShowSearchStyle(false); } if (res.data.length > 0) { if (!pickItem) { let aa = res.data; // res.data.map(i => { // i.list.map(j => { // aa.push(j); // }); // }); // 一级数据 let bb = aa; let len = bb.length; if (bb.length > 0) { bb.map(i => { if (i.children.length > 0) { len = len + i.children.length; i.children.map(j => { delete j.children; }); } else { delete i.children; } }); } setTotal(len); setTableData(bb); setSelectGroup(bb); } else { let aa = res.data; let len = aa.length; if (aa.length > 0) { aa.map(i => { if (i.children.length > 0) { len = len + i.children.length; i.children.map(j => { delete j.children; }); } else { delete i.children; } }); } setTotal(len); setTableData(aa); setSelectGroup(aa); } } else { setTotal(0); setTableData([]); } } }); }; // 获取表格数据 const updateTableDataAll = (e, searchWord) => { setTableLoading(true); setSelectedRowKeys([]); modelManageList({ modelName: searchWord, modelType: e, }).then(res => { setTableLoading(false); if (res.code === 0) { if (searchWord != '') { setShowSearchStyle(true); } else { setShowSearchStyle(false); } if (res.data.length > 0) { let aa = res.data; // res.getMe.map(i => { // i.list.map(j => { // aa.push(j); // }); // }); let bb = aa; let len = bb.length; if (bb.length > 0) { bb.map(i => { if (i.children.length > 0) { len = len + i.children.length; i.children.map(j => { delete j.children; }); } else { delete i.children; } }); } setTotal(len); setTableData(bb); setSelectGroup(bb); } else { setTotal(0); setTableData([]); } } }); }; const columns = [ { title: '模型类型', align: 'center', dataIndex: 'ModelTypeName', key: 'ModelTypeName', render: (text, record) => { // console.log(record); if (record.children) { // console.log(record.children.length); } const obj = { children: <>{record.RelModel == 0 ? <span size="middle">{text}</span> : <span />}</>, props: {}, }; obj.props.colSpan = 1; return obj; }, }, { title: '模型名称', align: 'center', dataIndex: 'ModelName', key: 'ModelName', render: (text, record) => { const obj = { children: <span>{searchStyle(text)} </span>, props: {}, }; obj.props.colSpan = 1; return obj; }, }, { title: '图像', align: 'center', dataIndex: 'Path', key: 'Path', render: (text, record) => { let time = new Date(); let timestamp = Date.parse(time); const obj = { children: ( <Image src={ window.location.origin + `/PandaConfiguration/Raw/File/ModelManage/ModelFilePreview/${encodeURIComponent(text)}? ${timestamp}` } height="50px" /> ), props: {}, }; obj.props.colSpan = 1; return obj; }, }, // { // title: '模型属性', // align: 'center', // width: 200, // dataIndex: 'property', // key: 'property', // render: (text, record) => { // const obj = { // children: <span>{text} </span>, // props: {}, // }; // obj.props.colSpan = 1; // return obj; // }, // }, // { // title: '设计者', // align: 'center', // dataIndex: 'people', // width: 80, // key: 'people', // render: (text, record) => { // const obj = { // children: <span>{text} </span>, // props: {}, // }; // obj.props.colSpan = 1; // return obj; // }, // }, { title: '创建日期', align: 'center', width: 150, dataIndex: 'createTime', key: 'createTime', render: (text, record) => { const obj = { children: <span>{text} </span>, props: {}, }; obj.props.colSpan = 1; return obj; }, }, { title: '操作', align: 'center', width: 150, key: 'action', render: record => { // console.log(record); let aa = ( <Space size="middle"> <Tooltip title="编辑"> <FormOutlined onClick={() => onedit(record)} style={{ fontSize: '16px', color: '#1890FF' }} /> </Tooltip> <Tooltip title="导出"> <DownloadOutlined onClick={() => ExportSingle(record)} style={{ fontSize: '16px', color: '#1890FF' }} /> </Tooltip> {record.children ? ( <Space size="middle"> <Tooltip title="关联父模型"> <ShareAltOutlined onClick={() => { message.warning('该模型存在子模型不能关联父模型'); }} style={{ fontSize: '16px', color: 'rgb(199 194 194)' }} /> </Tooltip> </Space> ) : ( <Space size="middle"> <Tooltip title="关联父模型"> <ShareAltOutlined onClick={() => associationModel(record)} style={{ fontSize: '16px', color: '#1890FF' }} /> </Tooltip> </Space> )} <Tooltip title="删除"> <DeleteOutlined onClick={() => ondelete(record)} style={{ fontSize: '16px', color: '#e86060' }} /> </Tooltip> </Space> ); const obj = { children: aa, props: {}, }; obj.props.colSpan = record.RelModel == 0 ? 1 : 1; return obj; }, }, { title: '添加子模型', align: 'center', dataIndex: 'stateModel', width: 100, key: 'stateModel', render: (text, record) => { const obj = { children: ( <> {record.RelModel == 0 ? ( <Space size="middle"> <Tooltip title="新增"> <PlusOutlined onClick={() => onadd(record)} style={{ fontSize: '16px', color: '#1890FF' }} /> </Tooltip> </Space> ) : ( <Space size="middle" /> )} </> ), props: {}, }; obj.props.colSpan = record.RelModel == 0 ? 1 : 1; return obj; }, }, ]; const onadd = e => { setObj(e); setChildAddTemplateVisible(true); }; const onedit = e => { setObj(e); setEditVisible(true); }; const associationModel = e => { setObj(e); setAssociationVisible(true); }; const onexport = e => { console.log(e); setObj(e); let a = document.createElement('a'); a.href = `${e.imgUrl}${encodeURIComponent(e.modelPath)}?_site=null`; console.log(a); let sufStr = e.modelPath.split('.').pop(); a.download = `${e.name}.${sufStr}`; a.click(); a.remove(); }; const ondelete = e => { setObj(e); setDeleteVisible(true); }; const submitSearchUser = () => { updateTableData(pickItem.name, searchWord); }; const handleSearch = e => { setSearchWord(e.target.value); // updateTableData(pickItem.name, e.target.value); }; const addModal = () => { setAddModalVisible(true); }; const rowSelection = { selectedRowKeys, onChange: (selectedRow, selectedRows) => { if (selectedRow.length < selectedRowKeys.length) { let aa; // 找到取消勾选一级模形id selectedRowKeys.map(i => { if (selectedRow.indexOf(i) == -1) { aa = i; } }); // 从已选数组中删除取消勾选一级模型的二级模型id keepRow.map(j => { if (j.ID == aa) { // 判断是否存在二级模型 if (j.children) { j.children.map(ii => { selectedRow.splice(selectedRow.findIndex(item => item.ID === ii.ID), 1); }); } } }); setSelectedRowKeys(selectedRow); } else { let aa = selectedRow; // 找到勾选一级模型的二级模型id存入已勾选列表 selectedRows.map(i => { // 判断是否存在二级模型 if (i.children) { i.children.map(i => { aa.push(i.ID); }); } }); setSelectedRowKeys(Array.from(new Set(aa))); } setKeepRow(selectedRows); // 控制批量操作模型按钮样式 if (selectedRow.length > 0) { setSelectColor({}); setMultiOperate(false); setMultiOperateButtonType('primary'); } else { setMultiOperate(true); setMultiOperateButtonType('default'); } }, renderCell: (checked, record, index, originNode) => { if (record.RelModel != 0) { return null; } return originNode; }, }; const onUnfold = (expanded, record) => { if (record.children) { const data = [...selectGroup]; let index = data.indexOf(record); // let index = selectGroup.find(i => i.type || i.name == record.name); if (expanded) { data.push(record); setSelectGroup(data); } else { data.splice(index, 1); setSelectGroup(data); } } }; // 模糊查询匹配的样式 const searchStyle = val => { let n; if (showSearchStyle) { n = val.replace(new RegExp(searchWord, 'g'), `<span style='color:red'>${searchWord}</span>`); } else { n = val; } return <div dangerouslySetInnerHTML={{ __html: n }} />; }; const addTemplate = () => { setAddTemplateVisible(true); }; const deleteModalData = () => { console.log(changeObj); DelModelType({ id: changeObj.ID, modelTypeName: changeObj.name }).then(res => { if (res.code === 0) { setDeleteModalVisible(false); notification.success({ message: '删除成功', duration: 2, }); if (pickItem.name == changeObj.name) { setPickItem(''); setChangeObj(''); setTreeLoading(true); typeList().then(res => { setTreeLoading(false); if (res.code === 0) { updateTableDataAll('', searchWord); setTreeData(res.data); } }); } else { updateTrees(); } } else { notification.error({ message: '删除失败', description: res.msg, }); } }); }; const deleteData = () => { setTableLoading(true); deleteByModel({ ids: obj.ID }).then(res => { setTableLoading(false); if (res.code === 0) { setDeleteVisible(false); notification.success({ message: '删除成功', duration: 2, }); updateTableData(pickItem.name, searchWord); } else { notification.error({ message: '删除失败', description: res.msg, }); } }); }; const multDeleteData = () => { setMultDeleteVisible(true); }; const multDelete = () => { setTableLoading(true); deleteByModel({ ids: selectedRowKeys.toString() }).then(res => { setTableLoading(false); if (res.code === 0) { setMultDeleteVisible(false); notification.success({ message: '删除成功', duration: 2, }); updateTableData(pickItem.name, searchWord); } else { notification.error({ message: '删除失败', description: res.msg, }); } }); }; const onAddTemplateSubmit = () => { setAddTemplateVisible(false); updateTableData(pickItem.name, searchWord); }; const onChildAddTemplateSubmit = () => { setChildAddTemplateVisible(false); updateTableData(pickItem.name, searchWord); }; const onEditTemplateSubmit = () => { setEditVisible(false); updateTableData(pickItem.name, searchWord); }; const onImportSubmit = () => { setPickItem(''); setImportVisible(false); setTreeLoading(true); typeList().then(res => { if (res.code === 0) { setTreeLoading(false); updateTableData('', searchWord); setTreeData(res.data); } }); // updateTableData(pickItem.name, searchWord); }; const onAssociationSubmit = () => { updateTableData(pickItem.name, searchWord); }; const oneditlist = (e, item) => { e.stopPropagation(); setChangeObj(item); setEditModalVisible(true); }; const ondeletelist = (e, item) => { e.stopPropagation(); setChangeObj(item); setDeleteModalVisible(true); }; const importFile = () => { setImportVisible(true); }; const ExportData = () => { if (selectedRowKeys.length == 0) { message.warning('请先选择导出的数据'); } else { window.location.href = DownLoadModelType({ modelList: selectedRowKeys.toString() }); // window.location.href = Export({ Ids: selectedRowKeys.toString() }); } }; const ExportDataAll = () => { window.location.href = DownLoadModelType({ modelList: 'all' }); // window.location.href = Export({ Ids: selectedRowKeys.toString() }); }; const ExportSingle = e => { console.log(e); window.location.href = DownLoadModelTypeSingle({ modeId: e.ID }); }; const choose = () => { setPickItem(''); setSearchWord(''); updateTableDataAll('', ''); }; // 用户批量操作 const userButtonMenu = ( <Menu> {/* <Menu.Item key="1" onClick={importFile} icon={<UploadOutlined />}> 批量导入模型 </Menu.Item> */} <Menu.Item key="1" onClick={ExportData} icon={<DownloadOutlined />}> 批量导出模型 </Menu.Item> <Menu.Item key="2" onClick={multDeleteData} icon={<DeleteOutlined />}> 批量删除模型 </Menu.Item> </Menu> ); return ( <div className={styles.base_container}> <Card style={{ width: '100%', height: 'calc(100vh - 130px)' }}> <div style={{ display: 'flex', justifyContent: 'space-around', width: '100%' }}> {/* 左侧类型树 */} <div style={{ minWidth: '250px' }}> <Spin spinning={treeLoading} tip="loading..."> <div style={{ display: 'flex', justifyContent: 'space-between', alignContent: 'center' }} > <span style={{ fontSize: '15px ', fontWeight: 'bold', }} > 模型类型 </span> <Tooltip title="添加模型类型"> <PlusSquareFilled onClick={() => addModal()} style={{ color: '#1890FF', fontSize: '25px', marginTop: '3px', }} /> </Tooltip> </div> <hr style={{ width: '100%', color: '#eeecec' }} /> <div style={{ height: 'calc(100vh - 250px)', overflowY: 'scroll', }} > <div onClick={choose} className={classnames({ [styles.allItem]: true, [styles.pickItem]: pickItem === '', })} > <span style={{ marginLeft: '14px', lineHeight: '36px' }}>全部类型</span> </div> {treeData.length > 0 && treeData.map((item, index) => ( <div className={classnames({ [styles.listItem]: true, [styles.pickItem]: item.ID === pickItem.ID, [styles.listHover]: item !== pickItem && item === hoverItemIndex, })} onClick={e => { setPickItem(item); setRember1(item); setSearchWord(''); }} onMouseEnter={() => { setHoverItemIndex(item); }} onMouseLeave={() => { setHoverItemIndex(''); }} key={item.ID} > <div className={styles.title}> <span>{item.name}</span> <span className={styles.tip}> <span> <FormOutlined onClick={e => oneditlist(e, item)} style={{ color: '#1890FF', fontSize: '16px' }} /> </span> <span style={{ marginLeft: '10px' }}> <DeleteOutlined onClick={e => ondeletelist(e, item)} style={{ color: '#e86060', fontSize: '16px' }} /> </span> </span> </div> </div> ))} </div> </Spin> </div> {/* 右侧表格 */} <div style={{ marginLeft: '20px', marginTop: '-10px', overflow: 'scroll' }}> <div style={{ height: '41px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', }} > <div> <span style={{ width: '200px', display: 'inline-block' }}> {pickItem ? pickItem.name : '全部类型'}(已选{selectedRowKeys.length}条) </span> <span style={{ lineHeight: '32px' }}>模型检索:</span> <Search style={{ width: 260 }} placeholder="请输入关键词" onChange={e => handleSearch(e)} onSearch={submitSearchUser} enterButton value={searchWord} /> </div> <div> <Button type="primary" icon={<PlusOutlined />} onClick={addTemplate} style={{ marginRight: '20px' }} > 新增 </Button> <Button type="primary" icon={<UploadOutlined />} onClick={importFile} style={{ marginRight: '20px' }} > 导入 </Button> <Button type="primary" icon={<DownloadOutlined />} onClick={ExportDataAll} style={{ marginRight: '20px' }} > 导出全部 </Button> {/* <Button type="primary" icon={<DeleteOutlined />} onClick={multDeleteData} style={{ marginLeft: '20px' }} > 删除 </Button> */} <Dropdown overlay={userButtonMenu} disabled={multiOperate} style={{ marginRight: '20px' }} > <Button type={multiOperateButtonType}> 模型批量操作 <DownOutlined /> </Button> </Dropdown> </div> </div> <Table rowSelection={{ ...rowSelection, selectedRowKeys }} rowClassName={setRowClassName} size="small" expandIconAsCell={false} expandIconColumnIndex={-1} rowKey={record => record.ID} locale={zhCN} bordered expandedRowKeys={selectGroup.map(item => item.ID)} // expandRowByClick columns={columns} dataSource={tableData} loading={tableLoading} style={{ minWidth: '100%' }} scroll={{ y: 'calc(100vh - 262px)', x: '800px' }} onExpand={onUnfold} onRow={record => ({ onDoubleClick: event => { event.stopPropagation(); onedit(record); }, // 双击 onClick: e => { setSelectColor(record); }, })} pagination={{ showTotal: (total, range) => { // console.log(range); return `共 ${totalData} 条`; }, pageSizeOptions: [10, 20, 50, 100], defaultPageSize: 10, showQuickJumper: true, showSizeChanger: true, current: page, onChange: (page, pageSize) => { setPage(page); }, }} /> </div> </div> </Card> {/* 新增模板类型 */} <AddModal visible={addModalVisible} onCancel={() => setAddModalVisible(false)} callBackSubmit={addBack} /> <EditModal visible={editModalVisible} onCancel={() => setEditModalVisible(false)} changeObj={changeObj} callBackSubmit={editBack} /> <AddTemplate visible={addTemplateVisible} onClose={() => setAddTemplateVisible(false)} treeData={treeData} placement="right" pickItem={pickItem} callBackSubmit={onAddTemplateSubmit} /> <ChildAddTemplate visible={childAddTemplateVisible} onClose={() => setChildAddTemplateVisible(false)} treeData={treeData} placement="right" pickItem={pickItem} obj={obj} callBackSubmit={onChildAddTemplateSubmit} /> <EditTemplate visible={editVisible} onClose={() => setEditVisible(false)} treeData={treeData} placement="right" pickItem={pickItem} obj={obj} callBackSubmit={onEditTemplateSubmit} /> <Modal visible={deleteModalVisible} onCancel={() => setDeleteModalVisible(false)} title="删除模型类型" okText="确认" cancelText="取消" onOk={deleteModalData} > <span> 是否删除<span style={{ color: 'red' }}>{changeObj.name}</span> </span> </Modal> <Modal visible={deleteVisible} onCancel={() => setDeleteVisible(false)} title="删除" okText="确认" cancelText="取消" onOk={deleteData} > <span>是否删除该模型</span> </Modal> <Modal visible={multDeleteVisible} onCancel={() => setMultDeleteVisible(false)} title="批量删除" okText="确认" cancelText="取消" onOk={multDelete} > <span>是否批量删除所选模型</span> </Modal> <ImportModal visible={importVisible} onCancel={() => setImportVisible(false)} callBackSubmit={onImportSubmit} /> <AssociationModel visible={associationVisible} obj={obj} onCancel={() => setAssociationVisible(false)} callBackSubmit={onAssociationSubmit} /> </div> ); }; export default DrawBoardManage;