import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { Form, Tabs, Row, Col, Input, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Radio } from 'antd'
|
|
import Utils from '@/utils/utils.js'
|
|
import ColumnForm from './columnform'
|
import CustomScript from './customscript'
|
import './index.scss'
|
|
const { TabPane } = Tabs
|
|
class VerifyCard extends Component {
|
static propTpyes = {
|
columns: PropTypes.array, // 显示列
|
dict: PropTypes.object, // 字典项
|
card: PropTypes.object,
|
}
|
|
state = {
|
verify: {},
|
excelColumns: [
|
{
|
title: 'Column',
|
dataIndex: 'Column',
|
width: '16%',
|
editable: true
|
},
|
{
|
title: 'Text',
|
dataIndex: 'Text',
|
width: '19%',
|
editable: true
|
},
|
{
|
title: '类型',
|
dataIndex: 'type',
|
width: '12%',
|
editable: true
|
},
|
{
|
title: '是否必填',
|
dataIndex: 'required',
|
width: '12%',
|
editable: true,
|
render: (text, record) => record.required === 'true' ? '是' : '否'
|
},
|
{
|
title: '最小值',
|
dataIndex: 'min',
|
width: '12%',
|
editable: true
|
},
|
{
|
title: '最大值',
|
dataIndex: 'max',
|
width: '12%',
|
editable: true
|
},
|
{
|
title: '操作',
|
align: 'center',
|
dataIndex: 'operation',
|
render: (text, record) =>
|
(
|
<div>
|
<span className="operation-btn" title={this.props.dict['header.edit']} onClick={() => this.handleEdit(record, 'columns')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
|
<span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'columns', 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
|
<span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'columns', 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
|
<Popconfirm
|
title={this.props.dict['header.form.query.delete']}
|
okText={this.props.dict['header.confirm']}
|
cancelText={this.props.dict['header.cancel']}
|
onConfirm={() => this.handleDelete(record, 'columns')
|
}>
|
<span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span>
|
</Popconfirm>
|
</div>
|
)
|
}
|
],
|
scriptsColumns: [
|
{
|
title: 'SQL',
|
dataIndex: 'sql',
|
width: '70%'
|
},
|
{
|
title: '状态',
|
dataIndex: 'status',
|
width: '10%',
|
render: (text, record) => record.status === 'false' ?
|
(
|
<div>
|
{this.props.dict['header.form.status.forbidden']}
|
<Icon style={{marginLeft: '5px'}} type="stop" theme="twoTone" twoToneColor="#ff4d4f" />
|
</div>
|
) :
|
(
|
<div>
|
{this.props.dict['header.form.status.open']}
|
<Icon style={{marginLeft: '5px'}} type="check-circle" theme="twoTone" twoToneColor="#52c41a" />
|
</div>
|
)
|
},
|
{
|
title: '操作',
|
align: 'center',
|
width: '20%',
|
dataIndex: 'operation',
|
render: (text, record) =>
|
(<div>
|
<span className="operation-btn" title={this.props.dict['header.edit']} onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
|
<span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'scripts', 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
|
<span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'scripts', 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
|
<span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record, 'scripts')} style={{color: '#8E44AD'}}><Icon type="swap" /></span>
|
<Popconfirm
|
title={this.props.dict['header.form.query.delete']}
|
okText={this.props.dict['header.confirm']}
|
cancelText={this.props.dict['header.cancel']}
|
onConfirm={() => this.handleDelete(record, 'scripts')
|
}>
|
<span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span>
|
</Popconfirm>
|
</div>)
|
}
|
]
|
}
|
|
UNSAFE_componentWillMount() {
|
let _verify = this.props.card.verify || {}
|
|
let _columns = _verify.columns || []
|
_columns = _columns.map(col => {
|
col.required = col.required || 'true'
|
col.type = col.type || 'Nvarchar(50)'
|
|
if (/^Nvarchar/ig.test(col.type)) {
|
col.limit = col.type.match(/\d+/)[0]
|
} else if (/^Decimal/ig.test(col.type)) {
|
col.limit = col.type.match(/\d+/ig)[1]
|
} else {
|
col.limit = ''
|
}
|
|
return col
|
})
|
|
this.setState({
|
verify: {
|
..._verify,
|
default: _verify.default || 'true',
|
sheet: _verify.sheet || 'Sheet1',
|
range: _verify.range || 0,
|
columns: _columns,
|
scripts: _verify.scripts || []
|
}
|
})
|
}
|
|
columnFieldInput = () => {
|
const { columns } = this.props
|
const { verify } = this.state
|
|
let _columns = JSON.parse(JSON.stringify(verify.columns))
|
|
let _cols = _columns.map(col => col.Column )
|
|
columns.forEach(col => {
|
if (col.field && !_cols.includes(col.field)) {
|
let _type = 'Nvarchar(50)'
|
let _limit = '50'
|
if (col.type === 'number' && col.decimal === 0) {
|
_type = 'Int'
|
_limit = ''
|
} else if (col.type === 'number') {
|
_type = 'Decimal(18,' + col.decimal + ')'
|
_limit = col.decimal
|
}
|
|
let _cell = {
|
uuid: col.uuid,
|
Column: col.field,
|
Text: col.label,
|
type: _type,
|
limit: _limit,
|
required: 'true'
|
}
|
|
if (_type !== 'Nvarchar(50)') {
|
_cell.min = 0
|
_cell.max = 999999
|
}
|
|
_columns.push(_cell)
|
}
|
})
|
|
this.setState({
|
verify: {
|
...verify,
|
columns: _columns
|
}
|
})
|
}
|
|
columnChange = (values) => {
|
let verify = JSON.parse(JSON.stringify(this.state.verify))
|
|
if (values.uuid) {
|
verify.columns = verify.columns.map(item => {
|
if (item.uuid === values.uuid) {
|
return values
|
} else {
|
return item
|
}
|
})
|
} else {
|
values.uuid = Utils.getuuid()
|
verify.columns.push(values)
|
}
|
|
this.setState({
|
verify: verify
|
})
|
}
|
|
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)
|
}
|
|
this.setState({
|
verify: verify
|
})
|
}
|
|
handleDelete = (record, type) => {
|
const { verify } = this.state
|
|
if (type === 'columns') {
|
verify.columns = verify.columns.filter(item => item.uuid !== record.uuid)
|
} else if (type === 'scripts') {
|
verify.scripts = verify.scripts.filter(item => item.uuid !== record.uuid)
|
}
|
this.setState({ verify: verify })
|
}
|
|
handleEdit = (record, type) => {
|
if (type === 'columns') {
|
this.columnForm.edit(record)
|
} else 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
|
}
|
})
|
}
|
|
this.setState({
|
verify: verify
|
})
|
}
|
|
handleUpDown = (record, type, direction) => {
|
let verify = JSON.parse(JSON.stringify(this.state.verify))
|
let index = 0
|
|
if (type === 'columns') {
|
verify.columns = verify.columns.filter((item, i) => {
|
if (item.uuid === record.uuid) {
|
index = i
|
}
|
|
return item.uuid !== record.uuid
|
})
|
if ((index === 0 && direction === 'up') || (index === verify.columns.length && direction === 'down')) {
|
return
|
}
|
|
if (direction === 'up') {
|
verify.columns.splice(index - 1, 0, record)
|
} else {
|
verify.columns.splice(index + 1, 0, record)
|
}
|
} else if (type === 'scripts') {
|
verify.scripts = verify.scripts.filter((item, i) => {
|
if (item.uuid === record.uuid) {
|
index = i
|
}
|
|
return item.uuid !== record.uuid
|
})
|
if ((index === 0 && direction === 'up') || (index === verify.scripts.length && direction === 'down')) {
|
return
|
}
|
|
if (direction === 'up') {
|
verify.scripts.splice(index - 1, 0, record)
|
} else {
|
verify.scripts.splice(index + 1, 0, record)
|
}
|
}
|
|
this.setState({
|
verify: verify
|
})
|
}
|
|
handleConfirm = () => {
|
const { verify } = this.state
|
// 表单提交时检查输入值是否正确
|
return new Promise((resolve, reject) => {
|
this.props.form.validateFieldsAndScroll((err, values) => {
|
if (!err) {
|
let _verify = {...verify, ...values}
|
|
let cols = _verify.columns.map(col => col.Column)
|
cols = Array.from(new Set(cols))
|
|
if (_verify.columns.length === 0) {
|
notification.warning({
|
top: 92,
|
message: '请设置Excel列字段!',
|
duration: 10
|
})
|
return
|
} else if (_verify.columns.length > cols.length) {
|
notification.warning({
|
top: 92,
|
message: 'Excel列字段名,不可重复!',
|
duration: 10
|
})
|
return
|
} else if (_verify.range === 1) {
|
let tEmptys = _verify.columns.filter(op => !op.Text)
|
if (tEmptys.length > 0) {
|
notification.warning({
|
top: 92,
|
message: '忽略首行时,会使用Text值校验Excel首行内容,Text值与Excel表首行内容相同,且均不可为空!',
|
duration: 10
|
})
|
return
|
}
|
}
|
|
resolve(_verify)
|
} else {
|
notification.warning({
|
top: 92,
|
message: '请设置Excel表名!',
|
duration: 10
|
})
|
}
|
})
|
})
|
}
|
|
onOptionChange = (e, key) => {
|
const { verify } = this.state
|
let value = e.target.value
|
|
this.setState({
|
verify: {...verify, default: value}
|
})
|
}
|
|
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: 15
|
})
|
} else if (errorType === 'N') {
|
notification.error({
|
top: 92,
|
message: '执行失败!',
|
duration: 15
|
})
|
} 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}
|
})
|
}
|
|
render() {
|
const { getFieldDecorator } = this.props.form
|
const { verify, excelColumns, scriptsColumns } = this.state
|
const formItemLayout = {
|
labelCol: {
|
xs: { span: 24 },
|
sm: { span: 8 }
|
},
|
wrapperCol: {
|
xs: { span: 24 },
|
sm: { span: 16 }
|
}
|
}
|
|
return (
|
<div id="verify-excel-box-tab">
|
<Tabs defaultActiveKey="1" className="verify-card-box" onChange={this.tabchange}>
|
<TabPane tab="基础验证" key="1">
|
<Form {...formItemLayout}>
|
<Row gutter={24}>
|
<Col span={8}>
|
<Form.Item label={'Excel表名'}>
|
{getFieldDecorator('sheet', {
|
initialValue: verify.sheet || '',
|
rules: [
|
{
|
required: true,
|
message: this.props.dict['form.required.input'] + this.props.dict['header.form.tablename'] + '!'
|
}
|
]
|
})(<Input placeholder="" autoComplete="off" />)}
|
</Form.Item>
|
</Col>
|
<Col span={8}>
|
<Form.Item label={'忽略行'}>
|
{getFieldDecorator('range', {
|
initialValue: verify.range || 0
|
})(<InputNumber min={0} max={100} precision={0} />)}
|
</Form.Item>
|
</Col>
|
<Col span={8}>
|
<Form.Item label={'默认sql'}>
|
<Radio.Group value={verify.default} onChange={this.onOptionChange}>
|
<Radio value="true">执行</Radio>
|
<Radio value="false">不执行</Radio>
|
</Radio.Group>
|
</Form.Item>
|
</Col>
|
</Row>
|
</Form>
|
</TabPane>
|
<TabPane tab="Excel列设置" key="2x">
|
<ColumnForm
|
dict={this.props.dict}
|
columns={verify.columns}
|
columnChange={this.columnChange}
|
wrappedComponentRef={(inst) => this.columnForm = inst}
|
/>
|
<Button className="excel-col-add" title="添加显示列字段" onClick={this.columnFieldInput} type="primary">
|
快捷添加
|
</Button>
|
<Table
|
bordered
|
rowKey="uuid"
|
className="custom-table"
|
dataSource={verify.columns}
|
columns={excelColumns}
|
pagination={false}
|
/>
|
</TabPane>
|
<TabPane tab="自定义脚本" key="6">
|
<CustomScript
|
dict={this.props.dict}
|
btn={this.props.card}
|
isdefault={verify.default}
|
usefulfields={verify.columns}
|
scripts={verify.scripts}
|
scriptsChange={this.scriptsChange}
|
wrappedComponentRef={(inst) => this.scriptsForm = inst}
|
/>
|
<Table
|
bordered
|
rowKey="uuid"
|
className="custom-table"
|
dataSource={verify.scripts}
|
columns={scriptsColumns}
|
pagination={false}
|
/>
|
</TabPane>
|
<TabPane tab="信息提示" key="7">
|
<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"> 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 || 15} 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 || 15} 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"> -1 </span>
|
不提示
|
</Form.Item>
|
</Col>
|
</Row>
|
</Form>
|
</TabPane>
|
</Tabs>
|
</div>
|
)
|
}
|
}
|
|
export default Form.create()(VerifyCard)
|