king
2020-09-14 76427d51a079a5fd1f45bf7188249e7a4647ae05
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -1,22 +1,29 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Tabs, Row, Col, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber } from 'antd'
import { fromJS } from 'immutable'
import { Form, Tabs, Row, Col, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Radio } from 'antd'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import ColumnForm from './columnform'
import CodeMirror from '@/templates/zshare/codemirror'
import './index.scss'
const { TabPane } = Tabs
const { confirm } = Modal
class VerifyCard extends Component {
  static propTpyes = {
    dict: PropTypes.object,    // 字典项
    config: PropTypes.object,
    card: PropTypes.object,
  }
  state = {
    verify: {},
    defaultscript: '', // 自定义脚本
    excelColumns: [
      {
        title: this.props.dict['model.form.field'],
@@ -44,12 +51,11 @@
              <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'columns', 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
              <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'columns', 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
              <Popconfirm
                title={this.props.dict['header.form.query.delete']}
                okText={this.props.dict['model.confirm']}
                cancelText={this.props.dict['model.cancel']}
                overlayClassName="popover-confirm"
                title={this.props.dict['model.query.delete']}
                onConfirm={() => this.handleDelete(record, 'columns')
              }>
                <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span>
                <span style={{color: '#ff4d4f', cursor: 'pointer'}}><Icon type="delete" /></span>
              </Popconfirm>
            </div>
          )
@@ -58,21 +64,94 @@
  }
  UNSAFE_componentWillMount() {
    let _verify = this.props.card.verify || {}
    const { config, card } = this.props
    let _verify = {}
    let _columns = _verify.columns || []
    _columns = _columns.map(col => {
      col.Width = col.Width || 20
    if (card.verify) {
      _verify = fromJS(card.verify).toJS()
    }
    _verify.enable = _verify.enable || 'false'
    // 同步显示列
    if (!_verify.columns || _verify.columns.length === 0) {
      _verify.columns = []
      config.columns.forEach(item => {
        if (!item.field) return
        _verify.columns.push({
          Column: item.field,
          Text: item.label,
          Width: 20,
          uuid: Utils.getuuid()
        })
      })
    }
    if (card.intertype !== 'system') {
      _verify.enable = 'false'
    }
    let defaultscript = ''
    if (!_verify.script && card.intertype === 'system') {
      let search = this.formatSearch(config.search)
      search = Utils.joinMainSearchkey(search)
      search = search ? 'where ' + search : ''
      
      return col
    })
      defaultscript = `update ${config.setting.tableName || ''} set idefine5= idefine5+1 ,modifydate=getdate(),cdefine5='已导出',modifyuserid=@userid@ ${search}`
    }
    this.setState({
      verify: {
        ..._verify,
        columns: _columns,
      }
      verify: _verify,
      defaultscript: defaultscript
    })
  }
  /**
   * @description 获取全部搜索条件
   * @param {Array} searches 搜索条件数组
   */
  formatSearch (searches) {
    if (!searches || searches.length === 0) return []
    let newsearches = []
    searches.forEach(search => {
      let item = {
        key: search.field,
        match: search.match,
        type: search.type,
        label: search.label,
        value: `@${search.field}@`,
        required: search.required === 'true'
      }
      if (item.type === 'group') {
        let copy = fromJS(item).toJS()
        copy.key = search.datefield
        item.value = `@${search.field}@`
        item.match = '='
        copy.type = 'daterange'
        copy.match = 'between'
        copy.value = [`@${search.datefield}@`, `@${search.datefield}1@`]
        if (search.transfer === 'true') {
          newsearches.push(item)
        }
        newsearches.push(copy)
        return
      } else if (item.type === 'dateweek') {
        item.value = [`@${search.field}@`, `@${search.field}1@`]
      } else if (item.type === 'daterange') {
        item.value = [`@${search.field}@`, `@${search.field}1@`]
      } else if (item.type === 'multiselect') {
        item.value = [`@${search.field}@`]
      }
      newsearches.push(item)
    })
    return newsearches
  }
  columnChange = (values) => {
@@ -87,6 +166,15 @@
        }
      })
    } else {
      let fields = verify.columns.map(item => item.Column)
      if (fields.includes(values.Column)) {
        notification.warning({
          top: 92,
          message: values.Column + '字段已存在!',
          duration: 5
        })
        return
      }
      values.uuid = Utils.getuuid()
      verify.columns.push(values)
    }
@@ -191,7 +279,7 @@
  }
  handleConfirm = () => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    let verify = fromJS(this.state.verify).toJS()
    
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
@@ -208,12 +296,141 @@
        return
      }
      resolve(verify)
      if (verify.enable === 'true') {
        this.props.form.validateFieldsAndScroll((err, values) => {
          if (!err) {
            values.sql = values.sql || ''
            let _quot = values.sql.match(/'{1}/g)
            let _lparen = values.sql.match(/\({1}/g)
            let _rparen = values.sql.match(/\){1}/g)
            _quot = _quot ? _quot.length : 0
            _lparen = _lparen ? _lparen.length : 0
            _rparen = _rparen ? _rparen.length : 0
            if (_quot % 2 !== 0) {
              notification.warning({
                top: 92,
                message: 'sql中\'必须成对出现',
                duration: 5
              })
              return
            } else if (_lparen !== _rparen) {
              notification.warning({
                top: 92,
                message: 'sql中()必须成对出现',
                duration: 5
              })
              return
            } else if (/--/ig.test(values.sql)) {
              notification.warning({
                top: 92,
                message: '自定义sql语句中,不可出现字符 -- ,注释请用 /*内容*/',
                duration: 5
              })
              return
            }
            let error = Utils.verifySql(values.sql, 'customscript')
            if (error) {
              notification.warning({
                top: 92,
                message: 'sql中不可使用' + error,
                duration: 5
              })
              return
            }
            let param = {
              func: 's_debug_sql',
              LText: values.sql
            }
            param.LText = param.LText.replace(/@\$|\$@/ig, '')
            param.LText = Utils.formatOptions(param.LText)
            param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
            param.secretkey = Utils.encrypt(param.LText, param.timestamp)
            Api.getLocalConfig(param).then(res => {
              if (res.status) {
                resolve({...verify, script: values.sql})
              } else {
                Modal.error({
                  title: res.message
                })
              }
            })
          } else {
            notification.warning({
              top: 92,
              message: '自定义脚本不可为空!',
              duration: 5
            })
          }
        })
      } else {
        resolve(verify)
      }
    })
  }
  changeEnable = (e) => {
    const { verify } = this.state
    this.setState({
      verify: {...verify, enable: e.target.value}
    })
  }
  columnFieldInput = () => {
    const { config } = this.props
    const { verify } = this.state
    let columns = fromJS(verify.columns).toJS()
    let fields = columns.map(item => item.Column)
    config.columns.forEach(item => {
      if (fields.includes(item.field) || !item.field) return
      fields.push(item.field)
      columns.push({
        Column: item.field,
        Text: item.label,
        Width: 20,
        uuid: Utils.getuuid()
      })
    })
    this.setState({
      verify: {...verify, columns: columns}
    })
  }
  clearField = () => {
    const { verify } = this.state
    const _this = this
    confirm({
      content: `确定清空Excel列吗?`,
      onOk() {
        _this.setState({
          verify: {
            ...verify,
            columns: []
          }
        })
      },
      onCancel() {}
    })
  }
  render() {
    const { verify, excelColumns } = this.state
    const { card } = this.props
    const { verify, excelColumns, defaultscript } = this.state
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -228,12 +445,23 @@
    return (
      <div id="verify-excelout-box-tab">
        <Tabs defaultActiveKey="1" className="verify-card-box" onChange={this.tabchange}>
          <TabPane tab="Excel导出列" key="1">
          <TabPane tab={
            <span>
              Excel导出列
              {verify.columns.length ? <span className="count-tip">{verify.columns.length}</span> : null}
            </span>
          } key="1">
            <ColumnForm
              dict={this.props.dict}
              columnChange={this.columnChange}
              wrappedComponentRef={(inst) => this.columnForm = inst}
            />
            <Button className="excel-col-add mk-green" title="添加显示列字段" onClick={this.columnFieldInput}>
              同步显示列
            </Button>
            <Button className="excel-col-add mk-red" title="清空Excel列" onClick={this.clearField}>
              清空Excel列
            </Button>
            <Table
              bordered
              rowKey="uuid"
@@ -243,6 +471,38 @@
              pagination={false}
            />
          </TabPane>
          {card.intertype === 'system' ? <TabPane tab={
            <span>
              自定义脚本
              {verify.enable === 'true' ? <span className="count-tip">1</span> : null}
            </span>
          } key="6">
            <Form {...formItemLayout} className="verify-form">
              <Row gutter={24}>
                <Col span={8}>
                  <Form.Item style={{marginBottom: 10}} label={'启用'}>
                    <Radio.Group defaultValue={verify.enable || 'false'} onChange={this.changeEnable}>
                      <Radio value="true">是</Radio>
                      <Radio value="false">否</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                <Col span={24} className="sql">
                  <Form.Item label={'sql'}>
                    {getFieldDecorator('sql', {
                      initialValue: verify.script || defaultscript,
                      rules: [
                        {
                          required: true,
                          message: this.props.dict['form.required.input'] + 'sql!'
                        }
                      ]
                    })(<CodeMirror />)}
                  </Form.Item>
                </Col>
              </Row>
            </Form>
          </TabPane> : null}
          <TabPane tab="信息提示" key="7">
            <Form {...formItemLayout}>
              <Row gutter={24}>