import React, {Component} from 'react'
|
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'
|
import Api from '@/api'
|
import CodeMirror from '@/templates/zshare/codemirror'
|
import './index.scss'
|
|
const { confirm } = Modal
|
const { Search } = Input
|
|
class ProcControl extends Component {
|
state = {
|
procName: '',
|
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) => {
|
let proc = value.replace(/^(\s*)|(\s*)$/ig, '')
|
|
if (!proc) {
|
this.setState({content: '', procName: ''})
|
return
|
}
|
|
let _param = {
|
func: 's_get_userproc',
|
LText: proc
|
}
|
|
_param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
|
_param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
|
|
this.setState({loading: true})
|
|
Api.genericInterface(_param).then(res => {
|
if (!res.status) {
|
notification.warning({
|
top: 92,
|
message: res.message,
|
duration: 5
|
})
|
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},
|
{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
|
}
|
|
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 { 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={'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="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} func={true} 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 Form.create()(ProcControl)
|