482 lines
14 KiB
JavaScript
482 lines
14 KiB
JavaScript
// 核心库
|
||
import React from 'react'
|
||
// 组件库
|
||
import { message, Button, Icon, Popconfirm, Empty } from 'antd'
|
||
import { Search, OrganizationTree } from '@woowalker/feui'
|
||
import ComponentBase from "../ComponentBase"
|
||
import Node from "./node"
|
||
import VPage from './VPage'
|
||
import EditModal from '../../components/Edit/EditModal'
|
||
import CombinationModal from '../../components/Combination/CombinationModal'
|
||
import TableModal from '../../components/Table/TableModal'
|
||
import FormModal from '../../components/FormModal'
|
||
import DataLoading from '../../components/common/DataLoading'
|
||
// 工具库
|
||
import { cloneDeep } from 'lodash'
|
||
import { addRuleAndGroups, extendRule, extendGroupRule, initFilter } from "../../utils/common"
|
||
// 样式
|
||
import styles from '../Component.css'
|
||
let formParam = ''
|
||
class TreeBaseComponent extends ComponentBase {
|
||
constructor (props) {
|
||
super(props)
|
||
this.state = {
|
||
data: {},
|
||
treeConfig: {},
|
||
treeLoadParam: {},
|
||
showAdd: false,
|
||
showModal: false
|
||
}
|
||
this.defaultTreeCode = 'tree'
|
||
};
|
||
componentDidMount () {
|
||
super.componentDidMount()
|
||
this.onLoadData()
|
||
}
|
||
|
||
componentWillReceiveProps (NextProps) {
|
||
super.componentWillReceiveProps(NextProps)
|
||
}
|
||
|
||
onLoadTreeData ({ treeCode, searchValue, onComplete }) {
|
||
const treeConfig = this.getTreeConfig({ treeCode })
|
||
if (treeConfig) {
|
||
const { sort, order, relationField, relationId, api, orgType, ignoreOrgRule } = treeConfig
|
||
|
||
if (!api) return
|
||
const treeLoadParam = this.state.treeLoadParam
|
||
let loadParam = treeLoadParam[treeCode]
|
||
|
||
if (!loadParam) {
|
||
loadParam = initFilter(this.props.login.OrgId, '', sort, order)
|
||
treeLoadParam[treeCode] = loadParam
|
||
}
|
||
loadParam['Level'] = -1
|
||
const rules = this.props && this.props.data && this.props.data.rules ? this.props.data.rules : []
|
||
const json = cloneDeep(loadParam)
|
||
|
||
formParam = this.props.formParam
|
||
if (formParam) {
|
||
for (var val in formParam) {
|
||
json[val] = formParam[val]
|
||
}
|
||
}
|
||
|
||
if (rules) {
|
||
rules.forEach(item => {
|
||
extendRule(json, item.field, item.operator, item.value, item.isSysParam)
|
||
})
|
||
}
|
||
if (orgType) {
|
||
json.OrgType = orgType
|
||
}
|
||
if (searchValue) {
|
||
addRuleAndGroups(json, searchValue)
|
||
}
|
||
|
||
//填加关联字段过滤
|
||
if (relationField && relationId) {
|
||
extendRule(json, relationField, 1, relationId)
|
||
}
|
||
|
||
// 是否忽略组织权限
|
||
if (ignoreOrgRule) {
|
||
json.IgnoreOrgRule = ignoreOrgRule
|
||
}
|
||
|
||
//配置的自定义查询条件
|
||
if (this.props.data?.Filter) {
|
||
json[this.props.data.Filter] = this.props.data.ID
|
||
}
|
||
|
||
// 配置的自定义过滤参数
|
||
if (this.props.data?.customParams) {
|
||
extendGroupRule(json.FilterGroup, this.props.data.customParams, 1, this.props.data.ID)
|
||
}
|
||
|
||
this.props.dispatch({
|
||
type: 'app/getTableData',
|
||
payload: json,
|
||
url: api,
|
||
onComplete: (ret) => {
|
||
if (ret) {
|
||
if (!ret.IsSuccessful) {
|
||
message.error(ret.ErrorMessage)
|
||
return
|
||
}
|
||
const datas = JSON.stringify(ret.Data)
|
||
this.setTreeData({
|
||
treeCode,
|
||
data: JSON.parse(datas.toLowerCase()),
|
||
onComplete,
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
获取树配置
|
||
*/
|
||
getTreeConfig (params) {
|
||
const { treeCode = this.defaultTreeCode } = params ? params : {}
|
||
let treeConfig = this.state.treeConfig
|
||
if (!treeConfig) {
|
||
treeConfig = {}
|
||
}
|
||
return treeConfig[treeCode]
|
||
}
|
||
|
||
/*
|
||
设置树配置
|
||
*/
|
||
setTreeConfig (params) {
|
||
const { treeConfig, onComplete } = params ? params : {}
|
||
let tempTreeConfig = this.state.treeConfig
|
||
if (!tempTreeConfig) {
|
||
tempTreeConfig = {}
|
||
}
|
||
if (treeConfig.treeCode === undefined) {
|
||
treeConfig.treeCode = this.defaultTreeCode
|
||
}
|
||
tempTreeConfig = {
|
||
...tempTreeConfig,
|
||
[treeConfig.treeCode]: treeConfig,
|
||
}
|
||
this.setState({
|
||
treeConfig: tempTreeConfig
|
||
}, () => {
|
||
if (typeof onComplete === 'function') {
|
||
onComplete()
|
||
}
|
||
})
|
||
}
|
||
|
||
/*
|
||
获取树数据
|
||
*/
|
||
getTreeData (params) {
|
||
const { treeCode = this.defaultTreeCode } = params ? params : {}
|
||
let data = this.state.treeData
|
||
if (!data) {
|
||
data = {}
|
||
}
|
||
return data[treeCode]
|
||
}
|
||
|
||
/*
|
||
设置树数据
|
||
*/
|
||
setTreeData ({ treeCode, data, onComplete }) {
|
||
let tempData = this.state.treeData
|
||
if (!tempData) {
|
||
tempData = {}
|
||
}
|
||
if (treeCode === undefined) {
|
||
treeCode = this.defaultTreeCode
|
||
}
|
||
tempData = {
|
||
...tempData,
|
||
[treeCode]: data,
|
||
}
|
||
this.setState({
|
||
treeData: tempData,
|
||
}, () => {
|
||
if (typeof onComplete === 'function') {
|
||
onComplete()
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 节点包含MENU_LEVEL:第几级(没有默认第一个颜色),ICON:下方图标(没有默认不显示)
|
||
*/
|
||
MyNode = (data) => {
|
||
const treeCode = this.defaultTreeCode
|
||
const treeConfig = this.getTreeConfig({ treeCode })
|
||
return (
|
||
<Node
|
||
key={`${data.node.id}--customNode`}
|
||
treeCode={treeCode}
|
||
treeConfig={treeConfig}
|
||
treePicFilter={this.state.picFilter}
|
||
nodeData={data}
|
||
{...this.props}
|
||
showModal={this.state.showModal}
|
||
getRenderBtn={this.getRenderBtn} />
|
||
)
|
||
};
|
||
|
||
click = visible => {
|
||
this.setState({ showModal: visible })
|
||
}
|
||
|
||
getRenderBtn = (params = {}) => {
|
||
const { record, btnConfig = {} } = params
|
||
// 编辑 新增 查看 复制新增 新增同级
|
||
if (
|
||
btnConfig.btnType === 5
|
||
|| btnConfig.btnType === 3
|
||
|| btnConfig.btnType === 8
|
||
|| btnConfig.btnType === 10
|
||
|| (btnConfig.btnType === -1 && record.parent_id)
|
||
) {
|
||
const isShow = btnConfig.btnType === 8
|
||
|
||
const isBatchEdit = false
|
||
const extKey = record ? (record.id + btnConfig.id) : btnConfig.id
|
||
const reloadKey = this.props.formCode + '_' + extKey + '_reload'
|
||
const data = {
|
||
isShow: isShow,
|
||
record: record || {},
|
||
isBatchEdit,
|
||
reloadKey,
|
||
|
||
}
|
||
if (this.props.data?.Filter) {
|
||
data.record[this.props.data.Filter] = this.props.data.ID
|
||
}
|
||
const extraSaveData = {}
|
||
if (this.props.data?.customParams) {
|
||
extraSaveData[this.props.data.customParams] = this.props.data.ID
|
||
}
|
||
const id = btnConfig.btnType !== 10 && record ? (btnConfig.btnType === -1 ? record.parent_id : record.id) : ''
|
||
const copySrcId = btnConfig.btnType === 10 && record ? record.id : ''
|
||
return (
|
||
<EditModal
|
||
key={record ? (record.id + btnConfig.id) : btnConfig.id}
|
||
formCode={this.props.formCode}
|
||
id={id}
|
||
copySrcId={copySrcId}
|
||
data={data}
|
||
extraSaveData={extraSaveData}
|
||
title={btnConfig.label}
|
||
formParam={formParam}
|
||
parentId={btnConfig.btnType === -1 ? record.parent_id : record.id}
|
||
isAddH={btnConfig.btnType === 3 || btnConfig.btnType === -1}
|
||
onSave={saveData => {
|
||
this.updateTreeDataBySave(saveData)
|
||
}}
|
||
click={this.click}>
|
||
<Icon type={btnConfig.icon} title={btnConfig.label} />
|
||
</EditModal>
|
||
)
|
||
}
|
||
// 节点删除
|
||
else if (btnConfig.btnType === 4) {
|
||
return (
|
||
<Popconfirm
|
||
title="是否确定删除?"
|
||
onConfirm={this.deleteTreeNode.bind(this, params)}
|
||
onVisibleChange={visible => this.setState({ showModal: visible })}
|
||
icon={<Icon type="exclamation-circle" style={{ color: '#faad14' }} />}
|
||
>
|
||
<Icon type={btnConfig.icon} title={btnConfig.label} />
|
||
</Popconfirm>
|
||
)
|
||
}
|
||
// 列表查看
|
||
else if (btnConfig.btnType === 12) {
|
||
return (
|
||
<TableModal
|
||
key={record ? (record.id + btnConfig.id) : btnConfig.id}
|
||
formCode={btnConfig.formCode}
|
||
id={record.id}
|
||
customParams={btnConfig.customParams}
|
||
formParam={formParam}
|
||
data={record}
|
||
title={btnConfig.label}
|
||
parentId={btnConfig.btnType === -1 ? record.parent_id : record.id}
|
||
click={this.click}>
|
||
<Icon type={btnConfig.icon} title={btnConfig.label} />
|
||
</TableModal>
|
||
)
|
||
}
|
||
// 组合表单
|
||
else if (btnConfig.btnType === 14) {
|
||
return (
|
||
<CombinationModal
|
||
key={record ? (record.id + btnConfig.id) : btnConfig.id}
|
||
formCode={btnConfig.formCode}
|
||
id={record.id}
|
||
customParams={btnConfig.customParams}
|
||
formParam={formParam}
|
||
data={record}
|
||
title={btnConfig.label}
|
||
parentId={btnConfig.btnType === -1 ? record.parent_id : record.id}
|
||
click={this.click}>
|
||
<Icon type={btnConfig.icon} title={btnConfig.label} />
|
||
</CombinationModal>
|
||
)
|
||
}
|
||
// 自定义弹窗
|
||
else if (btnConfig.btnType === 0) {
|
||
return (
|
||
<FormModal
|
||
key={record ? (record.id + btnConfig.id) : btnConfig.id}
|
||
formCode={btnConfig.formCode}
|
||
id={record.id}
|
||
customParams={btnConfig.customParams}
|
||
formParam={formParam}
|
||
data={record}
|
||
title={btnConfig.label}
|
||
parentId={btnConfig.btnType === -1 ? record.parent_id : record.id}
|
||
click={this.click}>
|
||
<Icon type={btnConfig.icon} title={btnConfig.label} />
|
||
</FormModal>
|
||
)
|
||
}
|
||
// 无树数据时,新增顶级节点
|
||
else {
|
||
const data = {}
|
||
if (this.props.data?.Filter) {
|
||
data.record = {
|
||
[this.props.data.Filter]: this.props.data.ID
|
||
}
|
||
}
|
||
const extraSaveData = {}
|
||
if (this.props.data?.customParams) {
|
||
extraSaveData[this.props.data.customParams] = this.props.data.ID
|
||
}
|
||
return (
|
||
<EditModal
|
||
formCode={this.props.formCode}
|
||
title='新增'
|
||
isAddH={true}
|
||
data={data}
|
||
onSave={saveData => {
|
||
this.updateTreeDataBySave(saveData)
|
||
}}
|
||
extraSaveData={extraSaveData}
|
||
click={this.click}>
|
||
{
|
||
btnConfig.btnType === -1
|
||
? <Icon type={btnConfig.icon} title={btnConfig.label} />
|
||
: <Button type="primary" icon="plus">添加</Button>
|
||
}
|
||
</EditModal>
|
||
)
|
||
}
|
||
}
|
||
|
||
deleteTreeNode = (params) => {
|
||
const { treeCode = this.defaultTreeCode, record } = params
|
||
const treeConfig = this.getTreeConfig({ treeCode })
|
||
if (treeConfig) {
|
||
const { deleteApi } = treeConfig
|
||
if (deleteApi) {
|
||
this.props.dispatch({
|
||
type: 'app/deleteItemBatch',
|
||
payload: {
|
||
ids: record.id
|
||
},
|
||
url: deleteApi,
|
||
onComplete: (ret) => {
|
||
if (ret) {
|
||
message.success('删除成功')
|
||
this.updateTreeDataBySave()
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
updateTreeDataBySave = () => {
|
||
this.onLoadTreeData({ treeCode: this.defaultTreeCode })
|
||
}
|
||
|
||
/*
|
||
根据树编号渲染树
|
||
*/
|
||
getRenderTreeByConfig (treeCode) {
|
||
if (treeCode === undefined) {
|
||
treeCode = this.defaultTreeCode
|
||
}
|
||
const treeConfig = this.getTreeConfig({ treeCode })
|
||
if (treeConfig) {
|
||
const treeData = this.getTreeData({ treeCode })
|
||
const { formCode, queryCode } = treeConfig
|
||
if (treeConfig.showModel == 1) {
|
||
return (
|
||
<>
|
||
<Search
|
||
formCode={formCode}
|
||
formParam={this.props.formParam}
|
||
code={queryCode}
|
||
onSearch={(value) => this.onLoadTreeData({ treeCode, searchValue: value })}
|
||
/>
|
||
{
|
||
treeData && treeData.length
|
||
? (
|
||
<VPage
|
||
treeData={treeData}
|
||
treeConfig={treeConfig}
|
||
formParam={formParam}
|
||
treePicFilter={this.state.picFilter}
|
||
getRenderBtn={this.getRenderBtn}
|
||
onSave={this.updateTreeDataBySave}
|
||
/>
|
||
)
|
||
: null
|
||
}
|
||
{
|
||
treeData && treeData.length === 0 && treeConfig.canAddNode
|
||
? <div className={styles.treeVBox}>{this.getRenderBtn()}</div>
|
||
: (
|
||
treeData && treeData.length === 0
|
||
? <div className={styles.treeVBox}><Empty style={{ position: 'relative', top: '50%', transform: 'translateY(-50%)' }} /></div>
|
||
: (!treeData ? <div className={styles.treeVBox}><DataLoading /></div> : null)
|
||
)
|
||
}
|
||
</>
|
||
)
|
||
}
|
||
return (
|
||
<>
|
||
<Search
|
||
formCode={formCode}
|
||
formParam={this.props.formParam}
|
||
code={queryCode}
|
||
onSearch={(value) => this.onLoadTreeData({ treeCode, searchValue: value })}
|
||
/>
|
||
<div className={styles.treeHBox}>
|
||
{
|
||
(treeData || []).map(item => {
|
||
return (
|
||
<OrganizationTree
|
||
key={`${item.node.id}--rootTree`}
|
||
data={item}
|
||
node={{
|
||
id: 'node.id',
|
||
label: 'node.name',
|
||
expand: 'expand',
|
||
children: 'children'
|
||
}}
|
||
expandLevel={treeConfig.expandLevel}
|
||
renderContent={this.MyNode}
|
||
/>
|
||
)
|
||
})
|
||
}
|
||
{
|
||
treeData && treeData.length === 0 && treeConfig.canAddNode
|
||
? this.getRenderBtn()
|
||
: (
|
||
treeData && treeData.length === 0
|
||
? <Empty style={{ position: 'relative', top: '50%', transform: 'translateY(-50%)' }} />
|
||
: (!treeData ? <DataLoading /> : null)
|
||
)
|
||
}
|
||
</div>
|
||
</>
|
||
)
|
||
}
|
||
return <div />
|
||
}
|
||
}
|
||
|
||
export default TreeBaseComponent
|