import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { fromJS } from 'immutable'
|
import { Form, Row, Col, Tooltip, Cascader, Input } from 'antd'
|
import { QuestionCircleOutlined } from '@ant-design/icons'
|
|
import asyncComponent from '@/utils/asyncComponent'
|
import MKEInput from './mkInput'
|
import MKNumberInput from './mkNumberInput'
|
import MKSelect from './mkSelect'
|
import './index.scss'
|
|
const { TextArea } = Input
|
|
const MKRadio = asyncComponent(() => import('./mkRadio'))
|
const MKTable = asyncComponent(() => import('./mkTable'))
|
const MKCheckbox = asyncComponent(() => import('./mkCheckbox'))
|
const StyleInput = asyncComponent(() => import('./styleInput'))
|
const MKFileUpload = asyncComponent(() => import('@/tabviews/zshare/fileupload'))
|
const MkPrintTemps = asyncComponent(() => import('@/menu/components/share/actioncomponent/actionform/mkPrintTemps'))
|
const MKColor = asyncComponent(() => import('@/mob/colorsketch'))
|
// const MKColor = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkColor'))
|
const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
|
const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent'))
|
|
class ModalForm extends Component {
|
static propTpyes = {
|
formlist: PropTypes.array,
|
inputSubmit: PropTypes.func,
|
transVals: PropTypes.func,
|
}
|
|
state = {
|
formlist: [], // 表单项
|
formId: ''
|
}
|
|
record = {}
|
|
componentDidMount () {
|
let record = {}
|
let controlFields = {}
|
let fieldMap = new Map()
|
let formId = (() => {
|
let uuid = []
|
let _options = '0123456789abcdefghigklmnopqrstuv'
|
for (let i = 0; i < 19; i++) {
|
uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
|
}
|
uuid = uuid.join('')
|
return uuid
|
})()
|
|
let formlist = this.props.formlist.filter(item => {
|
if (item.controlFields) { // 多层表单控制
|
controlFields[item.field] = item.controlFields
|
}
|
|
item.hidden = false
|
|
if (item.forbid && item.del) return false
|
|
if (item.forbid) {
|
item.hidden = true
|
}
|
if (item.options) {
|
item.oriOptions = fromJS(item.options).toJS()
|
}
|
item.$formId = formId
|
|
if (item.type === 'text') {
|
let _rules = [{
|
required: item.required,
|
message: item.label + '不可为空!'
|
}]
|
|
if (item.rules) {
|
_rules.push(...item.rules)
|
}
|
|
item.rules = _rules
|
} else if (item.type === 'number') {
|
item.rules = [{
|
required: item.required,
|
message: item.label + '不可为空!'
|
}, {
|
validator: (rule, value, callback) => this.checkNumber(rule, value, callback, item)
|
}]
|
} else if (item.type === 'textarea') {
|
item.rules = [
|
{
|
required: item.required,
|
message: item.label + '不可为空!'
|
}
|
]
|
} else if (item.type === 'table') {
|
item.rules = [
|
{
|
required: item.required,
|
message: '请添加' + item.label + '!'
|
}
|
]
|
} else {
|
item.rules = [
|
{
|
required: item.required,
|
message: '请选择' + item.label + '!'
|
}
|
]
|
}
|
|
record[item.field] = item.initval
|
|
fieldMap.set(item.field, item)
|
|
return true
|
})
|
|
Object.keys(controlFields).forEach(key => {
|
if (!fieldMap.has(key)) return
|
|
let supItem = fieldMap.get(key)
|
let supval = supItem.initval
|
|
if (supval && JSON.stringify(supval) === '[]') {
|
supval = ''
|
}
|
|
let fields = []
|
controlFields[key].forEach(item => {
|
if (!fieldMap.has(item.field)) return
|
|
let cell = fieldMap.get(item.field)
|
|
cell.$ctrls = cell.$ctrls || []
|
cell.$ctrls.push(key)
|
|
if (cell.hidden) {
|
|
} else if (supItem.hidden) {
|
cell.hidden = true
|
} else if (item.notNull) {
|
cell.hidden = !supval
|
} else if (supItem.type === 'checkbox' || supItem.type === 'multiselect') {
|
let vals = [...(supval || []), ...item.values]
|
if (vals.length === new Set(vals).size) {
|
cell.hidden = true
|
}
|
} else if (!item.values.includes(supval)) {
|
cell.hidden = true
|
}
|
|
fieldMap.set(item.field, cell)
|
|
fields.push(item)
|
})
|
|
supItem.controlFields = fields
|
|
fieldMap.set(key, supItem)
|
})
|
|
formlist = formlist.map(cell => {
|
let item = fieldMap.get(cell.field)
|
|
if (item.$ctrls && item.$ctrls.length === 1) {
|
delete item.$ctrls
|
}
|
|
if (item.linkField) {
|
let supInitVal = fieldMap.get(item.linkField).initval || ''
|
|
item.options = item.oriOptions.filter(option => option.ParentID === supInitVal || option.ParentID === '')
|
}
|
|
return item
|
})
|
|
this.record = record
|
|
this.setState({ formlist, formId })
|
}
|
|
checkNumber = (rule, value, callback, item) => {
|
let val = parseFloat(value)
|
|
if (!isNaN(val)) {
|
if (typeof(item.min) === 'number' && val < item.min) {
|
callback(item.label + '最小值为 ' + item.min)
|
} else if (typeof(item.max) === 'number' && val > item.max) {
|
callback(item.label + '最大值为 ' + item.max)
|
}
|
}
|
callback()
|
}
|
|
recordChange = (values, item) => {
|
this.record = {...this.record, ...values}
|
|
if (!item) return
|
|
if (item.$trans) {
|
this.props.transVals && this.props.transVals(values, item.field)
|
}
|
|
if (item.controlFields) {
|
let map = new Map()
|
this.state.formlist.forEach(cell => {
|
if (!cell.field) return
|
map.set(cell.field, cell)
|
})
|
|
let reset = (current) => {
|
let val = this.record[current.field]
|
|
if (val && JSON.stringify(val) === '[]') {
|
val = ''
|
}
|
|
current.controlFields.forEach(cell => {
|
let m = map.get(cell.field)
|
|
if (current.hidden) {
|
m.hidden = true
|
} else if (cell.notNull) {
|
m.hidden = !val
|
} else if (current.type === 'checkbox' || current.type === 'multiselect') {
|
let vals = [...(val || []), ...cell.values]
|
if (vals.length !== new Set(vals).size) {
|
m.hidden = false
|
} else {
|
m.hidden = true
|
}
|
} else {
|
m.hidden = !cell.values.includes(val)
|
}
|
|
if (!m.hidden && m.$ctrls) {
|
m.$ctrls.forEach(n => {
|
if (n === current.field || m.hidden) return
|
|
let oth = map.get(n)
|
let _val = this.record[n]
|
|
if (_val && JSON.stringify(_val) === '[]') {
|
_val = ''
|
}
|
|
let p = oth.controlFields.filter(q => q.field === m.field)[0]
|
|
if (oth.hidden || (p.notNull && !_val)) {
|
m.hidden = true
|
} else if (oth.type === 'checkbox' || oth.type === 'multiselect') {
|
let _vals = [...(_val || []), ...p.values]
|
if (_vals.length === new Set(_vals).size) {
|
m.hidden = true
|
}
|
} else if (!p.values.includes(_val)) {
|
m.hidden = true
|
}
|
})
|
}
|
|
if (m.hidden) {
|
m.initval = this.record[m.field]
|
}
|
|
map.set(cell.field, m)
|
|
if (m.controlFields) {
|
reset(m)
|
}
|
})
|
}
|
|
reset(item)
|
|
this.setState({
|
formlist: this.state.formlist.map(cell => {
|
if (!cell.field) return cell
|
|
let item = map.get(cell.field)
|
|
if (item && item.linkField) {
|
let supInitVal = this.record[item.linkField] || ''
|
|
item.options = item.oriOptions.filter(option => option.ParentID === supInitVal || option.ParentID === '')
|
}
|
|
return item || cell
|
})
|
})
|
} else if (item.reset_source) {
|
let reOptions = item.callback(this.record)
|
|
if (reOptions) {
|
this.setState({
|
formlist: this.state.formlist.map(cell => {
|
if (!cell.field || !reOptions[cell.field]) return cell
|
|
cell.options = reOptions[cell.field]
|
cell.timestamp = new Date().getTime()
|
|
return cell
|
})
|
})
|
}
|
}
|
}
|
|
getFields() {
|
const { getFieldDecorator } = this.props.form
|
const { formlist } = this.state
|
|
const fields = []
|
|
formlist.forEach((item, index) => {
|
if (item.hidden || item.forbid) return
|
|
let content = null
|
let label = item.label
|
if (item.tooltip) {
|
if (item.toolWidth) {
|
label = <Tooltip placement="topLeft" overlayStyle={{maxWidth: item.toolWidth}} title={<div onClick={(e) => e.stopPropagation()}>{item.tooltip}</div>}><QuestionCircleOutlined className="mk-form-tip" />{item.label}</Tooltip>
|
} else {
|
label = <Tooltip placement="topLeft" title={<div onClick={(e) => e.stopPropagation()}>{item.tooltip}</div>}><QuestionCircleOutlined className="mk-form-tip" />{item.label}</Tooltip>
|
}
|
}
|
|
if (item.type === 'text') {
|
content = (<MKEInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val}, item)} onSubmit={this.props.inputSubmit} />)
|
} else if (item.type === 'number') {
|
content = (<MKNumberInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val}, item)} onSubmit={this.props.inputSubmit} />)
|
} else if (item.type === 'select' || item.type === 'multiselect') {
|
content = (<MKSelect config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)} />)
|
} else if (item.type === 'color') {
|
content = (<MKColor config={item} allowClear={item.allowClear} onChange={(val) => this.recordChange({[item.field]: val})}/>)
|
} else if (item.type === 'styleInput') {
|
content = (<StyleInput config={item} onChange={(val) => this.recordChange({[item.field]: val})}/>)
|
} else if (item.type === 'radio') {
|
content = (<MKRadio config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)}/>)
|
} else if (item.type === 'checkbox') {
|
content = (<MKCheckbox config={item} onChange={(val) => this.recordChange({[item.field]: val}, item)}/>)
|
} else if (item.type === 'fileupload') {
|
content = (<MKFileUpload config={item} onChange={(val) => this.recordChange({[item.field]: val})} />)
|
} else if (item.type === 'cascader') {
|
content = (<Cascader allowClear={!!item.allowClear} onChange={(val) => this.recordChange({[item.field]: val}, item)} options={item.options} expandTrigger="hover" placeholder="" />)
|
} else if (item.type === 'textarea') {
|
content = (<TextArea rows={item.rows || 2} placeholder=""/>)
|
} else if (item.type === 'mkicon') {
|
content = (<MkEditIcon allowClear={item.allowClear}/>)
|
} else if (item.type === 'source') {
|
content = (<SourceComponent type="" placement="right"/>)
|
} else if (item.type === 'table') {
|
content = (<MKTable tip={item.tip || ''} columns={item.columns || []} actions={item.actions || []}/>)
|
} else if (item.type === 'hint') {
|
fields.push(
|
<Col span={24} key={index}>
|
<div style={{color: '#1890ff', borderBottom: '1px solid #e9e9e9', marginBottom: '15px', paddingLeft: '10px'}}>{item.label}</div>
|
</Col>
|
)
|
return
|
} else if (item.type === 'printTemps') {
|
content = <MkPrintTemps onChange={(val) => this.recordChange({[item.field]: val})}/>
|
}
|
|
if (!content) return
|
|
if (item.help) {
|
let help = null
|
if (typeof(item.help) === 'function') {
|
help = item.help(this.record)
|
} else {
|
help = <span style={{fontSize: '12px'}}>{item.help}</span>
|
}
|
fields.push(
|
<Col span={item.span || 12} key={index}>
|
<Form.Item label={label} help={help}>
|
{getFieldDecorator(item.field, {
|
initialValue: item.initval,
|
rules: item.rules
|
})(content)}
|
</Form.Item>
|
</Col>
|
)
|
} else {
|
fields.push(
|
<Col span={item.span || 12} key={index}>
|
<Form.Item label={label}>
|
{getFieldDecorator(item.field, {
|
initialValue: item.initval,
|
rules: item.rules
|
})(content)}
|
</Form.Item>
|
</Col>
|
)
|
}
|
})
|
|
return fields
|
}
|
|
handleConfirm = () => {
|
// 表单提交时检查输入值是否正确
|
return new Promise((resolve, reject) => {
|
this.props.form.validateFieldsAndScroll((err, values) => {
|
if (err) {
|
reject(err)
|
return
|
}
|
|
resolve(values)
|
})
|
})
|
}
|
|
render() {
|
const formItemLayout = {
|
labelCol: {
|
xs: { span: 24 },
|
sm: { span: 8 }
|
},
|
wrapperCol: {
|
xs: { span: 24 },
|
sm: { span: 16 }
|
}
|
}
|
|
return (
|
<Form {...formItemLayout} className="normal-form-field" id={this.state.formId}>
|
<Row gutter={24}>{this.getFields()}</Row>
|
</Form>
|
)
|
}
|
}
|
|
export default Form.create()(ModalForm)
|