king
2021-12-22 bd1dfc9e6c9b9f8076ca2783ce598e0936b4c664
src/templates/zshare/modalform/modaleditable/index.jsx
@@ -1,6 +1,9 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Table, Input, Popconfirm, Form, Icon, Radio } from 'antd'
import { Table, Input, Popconfirm, Form, Radio } from 'antd'
import { ArrowUpOutlined, ArrowDownOutlined, DeleteOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons'
import { formRule } from '@/utils/option.js'
import Utils from '@/utils/utils.js'
import './index.scss'
@@ -107,42 +110,52 @@
}
class EditTable extends Component {
  constructor(props) {
    super(props)
  static propTpyes = {
    type: PropTypes.string,         // 表单类型
    linkSubFields: PropTypes.array, // 关联字段
    onChange: PropTypes.func        // 数据变化
  }
    let _width = '40%'
  state = {
    columns: [],
    dataSource: [],
    count: 0,
    type: null,
    linkSubFields: []
  }
  UNSAFE_componentWillMount () {
    const { linkSubFields, type } = this.props
    let data = this.props['data-__meta'].initialValue
    if (!data) {
      data = []
    }
    let fields = []
    let dataItem = props.data ? props.data[0] : ''
    let dataItem = data[0] || ''
    if (props.type === 'link') {
      _width = '27%'
    } else if (props.type === 'select') {
      _width = Math.floor(80 / (props.linkSubFields.length + 2)) + '%'
      fields = props.linkSubFields.map(field => {
    if (type === 'select' || type === 'radio' || type === 'link') {
      fields = linkSubFields.map(cell => {
        return {
          title: field.label,
          dataIndex: field.field,
          width: _width,
          title: cell.label,
          dataIndex: cell.field,
          editable: true,
          datatype: dataItem && typeof(dataItem[field.field]) === 'number' ? 'number' : 'string'
          datatype: dataItem && typeof(dataItem[cell.field]) === 'number' ? 'number' : 'string'
        }
      })
    }
    let columns = [
      {
        title: 'Value',
        dataIndex: 'Value',
        width: _width,
        editable: true,
        datatype: dataItem && typeof(dataItem.Value) === 'number' ? 'number' : 'string'
      },
      {
        title: 'Text',
        dataIndex: 'Text',
        width: _width,
        editable: true,
        datatype: dataItem && typeof(dataItem.Text) === 'number' ? 'number' : 'string'
      },
@@ -150,46 +163,45 @@
      {
        title: '操作',
        align: 'center',
        width: '20%',
        dataIndex: 'operation',
        render: (text, record) =>
          this.state.dataSource.length >= 1 ? (
            <div>
              <span className="operation-btn" title={props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
              <span className="operation-btn" title={props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
              <span className="operation-btn" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><ArrowUpOutlined /></span>
              <span className="operation-btn" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><ArrowDownOutlined /></span>
              <Popconfirm
                overlayClassName="popover-confirm"
                title={props.dict['header.form.query.delete']}
                onConfirm={() => this.handleDelete(record.key)
              }>
                <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span>
                <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span>
              </Popconfirm>
            </div>
          ) : null,
      }
    ]
    if (props.type === 'link') {
    if (type === 'link') {
      columns.unshift({
        title: 'ParentID',
        dataIndex: 'ParentID',
        width: '27%',
        editable: true,
        datatype: dataItem && typeof(dataItem.ParentID) === 'number' ? 'number' : 'string'
      })
    }
    this.state = {
    this.setState({
      columns: columns.map(col => {
        if (col.dataIndex !== 'operation') {
          col = {...col, ...this.getColumnSearchProps(col)}
        }
        return col
      }),
      dataSource: props.data,
      count: props.data.length,
      type: props.type,
      linkSubFields: props.linkSubFields
    }
      dataSource: data,
      count: data.length,
      type: type,
      linkSubFields: linkSubFields
    })
  }
  getColumnSearchProps = column => ({
@@ -197,43 +209,44 @@
      <div style={{ padding: 8 }}>
        <Radio.Group onChange={(e) => this.changeDatatype(column, e)} value={column.datatype}>
          <Radio style={{display: 'block', height: '30px', lineHeight: '30px'}} value="string">
            String
            字符串
          </Radio>
          <Radio style={{display: 'block', height: '30px', lineHeight: '30px'}} value="number">
            Number
            数字
          </Radio>
        </Radio.Group>
      </div>
    ),
    filterIcon: () => (
      <Icon type="swap" style={{ color: column.datatype === 'number' ? '#1890ff' : undefined}} />
      <SwapOutlined style={{ color: column.datatype === 'number' ? '#1890ff' : ''}} />
    )
  })
  changeDatatype = (column, e) => {
    const { columns, dataSource } = this.state
    let value = e.target.value
    this.setState({
      dataSource: dataSource.map(item => {
        let val = item[column.dataIndex]
        if (value === 'number') {
          try {
            val = parseFloat(val)
            if (isNaN(val)) {
              val = ''
            }
          } catch {
    let _data = dataSource.map(item => {
      let val = item[column.dataIndex]
      if (value === 'number') {
        try {
          val = parseFloat(val)
          if (isNaN(val)) {
            val = ''
          }
        } else {
          val = '' + val
        } catch (e) {
          val = ''
        }
      } else {
        val = '' + val
      }
        item[column.dataIndex] = val
      item[column.dataIndex] = val
        return item
      }),
      return item
    })
    this.setState({
      dataSource: _data,
      columns: columns.map(col => {
        if (col.dataIndex === column.dataIndex) {
          col.datatype = value
@@ -245,6 +258,8 @@
        return col
      })
    }, () => {
      this.props.onChange(_data)
    })
  }
@@ -271,15 +286,22 @@
    this.setState({
      dataSource: _data
    }, () => {
      this.props.onChange(_data)
    })
  }
  handleDelete = key => {
    const dataSource = [...this.state.dataSource]
    this.setState({ dataSource: dataSource.filter(item => item.key !== key) })
    const { dataSource } = this.state
    let _data = dataSource.filter(item => item.key !== key)
    this.setState({ dataSource: _data }, () => {
      this.props.onChange(_data)
    })
  }
  handleAdd = () => {
  handleAdd = (e) => {
    e.stopPropagation()
    const { type, count, dataSource } = this.state
    const newData = {
      key: Utils.getuuid(),
@@ -289,9 +311,14 @@
    if (type === 'link') {
      newData.ParentID = `${count}`
    }
    let _data = [...dataSource, newData]
    this.setState({
      dataSource: [...dataSource, newData],
      dataSource: _data,
      count: count + 1
    }, () => {
      this.props.onChange(_data)
    })
  }
@@ -303,16 +330,17 @@
      ...item,
      ...row
    })
    this.setState({ dataSource: newData })
    this.setState({ dataSource: newData }, () => {
      this.props.onChange(newData)
    })
  }
  resetColumn = (type, linkSubFields) => {
    let dataSource = JSON.parse(JSON.stringify(this.state.dataSource))
    let _width = '40%'
    let fields = []
    if (type === 'select' && linkSubFields.length > this.state.linkSubFields) {
      let addcol = linkSubFields[linkSubFields.length - 1]
    if ((type === 'select' || type === 'radio') && linkSubFields.length > this.state.linkSubFields) {
      let addcol = linkSubFields.slice(-1)[0]
      dataSource = dataSource.map(data => {
        data[addcol.field] = data.Text
        return data
@@ -321,15 +349,11 @@
    let dataItem = dataSource ? dataSource[0] : ''
    if (type === 'link') {
      _width = '27%'
    } else if (type === 'select') {
      _width = Math.floor(80 / (linkSubFields.length + 2)) + '%'
    if (type === 'select' || type === 'radio' || type === 'link') {
      fields = linkSubFields.map(field => {
        return {
          title: field.label,
          dataIndex: field.field,
          width: _width,
          editable: true,
          datatype: dataItem && typeof(dataItem[field.field]) === 'number' ? 'number' : 'string'
        }
@@ -340,14 +364,12 @@
      {
        title: 'Value',
        dataIndex: 'Value',
        width: _width,
        editable: true,
        datatype: dataItem && typeof(dataItem.Value) === 'number' ? 'number' : 'string'
      },
      {
        title: 'Text',
        dataIndex: 'Text',
        width: _width,
        editable: true,
        datatype: dataItem && typeof(dataItem.Text) === 'number' ? 'number' : 'string'
      },
@@ -355,18 +377,18 @@
      {
        title: '操作',
        align: 'center',
        width: '20%',
        dataIndex: 'operation',
        render: (text, record) =>
          this.state.dataSource.length >= 1 ? (
            <div>
              <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
              <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
              <span className="operation-btn" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><ArrowUpOutlined /></span>
              <span className="operation-btn" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><ArrowDownOutlined /></span>
              <Popconfirm
                overlayClassName="popover-confirm"
                title={this.props.dict['header.form.query.delete']}
                onConfirm={() => this.handleDelete(record.key)
              }>
                <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span>
                <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span>
              </Popconfirm>
            </div>
          ) : null,
@@ -377,7 +399,6 @@
      columns.unshift({
        title: 'ParentID',
        dataIndex: 'ParentID',
        width: '27%',
        editable: true,
        datatype: dataItem && typeof(dataItem.ParentID) === 'number' ? 'number' : 'string'
      })
@@ -392,28 +413,14 @@
      }),
      dataSource: dataSource,
      type: type
    }, () => {
      this.props.onChange(dataSource)
    })
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) || this.props.type !== nextProps.type) {
      this.resetColumn(nextProps.type, nextProps.linkSubFields)
    } else if (!is(fromJS(this.props.data), fromJS(nextProps.data))) {
      let _data = []
      nextProps.data.forEach(item => {
        let _item = {key: Utils.getuuid()}
        this.state.columns.forEach(col => {
          _item[col.dataIndex] = item[col.dataIndex] || ''
          if (col.dataIndex !== 'ParentID' && !_item[col.dataIndex]) {
            _item[col.dataIndex] = item.Text
          }
        })
        _data.push(_item)
      })
      this.setState({
        dataSource: _data,
        count: nextProps.data.length
      })
    }
  }
@@ -443,7 +450,7 @@
    })
    return (
      <div className="common-modal-edit-table">
        <Icon className="add-row" type="plus" onClick={this.handleAdd} />
        <PlusOutlined className="add-row" onClick={this.handleAdd} />
        <Table
          components={components}
          rowClassName={() => 'editable-row'}