king
2023-10-18 81d0d7721bb14a34b1eef99fd9506c3eda4bda99
src/menu/sysinterface/index.jsx
@@ -1,14 +1,15 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal, Button, Popconfirm, message } from 'antd'
import { StopTwoTone, ApiOutlined, CopyOutlined, EditOutlined, CheckCircleTwoTone, DeleteOutlined } from '@ant-design/icons'
import { Modal, Button, Popconfirm, message, notification } from 'antd'
import { StopTwoTone, DatabaseOutlined, CopyOutlined, CheckCircleTwoTone, DeleteOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
import MKEmitter from '@/utils/events.js'
import './index.scss'
const SettingForm = asyncComponent(() => import('./settingform'))
const DataSource = asyncComponent(() => import('@/menu/datasource'))
const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
class InterfaceController extends Component {
@@ -19,12 +20,10 @@
  state = {
    visible: false,
    setvisible: false,
    interfaces: [],
    card: null,
    columns: [
      {
        title: '接口名称',
        title: '名称',
        dataIndex: 'name',
        width: '50%'
      },
@@ -53,15 +52,16 @@
        dataIndex: 'operation',
        render: (text, record) =>
          (<div style={{textAlign: 'center'}}>
            <span onClick={() => this.handleEdit(record)} style={{color: '#1890ff', cursor: 'pointer', fontSize: '16px', marginRight: '15px'}}><EditOutlined /></span>
            <span onClick={() => {this.copy(record)}} style={{color: '#26C281', cursor: 'pointer', fontSize: '16px', marginRight: '15px'}}><CopyOutlined /></span>
            <span onClick={() => this.handleStatus(record)} style={{color: '#8E44AD', cursor: 'pointer', fontSize: '16px', marginRight: '15px'}}><SwapOutlined /></span>
            <span onClick={() => this.copy(record)} style={{color: '#26C281', cursor: 'pointer', fontSize: '16px', marginRight: '15px'}}><CopyOutlined /></span>
            <Popconfirm
              overlayClassName="popover-confirm"
              title="确定删除?"
              onConfirm={() => this.deleteScript(record)
            }>
              <span style={{color: '#ff4d4f', cursor: 'pointer', fontSize: '16px'}}><DeleteOutlined /></span>
              <span style={{color: '#ff4d4f', cursor: 'pointer', fontSize: '16px', marginRight: '15px'}}><DeleteOutlined /></span>
            </Popconfirm>
            <DataSource config={record} updateConfig={this.update}/>
          </div>)
      }
    ]
@@ -73,6 +73,11 @@
  copy = (item) => {
    let msg = { key: 'interface', type: 'line', data: item }
    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
    if (srcid) {
      msg.$srcId = srcid
    }
    try {
      msg = window.btoa(window.encodeURIComponent(JSON.stringify(msg)))
@@ -102,8 +107,46 @@
    })
  }
  handleEdit = (record) => {
    this.setState({card: record, setvisible: true})
  handleStatus = (record) => {
    const { config } = this.props
    if (record.status === 'false') {
      if (record.setting.interType === 'system' && record.setting.execute !== 'false' && !record.setting.dataresource) {
        notification.warning({
          top: 92,
          message: '未设置数据源,不可启用!',
          duration: 5
        })
        return
      } else if (!record.setting.primaryKey) {
        notification.warning({
          top: 92,
          message: '未设置主键,不可启用!',
          duration: 5
        })
        return
      } else if (record.columns.length === 0) {
        notification.warning({
          top: 92,
          message: '未添加字段集,不可启用!',
          duration: 5
        })
        return
      }
    }
    record = fromJS(record).toJS()
    record.status = record.status === 'false' ? 'true' : 'false'
    let interfaces = this.state.interfaces.map(item => {
      if (item.uuid !== record.uuid) {
        return item
      }
      return record
    })
    this.setState({ interfaces })
    this.props.updateConfig({...config, interfaces})
  }
  deleteScript = (record) => {
@@ -117,41 +160,73 @@
  changeScripts = (interfaces) => {
    const { config } = this.props
    interfaces = interfaces.map(item => {
      item.$tables = this.getTables(item)
      return item
    })
    this.setState({ interfaces })
    this.props.updateConfig({...config, interfaces})
  }
  settingSave = () => {
  getTables = (record) => {
    let tables = []
    let cuts = []
    let cutreg = /(from|update|insert\s+into)\s+(@db@)?[a-z_]+/ig
    let trimreg = /(from|update|insert\s+into)\s+(@db@)?/ig
    if (record.setting.interType === 'system') {
      if (record.setting.execute !== 'false' && record.setting.dataresource) {
        let tbs = record.setting.dataresource.match(cutreg)
        tbs && cuts.push(...tbs)
      }
      record.scripts && record.scripts.forEach(script => {
        if (script.status === 'false') return
        let tbs = script.sql.match(cutreg)
        tbs && cuts.push(...tbs)
      })
    } else if (record.setting.tableName) {
      let tb = record.setting.tableName.replace(/@db@|\s+/ig, '')
      if (/[a-z_]+/ig.test(tb)) {
        tables.push(tb)
      }
    }
    cuts = cuts.map(item => item.replace(trimreg, ''))
    tables.push(...cuts)
    tables = tables.filter(Boolean)
    tables = Array.from(new Set(tables))
    return tables
  }
  update = (record) => {
    const { config } = this.props
    const { card } = this.state
    let interfaces = fromJS(this.state.interfaces).toJS()
    this.settingRef.handleConfirm().then(res => {
      interfaces = interfaces.map(item => {
        if (item.uuid === card.uuid) {
          res.uuid = item.uuid
    if (record.setting.primaryKey && record.columns.length > 0) {
      record.status = 'true'
    } else if (record.columns.length === 0) {
      record.status = 'false'
    }
    record.name = record.setting.name
    record.$tables = this.getTables(record)
          if (res.procMode !== 'inner' && res.preScripts && res.preScripts.filter(item => item.status !== 'false').length === 0) {
            message.warning('未设置前置脚本,不可启用!')
            res.status = 'false'
          } else if (res.callbackType === 'script' && res.cbScripts && res.cbScripts.filter(item => item.status !== 'false').length === 0) {
            message.warning('未设置回调脚本,不可启用!')
            res.status = 'false'
          }
    delete record.subColumns
          return res
        }
    let interfaces = this.state.interfaces.map(item => {
      if (item.uuid !== record.uuid) {
        return item
      })
      this.setState({
        card: null,
        setvisible: false,
        interfaces
      })
      this.props.updateConfig({...config, interfaces})
      }
      return record
    })
    this.setState({ interfaces })
    this.props.updateConfig({...config, interfaces})
    MKEmitter.emit('editLineId', record.uuid)
    setTimeout(() => {
      MKEmitter.emit('mkUpdateInter', record, {delay: 0})
    }, 10)
  }
  addInterface = () => {
@@ -160,11 +235,14 @@
    interfaces.push({
      uuid: Utils.getuuid(),
      name: 'interface ' + (interfaces.length + 1),
      procMode: 'script',
      callbackType: 'script',
      preScripts: [],
      cbScripts: []
      name: '数据源' + (interfaces.length + 1),
      status: 'false',
      format: 'array',
      type: 'interface',
      pageable: false,
      setting: { interType: 'system', name: '数据源' + (interfaces.length + 1), status: 'false' },
      columns: [],
      scripts: [],
    })
    this.setState({
@@ -174,13 +252,13 @@
  }
  render() {
    const { visible, setvisible, columns, interfaces, card } = this.state
    const { visible, columns, interfaces } = this.state
    return (
      <div style={{display: 'inline-block'}}>
        <Button className="mk-border-green" onClick={this.trigger}><ApiOutlined /> 接口管理</Button>
      <>
        <Button className="mk-border-danger" onClick={this.trigger}><DatabaseOutlined /> 公共数据源</Button>
        <Modal
          title="接口管理"
          title="公共数据源"
          wrapClassName="interface-controller-modal"
          visible={visible}
          width={800}
@@ -193,22 +271,10 @@
          ]}
          destroyOnClose
        > 
          <Button key="add-interface" className="mk-border-green" onClick={this.addInterface}> 添加 </Button>
          <EditTable key="manage-interface" actions={['move', 'copy']} type="interface" data={interfaces} columns={columns} onChange={this.changeScripts}/>
          <PlusOutlined key="add-interface" onClick={this.addInterface}/>
          <EditTable key="manage-interface" actions={['copy']} type="interface" data={interfaces} columns={columns} onChange={this.changeScripts}/>
        </Modal>
        <Modal
          title={card ? card.name : '接口'}
          wrapClassName="interface-edit-modal"
          visible={setvisible}
          width={900}
          maskClosable={false}
          onOk={this.settingSave}
          onCancel={() => { this.setState({ setvisible: false })}}
          destroyOnClose
        >
          <SettingForm config={card} wrappedComponentRef={(inst) => this.settingRef = inst}/>
        </Modal>
      </div>
      </>
    )
  }
}