king
2020-03-26 a24beb36feaa46f39cbb26ce5277e84f91241ce8
src/tabviews/zshare/verifycard/index.jsx
@@ -1,387 +1,346 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Tabs, Row, Col, Radio, Table, Icon, Select, notification } from 'antd'
import { Form, Tabs, notification, Spin, Icon } from 'antd'
import Utils from '@/utils/utils.js'
// import Utils from '@/utils/utils.js'
import Api from '@/api'
import ActionForm from './actionform'
import TabCard from './tabcard'
import './index.scss'
const { TabPane } = Tabs
const keycode = {
  65: 'A',
  66: 'B',
  67: 'C',
  68: 'D',
  69: 'E',
  70: 'F',
  71: 'G',
  72: 'H',
  73: 'I',
  74: 'J',
  75: 'K',
  76: 'L',
  77: 'M',
  78: 'N',
  79: 'O',
  80: 'P',
  81: 'Q',
  82: 'R',
  83: 'S',
  84: 'T',
  85: 'U',
  86: 'V',
  87: 'W',
  88: 'X',
  89: 'Y',
  90: 'Z'
}
class VerifyCard extends Component {
  static propTpyes = {
    config: PropTypes.object     // 页面配置
    MenuID: PropTypes.string,
    MenuName: PropTypes.string,
    permAction: PropTypes.object,
    permRoles: PropTypes.array,
    userConfig: PropTypes.object,
    columns: PropTypes.array,
    config: PropTypes.object,     // 页面配置
    handleParam: PropTypes.func   // 配置信息变化
  }
  state = {
    colColumns: [
      {
        title: '字段名',
        dataIndex: 'field',
        width: '35%'
      },
      {
        title: '操作',
        align: 'center',
        width: '25%',
        dataIndex: 'operation',
        render: (text, record) =>
          (<div>
            <span className="operation-btn" title="编辑" onClick={() => this.handleEdit(record, 'column')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
            <span className="operation-btn" title="上移" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
            <span className="operation-btn" title="下移" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
            <span className="operation-btn" title="状态切换" onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span>
          </div>)
      }
    ],
    actionColumns: [
      {
        title: '名称',
        dataIndex: 'label',
        width: '25%'
      },
      {
        title: '快捷键',
        dataIndex: 'shortcut',
        width: '25%',
        render: (text, record) => {
          if (!record.shortcut || typeof(record.shortcut) !== 'object' || record.shortcut.length === 0) return ''
          let _text = keycode[record.shortcut[1]]
          return record.shortcut[0] + ' + ' + _text
        }
      },
      {
        title: '打印机',
        dataIndex: 'printer',
        width: '30%'
      },
      {
        title: '操作',
        align: 'center',
        width: '20%',
        dataIndex: 'operation',
        render: (text, record) =>
          (<div>
            <span className="operation-btn" title="编辑" onClick={() => this.handleEdit(record, 'action')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
          </div>)
      }
    ]
    loading: true,
    menuParam: null,
    menuconfig: null
  }
  UNSAFE_componentWillMount() {
    const { config } = this.props
  UNSAFE_componentWillMount () {
    const { MenuID, MenuName, permAction, permRoles, config, userConfig, columns } = this.props
    let menuParam = []
    this.setState({
      config: JSON.parse(JSON.stringify(config))
      loadingview: true
    })
  }
  componentDidMount() {
    let printbtns = this.state.config.action.filter(item => item.OpenType === 'funcbutton' && item.funcType === 'print')
    printbtns.forEach(item => {
      if (!item.verify || !item.verify.linkUrl) {
        notification.warning({
          top: 92,
          message: '打印按钮《' + item.label + '》设置错误!',
          duration: 10
        })
      } else {
        let socket = null
        socket = new WebSocket('ws://' + item.verify.linkUrl)
        // 打开Socket
        socket.onopen = () =>{
          let request  = {
            requestID: '',
            version: '',
            cmd: 'getPrinters'
          }
          socket.send(JSON.stringify(request))
        }
        // 监听消息
        socket.onmessage = (event) => {
          let data = ''
          try {
            data = JSON.parse(event.data)
          } catch {
            data = ''
          }
          if (data && data.cmd === 'getPrinters' && data.status) {
            let printers = Array.from(new Set(data.printers))
            let _config = JSON.parse(JSON.stringify(this.state.config))
            _config.action = _config.action.map(cell => {
              if (item.uuid === cell.uuid) {
                cell.printer = cell.printer || data.defaultPrinter
                cell.printers = printers.map(print => {
                  return {
                    value: print,
                    text: print
                  }
                })
              }
              return cell
            })
            this.setState({
              config: _config
            })
          } else if (data && data.cmd === 'getPrinters' && !data.status) {
            notification.warning({
              top: 92,
              message: data.message,
              duration: 10
            })
          }
    menuParam.push({
      uuid: MenuID,
      type: 'main',
      label: MenuName + '(主表)',
      setting: {
        actionfixed: config.setting.actionfixed,
        columnfixed: config.setting.columnfixed,
        tableType: config.setting.tableType
      },
      action: config.action.map(item => {
        let _item = {
          uuid: item.uuid,
          label: item.label,
          shortcut: item.shortcut || ''
        }
        socket.onerror = () => {
        if (item.OpenType === 'funcbutton' && item.funcType === 'print') {
          _item.type = 'print'
          _item.verify = item.verify
          _item.printer = item.printer || ''
        }
        return _item
      }),
      columns: columns.map(item => {
        return {
          uuid: item.uuid,
          label: item.label,
          Width: item.Width,
          hidden: item.hidden || false,
          sort: item.sort || 0
        }
      })
    })
    let deffers = []
    config.tabgroups.forEach(groupId => {
      config[groupId].forEach(tab => {
        deffers.push(new Promise(resolve => {
          let param = {
            func: 'sPC_Get_LongParam',
            MenuID: tab.linkTab
          }
          Api.getSystemCacheConfig(param).then(res => {
            res.tab = tab
            resolve(res)
          })
        }))
      })
    })
    if (deffers.length > 0) {
      Promise.all(deffers).then(result => {
        let errors = result.filter(res => !res.status)
        if (errors.length > 0) {
          notification.warning({
            top: 92,
            message: '无法连接到:' + item.verify.linkUrl,
            message: errors[0].message,
            duration: 10
          })
          return
        }
      }
    })
  }
  columnChange = (values) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
        result.forEach(res => {
          if (!res.LongParam) return
    if (values.uuid) {
      verify.uniques = verify.uniques.map(item => {
        if (item.uuid === values.uuid) {
          return values
        } else {
          return item
        }
      })
    } else {
      values.uuid = Utils.getuuid()
      verify.uniques.push(values)
    }
          let subconfig = ''
          let subUserConfig = userConfig ? userConfig[res.tab.linkTab] : ''
    this.setState({
      verify: verify
    })
  }
          try {
            subconfig = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
          } catch (e) {
            console.warn('Parse Failure')
            errors.push('子标签《' + res.tab.label + '》参数解析错误!')
          }
  actionChange = (values) => {
    let config = JSON.parse(JSON.stringify(this.state.config))
          if (!subconfig || !subconfig.enabled) return
    config.action = config.action.map(item => {
      if (values.uuid === item.uuid) {
        item = {...item, ...values}
      }
          let _columns = []      // 显示列
          let _hideCol = []      // 隐藏及合并列中字段的uuid集
          let colMap = new Map()
      return item
    })
    this.setState({
      config: config
    })
  }
  handleEdit = (record, type) => {
    if (type === 'action') {
      this.actionForm.edit(record)
    } else if (type === 'column') {
      this.uniqueForm.edit(record)
    }
    let node = document.getElementById('verify-card-box-tab').parentNode
    if (node && node.scrollTop) {
      let inter = Math.ceil(node.scrollTop / 10)
      let timer = setInterval(() => {
        if (node.scrollTop - inter > 0) {
          node.scrollTop = node.scrollTop - inter
        } else {
          node.scrollTop = 0
          clearInterval(timer)
        }
      }, 10)
    }
  }
  handleStatus = (record) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    record.status = record.status === 'false' ? 'true' : 'false'
    verify.scripts = verify.scripts.map(item => {
      if (item.uuid === record.uuid) {
        return record
      } else {
        return item
      }
    })
    this.setState({
      verify: verify
    })
  }
  handleUpDown = (record, type, direction) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    let index = 0
    verify.customverifys = verify.customverifys.filter((item, i) => {
      if (item.uuid === record.uuid) {
        index = i
      }
      return item.uuid !== record.uuid
    })
    if ((index === 0 && direction === 'up') || (index === verify.customverifys.length && direction === 'down')) {
      return
    }
    if (direction === 'up') {
      verify.customverifys.splice(index - 1, 0, record)
    } else {
      verify.customverifys.splice(index + 1, 0, record)
    }
    this.setState({
      verify: verify
    })
  }
  handleConfirm = () => {
    const { config } = this.state
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let _config = {}
          _config.setting = values
          _config.action = config.action.map(item => {
            return {
              uuid: item.uuid,
              shortcut: item.shortcut || '',
              shortcutkey: item.shortcutkey || '',
              printer: item.printer || ''
          // 权限过滤
          subconfig.action = subconfig.action.filter(item => permAction[item.uuid])
          subconfig.columns = subconfig.columns.filter(col => {
            if (!col.field || !col.blacklist || col.blacklist.length === 0 || subconfig.setting.primaryKey === col.field) return true
            let _black = col.blacklist.filter(v => {
              return permRoles.indexOf(v) !== -1
            })
            if (_black.length > 0) {
              return false
            } else {
              return true
            }
          })
          resolve(_config)
          if (subUserConfig) {
            subconfig.setting.tableType = subUserConfig.setting.tableType
            subconfig.action = subconfig.action.map(item => {
              if (subUserConfig.action[item.uuid]) {
                item = {...item, ...subUserConfig.action[item.uuid]}
              }
              if (item.execMode) {
                item.OpenType = 'funcbutton'
              }
              if (item.OpenType === 'funcbutton' && item.funcType === 'print' && item.verify && item.printer) {
                item.verify.defaultPrinter = item.printer.defaultPrinter || ''
                if (item.verify.printerTypeList && item.printer.printerList) {
                  item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
                    cell.printer = item.printer.printerList[cell.Value] || ''
                    return cell
                  })
                }
              }
              return item
            })
          } else {
            subconfig.action = subconfig.action.map(item => {
              if (item.execMode) {
                item.OpenType = 'funcbutton'
              }
              return item
            })
          }
          // 1、筛选字段集,2、过滤隐藏列及合并列中的字段uuid
          subconfig.columns.forEach(col => {
            if (col.type === 'colspan' && col.sublist) { // 筛选隐藏列
              _hideCol = _hideCol.concat(col.sublist)
            } else if (col.Hide === 'true') {
              _hideCol.push(col.uuid)
            }
            colMap.set(col.uuid, col)
          })
          // 生成显示列,处理合并列中的字段
          subconfig.columns.forEach(col => {
            if (_hideCol.includes(col.uuid)) return
            if (col.type === 'colspan' && col.sublist) {
              let _col = JSON.parse(JSON.stringify(col))
              let subColumn = []
              _col.sublist.forEach(sub => {
                if (colMap.has(sub)) {
                  subColumn.push(colMap.get(sub))
                }
              })
              _col.subColumn = subColumn
              _columns.push(_col)
            } else {
              _columns.push(col)
            }
          })
          let _operations = subconfig.action.filter(item => item.position === 'grid')
          if (subconfig.gridBtn && subconfig.gridBtn.display && _operations.length > 0) {
            _columns.push({
              ...subconfig.gridBtn,
              operations: _operations
            })
          }
          // 添加用户显示列设置
          if (subUserConfig) {
            _columns = _columns.map(item => {
              if (subUserConfig.columns[item.uuid]) {
                item = {...item, ...subUserConfig.columns[item.uuid]}
              }
              return item
            })
            _columns.sort((pre, next) => {
              return pre.sort - next.sort
            })
          }
          menuParam.push({
            uuid: res.tab.linkTab,
            label: res.tab.label,
            setting: {tableType: subconfig.setting.tableType},
            action: subconfig.action.map(item => {
              let _item = {
                uuid: item.uuid,
                label: item.label,
                shortcut: item.shortcut || ''
              }
              if (item.OpenType === 'funcbutton' && item.funcType === 'print') {
                _item.type = 'print'
                _item.verify = item.verify
                _item.printer = item.printer || ''
              }
              return _item
            }),
            columns: _columns.map(item => {
              return {
                uuid: item.uuid,
                label: item.label,
                Width: item.Width,
                hidden: item.hidden || false,
                sort: item.sort || 0
              }
            })
          })
        })
        if (errors.length > 0) {
          notification.warning({
            top: 92,
            message: errors[0],
            duration: 10
          })
          return
        }
        this.setState({
          loading: false,
          menuParam: menuParam
        }, () => {
          this.getInitParam()
        })
      })
    })
    } else {
      this.setState({
        loading: false
      })
    }
  }
  getInitParam = () => {
    let config = JSON.parse(JSON.stringify(this.state.menuParam))
    let _config = {}
    config.forEach(tab => {
      let _tab = {
        label: tab.label,
        setting: tab.setting,
        action: {},
        columns: {}
      }
      tab.action.forEach(item => {
        _tab.action[item.uuid] = {
          printer: item.printer || '',
          shortcut: item.shortcut
        }
      })
      tab.columns.forEach((item, index) => {
        _tab.columns[item.uuid] = {
          Width: item.Width,
          hidden: item.hidden,
          sort: index
        }
      })
      _config[tab.uuid] = _tab
    })
    this.setState({
      menuconfig: _config
    })
    this.props.handleParam(_config)
  }
  changeconfig = (uuid, param) => {
    let _menuconfig = JSON.parse(JSON.stringify(this.state.menuconfig))
    _menuconfig[uuid] = param
    this.setState({
      menuconfig: _menuconfig
    })
    this.props.handleParam(_menuconfig)
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const { actionColumns, config } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    const { menuParam, loading } = this.state
    return (
      <div id="verify-card-box-tab">
        <Tabs defaultActiveKey="1" className="verify-card-box">
          <TabPane tab="基础设置" key="1">
            <Form {...formItemLayout}>
              <Row gutter={24}>
                <Col span={8}>
                  <Form.Item label="固定按钮">
                    {getFieldDecorator('actionfixed', {
                      initialValue: config.setting.actionfixed ? 'true' : 'false'
                    })(
                      <Radio.Group>
                        <Radio value="true">是</Radio>
                        <Radio value="false">否</Radio>
                      </Radio.Group>
                    )}
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label="固定表头">
                    {getFieldDecorator('columnfixed', {
                      initialValue: config.setting.columnfixed ? 'true' : 'false'
                    })(
                      <Radio.Group>
                        <Radio value="true">是</Radio>
                        <Radio value="false">否</Radio>
                      </Radio.Group>
                    )}
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label="表格属性">
                    {getFieldDecorator('tableType', {
                      initialValue: config.setting.tableType || 'checkbox'
                    })(
                      <Select>
                        <Select.Option value="">不可选</Select.Option>
                        <Select.Option value="radio">单选</Select.Option>
                        <Select.Option value="checkbox">多选</Select.Option>
                      </Select>
                    )}
                  </Form.Item>
                </Col>
              </Row>
            </Form>
          </TabPane>
          <TabPane tab="按钮设置" key="action">
            <ActionForm
              dict={this.props.dict}
              actionChange={this.actionChange}
              wrappedComponentRef={(inst) => this.actionForm = inst}
            />
            <Table
              bordered
              rowKey="uuid"
              className="custom-table"
              dataSource={config.action}
              columns={actionColumns}
              pagination={false}
            />
          </TabPane>
        </Tabs>
      <div id="verify-card-box-tab" className="verify-card-horizontal-box">
        {loading ? <Spin size="large" /> : null}
        {menuParam ? <Tabs defaultActiveKey={menuParam[0].uuid}>
          {menuParam.map(tab => {
            return (
              <TabPane tab={tab.label} key={tab.uuid}>
                <TabCard config={tab} handleconfig={this.changeconfig}/>
              </TabPane>
            )
          })}
        </Tabs> : null}
        {!loading && !menuParam ? <div className="message-fail"><Icon type="exclamation-circle" />信息获取失败</div> : null}
      </div>
    )
  }