king
2025-01-24 e1cee96b38805bcccf48e7bcb9d296f2bc54c720
src/tabviews/custom/components/share/normalTable/index.jsx
@@ -2,7 +2,8 @@
import PropTypes from 'prop-types'
import md5 from 'md5'
import { is, fromJS } from 'immutable'
import { Table, Typography, Col, Switch, message } from 'antd'
import { Table, Typography, Col, Switch, message, Pagination } from 'antd'
import { CaretRightOutlined, CaretDownOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import { getMark } from '@/utils/utils.js'
@@ -20,6 +21,51 @@
  '5:1': '20%', '6:1': '16.67%', '7:1': '14.29%', '8:1': '12.5%', '9:1': '11.11%',
  '10:1': '10%', '3:4': '133.33%', '2:3': '150%', '9:16': '177.78%'
}
// 字段透视
const triggerLink = (e, item, record) => {
  e.stopPropagation()
  if (item.linkThdMenu) {
    let __param = {
      $BID: record.$$uuid
    }
    if (item.field) {
      __param.$searchkey = item.field
      __param.$searchval = record[item.field] || ''
    }
    Object.keys(record).forEach(key => {
      if (/^\$/.test(key)) return
      __param[key] = record[key]
    })
    let tabmenu = item.linkThdMenu
    tabmenu.param = __param
    MKEmitter.emit('modifyTabs', tabmenu, true)
  } else if (item.linkurl) {
    let src = item.linkurl
    if (/@/.test(src)) {
      src = src.replace(/@id@/ig, record.$$uuid)
      src = src.replace(/@appkey@/ig, window.GLOB.appkey)
      src = src.replace(/@userid@/ig, sessionStorage.getItem('UserID'))
      src = src.replace(/@LoginUID@/ig, sessionStorage.getItem('LoginUID'))
      Object.keys(record).forEach(key => {
        if (/^\$/.test(key)) return
        let reg = new RegExp('@' + key + '@', 'ig')
        src = src.replace(reg, record[key])
      })
    }
    window.open(src)
  }
}
class BodyRow extends React.Component {
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.data), fromJS(nextProps.data)) || this.props.className !== nextProps.className
@@ -107,10 +153,10 @@
  }
  render() {
    let { col, config, record, className, style, triggerLink, ...resProps } = this.props
    let { col, config, record, className, style, openChange, ...resProps } = this.props
    if (!col) return (<td {...resProps} className={className} style={style}/>)
    if (col.type === 'text') {
      let content = ''
      if (record[col.field] !== undefined) {
@@ -126,15 +172,19 @@
          content = <span>{col.prefix || ''}<Encrypts value={content} />{col.postfix || ''}</span>
        }
        if (col.noValue === 'hide' && content < '1949-10-02') {
          content = ''
        }
        if (col.textFormat !== 'encryption') {
          content = (col.prefix || '') + content + (col.postfix || '')
        }
      }
      if (col.marks) {
        let mark = getMark(col.marks, record, style)
        style = style ? {...style} : {}
        style = mark.style
        let mark = getMark(col.marks, record, style)
        if (mark.icon) {
          if (mark.position === 'front') {
@@ -144,6 +194,14 @@
          }
        } else if (mark.innerStyle) {
          content = <span style={mark.innerStyle}>{content}</span>
        } else if (mark.space) {
          content = <><span dangerouslySetInnerHTML={{__html: mark.space}}></span>{content}</>
        } else if (mark.point) {
          if (mark.position === 'front') {
            content = <>{mark.point}{content}</>
          } else {
            content = <>{content}{mark.point}</>
          }
        }
      }
      if (col.blur) {
@@ -153,22 +211,35 @@
      if (col.rowspan === 'true') {
        resProps.rowSpan = record['$$' + col.field]
      }
      if (!record.$disabled && (col.linkThdMenu || col.linkurl)) {
        content = (
          <div>
            <div className="link-menu" onDoubleClick={(e) => triggerLink(e, col, record)}></div>
            {content}
          </div>
        )
      }
      if (col.$tree && record.$mk_floor) {
        className += ' mk-tree-td'
        if (record.$open) {
          content = <>
            <span className="mk-tree-node" style={{width: `calc(var(--tree-node-width) * ${record.$mk_floor})`}}><CaretRightOutlined onClick={(e) => openChange(e, record.$key)} /><CaretDownOutlined onClick={(e) => openChange(e, record.$key)}/></span>
            {content}
          </>
        } else {
          content = <>
            <span className="mk-tree-node" style={{width: `calc(var(--tree-node-width) * ${record.$mk_floor})`}}></span>
            {content}
          </>
        }
      }
      resProps.children = content
      if (!record.$disabled && (col.linkThdMenu || col.linkurl)) {
        return (<td {...resProps} className={className + ' clickable'} onClick={(e) => triggerLink(e, col, record)} style={style}/>)
      }
    } else if (col.type === 'number') {
      let content = ''
      try {
        content = parseFloat(record[col.field])
        if (isNaN(content)) {
          content = ''
        }
        if (col.noValue === 'hide' && content === 0) {
          content = ''
        }
      } catch (e) {
@@ -181,6 +252,9 @@
        }
        if (col.format === 'percent') {
          content = content * 100
          if (!col.round) {
            content = +content.toFixed(2)
          }
        } else if (col.format === 'abs') {
          content = Math.abs(content)
        }
@@ -189,6 +263,7 @@
        }
  
        if (col.format === 'thdSeparator') {
          content = content + ''
          content = content.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
        }
  
@@ -196,9 +271,9 @@
      }
      if (col.marks) {
        let mark = getMark(col.marks, record, style)
        style = style ? {...style} : {}
        style = mark.style
        let mark = getMark(col.marks, record, style)
        if (mark.icon) {
          if (mark.position === 'front') {
@@ -208,6 +283,14 @@
          }
        } else if (mark.innerStyle) {
          content = <span style={mark.innerStyle}>{content}</span>
        } else if (mark.space) {
          content = <><span dangerouslySetInnerHTML={{__html: mark.space}}></span>{content}</>
        } else if (mark.point) {
          if (mark.position === 'front') {
            content = <>{mark.point}{content}</>
          } else {
            content = <>{content}{mark.point}</>
          }
        }
      }
@@ -219,16 +302,11 @@
        resProps.rowSpan = record['$$' + col.field]
      }
      if (!record.$disabled && (col.linkThdMenu || col.linkurl)) {
        content = (
          <div>
            <div className="link-menu" onDoubleClick={(e) => triggerLink(e, col, record)}></div>
            {content}
          </div>
        )
      }
      resProps.children = content
      if (!record.$disabled && (col.linkThdMenu || col.linkurl)) {
        return (<td {...resProps} className={className + ' clickable'} onClick={(e) => triggerLink(e, col, record)} style={style}/>)
      }
    } else if (col.type === 'picture') {
      let photos = ''
      if (record[col.field]) {
@@ -252,7 +330,7 @@
        <div>
          {photos.map((url, i) => (
            <Col key={i} span={col.span || 24}>
              <MkPicture style={{paddingTop, backgroundSize: col.backgroundSize || 'cover'}} scale={scale} url={url} urls={photos}/>
              <MkPicture lostTip={col.lostTip !== 'false'} style={{paddingTop, backgroundSize: col.backgroundSize || 'cover'}} scale={scale} url={url} urls={photos}/>
            </Col>
          ))}
        </div>
@@ -313,6 +391,17 @@
        } else {
          _href += '?' + _param
        }
      } else if (/@/.test(_href)) {
        _href = _href.replace(/@id@/ig, record.$$uuid || '')
        _href = _href.replace(/@appkey@/ig, window.GLOB.appkey)
        _href = _href.replace(/@userid@/ig, sessionStorage.getItem('UserID'))
        _href = _href.replace(/@LoginUID@/ig, sessionStorage.getItem('LoginUID'))
        Object.keys(record).forEach(key => {
          if (/^\$/.test(key)) return
          let reg = new RegExp('@' + key + '@', 'ig')
          _href = _href.replace(reg, record[key])
        })
      }
      if (col.blur) {
@@ -336,13 +425,24 @@
          // eslint-disable-next-line
          let func = new Function('data', col.formula)
          content = func([record])
        } catch (e) {
          if (window.debugger) {
            console.warn(e)
          if (col.noValue === 'hide' && content === 0) {
            content = ''
          }
        } catch (e) {
          console.warn(e)
          content = ''
        }
      } else {
        if (col.eval === 'false' && col.noValue === 'hide') { // 空值隐藏
          Object.keys(record).forEach(key => {
            if (/^\$/.test(key)) return
            if (record[key]) return
            content = content.replace(new RegExp('[^@]*@' + key + '@', 'ig'), '')
          })
        }
        Object.keys(record).forEach(key => {
          let reg = new RegExp('@' + key + '@', 'ig')
          content = content.replace(reg, record[key])
@@ -351,11 +451,13 @@
          try {
            // eslint-disable-next-line
            content = eval(content)
          } catch (e) {
            if (window.debugger) {
              console.info(content)
              console.warn(e)
            if (col.noValue === 'hide' && content === 0) {
              content = ''
            }
          } catch (e) {
            window.mkInfo(content)
            console.warn(e)
            content = ''
          }
  
@@ -372,14 +474,19 @@
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      } else if (content !== '') {
        content = `${col.prefix || ''}${content}${col.postfix || ''}`
        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        if (!col.evalchars || col.evalchars.includes('enter')) {
          content = content.replace(/\n/ig, '<br/>')
        }
        if (!col.evalchars || col.evalchars.includes('space')) {
          content = content.replace(/\s/ig, '&nbsp;')
        }
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      }
      if (col.marks) {
        let mark = getMark(col.marks, record, style)
        style = style ? {...style} : {}
        style = mark.style
        let mark = getMark(col.marks, record, style)
        if (mark.icon) {
          if (mark.position === 'front') {
@@ -389,6 +496,14 @@
          }
        } else if (mark.innerStyle) {
          content = <span style={mark.innerStyle}>{content}</span>
        } else if (mark.space) {
          content = <><span dangerouslySetInnerHTML={{__html: mark.space}}></span>{content}</>
        } else if (mark.point) {
          if (mark.position === 'front') {
            content = <>{mark.point}{content}</>
          } else {
            content = <>{content}{mark.point}</>
          }
        }
      }
@@ -422,7 +537,10 @@
    loading: PropTypes.bool,         // 表格加载中
    refreshdata: PropTypes.func,     // 表格中排序列、页码的变化时刷新
    chgSelectData: PropTypes.func,   // 数据切换
    autoMatic: PropTypes.any
    autoMatic: PropTypes.any,
    allSearch: PropTypes.any,
    colsCtrls: PropTypes.any,
    parCtrl: PropTypes.any
  }
  state = {
@@ -435,11 +553,14 @@
    rowspans: null,       // 行合并字段信息
    pickup: false,        // 收起未选择项
    orderfields: {},      // 排序id与field转换
    pageOptions: []
    pageOptions: [],
    allColumns: null,
    reseting: false,
    openkeys: []
  }
  UNSAFE_componentWillMount () {
    const { setting, fields, columns } = this.props
    const { setting, columns, fields, colsCtrls, data } = this.props
    let radio = 5          // 虚化比例
    let _format = false    // 是否虚化处理
    let rowspans = []
@@ -463,38 +584,34 @@
          let cell = null
    
          if (item.type === 'colspan') {
            cell = { title: item.label, align: item.Align }
            cell = { title: item.label, align: item.Align, $key: item.uuid }
            cell.children = getColumns(item.subcols)
          } else {
            if (item.rowspan === 'true') {
              rowspans.push(item.field)
            }
            if (item.type === 'index') {
              item.field = '$Index'
              item.type = 'text'
            } else if (_format && !Math.floor(Math.random() * radio)) {
            if (_format && !Math.floor(Math.random() * radio)) {
              item.blur = true
            }
            if (item.marks && item.marks.length === 0) {
              item.marks = ''
            }
  
            if (item.field) {
              orderfields[item.uuid] = item.field
            } else if (item.sortField) {
              orderfields[item.uuid] = item.sortField
            }
  
            cell = {
              $key: item.uuid,
              align: item.Align,
              dataIndex: item.uuid,
              title: item.label,
              sorter: item.field && item.IsSort === 'true',
              sorter: (item.field || item.sortField) && item.IsSort === 'true',
              width: item.Width || 120,
              onCell: record => ({
                record,
                col: item,
                config: item.type === 'custom' ? {setting, columns: fields} : null,
                triggerLink: this.triggerLink
                openChange: item.$tree ? this.openChange : null,
              })
            }
          }
@@ -510,6 +627,7 @@
        fields.push(item.field)
        _columns.push({
          $key: item.uuid,
          align: item.Align,
          dataIndex: item.field,
          title: item.label,
@@ -542,24 +660,83 @@
      pageOptions = pageOptions.sort((a, b) => a - b)
    }
    if (setting.maxPageSize) {
      pageOptions = pageOptions.filter(item => item <= setting.maxPageSize)
    }
    let allColumns = null
    if (colsCtrls) {
      rowspans = null
      allColumns = [..._columns]
      _columns = this.getCurColumns(_columns, this.props.allSearch)
    }
    if (setting.$tree) {
      this.resetOpenKeys(data)
    }
    this.setState({
      pageSize: setting.pageSize || 10,
      pageOptions,
      allColumns,
      columns: _columns,
      rowspans,
      tableId,
      orderfields
    }, () => {
      const element = document.getElementById(tableId)
      element && element.style.setProperty('--mk-table-border-color', setting.borderColor || '#e8e8e8')
      element && element.style.setProperty('--mk-table-color', setting.color || 'rgba(0, 0, 0, 0.65)')
      element && element.style.setProperty('--mk-table-font-size', setting.fontSize || '14px')
      element && element.style.setProperty('--mk-table-font-weight', setting.fontWeight || 'normal')
    })
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    const { allSearch, parCtrl, setting, data } = this.props
    const { allColumns } = this.state
    if (allSearch && !is(fromJS(allSearch), fromJS(nextProps.allSearch))) {
      this.setState({
        reseting: true,
        columns: this.getCurColumns(allColumns, nextProps.allSearch)
      }, () => {
        this.setState({reseting: false})
      })
    } else if (parCtrl && !is(fromJS(this.props.columns), fromJS(nextProps.columns))) {
      let getColumns = (cols) => {
        return cols.map(item => {
          let cell = null
          if (item.type === 'colspan') {
            cell = { title: item.label, align: item.Align }
            cell.children = getColumns(item.subcols)
          } else {
            cell = {
              align: item.Align,
              dataIndex: item.uuid,
              title: item.label,
              sorter: (item.field || item.sortField) && item.IsSort === 'true',
              width: item.Width || 120,
              onCell: record => ({
                record,
                col: item,
                config: item.type === 'custom' ? {setting: this.props.setting, columns: this.props.fields} : null,
                openChange: item.$tree ? this.openChange : null,
              })
            }
          }
          return cell
        })
      }
      this.setState({
        columns: getColumns(nextProps.columns)
      })
    }
    if (setting.$tree && !is(fromJS(data), fromJS(nextProps.data))) {
      this.resetOpenKeys(nextProps.data)
    }
  }
  componentDidMount () {
@@ -588,6 +765,127 @@
    MKEmitter.removeListener('autoQueryData', this.autoQueryData)
    MKEmitter.removeListener('autoSelectData', this.autoSelectData)
    MKEmitter.removeListener('mkCheckTopLine', this.mkCheckTopLine)
  }
  resetOpenKeys = (data) => {
    const { setting } = this.props
    if (!data || data.length === 0 || !setting.defOpen) {
      this.setState({openkeys: []})
    } else if (setting.defOpen === 'topline') {
      let keys = []
      if (data[0].$open) {
        keys = [data[0].$key]
        data.forEach(item => {
          if (item.$pkeys && item.$pkeys.length > 1 && item.$pkeys.includes(data[0].$key)) {
            keys.push(...item.$pkeys)
          }
        })
        keys = Array.from(new Set(keys))
      }
      this.setState({openkeys: keys})
    } else {
      this.setState({openkeys: data.filter(item => !!item.$open).map(item => item.$key)})
    }
  }
  openChange = (e, key) => {
    const { setting, MenuID, data } = this.props
    const { openkeys, selectedRowKeys } = this.state
    e.stopPropagation()
    let _openkeys = []
    if (openkeys.includes(key)) {
      _openkeys = openkeys.filter(k => k !== key)
    } else {
      _openkeys = [...openkeys, key]
    }
    if (!setting.tableType || _openkeys.length > openkeys.length) {
      this.setState({openkeys: _openkeys})
      return
    }
    let newkeys = fromJS(selectedRowKeys).toJS()
    newkeys = newkeys.filter(k => {
      if (!data[k]) return false
      if (!data[k].$pkeys) return true
      return data[k].$pkeys.every(key => _openkeys.includes(key))
    })
    if (newkeys.length === selectedRowKeys.length) {
      this.setState({openkeys: _openkeys})
      return
    }
    let _index = ''
    if (newkeys.length > 0) {
      _index = newkeys.slice(-1)[0]
    }
    this.changedata(_index)
    this.setState({ openkeys: _openkeys, selectedRowKeys: newkeys, activeIndex: _index !== '' ? _index : null })
    let selects = data.filter((item, _index) => newkeys.includes(_index))
    this.props.chgSelectData(selects)
    if (setting.$hasSyncModule) {
      MKEmitter.emit('syncBalconyData', MenuID, selects, false)
    }
  }
  getCurColumns = (columns, allSearch) => {
    const { colsCtrls } = this.props
    let values = {}
    allSearch.forEach(item => {
      values[item.key] = item.value
    })
    let cols = null
    colsCtrls.some(item => {
      let originVal = item.field.map(f => values[f] || '').join('')
      let contrastVal = item.contrastValue
      let result = false
      if (item.match === '=') {
        result = originVal === contrastVal
      } else if (item.match === '!=') {
        result = originVal !== contrastVal
      } else if (item.match === 'regexp') {
        let reg = new RegExp(item.contrastValue, 'ig')
        result = reg.test(originVal)
      } else {
        originVal = isNaN(originVal) ? originVal : +originVal
        contrastVal = isNaN(contrastVal) ? contrastVal : +contrastVal
        if (item.match === '>') {
          result = originVal > contrastVal
        } else if (item.match === '<') {
          result = originVal < contrastVal
        }
      }
      if (!result) return false
      cols = item.cols
      return true
    })
    if (cols) {
      return columns.filter(col => cols.includes(col.$key))
    }
    return columns
  }
  autoSelectData = (id, index) => {
@@ -629,15 +927,27 @@
    this.props.refreshdata({pageIndex})
  }
  mkCheckTopLine = (menuId, id, type) => {
  mkCheckTopLine = (menuId, id, selected, orikeys) => {
    const { MenuID, data, setting } = this.props
    if (MenuID !== menuId || !data || data.length === 0) return
    if (MenuID !== menuId) return
    if (!data || data.length === 0) {
      MKEmitter.emit('resetSelectLine', menuId, '', '')
      return
    }
    if (type === 'sign') {
      let index = ''
      let keys = []
      let items = []
    let index = -1
    let keys = []
    let items = []
    if (id) {
      index = data.findIndex(item => item.$$uuid === id && !item.$disabled)
    }
    if (index !== -1) {
      keys = [index]
      items = [data[index]]
    } else if (selected === 'sign') {
      data.forEach((item, i) => {
        if (!item.$disabled && item.selected === 'true') {
          items.push(item)
@@ -645,33 +955,35 @@
          index = i
        }
      })
      this.changedata(index)
      this.setState({ selectedRowKeys: keys, activeIndex: index })
      this.props.chgSelectData(items)
      if (setting.$hasSyncModule) {
        MKEmitter.emit('syncBalconyData', MenuID, items, data.length === keys.length)
    } else if (selected === 'local') {
      if (orikeys && orikeys.length) {
        data.forEach((item, i) => {
          if (!item.$disabled && orikeys.includes(item.$$uuid)) {
            items.push(item)
            keys.push(i)
            index = i
          }
        })
      }
    } else if (selected !== 'false') {
      if (!data[0].$disabled) {
        index = 0
        keys = [index]
        items = [data[index]]
      }
    }
    if (index === -1) {
      MKEmitter.emit('resetSelectLine', menuId, '', '')
      return
    }
    let index = 0
    if (id) {
      index = data.findIndex(item => item.$$uuid === id)
      if (index === -1) {
        index = 0
      }
    }
    if (data[index].$disabled) return
    this.changedata(index)
    this.setState({ selectedRowKeys: [index], activeIndex: index })
    this.props.chgSelectData([data[index]])
    this.setState({ selectedRowKeys: keys, activeIndex: index })
    this.props.chgSelectData(items)
    if (setting.$hasSyncModule) {
      MKEmitter.emit('syncBalconyData', MenuID, [data[index]], data.length === 1)
      MKEmitter.emit('syncBalconyData', MenuID, items, data.length === keys.length)
    }
  }
@@ -691,7 +1003,7 @@
      MKEmitter.emit('resetSelectLine', MenuID, '', '')
      MKEmitter.emit('syncBalconyData', MenuID, data, data.length > 0)
      if (data.length === 0) {
        message.warning('未获取到数据!')
        message.warning(window.GLOB.dict['no_data'] || '未获取到数据!')
      }
    } else {
      this.setState({
@@ -706,52 +1018,10 @@
    }
  }
  // 字段透视
  triggerLink = (e, item, record) => {
    e.stopPropagation()
    let __param = {
      $searchkey: item.field,
      $searchval: record[item.field] || '',
      $BID: record.$$uuid
    }
    if (item.linkfields && item.linkfields.length > 0) {
      item.linkfields.forEach(field => {
        __param[field] = record[field] || ''
      })
    }
    if (item.linkThdMenu) {
      let tabmenu = item.linkThdMenu
      tabmenu.param = __param
      MKEmitter.emit('modifyTabs', tabmenu, true)
    } else if (item.linkurl) {
      let src = item.linkurl
      let con = '?'
      if (/\?/ig.test(src)) {
        con = '&'
      }
      if (item.linkfields && item.linkfields.length > 0) {
        item.linkfields.forEach(field => {
          if (field.toLowerCase() === 'id') return
          con += `${field}=${record[field] || ''}&`
        })
      }
      src = src + `${con}id=${record.$$uuid}&appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}`
      window.open(src)
    }
  }
  onSelectChange = (selectedRowKeys, e) => {
    const { setting, MenuID, data } = this.props
    if (this.state.pickup) return
    let index = ''
    let _activeIndex = null
@@ -818,21 +1088,44 @@
  }
  changeTable = (pagination, filters, sorter) => {
    const { orderfields } = this.state
    this.setState({
      pageIndex: pagination.current,
      pageSize: pagination.pageSize,
      selectedRowKeys: [],
      activeIndex: null,
      pickup: false
    })
    const { setting } = this.props
    const { orderfields, pageSize } = this.state
    if (orderfields) {
      sorter.field = orderfields[sorter.field] || ''
    }
    this.props.refreshdata(pagination, filters, sorter)
    if (setting.$tree) {
      this.setState({
        pageIndex: 1,
        selectedRowKeys: [],
        activeIndex: null,
        pickup: false
      })
      this.props.refreshdata({current: 1, pageSize: pageSize}, sorter)
    } else {
      this.setState({
        pageIndex: pagination.current,
        pageSize: pagination.pageSize,
        selectedRowKeys: [],
        activeIndex: null,
        pickup: false
      })
      this.props.refreshdata(pagination, sorter)
    }
  }
  onPaginationChange = (current, pageSize) => {
    this.setState({
      pageIndex: current,
      pageSize: pageSize,
      selectedRowKeys: [],
      activeIndex: null
    })
    this.props.refreshdata({current: current, pageSize: pageSize, fixed: true}, {})
  }
  changedata = (index) => {
@@ -888,22 +1181,9 @@
      if (setting.$hasSyncModule) {
        MKEmitter.emit('syncBalconyData', MenuID, selects, data.length === selects.length)
      }
    } else if (type === 'false') {
      this.setState({
        selectedRowKeys: [],
        activeIndex: null,
        pickup: false
      })
    } else if (type === 'repage') {
      this.setState({
        pageIndex: Index,
        selectedRowKeys: [],
        activeIndex: null,
        pickup: false
      })
    } else {
      this.setState({
        pageIndex: 1,
        pageIndex: type === 'false' ? this.state.pageIndex : 1,
        selectedRowKeys: [],
        activeIndex: null,
        pickup: false
@@ -977,12 +1257,14 @@
    if (!setting.doubleClick) return
    if (record.$disabled) return
    MKEmitter.emit('triggerBtnId', setting.doubleClick, [record], 'linkbtn')
    MKEmitter.emit('triggerBtnId', setting.doubleClick, [record], 'linkbtn', (record.$$uuid || '') + (record.$Index || ''))
  }
  render() {
    const { setting, statFValue, lineMarks, data } = this.props
    const { selectedRowKeys, activeIndex, pickup, tableId, pageOptions, columns } = this.state
    const { selectedRowKeys, activeIndex, pickup, pageOptions, columns, reseting, openkeys } = this.state
    if (reseting) return null
    // 设置表格选择属性:单选、多选、不可选
    let rowSelection = null
@@ -1007,21 +1289,23 @@
    // 数据收起时,过滤已选数据
    let _data = data || []
    if (pickup) {
      _data = _data.filter((item, index) => selectedRowKeys.includes(index))
    if (!setting.$tree) {
      if (pickup) {
        _data = _data.filter((item, index) => selectedRowKeys.includes(index))
      }
      _data = this.handleRowspan(_data)
    }
    _data = this.handleRowspan(_data)
    
    let _pagination = false
    if (setting.laypage !== 'false' && setting.laypage !== false) {
    if (setting.laypage && !setting.$tree) {
      _pagination = {
        current: this.state.pageIndex,
        pageSize: this.state.pageSize,
        pageSizeOptions: pageOptions,
        showSizeChanger: true,
        total: this.props.total || 0,
        showTotal: (total, range) => `${range[0]}-${range[1]} 共 ${total} 条`
        showTotal: (total, range) => `${range[0]}-${range[1]} ${window.GLOB.dict['of'] || '共'} ${total} ${window.GLOB.dict['items'] || '条'}`
      }
    }
@@ -1032,8 +1316,14 @@
    }
    let height = setting.height || false
    if (height && height <= 100) {
      height = height + 'vh'
    if (height) {
      if (height <= 100) {
        if (height < 0) {
          height = `calc(100vh - ${-height}px)`
        } else {
          height = height + 'vh'
        }
      }
    }
    let loading = this.props.loading
    if (setting.mask === 'hidden') {
@@ -1050,10 +1340,17 @@
      }
    }
    let style = {
      '--mk-table-border-color': setting.borderColor || '#e8e8e8',
      '--mk-table-color': setting.color || 'rgba(0, 0, 0, 0.65)',
      '--mk-table-font-size': setting.fontSize || '14px',
      '--mk-table-font-weight': setting.fontWeight || 'normal'
    }
    return (
      <div className={`normal-custom-table ${setting.tableHeader || ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || 'middle'} table-col-${columns.length} ${fixed}`} id={tableId}>
        {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && data && data.length > 0 ?
          <Switch title="收起" className="main-pickup" checkedChildren="开" unCheckedChildren="关" checked={pickup} onChange={this.pickupChange} /> : null
      <div className={`normal-custom-table ${setting.tableHeader || ''} ${setting.parity === 'true' ? 'mk-parity' : ''} ${height ? 'fixed-table-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || 'middle'} table-col-${columns.length} ${fixed} ${setting.empSign === 'hidden' ? 'mk-empty-hide' : ''}`} style={style}>
        {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && data && data.length > 0 && !setting.$tree ?
          <Switch title="收起" className="main-pickup" checkedChildren={window.GLOB.dict['open'] || '开'} unCheckedChildren={window.GLOB.dict['shut'] || '关'} checked={pickup} onChange={this.pickupChange} /> : null
        }
        <Table
          components={components}
@@ -1065,11 +1362,26 @@
          loading={loading}
          scroll={{ x: '100%', y: height }}
          onRow={(record, index) => {
            let className = ''
            if (index === activeIndex) {
              className = ' mk-row-active '
            }
            if (setting.$tree) {
              if (record.$open && openkeys.includes(record.$key)) {
                className += ' mk-tree-open '
              }
              if (record.$pkeys && !record.$pkeys.every(key => openkeys.includes(key))) {
                className += ' mk-tree-hide '
              }
            }
            return {
              lineMarks: setting.tableMode !== 'fast' ? lineMarks : null,
              lineMarks: lineMarks,
              data: record,
              title: setting.tipField ? record[setting.tipField] : '',
              className: index === activeIndex ? ' mk-row-active ' : '',
              className: className,
              onClick: () => {this.changeRow(record, index)},
              onDoubleClick: () => {this.doubleClickLine(record)}
            }
@@ -1077,6 +1389,17 @@
          onChange={this.changeTable}
          pagination={_pagination}
        />
        {setting.laypage && setting.$tree ? <Pagination
          showSizeChanger
          className="mk-tree-pagination"
          onChange={this.onPaginationChange}
          onShowSizeChange={this.onPaginationChange}
          current={this.state.pageIndex}
          pageSize={this.state.pageSize}
          pageSizeOptions={pageOptions}
          total={this.props.total || 0}
          showTotal={(total, range) => `${range[0]}-${range[1]} ${window.GLOB.dict['of'] || '共'} ${total} ${window.GLOB.dict['items'] || '条'}`}
        /> : null}
        {_footer ? <div className={'normal-table-footer ' + (_pagination ? 'pagination' : '')}>{_footer}</div> : null}
      </div>
    )