king
2023-11-26 bdfec77e57c90ad4750e08ee822818ce991b019f
src/menu/datasource/verifycard/index.jsx
@@ -2,7 +2,7 @@
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message, Button, Input } from 'antd'
import { StopOutlined, CheckCircleOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined, BorderOutlined, SnippetsOutlined } from '@ant-design/icons'
import { StopOutlined, CheckCircleOutlined, TableOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined, BorderOutlined, SnippetsOutlined } from '@ant-design/icons'
import moment from 'moment'
import md5 from 'md5'
@@ -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,
@@ -215,6 +217,27 @@
    columns.reverse()
    subColumns.reverse()
    columns.forEach(col => {
      if (!col.datatype) return
      if (/^nvarchar/.test(col.datatype)) {
        col.datatype = col.datatype.replace(/^nvarchar/, 'Nvarchar')
      } else if (/^decimal/.test(col.datatype)) {
        col.datatype = col.datatype.replace(/^decimal/, 'Decimal')
      } else if (/^int/.test(col.datatype)) {
        col.datatype = col.datatype.replace(/^int/, 'Int')
      }
    })
    subColumns.forEach(col => {
      if (!col.datatype) return
      if (/^nvarchar/.test(col.datatype)) {
        col.datatype = col.datatype.replace(/^nvarchar/, 'Nvarchar')
      } else if (/^decimal/.test(col.datatype)) {
        col.datatype = col.datatype.replace(/^decimal/, 'Decimal')
      } else if (/^int/.test(col.datatype)) {
        col.datatype = col.datatype.replace(/^int/, 'Int')
      }
    })
    this.setState({
      scripts,
@@ -369,6 +392,7 @@
    if (values.uuid) {
      scripts = scripts.map(item => {
        if (item.uuid === values.uuid) {
          values.$index = item.$index || ''
          return values
        } else {
          return item
@@ -637,6 +661,25 @@
      let r = SettingUtils.getDebugSql(setting, _scripts, _columns, searches, config.type)
      let _debugId = md5(r.sql)
      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) {
        resolve()
@@ -657,6 +700,57 @@
            resolve()
          })
        } else {
          if (/列名\s*'[a-zA-Z0-9_-]+'\s*无效/.test(result.message)) {
            let tail = ''
            let type = ''
            if (setting.execute !== 'false' && setting.queryType !== 'statistics') {
              searches.forEach(item => {
                if (item.forbid) return
                item.key.split(',').forEach(field => {
                  if (new RegExp(`'${field}'`).test(result.message)) {
                    tail = field
                    type = '搜索条件'
                  }
                })
              })
            }
            if (!tail && setting.order) {
              let keys = setting.order.replace(/\s+(asc|desc)/ig, '').replace(/\s+/g, '')
              keys.split(',').forEach(field => {
                if (new RegExp(`'${field}'`).test(result.message)) {
                  tail = field
                  type = '排序'
                }
              })
            }
            if (!tail) {
              columns.forEach(item => {
                if (new RegExp(`'${item.field}'`).test(result.message)) {
                  tail = item.field
                  if (config.subtype === 'basetable') {
                    type = '显示列'
                  } else {
                    type = '字段集'
                  }
                }
              })
              if (!tail && config.subtype === 'dualdatacard') {
                subColumns.forEach(item => {
                  if (new RegExp(`'${item.field}'`).test(result.message)) {
                    tail = item.field
                    type = '子表字段集'
                  }
                })
              }
            }
            if (tail) {
              result.message = result.message.replace(/ROLLBACK TRANSACTION 请求没有对应的 BEGIN TRANSACTION。/, '')
              result.message = <>{result.message}<span style={{color: 'red'}}>注:{type}中存在字段{tail}</span></>
            }
          }
          if (type === 'submit') {
            Modal.confirm({
              title: result.message,
@@ -844,11 +938,25 @@
    const { columns } = this.state
    let m = []
    let n = []
    let s = []
    columns.forEach(col => {
      m.push(`${col.field} ${col.datatype}`)
      n.push(col.field)
      m.unshift(`${col.field} ${col.datatype}`)
      n.unshift(col.field)
      if (/decimal|int/ig.test(col.datatype)) {
        s.unshift(`${Math.round(Math.random() * 10)} as ${col.field}`)
      } else if (/datetime/.test(col.datatype)) {
        s.unshift(`'${moment().format('YYYY-MM-DD HH:mm:ss')}' as ${col.field}`)
      } else if (/date/.test(col.datatype)) {
        s.unshift(`'${moment().format('YYYY-MM-DD')}' as ${col.field}`)
      } else {
        s.unshift(`'${col.label}' as ${col.field}`)
      }
    })
    if (window.debugger) {
      console.info('select ' + s.join(', '))
    }
    let oInput = document.createElement('input')
    oInput.value = `/*${m.join(',')}*/
@@ -951,7 +1059,7 @@
        if (item.f_type !== 0) return
        if (/nvarchar|int|decimal/ig.test(item.FieldType) || item.FieldType === 'date' || item.FieldType === 'datetime') {
          fields.push({
          fields.unshift({
            uuid: Utils.getuuid(),
            label: item.FieldDec,
            field: item.FieldName,
@@ -1016,7 +1124,15 @@
              updatefield={this.updatefields}
            />
            <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.datasource = inst} data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/>
          </TabPane> : null}
          </TabPane> : <TabPane tab={
            <span>
              字段集<TableOutlined style={{marginLeft: '5px', fontSize: '12px'}} />
              {columns.length ? <span className="count-tip">{columns.length}</span> : null}
            </span>
          } key="columns">
            <div className="base-table-columns"></div>
            <EditTable actions={[]} searchKey={searchKey} type="datasourcefield" data={columns} columns={colColumns}/>
          </TabPane>}
          {config.subtype === 'dualdatacard' ? <TabPane tab={
            <span>
              子表字段集
@@ -1035,8 +1151,8 @@
            <span>
              自定义脚本
              {scripts.length ? <span className="count-tip">{scripts.length}</span> : null}
              {config.type !== 'interface' && activeKey === 'setting' ? <CopyOutlined title="复制数据源" className="mk-copy-datasource" onClick={(e) => {e.stopPropagation();this.copyDatasource()}}/> : null}
              {config.type !== 'interface' && activeKey === 'setting' ? <SnippetsOutlined title="导入数据源" className="mk-paste-datasource" onClick={(e) => {e.stopPropagation();this.setState({pvisible: true})}}/> : null}
              {activeKey === 'setting' ? <CopyOutlined title="复制数据源" className="mk-copy-datasource" onClick={(e) => {e.stopPropagation();this.copyDatasource()}}/> : null}
              {activeKey === 'setting' ? <SnippetsOutlined title="导入数据源" className="mk-paste-datasource" onClick={(e) => {e.stopPropagation();this.setState({pvisible: true})}}/> : null}
              {activeKey === 'columns' ? <CopyOutlined title="以逗号拼接形式复制字段" className="mk-copy-fields" onClick={(e) => {e.stopPropagation();this.copyColumns()}}/> : null}
              {activeKey === 'subcolumns' ? <CopyOutlined title="以逗号拼接形式复制字段" className="mk-copy-fields" onClick={(e) => {e.stopPropagation();this.copySubColumns()}}/> : null}
              {activeKey === 'subcolumns' || activeKey === 'columns' ? <span onClick={(e) => {e.stopPropagation()}}><Search className="mk-search-fields" defaultValue={searchKey} allowClear onSearch={(val, e) => {e.stopPropagation();this.setState({searchKey: val})}} /></span> : null}