import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { fromJS } from 'immutable'
|
import { Form, Tabs, Row, Col, Input, Button, Popconfirm, notification, Modal, message, Select, Cascader, Tooltip, InputNumber, Radio, Typography } from 'antd'
|
import { StopTwoTone, CheckCircleTwoTone, EditOutlined, SwapOutlined, DeleteOutlined, QuestionCircleOutlined } from '@ant-design/icons'
|
import moment from 'moment'
|
|
import Api from '@/api'
|
import Utils from '@/utils/utils.js'
|
import MKEmitter from '@/utils/events.js'
|
import MenuUtils from '@/utils/utils-custom.js'
|
import UniqueForm from './uniqueform'
|
import CustomScript from './customscript'
|
import asyncComponent from '@/utils/asyncComponent'
|
import './index.scss'
|
|
const { TabPane } = Tabs
|
const { confirm } = Modal
|
const { Paragraph } = Typography
|
const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
|
const FullScripts = asyncComponent(() => import('@/templates/zshare/verifycard/fullScripts'))
|
|
class VerifyTableCard extends Component {
|
static propTpyes = {
|
columns: PropTypes.array, // 显示列
|
card: PropTypes.object,
|
}
|
|
state = {
|
verify: {},
|
fields: [],
|
modules: [],
|
fieldLabel: {},
|
systemScripts: [],
|
activeKey: 'basemsg',
|
uniqueColumns: [
|
{
|
title: '列名',
|
dataIndex: 'fieldlabel',
|
width: '20%'
|
},
|
{
|
title: '字段',
|
dataIndex: 'field',
|
width: '25%',
|
editable: true,
|
inputType: 'multiStr',
|
options: []
|
},
|
{
|
title: '报错编码',
|
dataIndex: 'errorCode',
|
width: '10%',
|
editable: true,
|
inputType: 'select',
|
options: [
|
{ value: 'E', text: 'E' },
|
{ value: 'N', text: 'N' },
|
{ value: 'F', text: 'F' },
|
{ value: 'NM', text: 'NM' }
|
]
|
},
|
{
|
title: '验证类型',
|
dataIndex: 'verifyType',
|
width: '14%',
|
render: (text, record) => {
|
let names = {
|
physical: '物理验证(全量验证)',
|
logic: '逻辑验证(全量验证)',
|
physical_temp: '物理验证(仅临时表)',
|
logic_temp: '逻辑验证(仅临时表)',
|
}
|
|
return names[text] || '物理验证(全量验证)'
|
},
|
inputType: 'select',
|
editable: true,
|
options: [
|
{ value: 'physical', text: '物理验证(全量验证)' },
|
{ value: 'logic', text: '逻辑验证(全量验证)' },
|
{ value: 'physical_temp', text: '物理验证(仅临时表)' },
|
{ value: 'logic_temp', text: '逻辑验证(仅临时表)' }
|
]
|
},
|
{
|
title: '是否启用',
|
dataIndex: 'status',
|
width: '12%',
|
editable: true,
|
required: false,
|
inputType: 'switch',
|
render: (text, record) => record.status === 'false' ?
|
(
|
<div>
|
禁用
|
<StopTwoTone style={{marginLeft: '5px'}} twoToneColor="#ff4d4f" />
|
</div>
|
) :
|
(
|
<div>
|
启用
|
<CheckCircleTwoTone style={{marginLeft: '5px'}} twoToneColor="#52c41a" />
|
</div>
|
)
|
},
|
],
|
scriptsColumns: [
|
{
|
title: 'SQL',
|
dataIndex: 'sql',
|
width: '60%',
|
render: (text) => {
|
let title = text.match(/^\s*\/\*.+\*\//)
|
title = title && title[0] ? title[0] : ''
|
let _text = title ? text.replace(title, '') : text
|
|
return (
|
<div>
|
{title ? <span style={{color: '#a50'}}>{title}<span style={{fontSize: '12px', marginLeft: '5px'}}>{_text.length}</span></span> : null}
|
<Paragraph copyable={{ text: text }} ellipsis={{ rows: 4, expandable: true }}>{_text}</Paragraph>
|
</div>
|
)
|
}
|
},
|
{
|
title: '执行位置',
|
dataIndex: 'position',
|
width: '10%',
|
render: (text, record) => {
|
if (record.position === 'init') {
|
return <span style={{color: 'orange'}}>初始化</span>
|
} else if (record.position === 'front') {
|
return <span style={{color: '#26C281'}}>sql前</span>
|
} else {
|
return <span style={{color: '#1890ff'}}>sql后</span>
|
}
|
}
|
},
|
{
|
title: '状态',
|
dataIndex: 'status',
|
width: '10%',
|
render: (text, record) => record.status === 'false' ?
|
(
|
<div>
|
禁用
|
<StopTwoTone style={{marginLeft: '5px'}} twoToneColor="#ff4d4f" />
|
</div>
|
) :
|
(
|
<div>
|
启用
|
<CheckCircleTwoTone style={{marginLeft: '5px'}} twoToneColor="#52c41a" />
|
</div>
|
)
|
},
|
{
|
title: '操作',
|
align: 'center',
|
width: '20%',
|
dataIndex: 'operation',
|
render: (text, record) =>
|
(<div style={{textAlign: 'center'}}>
|
<span className="operation-btn" onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><EditOutlined /></span>
|
<span className="operation-btn" title="状态切换" onClick={() => this.handleStatus(record, 'scripts')} style={{color: '#8E44AD'}}><SwapOutlined /></span>
|
<Popconfirm
|
overlayClassName="popover-confirm"
|
title="确定删除吗?"
|
onConfirm={() => this.handleDelete(record, 'scripts')
|
}>
|
<span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
|
</Popconfirm>
|
</div>)
|
}
|
]
|
}
|
|
UNSAFE_componentWillMount() {
|
const { columns, submit, setting, uuid } = this.props.config
|
let _verify = fromJS(submit).toJS()
|
_verify.sheet = _verify.sheet || setting.tableName
|
|
let fieldLabel = {}
|
|
columns.forEach(col => {
|
fieldLabel[col.field] = col.label
|
})
|
|
let supId = ''
|
if (setting && setting.supModule) {
|
let pid = setting.supModule[setting.supModule.length - 1]
|
if (pid && pid !== 'empty') {
|
supId = pid
|
} else {
|
supId = ''
|
}
|
}
|
|
let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, uuid, supId)
|
|
this.setState({
|
fields: fromJS(columns).toJS().filter(item => item.field !== setting.primaryKey),
|
fieldLabel,
|
modules: modules,
|
verify: _verify
|
}, () => {
|
this.resetUniqueColumns()
|
})
|
}
|
|
componentDidMount () {
|
this.getsysScript()
|
}
|
|
getsysScript = () => {
|
if (sessionStorage.getItem('mk_sys_scripts')) {
|
this.setState({
|
systemScripts: JSON.parse(sessionStorage.getItem('mk_sys_scripts'))
|
})
|
return
|
}
|
|
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)
|
|
let _sParam = {
|
func: 'sPC_Get_SelectedList',
|
LText: _scriptSql,
|
obj_name: 'data',
|
arr_field: 'funcname,longparam'
|
}
|
|
_sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
|
_sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp)
|
|
_sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证
|
|
Api.getCloudConfig(_sParam).then(res => {
|
if (res.status) {
|
let _scripts = res.data.map(item => {
|
return {
|
name: item.funcname,
|
value: window.decodeURIComponent(window.atob(item.longparam))
|
}
|
})
|
|
sessionStorage.setItem('mk_sys_scripts', JSON.stringify(_scripts))
|
|
this.setState({
|
systemScripts: _scripts
|
})
|
} else {
|
notification.warning({
|
top: 92,
|
message: res.message,
|
duration: 5
|
})
|
}
|
})
|
}
|
|
resetUniqueColumns = () => {
|
const { uniqueColumns, fields } = this.state
|
|
let unFields = fromJS(fields).toJS()
|
unFields.unshift({
|
field: 'BID',
|
label: 'BID'
|
})
|
|
this.setState({uniqueColumns: uniqueColumns.map(col => {
|
if (col.dataIndex === 'field') {
|
col.options = unFields
|
}
|
|
return col
|
})})
|
}
|
|
uniqueChange = (values) => {
|
let verify = JSON.parse(JSON.stringify(this.state.verify))
|
|
values.status = 'true'
|
values.uuid = Utils.getuuid()
|
verify.uniques.push(values)
|
|
this.setState({
|
verify: verify
|
})
|
}
|
|
changeUniques = (uniques) => {
|
const { verify, fieldLabel } = this.state
|
|
uniques = uniques.map(item => {
|
item.status = item.status || 'true'
|
|
if (Array.isArray(item.field)) {
|
item.fieldlabel = item.field.map(field => {
|
return fieldLabel[field] || field
|
})
|
|
item.fieldlabel = item.fieldlabel.join(',')
|
item.field = item.field.join(',')
|
}
|
|
return item
|
})
|
|
this.setState({verify: {...verify, uniques}})
|
}
|
|
scriptsChange = (values) => {
|
let verify = JSON.parse(JSON.stringify(this.state.verify))
|
|
if (values.uuid) {
|
verify.scripts = verify.scripts.map(item => {
|
if (item.uuid === values.uuid) {
|
return values
|
} else {
|
return item
|
}
|
})
|
} else {
|
values.uuid = Utils.getuuid()
|
verify.scripts.push(values)
|
}
|
|
MKEmitter.emit('editLineId', values.uuid)
|
|
this.setState({
|
verify: verify
|
})
|
}
|
|
handleDelete = (record, type) => {
|
const { verify } = this.state
|
|
if (type === 'scripts') {
|
verify.scripts = verify.scripts.filter(item => item.uuid !== record.uuid)
|
} else if (type === 'unique') {
|
verify.uniques = verify.uniques.filter(item => item.uuid !== record.uuid)
|
}
|
|
this.setState({ verify: verify })
|
}
|
|
handleEdit = (record, type) => {
|
if (type === 'scripts') {
|
this.scriptsForm.edit(record)
|
}
|
|
let node = document.getElementById('verify-excel-box-tab').parentNode
|
|
if (node && node.scrollTop) {
|
let inter = Math.ceil(node.scrollTop / 10)
|
|
let timer = setInterval(() => {
|
if (node.scrollTop - inter > 0) {
|
node.scrollTop = node.scrollTop - inter
|
} else {
|
node.scrollTop = 0
|
clearInterval(timer)
|
}
|
}, 10)
|
}
|
}
|
|
handleStatus = (record, type) => {
|
let verify = JSON.parse(JSON.stringify(this.state.verify))
|
record.status = record.status === 'false' ? 'true' : 'false'
|
|
if (type === 'scripts') {
|
verify.scripts = verify.scripts.map(item => {
|
if (item.uuid === record.uuid) {
|
return record
|
} else {
|
return item
|
}
|
})
|
} else if (type === 'unique') {
|
verify.uniques = verify.uniques.map(item => {
|
if (item.uuid === record.uuid) {
|
return record
|
} else {
|
return item
|
}
|
})
|
}
|
|
this.setState({
|
verify: verify
|
})
|
}
|
|
handleConfirm = () => {
|
const { verify } = this.state
|
|
// 表单提交时检查输入值是否正确
|
return new Promise((resolve, reject) => {
|
if (!verify.sheet || (verify.intertype === 'inner' && !verify.innerFunc)) {
|
notification.warning({
|
top: 92,
|
message: '请完善基础验证信息!',
|
duration: 5
|
})
|
reject()
|
}
|
|
let _loading = false
|
if (this.scriptsForm && this.scriptsForm.state.editItem) {
|
_loading = true
|
this.setState({activeKey: 'scripts'})
|
} else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) {
|
_loading = true
|
this.setState({activeKey: 'scripts'})
|
}
|
|
if (_loading) {
|
confirm({
|
content: `存在未保存项,确定提交吗?`,
|
onOk() {
|
resolve(verify)
|
},
|
onCancel() {}
|
})
|
} else {
|
resolve(verify)
|
}
|
})
|
}
|
|
showError = (errorType) => {
|
if (errorType === 'S') {
|
notification.success({
|
top: 92,
|
message: '执行成功!',
|
duration: 2
|
})
|
} else if (errorType === 'Y') {
|
Modal.success({
|
title: '执行成功!'
|
})
|
} else if (errorType === 'F') {
|
notification.error({
|
className: 'notification-custom-error',
|
top: 92,
|
message: '执行失败!',
|
duration: 10
|
})
|
} else if (errorType === 'N') {
|
notification.error({
|
top: 92,
|
message: '执行失败!',
|
duration: 10
|
})
|
} else if (errorType === 'E') {
|
Modal.error({
|
title: '执行失败!'
|
})
|
} else if (errorType === 'NM') {
|
message.error('执行失败!')
|
}
|
}
|
|
timeChange = (val, type) => {
|
const { verify } = this.state
|
|
this.setState({
|
verify: {...verify, [type]: val}
|
})
|
}
|
|
tabchange = (val) => {
|
const { activeKey, verify } = this.state
|
|
if (activeKey === 'basemsg') {
|
if (!verify.sheet || (verify.intertype === 'inner' && !verify.innerFunc)) {
|
notification.warning({
|
top: 92,
|
message: '请完善基础验证信息!',
|
duration: 5
|
})
|
return
|
}
|
}
|
this.setState({activeKey: val})
|
}
|
|
onOptionChange = (value, key) => {
|
const { verify } = this.state
|
|
this.setState({
|
verify: {...verify, [key]: value}
|
})
|
}
|
|
render() {
|
const { config } = this.props
|
const { verify, scriptsColumns, uniqueColumns, activeKey, fields, modules } = this.state
|
const formItemLayout = {
|
labelCol: {
|
xs: { span: 24 },
|
sm: { span: 8 }
|
},
|
wrapperCol: {
|
xs: { span: 24 },
|
sm: { span: 16 }
|
}
|
}
|
let isPop = sessionStorage.getItem('editMenuType') === 'popview'
|
|
return (
|
<div id="verify-excel-box-tab">
|
<Tabs activeKey={activeKey} className="tablein-verify-card-box" onChange={this.tabchange}>
|
<TabPane tab="基础验证" key="basemsg">
|
<Form {...formItemLayout}>
|
<Row gutter={24}>
|
<Col span={8}>
|
<Form.Item required label="表名">
|
<Input value={verify.sheet} placeholder="" autoComplete="off" onChange={(e) => this.onOptionChange(e.target.value, 'sheet')}/>
|
</Form.Item>
|
</Col>
|
<Col span={8}>
|
<Form.Item required label={'接口类型'}>
|
<Radio.Group value={verify.intertype} onChange={(e) => this.onOptionChange(e.target.value, 'intertype')}>
|
<Radio value="system">系统</Radio>
|
<Radio value="inner">内部</Radio>
|
</Radio.Group>
|
</Form.Item>
|
</Col>
|
{verify.intertype === 'inner' ? <Col span={8}>
|
<Form.Item required label="内部接口">
|
<Input value={verify.innerFunc} placeholder="" autoComplete="off" onChange={(e) => this.onOptionChange(e.target.value, 'innerFunc')}/>
|
</Form.Item>
|
</Col> : null}
|
{verify.intertype === 'inner' ? <Col span={8}>
|
<Form.Item required label="记录用户">
|
<Radio.Group value={verify.recordUser || 'false'} onChange={(e) => this.onOptionChange(e.target.value, 'recordUser')}>
|
<Radio value="false">否</Radio>
|
<Radio value="true">是</Radio>
|
</Radio.Group>
|
</Form.Item>
|
</Col> : null}
|
{verify.intertype === 'system' ? <Col span={8}>
|
<Form.Item required label="默认sql">
|
<Radio.Group value={verify.default} onChange={(e) => this.onOptionChange(e.target.value, 'default')}>
|
<Radio value="true">执行</Radio>
|
<Radio value="false">不执行</Radio>
|
</Radio.Group>
|
</Form.Item>
|
</Col> : null}
|
<Col span={8}>
|
<Form.Item label={
|
<Tooltip placement="topLeft" title="《刷新行》与《刷新行 / 组件》只在数据提交为 修改项 时有效。">
|
<QuestionCircleOutlined className="mk-form-tip" />
|
成功后
|
</Tooltip>
|
}>
|
<Select value={verify.execSuccess} onChange={(val) => this.onOptionChange(val, 'execSuccess')}>
|
<Select.Option value="never">不刷新</Select.Option>
|
<Select.Option value="line" disabled={config.wrap.commit !== 'change'}>刷新行</Select.Option>
|
<Select.Option value="grid">刷新组件</Select.Option>
|
<Select.Option value="line_grid" disabled={config.wrap.commit !== 'change'}>刷新行 / 组件</Select.Option>
|
<Select.Option value="mainline">上级(行)</Select.Option>
|
</Select>
|
</Form.Item>
|
</Col>
|
<Col span={8}>
|
<Form.Item label="失败后">
|
<Select value={verify.execError} onChange={(val) => this.onOptionChange(val, 'execError')}>
|
<Select.Option value="never">不刷新</Select.Option>
|
<Select.Option value="line" disabled={config.wrap.commit !== 'change'}>刷新行</Select.Option>
|
<Select.Option value="grid">刷新组件</Select.Option>
|
<Select.Option value="line_grid" disabled={config.wrap.commit !== 'change'}>刷新行 / 组件</Select.Option>
|
<Select.Option value="mainline">上级(行)</Select.Option>
|
</Select>
|
</Form.Item>
|
</Col>
|
{isPop ? <Col span={8}>
|
<Form.Item label="成功后">
|
<Radio.Group style={{whiteSpace: 'nowrap'}} value={verify.closetab || 'false'} onChange={(e) => this.onOptionChange(e.target.value, 'closetab')}>
|
<Radio value="false">标签不关闭</Radio>
|
<Radio value="true">标签关闭</Radio>
|
</Radio.Group>
|
</Form.Item>
|
</Col> : null}
|
<Col span={8}>
|
<Form.Item label={
|
<Tooltip placement="topLeft" title="执行成功后(或弹窗标签关闭时),需要同步刷新的组件。注:选择当前组件的上级组件无效,刷新上级组件请选择成功后“上级(行)”。">
|
<QuestionCircleOutlined className="mk-form-tip" />
|
刷新组件
|
</Tooltip>
|
}>
|
<Cascader options={modules} value={verify.syncComponent || []} expandTrigger="hover" allowClear placeholder="" onChange={(val) => this.onOptionChange(val, 'syncComponent')}/>
|
</Form.Item>
|
</Col>
|
</Row>
|
</Form>
|
</TabPane>
|
<TabPane disabled={verify.intertype !== 'system'} tab={
|
<span>
|
唯一性验证
|
{verify.uniques.length ? <span className="count-tip">{verify.uniques.length}</span> : null}
|
</span>
|
} key="unique">
|
<UniqueForm fields={fields} uniqueChange={this.uniqueChange}/>
|
<EditTable actions={['edit', 'move', 'del']} data={verify.uniques} columns={uniqueColumns} onChange={this.changeUniques}/>
|
</TabPane>
|
<TabPane disabled={verify.intertype !== 'system'} tab={
|
<span>
|
自定义脚本
|
{verify.scripts.length ? <span className="count-tip">{verify.scripts.length}</span> : null}
|
</span>
|
} key="scripts">
|
<FullScripts
|
scripts={verify.scripts}
|
getScriptsFullForm={() => this.scriptsFullForm}
|
getScriptsForm={() => this.scriptsForm}
|
handleStatus={this.handleStatus}
|
handleDelete={this.handleDelete}
|
>
|
<CustomScript
|
type="fullscreen"
|
btn={verify}
|
usefulfields={fields}
|
scripts={verify.scripts}
|
systemScripts={this.state.systemScripts}
|
scriptsChange={this.scriptsChange}
|
wrappedComponentRef={(inst) => this.scriptsFullForm = inst}
|
/>
|
</FullScripts>
|
<CustomScript
|
btn={verify}
|
usefulfields={fields}
|
scripts={verify.scripts}
|
systemScripts={this.state.systemScripts}
|
scriptsChange={this.scriptsChange}
|
wrappedComponentRef={(inst) => this.scriptsForm = inst}
|
/>
|
<EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
|
</TabPane>
|
<TabPane tab="信息提示" key="tip">
|
<Form {...formItemLayout}>
|
<Row gutter={24}>
|
<Col offset={6} span={6}>
|
<Form.Item label="提示编码">
|
<span className="errorval"> S </span>
|
<Button onClick={() => {this.showError('S')}} type="primary" size="small">
|
查看
|
</Button>
|
</Form.Item>
|
</Col>
|
<Col span={8}>
|
<Form.Item label="停留时间">
|
<InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={24}>
|
<Col offset={6} span={6}>
|
<Form.Item label="提示编码">
|
<span className="errorval"> Y </span>
|
<Button onClick={() => {this.showError('Y')}} type="primary" size="small">
|
查看
|
</Button>
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={24}>
|
<Col offset={6} span={6}>
|
<Form.Item label="提示编码">
|
<span className="errorval"> -1 </span>
|
执行成功无提示。
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={24}>
|
<Col offset={6} span={6}>
|
<Form.Item label="提示编码">
|
<span className="errorval"> N </span>
|
<Button onClick={() => {this.showError('N')}} type="primary" size="small">
|
查看
|
</Button>
|
</Form.Item>
|
</Col>
|
<Col span={8}>
|
<Form.Item label="停留时间">
|
<InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={24}>
|
<Col offset={6} span={6}>
|
<Form.Item label="提示编码">
|
<span className="errorval"> F </span>
|
<Button onClick={() => {this.showError('F')}} type="primary" size="small">
|
查看
|
</Button>
|
</Form.Item>
|
</Col>
|
<Col span={8}>
|
<Form.Item label="停留时间">
|
<InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={24}>
|
<Col offset={6} span={6}>
|
<Form.Item label="提示编码">
|
<span className="errorval"> E </span>
|
<Button onClick={() => {this.showError('E')}} type="primary" size="small">
|
查看
|
</Button>
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={24}>
|
<Col offset={6} span={6}>
|
<Form.Item label="提示编码">
|
<span className="errorval"> NM </span>
|
<Button onClick={() => {this.showError('NM')}} type="primary" size="small">
|
查看
|
</Button>
|
</Form.Item>
|
</Col>
|
</Row>
|
<Row gutter={24}>
|
<Col offset={6} span={6}>
|
<Form.Item label="提示编码">
|
<span className="errorval"> -2 </span>
|
执行失败无提示
|
</Form.Item>
|
</Col>
|
</Row>
|
</Form>
|
</TabPane>
|
</Tabs>
|
</div>
|
)
|
}
|
}
|
|
export default Form.create()(VerifyTableCard)
|