king
2023-08-24 0c1a33a33b45fc3265cb7fef20beb48407cd6c98
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -1,9 +1,10 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Radio, Spin, Typography, Popconfirm } from 'antd'
import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Spin, Typography, Popconfirm } from 'antd'
import { EditOutlined, StopOutlined, CheckCircleOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
import moment from 'moment'
import md5 from 'md5'
import Api from '@/api'
import Utils from '@/utils/utils.js'
@@ -11,7 +12,6 @@
import ColumnForm from './columnform'
import DataSource from './datasource'
import CustomScript from './customscript'
import CodeMirror from '@/templates/zshare/codemirror'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
@@ -28,8 +28,8 @@
  state = {
    verify: {},
    debugId: '',
    activeKey: 'setting',
    defaultscript: '', // 自定义脚本
    excelColumns: [
      {
        title: '字段',
@@ -37,7 +37,7 @@
        inputType: 'input',
        editable: true,
        unique: true,
        width: '17%'
        width: '16%'
      },
      {
        title: '名称',
@@ -45,7 +45,7 @@
        inputType: 'input',
        editable: true,
        unique: true,
        width: '17%'
        width: '16%'
      },
      {
        title: '列宽',
@@ -54,7 +54,7 @@
        min: 5,
        max: 200,
        editable: true,
        width: '12%',
        width: '10%',
        render: (text) => text || 20
      },
      {
@@ -63,7 +63,7 @@
        inputType: 'select',
        editable: true,
        required: false,
        width: '14%',
        width: '12%',
        render: (text) => {
          if (text === 'image') {
            return '图片'
@@ -85,7 +85,7 @@
        inputType: 'radio',
        editable: true,
        required: false,
        width: '14%',
        width: '12%',
        render: (text) => {
          if (text === 'true') {
            return '是'
@@ -114,7 +114,7 @@
        inputType: 'radio',
        editable: true,
        required: false,
        width: '14%',
        width: '12%',
        render: (text) => {
          if (text !== 'false') {
            return '是'
@@ -126,7 +126,19 @@
          {value: 'true', text: '是'},
          {value: 'false', text: '否'}
        ]
      }
      },
      {
        title: '红色标题',
        dataIndex: 'required',
        width: '10%',
        editable: true,
        inputType: 'radio',
        render: (text, record) => record.required === 'true' ? <span style={{color: 'red'}}>是</span> : '否',
        options: [
          {value: 'true', text: '是'},
          {value: 'false', text: '否'}
        ]
      },
    ],
    scriptsColumns: [
      {
@@ -151,12 +163,10 @@
        dataIndex: 'position',
        width: '10%',
        render: (text, record) => {
          if (record.position === 'init') {
            return <span style={{color: 'orange'}}>初始化</span>
          } else if (record.position === 'front') {
            return <span style={{color: '#26C281'}}>sql前</span>
          if (record.position === 'back') {
            return <span style={{color: '#1890ff'}}>后置</span>
          } else {
            return <span style={{color: '#1890ff'}}>sql后</span>
            return <span style={{color: '#26C281'}}>前置</span>
          }
        }
      },
@@ -207,31 +217,25 @@
      _verify = fromJS(card.verify).toJS()
    }
    _verify.enable = _verify.enable || 'false'
    _verify.dataType = _verify.dataType || 'default'
    _verify.columns = _verify.columns || []
    _verify.scripts = _verify.scripts || []
    if (card.intertype !== 'system') {
      _verify.enable = 'false'
    }
    if (_verify.columns[0] && (!_verify.columns[0].type || !_verify.columns[0].output)) {
      _verify.columns = _verify.columns.map(col => {
        col.type = col.type || 'text'
        col.output = col.output || 'true'
        return col
      })
    }
    _verify.columns = _verify.columns.map(col => {
      col.type = col.type || 'text'
      col.output = col.output || 'true'
      col.required = col.required || 'false'
    let defaultscript = ''
    if (!_verify.script && card.intertype === 'system') {
      let search = this.formatSearch(config.search)
      search = Utils.joinMainSearchkey(search)
      search = search.replace(/@\$@/ig, '')
      search = search ? 'where ' + search : ''
      defaultscript = `update ${config.setting.tableName || ''} set idefine5= idefine5+1 ,modifydate=getdate(),cdefine5='已导出',modifyuserid=@userid@ ${search}`
    }
      if (!['text', 'image', 'number'].includes(col.type)) {
        if (/^Decimal/ig.test(col.type)) {
          col.type = 'number'
        } else {
          col.type = 'text'
        }
      }
      return col
    })
    let appType = sessionStorage.getItem('appType')
    let searches = []
@@ -296,62 +300,54 @@
      searches = search
    } else {
      let search = []
      searches = fromJS(config.search || []).toJS()
      if (config.setting && config.setting.useMSearch === 'true' && window.GLOB.customMenu) {
        let menu = fromJS(window.GLOB.customMenu).toJS()
        let _search = null
        let filterComponent = (box) => {
        let filterComponent = (box, mainSearch) => {
          box.components.forEach(item => {
            if (_search) return
            if (item.type === 'search') {
              box.slist = [...box.slist, item.search]
            } else if (item.uuid === config.uuid) {
              _search = box.slist.pop()
            if (item.type !== 'search') return
            mainSearch = item.search
          })
          let has = false
          box.components.forEach(item => {
            if (item.uuid === config.uuid) {
              has = true
            } else if (item.type === 'group') {
              item.components.forEach(m => {
                if (m.uuid !== config.uuid) return
                _search = box.slist.pop()
              })
            } else if (item.type === 'tabs') {
              item.subtabs.forEach(tab => {
                tab.slist = [...box.slist]
                filterComponent(tab)
                has = true
              })
            }
          })
        }
        menu.slist = []
        filterComponent(menu)
        if (_search) {
          search = _search
        } else {
          menu.components.forEach(item => {
            if (item.type !== 'search') return
            search = item.search
          })
        }
      }
      searches = fromJS(config.search || []).toJS()
      if (search.length > 0) {
        let keys = searches.map(item => (item.field ? item.field.toLowerCase() : ''))
        search.forEach(item => {
          if (item.field && !keys.includes(item.field.toLowerCase())) {
            searches.push(item)
          if (has) {
            if (mainSearch) {
              let keys = searches.map(item => (item.field ? item.field.toLowerCase() : ''))
              mainSearch.forEach(item => {
                if (item.field && !keys.includes(item.field.toLowerCase())) {
                  searches.push(item)
                }
              })
            }
          } else {
            box.components.forEach(item => {
              if (item.type !== 'tabs') return
              item.subtabs.forEach(tab => {
                filterComponent(tab, mainSearch)
              })
            })
          }
        })
        }
        filterComponent(menu, null)
      }
    }
    this.setState({
      verify: _verify,
      searches: searches,
      activeKey: card.intertype === 'system' && _verify.dataType === 'custom' ? 'setting' : 'columns',
      defaultscript: defaultscript
      activeKey: card.intertype === 'system' && _verify.dataType === 'custom' ? 'setting' : 'columns'
    })
  }
@@ -397,53 +393,6 @@
    })
  }
  /**
   * @description 获取全部搜索条件
   * @param {Array} searches 搜索条件数组
   */
  formatSearch (searches) {
    if (!searches || searches.length === 0) return []
    let newsearches = []
    searches.forEach(search => {
      if (!search.field) return
      let item = {
        key: search.field,
        match: search.match,
        type: search.type,
        label: search.label,
        value: search.initval,
        required: search.required === 'true'
      }
      if (item.type === 'group') {
        item.key = search.datefield
        item.type = 'daterange'
        item.match = 'between'
        item.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')].join(',')
        newsearches.push(item)
        return
      } else if (item.type === 'date') {
        item.value = moment().format('YYYY-MM-DD')
      } else if (item.type === 'datemonth') {
        item.value = moment().format('YYYY-MM')
      } else if (item.type === 'dateweek') {
        item.value = moment().format('YYYY-MM-DD')
      } else if (item.type === 'daterange') {
        item.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')].join(',')
      } else if (item.type === 'multiselect' || (item.type === 'checkcard' && search.multiple === 'true')) {
        item.type = 'multi'
        item.value = '@$@'
      } else {
        item.value = '@$@'
      }
      newsearches.push(item)
    })
    return newsearches
  }
  columnChange = (values) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
@@ -459,6 +408,7 @@
    values.uuid = Utils.getuuid()
    values.abs = 'false'
    values.output = 'true'
    values.required = 'false'
    verify.columns.push(values)
    this.setState({
@@ -559,11 +509,20 @@
        return
      }
      if (activeKey === 'backscript' && verify.enable === 'true') {
        this.checkScript(resolve, reject)
      } else if (activeKey === 'setting') {
      if (activeKey === 'setting') {
        this.settingForm.handleConfirm().then(res => {
          let _verify = {...verify, ...res}
          if (res.dataType !== 'custom') {
            delete _verify.tableName
            delete _verify.dataresource
            delete _verify.queryType
            delete _verify.defaultSql
            delete _verify.order
            _verify.scripts = []
          }
          this.setState({
            verify: _verify
          }, () => {
@@ -636,104 +595,6 @@
    })
  }
  checkScript = (_resolve, _reject) => {
    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',
          exec_type: 'y',
          LText: values.sql
        }
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
        param.LText = param.LText.replace(/\n/g, ' ')
        param.LText = Utils.formatOptions(param.LText)
        param.secretkey = Utils.encrypt('', param.timestamp)
        this.setState({
          loading: true
        })
        Api.genericInterface(param).then(res => {
          this.setState({
            loading: false
          })
          if (res.status) {
            let verify = {...this.state.verify, script: values.sql}
            this.setState({verify: verify}, () => {
              _resolve(verify)
            })
          } else {
            Modal.error({
              title: res.message
            })
          }
        })
      } else {
        notification.warning({
          top: 92,
          message: '自定义脚本不可为空!',
          duration: 5
        })
        _reject()
      }
    })
  }
  changeEnable = (e) => {
    const { verify } = this.state
    this.setState({
      verify: {...verify, enable: e.target.value}
    })
  }
  columnFieldInput = () => {
    const { config } = this.props
    const { verify } = this.state
@@ -751,6 +612,7 @@
        Width: 20,
        abs: 'false',
        output: 'true',
        required: 'false',
        type: 'text',
        uuid: Utils.getuuid()
      }
@@ -762,6 +624,31 @@
      columns.push(cell)
    })
    if (config.subtype === 'dualdatacard') {
      config.subColumns.forEach(item => {
        if (fields.includes(item.field) || !item.field) return
        fields.push(item.field)
        let cell = {
          Column: item.field,
          Text: item.label,
          Width: 20,
          abs: 'false',
          output: 'true',
          required: 'false',
          type: 'text',
          uuid: Utils.getuuid()
        }
        if (item.type === 'number') {
          cell.type = 'number'
          cell.decimal = item.decimal
        }
        columns.push(cell)
      })
    }
    this.setState({
      verify: {...verify, columns: columns}
@@ -789,21 +676,37 @@
  changeColumns = (columns) => {
    const { verify } = this.state
    if (columns[0] && !['image', 'text', 'number'].includes(columns[0].type)) {
      columns = columns.map(col => {
        let _cell = {
          uuid: Utils.getuuid(),
          Column: col.Column,
          Text: col.Text,
          Width: 20,
          abs: 'false',
          output: col.output || 'true',
          type: 'text',
        }
    columns = columns.map(col => {
      col.type = col.type || 'text'
      col.output = col.output || 'true'
      col.required = col.required || 'false'
        return _cell
      })
    }
      if (!['text', 'image', 'number'].includes(col.type)) {
        if (/^Decimal/ig.test(col.type)) {
          col.type = 'number'
        } else {
          col.type = 'text'
        }
      }
      return col
    })
    // if (columns[0] && !['image', 'text', 'number'].includes(columns[0].type)) {
    //   columns = columns.map(col => {
    //     let _cell = {
    //       uuid: Utils.getuuid(),
    //       Column: col.Column,
    //       Text: col.Text,
    //       Width: 20,
    //       abs: 'false',
    //       output: col.output || 'true',
    //       required: col.required || 'false',
    //       type: 'text',
    //     }
    //     return _cell
    //   })
    // }
    this.setState({verify: {...verify, columns}})
  }
@@ -813,13 +716,7 @@
    const { card } = this.props
    const { activeKey, verify } = this.state
    if (activeKey === 'backscript' && verify.enable === 'true') {
      this.checkScript(() => {
        this.setState({
          activeKey: val
        })
      }, () => {})
    } else if (card.intertype !== 'system' || verify.dataType !== 'custom') {
    if (card.intertype !== 'system' || verify.dataType !== 'custom') {
      this.setState({activeKey: val})
      return
    } else if (activeKey === 'setting') {
@@ -892,7 +789,7 @@
    }
  }
  scriptsChange = (values, callback) => {
  scriptsChange = (values, callback, skip) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    if (values.uuid) {
@@ -908,24 +805,31 @@
      verify.scripts.push(values)
    }
    this.setState({loading: true})
    this.sqlverify(() => { // 验证成功
    if (skip) {
      this.setState({
        loading: false,
        verify: verify
      })
      callback(true)
    }, () => {             // 验证失败
      this.setState({
        loading: false
      })
      callback(false)
    }, verify.scripts)
    } else {
      this.setState({loading: true})
      this.sqlverify(() => { // 验证成功
        this.setState({
          loading: false,
          verify: verify
        })
        callback(true)
      }, () => {             // 验证失败
        this.setState({
          loading: false
        })
        callback(false)
      }, verify.scripts)
    }
  }
  sqlverify = (_resolve, _reject, scripts) => {
    const { searches, verify } = this.state
    const { searches, verify, debugId } = this.state
    if (verify.dataType !== 'custom') {
      _resolve()
@@ -933,7 +837,15 @@
    }
    let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    let sql = SettingUtils.getDebugSql(verify, scripts, (verify.useSearch === 'true' ? searches : []), Utils, timestamp)
    let sql = SettingUtils.getDebugSql(verify, scripts, (verify.useSearch === 'true' ? searches : []), Utils, '2023-04-20 15:29:37')
    let _debugId = md5(sql)
    if (debugId === _debugId) {
      _resolve()
      return
    }
    let param = {
      func: 's_debug_sql',
      exec_type: 'y',
@@ -945,6 +857,7 @@
    Api.genericInterface(param).then(result => {
      if (result.status) {
        this.setState({debugId: _debugId})
        _resolve()
      } else {
        _reject()
@@ -956,13 +869,27 @@
  }
  updateDataType = (val) => {
    this.setState({verify: {...this.state.verify, dataType: val}})
    const { config } = this.props
    let verify = {...this.state.verify, dataType: val}
    if (val === 'custom' && config.setting) {
      verify.tableName = verify.tableName || config.setting.tableName || ''
      verify.dataresource = verify.dataresource || config.setting.dataresource || ''
      verify.queryType = verify.queryType || config.setting.queryType || ''
      verify.defaultSql = verify.defaultSql || config.setting.execute || ''
      verify.order = verify.order || config.setting.order || ''
      if (verify.scripts.length === 0 && config.scripts && config.scripts.length > 0) {
        verify.scripts = fromJS(config.scripts).toJS()
      }
    }
    this.setState({verify: verify})
  }
  render() {
    const { card } = this.props
    const { verify, excelColumns, defaultscript, scriptsColumns, activeKey, loading, searches } = this.state
    const { getFieldDecorator } = this.props.form
    const { verify, excelColumns, scriptsColumns, activeKey, loading, searches } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -995,7 +922,7 @@
            <Button className="excel-col-add mk-red" title="清空Excel列" onClick={this.clearField}>
              清空Excel列
            </Button>
            <div style={{color: '#959595', fontSize: '13px', paddingLeft: '10px'}}>如需导出序号,请使用字段 $Index;数值类型导出时可进行数据处理(取绝对值、保留小数位)。</div>
            <div style={{color: '#959595', fontSize: '13px', paddingLeft: '10px'}}>如需导出序号,请使用字段 $Index;数值类型导出时可进行数据处理(取绝对值、保留小数位);红色标题导出时列头文字为红色。</div>
            <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelcolumn" wrappedComponentRef={(inst) => this.columnRef = inst} data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
          </TabPane>
          {card.intertype === 'system' ? <TabPane tab={
@@ -1013,44 +940,11 @@
            />
            <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
          </TabPane> : null}
          {card.intertype === 'system' ? <TabPane tab={
            <span>
              回调脚本
              {verify.enable === 'true' ? <span className="count-tip">1</span> : null}
            </span>
          } key="backscript">
            <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>
                <div style={{color: '#959595', fontSize: '13px', paddingTop: '30px', float: 'right'}}>执行成功后的回调函数。</div>
                <Col span={24} className="sql">
                  <Form.Item label={'sql'}>
                    {getFieldDecorator('sql', {
                      initialValue: verify.script || defaultscript,
                      rules: [
                        {
                          required: true,
                          message: '请输入sql!'
                        }
                      ]
                    })(<CodeMirror />)}
                  </Form.Item>
                </Col>
              </Row>
            </Form>
          </TabPane> : null}
          <TabPane tab="信息提示" key="message">
            <Form {...formItemLayout}>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> S </span>
                    <Button onClick={() => {this.showError('S')}} type="primary" size="small">
                      查看
@@ -1058,14 +952,14 @@
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'停留时间'}>
                  <Form.Item label="停留时间">
                    <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> Y </span>
                    <Button onClick={() => {this.showError('Y')}} type="primary" size="small">
                      查看
@@ -1075,7 +969,15 @@
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> -1 </span>
                    执行成功无提示。
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> N </span>
                    <Button onClick={() => {this.showError('N')}} type="primary" size="small">
                      查看
@@ -1083,14 +985,14 @@
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'停留时间'}>
                  <Form.Item label="停留时间">
                    <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> F </span>
                    <Button onClick={() => {this.showError('F')}} type="primary" size="small">
                      查看
@@ -1098,14 +1000,14 @@
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={'停留时间'}>
                  <Form.Item label="停留时间">
                    <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> E </span>
                    <Button onClick={() => {this.showError('E')}} type="primary" size="small">
                      查看
@@ -1115,7 +1017,7 @@
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                  <Form.Item label="提示编码">
                    <span className="errorval"> NM </span>
                    <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
                      查看
@@ -1125,9 +1027,9 @@
              </Row>
              <Row gutter={24}>
                <Col offset={6} span={6}>
                  <Form.Item label={'提示编码'}>
                    <span className="errorval"> -1 </span>
                    不提示
                  <Form.Item label="提示编码">
                    <span className="errorval"> -2 </span>
                    执行失败无提示
                  </Form.Item>
                </Col>
              </Row>