king
2024-08-20 58826d6f4eab9f8c9acf9fa8696f60039c645cfe
src/menu/datasource/verifycard/index.jsx
@@ -4,7 +4,6 @@
import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message, Button, Input } from 'antd'
import { StopOutlined, CheckCircleOutlined, TableOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined, BorderOutlined, SnippetsOutlined } from '@ant-design/icons'
import moment from 'moment'
import md5 from 'md5'
import Api from '@/api'
import Utils from '@/utils/utils.js'
@@ -42,15 +41,16 @@
    loading: false,
    colLoading: false,
    searchKey: '',
    initsql: '',          // sql验证时变量声明及赋值
    usefulfields: '',
    defaultsql: '',       // 默认Sql
    defaultsql: '',
    systemScripts: [],
    median: {},
    visible: false,
    editLineId: '',
    pvisible: false,
    reload: false,
    script: null,
    oriConfig: null,
    scriptValue: '',
    cols: null,
    colColumns: [
@@ -59,6 +59,7 @@
        dataIndex: 'label',
        inputType: 'input',
        editable: true,
        searchable: true,
        width: '28%'
      },
      {
@@ -68,6 +69,7 @@
        editable: true,
        unique: true,
        strict: true,
        searchable: true,
        copy: true,
        rules: [{
          pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
@@ -198,24 +200,26 @@
    let _setting = fromJS(config.setting).toJS()
    let scripts = config.scripts ? fromJS(config.scripts).toJS() : []
    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
      window.GLOB.funcs.forEach(m => {
        let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
        if (_setting.dataresource) {
          _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`)
        }
        scripts && scripts.forEach(item => {
          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
        })
      })
    }
    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
    //   window.GLOB.funcs.forEach(m => {
    //     let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
    //     if (_setting.dataresource) {
    //       _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`)
    //     }
    //     scripts && scripts.forEach(item => {
    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
    //     })
    //   })
    // }
    let columns = config.columns ? fromJS(config.columns).toJS() : []
    let subColumns = config.subColumns ? fromJS(config.subColumns).toJS() : []
    columns.reverse()
    if (!config.fixedCol) {
      columns.reverse()
    }
    subColumns.reverse()
    columns.forEach(col => {
      if (!col.datatype) return
      if (/^nvarchar/.test(col.datatype)) {
@@ -245,7 +249,13 @@
      median: _setting,
      searches: formatSearch(search),
      searchKey: '',
      debugId: _setting.debugId || ''
      debugId: _setting.debugId || '',
      oriConfig: fromJS({
        scripts,
        columns: columns,
        subColumns: subColumns,
        setting: _setting
      }).toJS()
    })
    this.getsysScript()
@@ -261,18 +271,18 @@
    let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from  s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort`
    _scriptSql = Utils.formatOptions(_scriptSql)
    _scriptSql = Utils.formatOptions(_scriptSql, 'x')
    let _sParam = {
      func: 'sPC_Get_SelectedList',
      LText: _scriptSql,
      obj_name: 'data',
      arr_field: 'funcname,longparam'
      arr_field: 'funcname,longparam',
      exec_type: 'x'
    }
    
    _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp)
    _sParam.secretkey = Utils.encrypt('', _sParam.timestamp)
    _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证
    
    Api.getCloudConfig(_sParam).then(res => {
@@ -390,6 +400,7 @@
    if (values.uuid) {
      scripts = scripts.map(item => {
        if (item.uuid === values.uuid) {
          values.$index = item.$index || ''
          return values
        } else {
          return item
@@ -542,7 +553,7 @@
  submitDataSource = () => {
    const { config, mainSearch } = this.props
    const { activeKey, setting, columns, subColumns, scripts, cols } = this.state
    const { activeKey, setting, columns, subColumns, scripts, cols, median, searches } = this.state
    if (config.subtype === 'dualdatacard') {
      let arr = columns.map(col => col.field.toLowerCase())
@@ -561,6 +572,42 @@
        })
        return Promise.reject()
      }
    } else if (config.subtype === 'editable') {
      let _arr = []
      columns.forEach(col => {
        let key = col.field.toLowerCase()
        if (['jskey', 'data_type', 'bid'].includes(key)) {
          _arr.push(col.field)
        }
      })
      if (_arr.length > 0) {
        notification.warning({
          top: 92,
          message: '字段集中不可使用' + _arr.join('、') + '!注:此字段为提交时的系统字段。',
          duration: 5
        })
        return Promise.reject()
      }
    }
    if (median.interType === 'system') {
      let _loading = false
      if (this.scriptsForm && this.scriptsForm.state.editItem) {
        _loading = true
      } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) {
        _loading = true
      }
      if (_loading) {
        notification.warning({
          top: 92,
          message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!',
          duration: 5
        })
        this.setState({activeKey: 'scripts'})
        return Promise.reject()
      }
    }
    return new Promise((resolve, reject) => {
@@ -571,12 +618,13 @@
          if (res.useMSearch === 'true') { // 使用主搜索条件
            search = [...search, ...mainSearch]
          }
          let _searches = formatSearch(search)
          this.setState({
            searches: formatSearch(search),
            searches: _searches,
            setting: res
          }, () => {
            this.sqlverify(() => { resolve({setting: res, columns, subColumns, scripts, cols }) }, reject, 'submit')
            this.sqlverify(() => { resolve({setting: res, columns, subColumns, scripts, cols, searches: _searches }) }, reject, 'submit')
          })
        }, () => {
          reject()
@@ -591,7 +639,7 @@
          reject()
          return
        }
        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols }) }, reject, 'submit')
        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols, searches }) }, reject, 'submit')
      } else if (activeKey === 'subcolumns') {
        if (this.subdatasource && this.subdatasource.state.editingKey) {
          notification.warning({
@@ -602,28 +650,37 @@
          reject()
          return
        }
        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols }) }, reject, 'submit')
        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols, searches }) }, reject, 'submit')
      } else if (activeKey === 'scripts') {
        let _loading = false
        if (this.scriptsForm && this.scriptsForm.state.editItem) {
          _loading = true
        } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) {
          _loading = true
        }
        if (_loading) {
          notification.warning({
            top: 92,
            message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!',
            duration: 5
          })
          reject()
          return
        }
        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols }) }, reject, 'submit')
        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols, searches }) }, reject, 'submit')
      }
    })
  }
  closeDataSource = (callback) => {
    const { setting, columns, subColumns, scripts, oriConfig } = this.state
    let line = scripts.map(item => item.sql).join('')
    line += columns.map(item => item.field + item.datatype).join('')
    line += subColumns.map(item => item.field + item.datatype).join('')
    line += setting.interType + (setting.dataresource || '') + (setting.order || '') + (setting.primaryKey || '')
    let _line = oriConfig.scripts.map(item => item.sql).join('')
    _line += oriConfig.columns.map(item => item.field + item.datatype).join('')
    _line += oriConfig.subColumns.map(item => item.field + item.datatype).join('')
    _line += oriConfig.setting.interType + (oriConfig.setting.dataresource || '') + (oriConfig.setting.order || '') + (oriConfig.setting.primaryKey || '')
    if (line !== _line) {
      confirm({
        content: '数据源已修改,确定取消吗?',
        onOk() {
          callback()
        },
        onCancel() {}
      })
    } else {
      callback()
    }
  }
  sqlverify = (resolve, reject, type, testScripts) => {
@@ -655,22 +712,29 @@
      if (config.subtype === 'dualdatacard') {
        _columns = [...columns, ...subColumns]
      }
      let r = SettingUtils.getDebugSql(setting, _scripts, _columns, searches, config.type)
      let _debugId = md5(r.sql)
      let r = SettingUtils.getDebugSql(setting, _scripts, _columns, searches, config.subtype, config.hasExtend)
      if (r.custompage && _columns.findIndex(col => col.field === 'mk_total') === -1) {
        Modal.warning({
          title: `数据源或自定义脚本中使用自定义分页排序时,请在字段集中添加 mk_total。`,
          okText: '知道了',
          onOk: () => {
            reject()
          }
        })
        return
      if (r.custompage && setting.laypage === 'true' && _columns.findIndex(col => col.field === 'mk_total') === -1) {
        if (config.subtype !== 'basetable') {
          Modal.warning({
            title: `数据源或自定义脚本中使用自定义分页排序时,请在字段集中添加 mk_total。`,
            okText: '知道了',
            onOk: () => {
              reject()
            }
          })
          return
        } else {
          notification.warning({
            top: 92,
            message: '数据源或自定义脚本中使用自定义分页排序时,请在显示列中添加 mk_total。',
            duration: 5
          })
        }
      }
      if (debugId === _debugId) {
      if (debugId === r.debugId) {
        resolve()
        return
      }
@@ -685,7 +749,7 @@
      Api.sDebug(r.sql).then(result => {
        if (result.status || result.ErrCode === '-2') {
          this.setState({debugId: _debugId}, () => {
          this.setState({debugId: r.debugId}, () => {
            resolve()
          })
        } else {
@@ -779,7 +843,9 @@
      return
    }
    let editLineId = ''
    if (script) {
      editLineId = script.uuid
      _scripts = _scripts.map(item => {
        if (script.uuid === item.uuid) {
          item.sql = scriptValue
@@ -794,10 +860,11 @@
        status: 'true'
      }
      editLineId = _script.uuid
      _scripts.push(_script)
    }
    this.setState({loading: true})
    this.setState({loading: true, editLineId})
    this.sqlverify(() => {this.setState({scripts: _scripts, script: null, scriptValue: '', loading: false})}, () => {this.setState({loading: false})}, 'script', _scripts)
  }
@@ -924,12 +991,19 @@
  }
  copyColumns = () => {
    const { columns } = this.state
    const { config } = this.props
    const { columns, subColumns, setting } = this.state
    let _columns = columns
    let m = []
    let n = []
    let s = []
    columns.forEach(col => {
    if (subColumns && subColumns.length) {
      _columns = [...columns, ...subColumns]
    }
    _columns.forEach(col => {
      m.unshift(`${col.field} ${col.datatype}`)
      n.unshift(col.field)
      if (/decimal|int/ig.test(col.datatype)) {
@@ -944,12 +1018,60 @@
    })
    if (window.debugger) {
      console.info('select ' + s.join(', '))
      window.mkInfo('select ' + s.join(', '))
    }
    let extend = ''
    if (config.hasExtend) {
      extend = []
      let mapCol = (cols) => {
        cols.forEach(col => {
          if (col.type === 'extend') {
            let datatype = 'Nvarchar(50)'
            _columns.forEach(c => {
              if (c.field === col.field) {
                datatype = c.datatype
              }
            })
            for (let i = 1; i < col.quota; i++) {
              extend.push(`${col.field}${i} ${datatype}`)
            }
          } else if (col.type === 'colspan' && col.subcols) {
            mapCol(col.subcols)
          }
        })
      }
      mapCol(config.cols)
      extend = `
      /* 扩展列字段 */
      /* ${extend.join(',')} */
      `
    }
    let oInput = document.createElement('input')
    oInput.value = `/*${m.join(',')}*/
      ${n.join(',')}`
    oInput.value = `create table #${setting.tableName || 'tb'}
    (${m.join(',')},sort_id INT IDENTITY(1,1))
    insert into #${setting.tableName || 'tb'}
    (${n.join(',')})
    select ${n.join(',')}
    from ${setting.dataresource ? `(${setting.dataresource.replace(/\n/g, ' ')}) tb` : setting.tableName || 'tb'}
    order by @orderBy@
    declare @mk_total int
    set @mk_total = 0
    select @mk_total = count(1) from #${setting.tableName || 'tb'}
      declare @pageIndex_top int
      set @pageIndex_top=(@pageIndex@-1)*@pageSize@
      if @mk_total > @pageIndex@*@pageSize@
        delete #${setting.tableName || 'tb'} where sort_id > @pageIndex@*@pageSize@
      if @pageIndex_top > 0
        delete #${setting.tableName || 'tb'} where sort_id <= @pageIndex_top
    drop table #${setting.tableName || 'tb'}${extend}`
    document.body.appendChild(oInput)
    oInput.select()
    document.execCommand('Copy')
@@ -982,8 +1104,6 @@
  addProcess = () => {
    const { config } = this.props
    const { columns } = this.state
    if (config.subtype === 'dualdatacard') return
    let fields = []
    let cols = []
@@ -1076,7 +1196,7 @@
  render() {
    const { config } = this.props
    const { columns, subColumns, median, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql, visible, pvisible, reload, script, scriptValue, searchKey } = this.state
    const { columns, subColumns, median, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql, visible, pvisible, reload, script, scriptValue, searchKey, editLineId } = this.state
    return (
      <div className="model-data-source-wrap">
@@ -1100,7 +1220,7 @@
              wrappedComponentRef={(inst) => this.settingForm = inst}
            /> : null}
          </TabPane>
          {config.subtype !== 'basetable' ? <TabPane tab={
          {!['basetable', 'invoice', 'invTable'].includes(config.subtype) ? <TabPane tab={
            <span>
              字段集
              {columns.length ? <span className="count-tip">{columns.length}</span> : null}
@@ -1156,14 +1276,14 @@
                })
                return
              }
              this.setState({visible: true, script: null, scriptValue: ''})
              this.setState({visible: true, script: null, scriptValue: '', editLineId: ''})
            }}/> : null}
            <CustomScriptsForm
              type={config.type}
              hasExtend={config.hasExtend}
              setting={setting}
              searches={searches}
              defaultsql={defaultsql}
              initsql={this.state.initsql}
              customScripts={scripts}
              systemScripts={this.state.systemScripts}
              scriptsChange={this.scriptsChange}
@@ -1206,8 +1326,14 @@
                  </div>
                )
              } else {
                let sign = ''
                if (script && script.uuid === item.uuid) {
                  sign = 'active'
                } else if (editLineId === item.uuid) {
                  sign = 'edited'
                }
                return (
                  <div className={'script-item ' + (script && script.uuid === item.uuid ? 'active' : '') } key={item.uuid}>
                  <div className={'script-item ' + sign} key={item.uuid}>
                    <div style={{cursor: 'pointer'}} onClick={() => {
                      this.setState({script: item, scriptValue: item.sql})
                    }}>