577 lines
21 KiB
JavaScript
577 lines
21 KiB
JavaScript
|
|
// 核心库
|
|||
|
|
import React, { Component } from 'react'
|
|||
|
|
import { connect } from 'dva'
|
|||
|
|
// 组件库
|
|||
|
|
import { Tree, Icon, Tabs, Input, message } from 'antd'
|
|||
|
|
import { Scrollbars } from 'react-custom-scrollbars'
|
|||
|
|
import { PictureThumb } from '@woowalker/feui'
|
|||
|
|
import ListPage from '../../components/Table/ListPage'
|
|||
|
|
import Edit from '../../components/Edit/Edit'
|
|||
|
|
import CombinationPage from '../../components/Combination/CombinationPage'
|
|||
|
|
import FormPage from '../../components/FormPage'
|
|||
|
|
// 工具库
|
|||
|
|
import { cloneDeep, isEqual } from 'lodash'
|
|||
|
|
import { getDataFieldValue, permissionUtils, getCustomParams, flatTreeData } from '../../utils/common'
|
|||
|
|
// 样式
|
|||
|
|
import classNames from 'classnames'
|
|||
|
|
import styles from '../Component.css'
|
|||
|
|
import customTabStyles from '../../components/Combination/combinationPage.css'
|
|||
|
|
|
|||
|
|
class VPage extends Component {
|
|||
|
|
constructor (props) {
|
|||
|
|
super(props)
|
|||
|
|
this.state = {
|
|||
|
|
activeKey: '',
|
|||
|
|
// 是否多选
|
|||
|
|
multiCheck: props.treeConfig.multiCheck,
|
|||
|
|
multiCheckCount: props.treeConfig.multiCheckCount,
|
|||
|
|
// 多选选中的节点
|
|||
|
|
selectedKeys: this.getDefaultSelectedKeys(props),
|
|||
|
|
// 拍平后的树数据
|
|||
|
|
flatedTreeData: [],
|
|||
|
|
searchTreeData: [],
|
|||
|
|
// 是否收起左侧树
|
|||
|
|
collapse: false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
componentDidMount () {
|
|||
|
|
const { treeData } = this.props
|
|||
|
|
this.checkFlatTreeData(treeData)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UNSAFE_componentWillReceiveProps (nextProps) {
|
|||
|
|
if (!isEqual(nextProps.treeData, this.props.treeData)) {
|
|||
|
|
this.checkFlatTreeData(nextProps.treeData)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getThumbData = () => {
|
|||
|
|
const { treePicFilter } = this.props
|
|||
|
|
|
|||
|
|
const thumbCodes = []
|
|||
|
|
const thumbConfigs = []
|
|||
|
|
if (Array.isArray(treePicFilter) && treePicFilter.length) {
|
|||
|
|
treePicFilter.forEach(({ Nav_PicFilterDetail = [], Nav_Picture }) => {
|
|||
|
|
thumbCodes.push(Nav_Picture.CODE)
|
|||
|
|
thumbConfigs.push({
|
|||
|
|
target: Nav_Picture.CODE,
|
|||
|
|
rules: Nav_PicFilterDetail.map(npd => ({
|
|||
|
|
field: npd.FIELD_TYPE === 1 ? `Node.${npd.NAME}` : npd.NAME,
|
|||
|
|
operate: Number(npd.OPERATE),
|
|||
|
|
value: typeof npd.VALUE === 'string' ? npd.VALUE.toLowerCase() : npd.VALUE
|
|||
|
|
}))
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
return { thumbCodes, thumbConfigs }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getDefaultSelectedKeys = (props) => {
|
|||
|
|
const { multiCheck, multiCheckCount } = props.treeConfig
|
|||
|
|
const defaultSelectedKeys = []
|
|||
|
|
if (props.treeData && Array.isArray(props.treeData)) {
|
|||
|
|
props.treeData.forEach(({ node = { id: '' } }) => {
|
|||
|
|
node.id && defaultSelectedKeys.push(node.id)
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
return multiCheck ? (multiCheckCount ? defaultSelectedKeys.slice(0, multiCheckCount) : defaultSelectedKeys) : [defaultSelectedKeys[0]]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getDefaultExpandedKeys = () => {
|
|||
|
|
const { treeData, treeConfig } = this.props
|
|||
|
|
const { expandLevel } = treeConfig
|
|||
|
|
if (expandLevel) {
|
|||
|
|
const keys = []
|
|||
|
|
function checkTreeDataLevel (data) {
|
|||
|
|
data.forEach(item => {
|
|||
|
|
if (item.level < expandLevel) {
|
|||
|
|
keys.push(item.node.id)
|
|||
|
|
if (Array.isArray(item.children) && item.children.length) {
|
|||
|
|
checkTreeDataLevel(item.children)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
checkTreeDataLevel(treeData)
|
|||
|
|
return keys
|
|||
|
|
}
|
|||
|
|
return []
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkShowBtn = (btn, nodeData) => {
|
|||
|
|
let isShow = !btn.btn_condition
|
|||
|
|
if (btn.btn_condition) {
|
|||
|
|
// 菜单参数
|
|||
|
|
const { currActivatedMenu } = this.props.app || {}
|
|||
|
|
const menuFormParameter = currActivatedMenu?.MENU_FORM_PARAMS
|
|||
|
|
// 按钮配置条件
|
|||
|
|
const conditionsOr = btn.btn_condition.split('|')
|
|||
|
|
const conditionsAnd = btn.btn_condition.split('&')
|
|||
|
|
if (conditionsOr.length === 1 && conditionsAnd.length === 1) {
|
|||
|
|
// 只配置了一个条件
|
|||
|
|
const fields = btn.btn_condition.split(',')
|
|||
|
|
const val = getDataFieldValue(nodeData, fields[0].toLowerCase())
|
|||
|
|
// 条件直接命中菜单参数,则直接显示
|
|||
|
|
if (btn.btn_condition === menuFormParameter) {
|
|||
|
|
isShow = true
|
|||
|
|
}
|
|||
|
|
// 1 等于
|
|||
|
|
else if (parseInt(fields[1], 10) === 1) {
|
|||
|
|
if (String(val) === String(fields[2].toLowerCase())) {
|
|||
|
|
isShow = true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 2 不等于
|
|||
|
|
else if (parseInt(fields[1], 10) === 2) {
|
|||
|
|
if (String(val) !== String(fields[2].toLowerCase())) {
|
|||
|
|
isShow = true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else if (conditionsOr.length > 1) {
|
|||
|
|
// 或条件
|
|||
|
|
for (let conditionOr of conditionsOr) {
|
|||
|
|
const fields = conditionOr.split(',')
|
|||
|
|
const val = getDataFieldValue(nodeData, fields[0].toLowerCase())
|
|||
|
|
// 条件直接命中菜单参数,则直接显示
|
|||
|
|
if (conditionOr === menuFormParameter) {
|
|||
|
|
isShow = true
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
// 1 等于
|
|||
|
|
else if (parseInt(fields[1], 10) === 1) {
|
|||
|
|
if (String(val) === String(fields[2].toLowerCase())) {
|
|||
|
|
isShow = true
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 2 不等于
|
|||
|
|
else if (parseInt(fields[1], 10) === 2) {
|
|||
|
|
if (String(val) !== String(fields[2].toLowerCase())) {
|
|||
|
|
isShow = true
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else if (conditionsAnd.length > 1) {
|
|||
|
|
// 与条件
|
|||
|
|
const showResults = []
|
|||
|
|
for (let conditionAnd of conditionsAnd) {
|
|||
|
|
const fields = conditionAnd.split(',')
|
|||
|
|
const val = getDataFieldValue(nodeData, fields[0].toLowerCase())
|
|||
|
|
// 条件直接命中菜单参数,则直接显示
|
|||
|
|
if (conditionAnd === menuFormParameter) {
|
|||
|
|
showResults.push(true)
|
|||
|
|
}
|
|||
|
|
// 1 等于
|
|||
|
|
else if (parseInt(fields[1], 10) === 1) {
|
|||
|
|
if (String(val) === String(fields[2].toLowerCase())) {
|
|||
|
|
showResults.push(true)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 2 不等于
|
|||
|
|
else if (parseInt(fields[1], 10) === 2) {
|
|||
|
|
if (String(val) !== String(fields[2].toLowerCase())) {
|
|||
|
|
showResults.push(true)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
isShow = showResults.length === conditionsAnd.length
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return isShow
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkMultiShowBtn = (btn) => {
|
|||
|
|
const { currActivatedMenu } = this.props.app || {}
|
|||
|
|
const menuFormParameter = currActivatedMenu?.MENU_FORM_PARAMS
|
|||
|
|
|
|||
|
|
let isShow = !btn.btn_condition || !menuFormParameter
|
|||
|
|
if (btn.btn_condition && menuFormParameter) {
|
|||
|
|
const conditionsOr = btn.btn_condition.split('|')
|
|||
|
|
const conditionsAnd = btn.btn_condition.split('&')
|
|||
|
|
if (conditionsOr.length === 1 && conditionsAnd.length === 1) {
|
|||
|
|
// 只配置了一个条件
|
|||
|
|
if (btn.btn_condition === menuFormParameter) {
|
|||
|
|
isShow = true
|
|||
|
|
}
|
|||
|
|
} else if (conditionsOr.length > 1) {
|
|||
|
|
// 或条件
|
|||
|
|
for (let conditionOr of conditionsOr) {
|
|||
|
|
if (conditionOr === menuFormParameter) {
|
|||
|
|
isShow = true
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else if (conditionsAnd.length > 1) {
|
|||
|
|
// 与条件
|
|||
|
|
const showResults = []
|
|||
|
|
for (let conditionAnd of conditionsAnd) {
|
|||
|
|
if (conditionAnd === menuFormParameter) {
|
|||
|
|
showResults.push(true)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
isShow = showResults.length === conditionsAnd.length
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return isShow
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkRenderBtn = (nodeData, treeConfig) => {
|
|||
|
|
const { btns = [] } = treeConfig
|
|||
|
|
const btnsTmp = []
|
|||
|
|
btns.forEach(btn => {
|
|||
|
|
if (!btn.isRule || permissionUtils(this.props.login).checkBtn(treeConfig.formId, btn.pId || btn.id)) {
|
|||
|
|
// 如果配置了树多选,那么直接显示所配置的所有页面
|
|||
|
|
if (treeConfig.multiCheck ? this.checkMultiShowBtn(btn) : this.checkShowBtn(btn, nodeData)) {
|
|||
|
|
btn.btnType === 3 && btn.isSameLevel && (btn.btnType = -1) // 新增同级
|
|||
|
|
btnsTmp.push(btn)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
return btnsTmp
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkFlatTreeData = (treeData) => {
|
|||
|
|
// 拍平树数据
|
|||
|
|
const flatedTreeData = []
|
|||
|
|
flatTreeData(treeData, flatedTreeData)
|
|||
|
|
this.setState({
|
|||
|
|
flatedTreeData: cloneDeep(flatedTreeData)
|
|||
|
|
}, () => {
|
|||
|
|
const { flatedTreeData, selectedKeys } = this.state
|
|||
|
|
const allKeys = flatedTreeData.map(({ node }) => node.id)
|
|||
|
|
const validKeys = selectedKeys.filter(item => allKeys.indexOf(item) !== -1)
|
|||
|
|
this.handleTreeNodesSelect(validKeys.length ? validKeys : this.getDefaultSelectedKeys(this.props))
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkFlatTreeNodes = (treeData, treeConfig, selectedKeys) => {
|
|||
|
|
const selectedNodes = this.state.flatedTreeData.filter(item => selectedKeys.indexOf(item.node.id) !== -1)
|
|||
|
|
treeData.forEach(item => {
|
|||
|
|
const showBtns = this.checkRenderBtn(item, treeConfig)
|
|||
|
|
|
|||
|
|
item.btns = showBtns.map(btnConfig => {
|
|||
|
|
// false 以按钮形式展示 true 以页面形式展示
|
|||
|
|
let typePage = btnConfig.btnType === 5 || btnConfig.btnType === 12 || btnConfig.btnType === 14 || btnConfig.btnType === 0
|
|||
|
|
// component 的赋值逻辑请参考 TreeBaseComponent -> Hindex -> getRenderBtn (取的是 modal 里面的表单)
|
|||
|
|
const { getRenderBtn, onSave } = this.props
|
|||
|
|
let component = getRenderBtn({ record: item.node, btnConfig })
|
|||
|
|
// 表单编辑
|
|||
|
|
if (btnConfig.btnType === 5) {
|
|||
|
|
const params = {
|
|||
|
|
id: item.node.id,
|
|||
|
|
parentId: item.node.id,
|
|||
|
|
formCode: treeConfig.formCode,
|
|||
|
|
data: {
|
|||
|
|
record: item.node
|
|||
|
|
},
|
|||
|
|
onSave: (params) => {
|
|||
|
|
onSave instanceof Function && onSave(params)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
component = <Edit {...params} />
|
|||
|
|
}
|
|||
|
|
// 列表查看
|
|||
|
|
else if (btnConfig.btnType === 12) {
|
|||
|
|
const params = {
|
|||
|
|
formCode: btnConfig.formCode,
|
|||
|
|
formParam: this.props.formParam,
|
|||
|
|
data: {
|
|||
|
|
// 当前选中的节点
|
|||
|
|
selectedNodes,
|
|||
|
|
// 传递给页面选中的节点参数
|
|||
|
|
TreeSelected: selectedKeys,
|
|||
|
|
TreeSelectId: btnConfig.customParams,
|
|||
|
|
// 页面操作取消树节点选中
|
|||
|
|
setTreeNodeUnCheck: this.handleTreeNodesUnCheck,
|
|||
|
|
rules: [
|
|||
|
|
{
|
|||
|
|
field: 'TreeSelected',
|
|||
|
|
operator: 1,
|
|||
|
|
value: selectedKeys,
|
|||
|
|
isCustom: true
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
isQuery: true
|
|||
|
|
}
|
|||
|
|
if (btnConfig.customParams) {
|
|||
|
|
params.data.rules.push({
|
|||
|
|
field: btnConfig.customParams,
|
|||
|
|
operator: 1,
|
|||
|
|
value: item.node.id
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
component = <ListPage {...params} />
|
|||
|
|
}
|
|||
|
|
// 组合表单
|
|||
|
|
else if (btnConfig.btnType === 14) {
|
|||
|
|
const params = {
|
|||
|
|
formCode: btnConfig.formCode,
|
|||
|
|
formParam: this.props.formParam,
|
|||
|
|
data: {
|
|||
|
|
// 当前选中的节点
|
|||
|
|
selectedNodes,
|
|||
|
|
// 传递给页面选中的节点参数
|
|||
|
|
TreeSelected: selectedKeys,
|
|||
|
|
// 页面操作取消树节点选中
|
|||
|
|
setTreeNodeUnCheck: this.handleTreeNodesUnCheck,
|
|||
|
|
rules: [
|
|||
|
|
{
|
|||
|
|
field: btnConfig.customParams,
|
|||
|
|
operator: 1,
|
|||
|
|
value: item.node.id,
|
|||
|
|
isCustom: true
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
component = <CombinationPage {...params} />
|
|||
|
|
}
|
|||
|
|
// 自定义弹窗
|
|||
|
|
else if (btnConfig.btnType === 0) {
|
|||
|
|
const record = item.node
|
|||
|
|
const custParams = getCustomParams(btnConfig.customParams)
|
|||
|
|
const params = {
|
|||
|
|
id: record.id,
|
|||
|
|
parentId: record.id,
|
|||
|
|
formCode: btnConfig.formCode,
|
|||
|
|
formParam: this.props.formParam,
|
|||
|
|
data: {
|
|||
|
|
...record,
|
|||
|
|
...custParams,
|
|||
|
|
customParams: btnConfig.customParams,
|
|||
|
|
// 当前选中的节点
|
|||
|
|
selectedNodes,
|
|||
|
|
// 传递给页面选中的节点参数
|
|||
|
|
TreeSelected: selectedKeys,
|
|||
|
|
// 页面操作取消树节点选中
|
|||
|
|
setTreeNodeUnCheck: this.handleTreeNodesUnCheck
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
component = <FormPage {...params} />
|
|||
|
|
}
|
|||
|
|
return {
|
|||
|
|
typePage,
|
|||
|
|
component,
|
|||
|
|
btnConfig
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
renderTreeNodes = (treeData, thumbData) => {
|
|||
|
|
return treeData.map(item => {
|
|||
|
|
const { children, node } = item
|
|||
|
|
const { name, is_exist_alarm, child_exist_alarm, appliance_id, nav_appliance } = node
|
|||
|
|
|
|||
|
|
const alert = `${name}${is_exist_alarm ? '(节点异常)' : child_exist_alarm ? '(存在子节点异常)' : (appliance_id != null && nav_appliance?.is_report == false) ? '(器具未采集数据)' : ''}`
|
|||
|
|
const color = is_exist_alarm ? 'red' : child_exist_alarm ? 'orange' : (appliance_id != null && nav_appliance?.is_report == false) ? 'rgba(170, 170, 170)' : 'inhert'
|
|||
|
|
const title = (
|
|||
|
|
<span title={alert}>
|
|||
|
|
<span style={{ color }}>{name}</span>
|
|||
|
|
{
|
|||
|
|
is_exist_alarm || child_exist_alarm || (appliance_id != null && nav_appliance?.is_report == false)
|
|||
|
|
? (
|
|||
|
|
<Icon
|
|||
|
|
type={is_exist_alarm || child_exist_alarm ? 'alert' : 'disconnect'}
|
|||
|
|
style={{ color: is_exist_alarm ? 'red' : child_exist_alarm ? 'orange' : 'rgba(170, 170, 170)', marginLeft: 2 }}
|
|||
|
|
/>
|
|||
|
|
)
|
|||
|
|
: ''
|
|||
|
|
}
|
|||
|
|
</span>
|
|||
|
|
)
|
|||
|
|
const style = { width: 24, height: 24, position: 'relative', top: '-1px' }
|
|||
|
|
if (children) {
|
|||
|
|
return (
|
|||
|
|
<Tree.TreeNode
|
|||
|
|
title={title}
|
|||
|
|
key={node.id}
|
|||
|
|
icon={
|
|||
|
|
<PictureThumb
|
|||
|
|
thumbCodes={thumbData.thumbCodes}
|
|||
|
|
thumbConfigs={thumbData.thumbConfigs}
|
|||
|
|
nodeData={item}
|
|||
|
|
defaultThumb={require('../../assets/file.png')}
|
|||
|
|
style={style}
|
|||
|
|
/>
|
|||
|
|
}
|
|||
|
|
>
|
|||
|
|
{this.renderTreeNodes(children, thumbData)}
|
|||
|
|
</Tree.TreeNode>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
return (
|
|||
|
|
<Tree.TreeNode
|
|||
|
|
title={title}
|
|||
|
|
key={node.id}
|
|||
|
|
icon={
|
|||
|
|
<PictureThumb
|
|||
|
|
thumbCodes={thumbData.thumbCodes}
|
|||
|
|
thumbConfigs={thumbData.thumbConfigs}
|
|||
|
|
defaultThumb={require('../../assets/file.png')}
|
|||
|
|
nodeData={item}
|
|||
|
|
style={style}
|
|||
|
|
/>
|
|||
|
|
}
|
|||
|
|
/>
|
|||
|
|
)
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
handleTreeNodesSelect = (selectedKeys) => {
|
|||
|
|
const { treeConfig } = this.props
|
|||
|
|
const { flatedTreeData, activeKey } = this.state
|
|||
|
|
// 获取选中节点所配置的按钮页面,并直接附在 flatedTreeData 数据之上
|
|||
|
|
this.checkFlatTreeNodes(flatedTreeData, treeConfig, selectedKeys)
|
|||
|
|
// 查找被激活 tab 的 key 值
|
|||
|
|
const findNode = flatedTreeData.find(item => item.node.id === selectedKeys[0])
|
|||
|
|
const pageBtns = findNode && findNode.btns ? findNode.btns.filter(btn => btn.typePage) : []
|
|||
|
|
const currActived = pageBtns.find(item => item.btnConfig.id === activeKey)
|
|||
|
|
this.setState({
|
|||
|
|
selectedKeys,
|
|||
|
|
activeKey: !currActived ? (pageBtns.length > 1 ? pageBtns[0].btnConfig.id : '') : activeKey
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
handleTreeNodesCheck = ({ checked: selectedKeys }) => {
|
|||
|
|
const { multiCheckCount } = this.state
|
|||
|
|
if (multiCheckCount && selectedKeys.length > multiCheckCount) {
|
|||
|
|
message.error(`最多可选${multiCheckCount}个节点`)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
this.handleTreeNodesSelect(selectedKeys)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
handleTreeNodesUnCheck = (applianceId) => {
|
|||
|
|
const { flatedTreeData, selectedKeys } = this.state
|
|||
|
|
const find = flatedTreeData.find(item => item.node?.appliance_id === applianceId)
|
|||
|
|
if (find) {
|
|||
|
|
const copyKeys = cloneDeep(selectedKeys)
|
|||
|
|
const findIndex = copyKeys.findIndex(item => item === find.node?.id)
|
|||
|
|
findIndex !== -1 && copyKeys.splice(findIndex, 1)
|
|||
|
|
this.handleTreeNodesCheck({ checked: copyKeys })
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
renderTabBar = (pageBtns) => {
|
|||
|
|
const { activeKey } = this.state
|
|||
|
|
return (
|
|||
|
|
<div className={customTabStyles.tabBar__wrap}>
|
|||
|
|
{
|
|||
|
|
pageBtns.map(item => {
|
|||
|
|
return (
|
|||
|
|
<div
|
|||
|
|
key={`${item.btnConfig.id}--customTabBar`}
|
|||
|
|
onClick={() => this.setState({ activeKey: item.btnConfig.id })}
|
|||
|
|
className={classNames(customTabStyles.tabBar__tab, { [customTabStyles.activated]: item.btnConfig.id === activeKey })}>
|
|||
|
|
{item.btnConfig.label}
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
handleSearch = (evt) => {
|
|||
|
|
const { value } = evt.target
|
|||
|
|
const searchTreeData = this.state.flatedTreeData.filter(({ node = {} }) => (node.name || '').indexOf(value) !== -1)
|
|||
|
|
this.setState({ searchTreeData: value ? searchTreeData : [] })
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
render () {
|
|||
|
|
const { treeData, treeConfig } = this.props
|
|||
|
|
const thumbData = this.getThumbData()
|
|||
|
|
const defaultExpandedKeys = this.getDefaultExpandedKeys()
|
|||
|
|
const expandProps = defaultExpandedKeys.length ? { defaultExpandedKeys } : { defaultExpandAll: true }
|
|||
|
|
|
|||
|
|
const { activeKey, multiCheck, selectedKeys, flatedTreeData, searchTreeData, collapse } = this.state
|
|||
|
|
// 多选时,所有节点都会展示全部配置的页面,单选时,就一个 selectedKeys[0],所以直接取 selectedKeys[0] 来获取配置的页面
|
|||
|
|
const targetNodes = flatedTreeData.find(item => item.node.id === selectedKeys[0]) || { node: {} }
|
|||
|
|
const toolBtns = targetNodes.btns ? targetNodes.btns.filter(btn => !btn.typePage) : []
|
|||
|
|
const pageBtns = targetNodes.btns ? targetNodes.btns.filter(btn => btn.typePage) : []
|
|||
|
|
const selectedTitle = multiCheck && selectedKeys.length > 1 ? `${selectedKeys.length}个` : targetNodes.node.name
|
|||
|
|
const selectedEvtKey = multiCheck && selectedKeys.length > 1 ? selectedKeys.join(';') : targetNodes.node.id
|
|||
|
|
return (
|
|||
|
|
<div className={styles.treeV}>
|
|||
|
|
<div className={classNames(styles.treeVLeft, { [styles.treeVCollapse]: collapse })}>
|
|||
|
|
<Icon
|
|||
|
|
type={collapse ? 'menu-unfold' : 'menu-fold'}
|
|||
|
|
title={collapse ? '展开' : '收起'}
|
|||
|
|
onClick={() => this.setState({ collapse: !collapse })}
|
|||
|
|
className={styles.treeVFold}
|
|||
|
|
/>
|
|||
|
|
<div onClick={() => collapse && this.setState({ collapse: false })} className={styles.treeVWrap}>
|
|||
|
|
<span className={styles.treeVTitle}>{treeConfig.labelName}</span>
|
|||
|
|
<div className={styles.treeVDivider}></div>
|
|||
|
|
<div className={styles.treeVSelect}>
|
|||
|
|
<div title={selectedTitle || '无'} className={styles.treeVSelectTitle}>当前选中:{selectedTitle || '无'}</div>
|
|||
|
|
<div className={styles.treeVSelectBtns}>
|
|||
|
|
{
|
|||
|
|
!multiCheck || selectedKeys.length === 1
|
|||
|
|
? toolBtns.map(tb => tb.component)
|
|||
|
|
: null
|
|||
|
|
}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<Input.Search
|
|||
|
|
allowClear
|
|||
|
|
onChange={this.handleSearch}
|
|||
|
|
placeholder='关键字搜索'
|
|||
|
|
className={styles.treeVSearch}
|
|||
|
|
/>
|
|||
|
|
<div className={styles.treeVTree}>
|
|||
|
|
<Scrollbars autoHide autoHideTimeout={1000} autoHideDuration={200}>
|
|||
|
|
<Tree
|
|||
|
|
showIcon
|
|||
|
|
checkStrictly
|
|||
|
|
checkable={multiCheck}
|
|||
|
|
selectable={!multiCheck}
|
|||
|
|
checkedKeys={selectedKeys}
|
|||
|
|
selectedKeys={selectedKeys}
|
|||
|
|
{...expandProps}
|
|||
|
|
switcherIcon={<Icon type='caret-down' style={{ fontSize: 18 }} />}
|
|||
|
|
onSelect={this.handleTreeNodesSelect}
|
|||
|
|
onCheck={this.handleTreeNodesCheck}
|
|||
|
|
>
|
|||
|
|
{this.renderTreeNodes(searchTreeData.length ? searchTreeData : treeData, thumbData)}
|
|||
|
|
</Tree>
|
|||
|
|
</Scrollbars>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div key={selectedEvtKey} className={classNames(styles.treeVRight, { [styles.treeVCollapse]: collapse })}>
|
|||
|
|
{
|
|||
|
|
pageBtns.length
|
|||
|
|
? (
|
|||
|
|
pageBtns.length > 1
|
|||
|
|
? (
|
|||
|
|
<Tabs
|
|||
|
|
activeKey={activeKey}
|
|||
|
|
renderTabBar={() => this.renderTabBar(pageBtns)}
|
|||
|
|
animated={false}
|
|||
|
|
className='combination-page__mainTab'
|
|||
|
|
>
|
|||
|
|
{
|
|||
|
|
pageBtns.map(pb => (
|
|||
|
|
<Tabs.TabPane key={pb.btnConfig.id} tab={pb.btnConfig.label}>{pb.component}</Tabs.TabPane>
|
|||
|
|
))
|
|||
|
|
}
|
|||
|
|
</Tabs>
|
|||
|
|
)
|
|||
|
|
: pageBtns[0].component
|
|||
|
|
)
|
|||
|
|
: null
|
|||
|
|
}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default connect(({ login, app }) => ({ login, app }))(VPage)
|