king
2023-01-05 876a5e6657d67df66bb525d02dd6d147ba81cae5
src/views/systemproc/proc/index.jsx
@@ -1,5 +1,6 @@
import React, {Component} from 'react'
import { Input, notification } from 'antd'
import { Input, notification, Button, Form, Modal, Empty } from 'antd'
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons'
import moment from 'moment'
import Utils from '@/utils/utils.js'
@@ -7,17 +8,52 @@
import CodeMirror from '@/templates/zshare/codemirror'
import './index.scss'
const { confirm } = Modal
const { Search } = Input
class ProcControl extends Component {
  state = {
    procName: '',
    content: null,
    loading: false
    content: '',
    loading: false,
    visible: false,
    searchable: false,
    inputing: false,
    procList: [],
    permFuncs: []
  }
  componentDidMount () {
    if (sessionStorage.getItem('permFuncField')) {
      this.setState({permFuncs: JSON.parse(sessionStorage.getItem('permFuncField'))})
    } else {
      Api.getCloudConfig({func: 'sPC_Get_Roles_sModular'}).then(res => {
        if (res.status) {
          let _permFuncs = []
          if (res.sModular && res.sModular.length > 0) {
            res.sModular.forEach(field => {
              if (field.ModularNo) {
                _permFuncs.push(field.ModularNo)
              }
            })
            _permFuncs = _permFuncs.sort()
          }
          if (_permFuncs.length) {
            this.setState({permFuncs: _permFuncs})
    
            sessionStorage.setItem('permFuncField', JSON.stringify(_permFuncs))
          }
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
        }
      })
    }
  }
  search = (value) => {
@@ -47,31 +83,330 @@
        })
        this.setState({content: '', procName: '', loading: false})
        return
      } else if (!res.Ltext) {
        this.setState({content: '', procName: '', loading: false})
      } else {
        this.setState({content: res.Ltext.replace(/mchr13k/ig, '\n'), procName: proc, loading: false})
      }
    })
  }
  save = (type) => {
    const { content, procName, permFuncs } = this.state
    let value = content.replace(/^(\s*)|(\s*)$/ig, '')
    if (!value) {
      notification.warning({
        top: 92,
        message: '存储过程不可为空',
        duration: 5
      })
      return
    } else {
      let chars = [
        {key: 'drop', reg: /(^|\s)drop\s/ig},
        {key: 'alter', reg: /(^|\s)alter\s/ig},
        {key: 'object', reg: /(^|\s)object(\s|\()/ig},
        {key: 'kill', reg: /(^|\s)kill\s/ig},
        {key: '--', reg: /--/ig}
      ]
      let error = ''
      if (!/create(\s+)proc/ig.test(value)) {
        error = '脚本中必须使用create proc'
      }
      chars.forEach(char => {
        if (!error && char.reg.test(value)) {
          error = '不可使用' + char.key
        }
      })
      if (error) {
        notification.warning({
          top: 92,
          message: error,
          duration: 5
        })
        return
      }
    }
    if (!procName) {
      if (permFuncs.length > 0) {
        this.setState({visible: true})
      } else {
        notification.warning({
          top: 92,
          message: '未获取到授权编码不可新建!',
          duration: 5
        })
      }
      return
    }
    let dropfunc = `IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('${procName}') AND type in (N'P', N'PC'))  mdrpk PROCEDURE ${procName}`
    let createfunc = value.replace(/\n/ig, 'mchr13k')
    let dropParam = {
      func: 'sPC_TableData_InUpDe',
      LText: Utils.formatOptions(dropfunc),
      TypeCharOne: 'proc' // 删除存储过程
    }
    dropParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    dropParam.secretkey = Utils.encrypt(dropParam.LText, dropParam.timestamp)
    dropParam.open_key = Utils.encryptOpenKey(dropParam.secretkey, dropParam.timestamp)
    let createParam = {
      func: 'sPC_TableData_InUpDe',
      LText: Utils.formatOptions(createfunc),
      TypeCharOne: 'proc' // 创建存储过程
    }
    createParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    createParam.secretkey = Utils.encrypt(createParam.LText, createParam.timestamp)
    createParam.open_key = Utils.encryptOpenKey(createParam.secretkey, createParam.timestamp)
    let saveParam = {
      func: 's_proc_save',
      sql_script: window.btoa(window.encodeURIComponent(createfunc)),
      proc_name: procName,
      save_type: type !== 'prev' ? 'auto' : '' // 'auto' 时 会清y的数据
    }
    this.setState({loading: true})
    Api.genericInterface(dropParam).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        this.setState({loading: false})
        return
      }
      this.setState({content: res.Ltext.replace(/mchr13k/ig, '\n'), procName: proc, loading: false})
      Api.genericInterface(createParam).then(result => {
        if (!result.status) {
          notification.warning({
            top: 92,
            message: result.message,
            duration: 5
          })
          this.setState({loading: false})
          return
        }
        Api.genericInterface(saveParam).then(response => {
          this.setState({loading: false})
          if (!response.status) {
            notification.warning({
              top: 92,
              message: response.message,
              duration: 5
            })
          } else {
            notification.success({
              top: 92,
              message: '保存成功。',
              duration: 5
            })
          }
        })
      })
    })
  }
  prev = () => {
    const { procName } = this.state
    const that = this
    let saveParam = {
      func: 's_proc_ctrl_z',
      proc_name: procName
    }
    confirm({
      title: '确定切换上一版本吗?',
      content: '',
      onOk() {
        that.setState({loading: true})
        Api.genericInterface(saveParam).then(res => {
          that.setState({loading: false})
          if (!res.status || !res.Ltext) {
            notification.warning({
              top: 92,
              message: !res.status ? res.message : '没有可以后退的版本',
              duration: 5
            })
            return
          }
          let value = window.decodeURIComponent(window.atob(res.Ltext))
          value  = value.replace(/mchr13k/ig, '\n')
          that.setState({content: value}, () => {
            that.save('prev')
          })
        })
      },
      onCancel() {}
    })
  }
  next = () => {
    const { procName } = this.state
    const that = this
    let saveParam = {
      func: 's_proc_ctrl_y',
      proc_name: procName
    }
    confirm({
      title: '确定切换下一版本吗?',
      content: '',
      onOk() {
        that.setState({loading: true})
        Api.genericInterface(saveParam).then(res => {
          that.setState({loading: false})
          if (!res.status || !res.Ltext) {
            notification.warning({
              top: 92,
              message: !res.status ? res.message : '没有可以撤销后退的版本',
              duration: 5
            })
            return
          }
          let value = window.decodeURIComponent(window.atob(res.Ltext))
          value  = value.replace(/mchr13k/ig, '\n')
          that.setState({content: value}, () => {
            that.save()
          })
        })
      },
      onCancel() {}
    })
  }
  handleConfirm = () => {
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (err) return
      this.setState({procName: values.name}, () => {
        this.save()
      })
    })
  }
  searchAll = (value) => {
    let param = {
      func: 's_proc_search',
      proc_name: value || ''
    }
    this.setState({loading: true})
    Api.genericInterface(param).then(res => {
      this.setState({loading: false})
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
      this.setState({procList: res.data || []})
    })
  }
  changeProc = (name) => {
    const { loading } = this.state
    if (loading) {
      notification.warning({
        top: 92,
        message: '查询中请稍后。',
        duration: 5
      })
      return
    }
    this.setState({inputing: true, procName: name}, () => {
      this.setState({inputing: false})
      this.search(name)
    })
  }
  render () {
    const { loading, content } = this.state
    const { getFieldDecorator } = this.props.form
    const { loading, content, procName, visible, permFuncs, searchable, procList, inputing } = this.state
    let _patten = permFuncs.length ? new RegExp('^(' + permFuncs.join('|') + ')[0-9a-zA-Z_]*$', 'g') : ''
    return (
      <div className="mk-proc-wrap">
        <div className="control-wrap">
          <div className="search-wrap">
            <Search placeholder="请输入存储过程名称" disabled={loading} enterButton="确定" onSearch={this.search}/>
          </div>
          <div className="action-wrap">
        <div className={'searh-list' + (searchable ? ' open' : '')}>
          <Search placeholder="存储过程名称查询" disabled={loading} onSearch={this.searchAll}/>
          <div className="proc-list">
            {procList.map((item, index) => (<div className="proc-item" onClick={() => this.changeProc(item.proc_name)} key={index}>{item.proc_name}</div>))}
            {procList.length === 0 ? <Empty /> : null}
          </div>
        </div>
        <div className="edit-wrap">
          <CodeMirror value={content} onChange={(val) => this.setState({content: val})}/>
        <div className="proc-wrap">
          <div className="control-wrap">
            <div className="search-wrap">
              {searchable ? <MenuUnfoldOutlined onClick={() => this.setState({searchable: !searchable})}/> : <MenuFoldOutlined onClick={() => this.setState({searchable: !searchable})}/>}
              {!inputing ? <Search placeholder="请输入存储过程名称" defaultValue={procName} disabled={loading} enterButton="确定" onSearch={this.search}/> : null}
            </div>
            <div className="action-wrap">
              <Button key="save" className="mk-btn mk-green" disabled={loading} onClick={() => this.save()}>保存</Button>
              <Button key="prev" className="mk-btn mk-primary" disabled={!procName || loading} onClick={this.prev}>上一版本</Button>
              <Button key="next" className="mk-btn mk-primary" disabled={!procName || loading} onClick={this.next}>下一版本</Button>
            </div>
          </div>
          <div className="edit-wrap">
            <CodeMirror value={content} onChange={(val) => this.setState({content: val})}/>
          </div>
        </div>
        <Modal
          title="新建"
          wrapClassName="mk-create-func"
          visible={visible}
          onOk={this.handleConfirm}
          width={540}
          onCancel={() => {this.setState({ visible: false })}}
          destroyOnClose
        >
          <Form.Item label="存储过程名称">
            {getFieldDecorator('name', {
              initialValue: '',
              rules: [
                {
                  required: true,
                  message: '请输入存储过程名称!'
                },
                {
                  pattern: _patten,
                  message: `只允许包含数字、字母和下划线,且以${permFuncs.join(', ')}等字符开始。`
                }
              ]
            })(<Input placeholder="" autoComplete="off" />)}
          </Form.Item>
        </Modal>
      </div>
    )
  }
}
export default ProcControl
export default Form.create()(ProcControl)