// 核心库
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 =