mh_jy_safe_web/src/feui/search/index.js
2025-08-25 10:08:30 +08:00

256 lines
7.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 核心库
import React from 'react'
import { connect } from 'dva'
// 组件库
import { Tabs } from 'antd'
import AdvanceSearch from './AdvanceSearch'
import SearchGroupField from './SearchGroupField'
import EditTabPane from './EditTabPane'
// 工具库
import {
uuid,
extendInclude,
extendRule,
initQueryFilter,
initFilter
} from '../utils/common'
const TabPane = Tabs.TabPane
class Search extends React.Component {
constructor (props) {
super(props)
this.state = {
activeKey: '',
filterList: [],
formId: '' // 接口获取到的 formId因为可能 props.formId 没有
}
this.domId = uuid()
// AdvanceSearch 的实例
this.refsOfField = {}
// SearchGroupField 的实例
this.refsOfGroup = {}
}
componentDidMount () {
const { preventDefaultSearch, onRef } = this.props
this.loadFilterList().then(filterList => {
/**
* 如果 filterList 存在,那么初次搜索会在 AdvanceSearch 组件 ComponentDidMount 时完成,
* 如果 filterList 不存在,那么初次搜索在此处调用
*/
!filterList.length && !preventDefaultSearch && this.handleSearch()
})
onRef instanceof Function && onRef(this)
}
componentDidUpdate () {
const targetDom = document.getElementsByClassName(this.domId)[0]
if (targetDom) {
const computedStyle = window.getComputedStyle(targetDom)
const { width, height, marginTop, marginBottom, marginLeft, marginRight } = computedStyle
this.props.onSize instanceof Function && this.props.onSize({
width: parseInt(width),
height: parseInt(height),
fullWidth: parseInt(marginLeft) + parseInt(width) + parseInt(marginRight),
fullHeight: parseInt(marginTop) + parseInt(height) + parseInt(marginBottom)
})
}
}
loadFilterList = () => {
const { login, formCode, formId, dispatch } = this.props
const sysFieldsParams = initFilter(login.OrgId, formCode, '', 0, 1, formId)
const userFieldsParams = initQueryFilter(login.OrgId, 1, 100, 'CREATE_TIME', 0)
extendRule(userFieldsParams, formCode ? 'Nav_PageForm.CODE' : 'PAGE_FORM_ID', 1, formCode || formId)
extendRule(userFieldsParams, 'Nav_UserCustomConfig.USER_ID', 1, login.userId)
extendInclude(userFieldsParams, 'Nav_Fields')
extendInclude(userFieldsParams, 'Nav_Groups')
return Promise.all([
dispatch({ type: 'search/getSysFields', payload: sysFieldsParams }),
dispatch({ type: 'search/getUserFields', payload: userFieldsParams })
]).then(res => {
if (res && Array.isArray(res)) {
const [sysFields, userFields] = res
const panes = []
if (sysFields) {
const { Nav_Form, Nav_FormQuery = [] } = sysFields
Nav_FormQuery.forEach((item) => {
panes.push({
isSysQuery: true,
ID: item.ID,
TITLE: item.LABEL,
Nav_Fields: item.Nav_Querys,
SHARE_KEY: item.SHARE_KEY,
IS_REMEMBER: item.IS_REMEMBER
})
})
// eslint-disable-next-line react/no-direct-mutation-state
Nav_Form && (this.state.formId = Nav_Form ? Nav_Form.ID : '')
}
if (userFields) {
userFields.forEach((item) => {
if (item.Nav_Fields && item.Nav_Fields.length) {
item.Nav_Groups = item.Nav_Groups ? item.Nav_Groups.filter(t => t.IS_DISPLAY) : null
panes.push(item)
}
})
}
return this.setFilterList(panes)
}
return []
})
}
setFilterList = (panes) => {
const { code } = this.props
let activeKey = panes[0] ? panes[0].ID : ''
const filterList = []
panes.forEach(item => {
if (item.IS_DEFAULT) {
activeKey = item.ID
}
if (item.Nav_Fields) {
const list = []
item.Nav_Fields.forEach(field => (!code || field.CODE == code) && list.push(field))
list.sort(function (x, y) { return x.NUM > y.NUM ? 1 : -1 })
item.Nav_Fields = list
}
if (item.Nav_Groups) {
const list = []
item.Nav_Groups.forEach(group => {
if ((code && group.CODE == code && group.IS_DISPLAY) || (!code && group.IS_DISPLAY)) {
list.push(group)
}
})
list.sort(function (x, y) { return x.NUM > y.NUM ? 1 : -1 })
item.Nav_Groups = list
}
if (item.Nav_Fields && item.Nav_Fields.length) {
filterList.push(item)
}
})
this.setState({
activeKey,
filterList
})
return filterList
}
// 执行搜索 提供给 ref 调用
handleSearch = (id) => {
const { currActivatedMenu } = this.props.app || {}
const rule = {
rules: [],
groups: [],
orgType: 0,
menuParameter: currActivatedMenu && currActivatedMenu.MENU_FORM_PARAMS ? currActivatedMenu.MENU_FORM_PARAMS : ''
}
let errorLabel = false
id = id || this.state.activeKey
if (this.refsOfField[id]) {
errorLabel = this.refsOfField[id].getSearchParams(rule.rules, rule.groups)
}
if (this.refsOfGroup[id]) {
errorLabel = this.refsOfGroup[id].getSearchParams(rule.groups)
}
if (errorLabel) return
const { onSearch } = this.props
onSearch instanceof Function && onSearch(rule)
return rule
}
// 添加一组 GroupField 根配置
handleAddGroupConfig = (id) => {
if (this.refsOfGroup[id]) {
this.refsOfGroup[id].addGroupConfig()
}
}
// UserCustomSearchEditModel 弹框关闭事件
onEditModalClose = () => {
this.loadFilterList().then(() => {
this.handleSearch()
})
}
changeTab = (activeKey) => {
const loaded = this.refsOfField[activeKey]
this.setState({ activeKey }, () => {
// setTimeout 是因为首次切换 tab 时,由于子组件的 setState 还没执行完,导致搜索参数还未初始化完
loaded ? this.handleSearch() : setTimeout(this.handleSearch, 0)
})
}
renderTabBar = (props, DefaultTabBar) => {
const { filterList } = this.state
if (filterList.length <= 1) {
return <span />
}
return <DefaultTabBar {...props} />
}
render () {
const { filterList, activeKey, formId: stateFormId } = this.state
if (!filterList.length) return <div />
const { code, formId: propsFormId, presetValue } = this.props
return (
<Tabs
size='small'
animated={false}
activeKey={activeKey}
renderTabBar={this.renderTabBar}
onChange={this.changeTab}
className={`opt-search ${this.domId}`}
>
{
filterList.map(item => (
<TabPane
key={item.ID}
tab={
<EditTabPane
{...this.props}
data={item}
activeKey={activeKey}
refsOfField={this.refsOfField}
refsOfGroup={this.refsOfGroup}
onEditModalClose={this.onEditModalClose}
/>
}
>
<AdvanceSearch
{...this.props}
filterList={filterList}
filterItem={item}
onRef={ref => { this.refsOfField[item.ID] = ref }}
fields={item.Nav_Fields}
onAddGroupConfig={() => this.handleAddGroupConfig(item.ID)}
onEditModalClose={this.onEditModalClose}
onSearch={() => this.handleSearch(item.ID)}
/>
<SearchGroupField
{...this.props}
onRef={ref => { this.refsOfGroup[item.ID] = ref }}
code={code}
formId={propsFormId || stateFormId}
customConfigId={item.ID}
fields={item.Nav_Fields}
groups={item.Nav_Groups}
presetValue={presetValue}
onSearch={() => this.handleSearch(item.ID)}
/>
</TabPane>
))
}
</Tabs>
)
}
}
export default connect(({ app, login }) => ({ app, login }))(Search)