import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { is, fromJS } from 'immutable'
|
import { Form, Row, Col, Input, InputNumber, Select, DatePicker, notification, Collapse } from 'antd'
|
import moment from 'moment'
|
import { formRule } from '@/utils/option.js'
|
import FileUpload from '@/tabviews/zshare/fileupload'
|
import './index.scss'
|
|
const {MonthPicker} = DatePicker
|
const { TextArea } = Input
|
const { Panel } = Collapse
|
|
class MainSearch extends Component {
|
static propTpyes = {
|
setting: PropTypes.object, // 基本信息
|
groups: PropTypes.array, // 表单组
|
dict: PropTypes.object, // 字典项
|
data: PropTypes.any, // 表格数据
|
configMap: PropTypes.object, // 按钮及下拉表单配置信息集
|
inputSubmit: PropTypes.func // input回车提交
|
}
|
|
state = {
|
datatype: null,
|
readtype: null,
|
readin: null,
|
fieldlen: null,
|
groups: null,
|
formlist: [],
|
encrypts: [], // 加密字段
|
intercepts: [], // 截取字段
|
record: {}
|
}
|
|
UNSAFE_componentWillReceiveProps (nextProps) {
|
const { datatype, encrypts } = this.state
|
if (nextProps.data && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
|
|
let _fieldsvalue = {}
|
let _record = {}
|
Object.keys(nextProps.data).forEach(key => {
|
if (this.props.form.getFieldValue(key) !== undefined) {
|
if (datatype[key] === 'multiselect') {
|
let _val = nextProps.data[key] ? nextProps.data[key].split(',').filter(Boolean) : []
|
_fieldsvalue[key] = _val
|
} else if (datatype[key] === 'date') {
|
let _val = nextProps.data[key] ? nextProps.data[key] : null
|
|
if (_val) {
|
_val = moment(_val, 'YYYY-MM-DD')
|
}
|
|
_fieldsvalue[key] = _val
|
} else if (datatype[key] === 'datemonth') {
|
let _val = nextProps.data[key] ? nextProps.data[key] : null
|
|
if (_val) {
|
_val = moment(_val, 'YYYY-MM')
|
}
|
|
_fieldsvalue[key] = _val
|
} else if (datatype[key] === 'datetime') {
|
let _val = nextProps.data[key] ? nextProps.data[key] : null
|
|
if (_val) {
|
_val = moment(_val, 'YYYY-MM-DD HH:mm:ss')
|
}
|
|
_fieldsvalue[key] = _val
|
} else if (datatype[key] === 'fileupload') {
|
let _val = nextProps.data[key] ? nextProps.data[key] : ''
|
|
_fieldsvalue[key] = _val
|
} else if (datatype[key] === 'text' || datatype[key] === 'textarea') {
|
let _value = nextProps.data[key]
|
if (encrypts.includes(key)) { // 加密字段
|
try {
|
_value = window.btoa(window.encodeURIComponent(_value))
|
} catch (e) {
|
console.warn(e)
|
}
|
}
|
|
_fieldsvalue[key] = _value
|
} else {
|
_fieldsvalue[key] = nextProps.data[key]
|
}
|
} else {
|
let _value = nextProps.data[key]
|
if (encrypts.includes(key)) { // 加密字段
|
try {
|
_value = window.btoa(window.encodeURIComponent(_value))
|
} catch (e) {
|
console.warn(e)
|
}
|
}
|
|
_record[key] = _value
|
}
|
})
|
|
if (Object.keys(_fieldsvalue).length > 0) {
|
this.props.form.setFieldsValue(_fieldsvalue)
|
}
|
|
this.setState({
|
record: _record
|
})
|
}
|
}
|
|
UNSAFE_componentWillMount () {
|
const { data, groups } = this.props
|
|
let datatype = {}
|
let readtype = {}
|
let readin = {}
|
let fieldlen = {}
|
let _formlist = []
|
let encrypts = []
|
let intercepts = []
|
|
let _groups = groups.map(group => {
|
group.sublist = group.sublist.map(item => {
|
let _readin = item.readin !== 'false'
|
if (item.type === 'funcvar') {
|
_readin = false
|
item.initval = '' // 初始化为空
|
}
|
|
if (item.type === 'textarea' && item.encryption === 'true') {
|
encrypts.push(item.field)
|
}
|
if (item.interception === 'true') {
|
intercepts.push(item.field)
|
}
|
|
item.initVal = item.initval ? JSON.parse(JSON.stringify(item.initval)) : ''
|
|
let _fieldlen = item.fieldlength || 50
|
if (item.type === 'textarea' || item.type === 'fileupload' || item.type === 'multiselect') {
|
_fieldlen = item.fieldlength || 512
|
} else if (item.type === 'number') {
|
_fieldlen = item.decimal ? item.decimal : 0
|
}
|
|
datatype[item.field] = item.type
|
readtype[item.field] = item.readonly === 'true'
|
readin[item.field] = _readin
|
fieldlen[item.field] = _fieldlen
|
|
if (_readin && !/^date/.test(item.type) && data && data.hasOwnProperty(item.field)) {
|
let newval = data[item.field]
|
|
if (encrypts.includes(item.field) && newval) {
|
try {
|
newval = window.decodeURIComponent(window.atob(newval))
|
} catch (e) {
|
console.warn(e)
|
}
|
}
|
|
item.initval = newval
|
}
|
|
if (item.supvalue) {
|
item.supvalue = item.supvalue.split(',')
|
}
|
|
_formlist.push(item)
|
|
return item
|
})
|
|
return group
|
})
|
|
_groups = _groups.map(group => {
|
group.sublist = group.sublist.map(item => {
|
if (item.type === 'link') {
|
let supItem = _formlist.filter(form => form.field === item.linkField)[0]
|
|
// 关联显示列中的字段值,通过该值过滤下拉选项
|
if (!supItem && data && data.hasOwnProperty(item.linkField)) {
|
supItem = {initval: data[item.linkField]}
|
}
|
|
if (!supItem) {
|
notification.warning({
|
top: 92,
|
message: '未查询到表单《' + item.label + '》关联字段!',
|
duration: 5
|
})
|
} else {
|
item.options = item.oriOptions.filter(option => option.ParentID === supItem.initval)
|
}
|
}
|
return item
|
})
|
|
return group
|
})
|
|
this.setState({
|
readtype: readtype,
|
datatype: datatype,
|
readin: readin,
|
fieldlen: fieldlen,
|
formlist: _formlist,
|
groups: _groups
|
})
|
}
|
|
resetform = (groups, supfields, index, fieldsvalue) => {
|
index++
|
let subfields = []
|
|
supfields.forEach(supfield => {
|
groups = groups.map(group => {
|
group.sublist = group.sublist.map(item => {
|
if (item.type === 'link' && item.linkField === supfield.field) {
|
item.options = item.oriOptions.filter(option => option.ParentID === supfield.initval)
|
item.initval = item.options[0] ? item.options[0].Value : ''
|
|
fieldsvalue[item.field] = item.initval
|
|
subfields.push(item)
|
}
|
|
return item
|
})
|
return group
|
})
|
})
|
|
if (subfields.length === 0 || index > 6) {
|
return {groups: groups, fieldsvalue: fieldsvalue}
|
} else {
|
return this.resetform(groups, subfields, index, fieldsvalue)
|
}
|
}
|
|
selectChange = (_field, value, option) => {
|
const { record } = this.state
|
let groups = JSON.parse(JSON.stringify(this.state.groups))
|
|
let subfields = []
|
let fieldsvalue = {}
|
let _record = {}
|
groups = groups.map(group => {
|
group.sublist = group.sublist.map(item => {
|
if (item.type === 'link' && item.linkField === _field.field) {
|
item.options = item.oriOptions.filter(option => option.ParentID === value)
|
item.initval = item.options[0] ? item.options[0].Value : ''
|
|
fieldsvalue[item.field] = item.initval
|
|
subfields.push(item)
|
}
|
return item
|
})
|
return group
|
})
|
|
// 表单切换时,更新关联字段
|
if (_field.type === 'select' && _field.linkSubField && _field.linkSubField.length > 0 && option.props.data) {
|
let _data = option.props.data
|
_field.linkSubField.forEach(subfield => {
|
if (this.props.form.getFieldValue(subfield) !== undefined) {
|
fieldsvalue[subfield] = _data[subfield]
|
} else {
|
_record[subfield] = _data[subfield]
|
}
|
})
|
}
|
|
if (subfields.length === 0) {
|
if (Object.keys(fieldsvalue).length > 0) {
|
this.props.form.setFieldsValue(fieldsvalue)
|
}
|
if (Object.keys(_record).length > 0) {
|
this.setState({
|
record: {...record, ..._record}
|
})
|
}
|
} else {
|
let result = this.resetform(groups, subfields, 0, fieldsvalue)
|
|
if (Object.keys(result.fieldsvalue).length > 0) {
|
this.props.form.setFieldsValue(fieldsvalue)
|
}
|
|
let _param = {
|
groups: result.groups
|
}
|
|
if (Object.keys(_record).length > 0) {
|
_param.record = {...record, ..._record}
|
}
|
|
this.setState(_param)
|
}
|
}
|
|
getFields(formlist) {
|
const { getFieldDecorator } = this.props.form
|
|
const fields = []
|
let cols = 2
|
if (this.props.setting && this.props.setting.cols) {
|
cols = parseInt(this.props.setting.cols)
|
if (cols > 4 || cols < 1) {
|
cols = 2
|
}
|
}
|
|
formlist.forEach((item, index) => {
|
if (item.hidden === 'true') return
|
|
if (item.supField && !item.supvalue.includes(this.props.form.getFieldValue(item.supField))) return
|
|
if (item.type === 'text') {
|
fields.push(
|
<Col span={24 / cols} key={index}>
|
<Form.Item label={item.label}>
|
{getFieldDecorator(item.field, {
|
initialValue: item.initval || '',
|
rules: [
|
{
|
required: item.required === 'true',
|
message: this.props.dict['form.required.input'] + item.label + '!'
|
},
|
{
|
max: formRule.input.max,
|
message: formRule.input.message
|
}
|
]
|
})(<Input placeholder="" autoComplete="off" disabled={item.readonly === 'true'} onPressEnter={this.handleSubmit} />)}
|
</Form.Item>
|
</Col>
|
)
|
} else if (item.type === 'number') { // 数字
|
let min = (item.min || item.min === 0) ? item.min : -Infinity
|
let max = (item.max || item.max === 0) ? item.max : Infinity
|
let _initval = item.initval
|
let precision = (item.decimal || item.decimal === 0) ? item.decimal : null
|
|
fields.push(
|
<Col span={24 / cols} key={index}>
|
<Form.Item label={item.label}>
|
{getFieldDecorator(item.field, {
|
initialValue: _initval,
|
rules: [
|
{
|
required: true,
|
message: this.props.dict['form.required.input'] + item.label + '!'
|
}
|
]
|
})(
|
precision === null ?
|
<InputNumber min={min} max={max} disabled={item.readonly === 'true'} onPressEnter={this.handleSubmit} /> :
|
<InputNumber min={min} max={max} precision={precision} disabled={item.readonly === 'true'} onPressEnter={this.handleSubmit} />
|
)}
|
</Form.Item>
|
</Col>
|
)
|
} else if (item.type === 'select' || item.type === 'link') { // 下拉搜索
|
let hasSubField = false
|
if (item.linkSubField && item.linkSubField.length > 0) { // 存在关联字段,数据存储
|
hasSubField = true
|
}
|
|
fields.push(
|
<Col span={24 / cols} key={index}>
|
<Form.Item label={item.label}>
|
{getFieldDecorator(item.field, {
|
initialValue: item.initval,
|
rules: [
|
{
|
required: item.required === 'true',
|
message: this.props.dict['form.required.select'] + item.label + '!'
|
}
|
]
|
})(
|
<Select
|
showSearch
|
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
onChange={(value, option) => {this.selectChange(item, value, option)}}
|
disabled={item.readonly === 'true'}
|
>
|
{item.options.map(option =>
|
<Select.Option id={option.key} data={hasSubField ? option : ''} title={option.Text} key={option.key} value={option.Value}>{option.Text}</Select.Option>
|
)}
|
</Select>
|
)}
|
</Form.Item>
|
</Col>
|
)
|
} else if (item.type === 'multiselect') { // 多选
|
let _initval = item.initval ? item.initval.split(',').filter(Boolean) : []
|
fields.push(
|
<Col span={24 / cols} key={index}>
|
<Form.Item label={item.label}>
|
{getFieldDecorator(item.field, {
|
initialValue: _initval,
|
rules: [
|
{
|
required: item.required === 'true',
|
message: this.props.dict['form.required.select'] + item.label + '!'
|
}
|
]
|
})(
|
<Select
|
showSearch
|
mode="multiple"
|
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
disabled={item.readonly === 'true'}
|
>
|
{item.options.map(option =>
|
<Select.Option id={option.key} title={option.Text} key={option.key} value={option.Value}>{option.Text}</Select.Option>
|
)}
|
</Select>
|
)}
|
</Form.Item>
|
</Col>
|
)
|
} else if (item.type === 'date') { // 时间搜索
|
let _initval = this.props.data ? this.props.data[item.field] : ''
|
if (_initval && this.state.readin[item.field]) {
|
_initval = moment(_initval, 'YYYY-MM-DD')
|
} else {
|
_initval = item.initval ? moment().subtract(item.initval, 'days') : null
|
}
|
|
fields.push(
|
<Col span={24 / cols} key={index}>
|
<Form.Item label={item.label}>
|
{getFieldDecorator(item.field, {
|
initialValue: _initval,
|
rules: [
|
{
|
required: item.required === 'true',
|
message: this.props.dict['form.required.select'] + item.label + '!'
|
}
|
]
|
})(
|
<DatePicker disabled={item.readonly === 'true'} />
|
)}
|
</Form.Item>
|
</Col>
|
)
|
} else if (item.type === 'datemonth') {
|
let _initval = this.props.data ? this.props.data[item.field] : ''
|
if (_initval && this.state.readin[item.field]) {
|
_initval = moment(_initval, 'YYYY-MM')
|
} else {
|
_initval = item.initval ? moment().subtract(item.initval, 'month') : null
|
}
|
|
fields.push(
|
<Col span={24 / cols} key={index}>
|
<Form.Item label={item.label}>
|
{getFieldDecorator(item.field, {
|
initialValue: _initval,
|
rules: [
|
{
|
required: item.required === 'true',
|
message: this.props.dict['form.required.select'] + item.label + '!'
|
}
|
]
|
})(
|
<MonthPicker disabled={item.readonly === 'true'} />
|
)}
|
</Form.Item>
|
</Col>
|
)
|
} else if (item.type === 'datetime') {
|
let _initval = this.props.data ? this.props.data[item.field] : ''
|
|
if (_initval && this.state.readin[item.field]) {
|
_initval = moment(_initval, 'YYYY-MM-DD HH:mm:ss')
|
} else {
|
_initval = item.initval ? moment().subtract(item.initval, 'days') : null
|
}
|
|
fields.push(
|
<Col span={24 / cols} key={index}>
|
<Form.Item label={item.label}>
|
{getFieldDecorator(item.field, {
|
initialValue: _initval,
|
rules: [
|
{
|
required: item.required === 'true',
|
message: this.props.dict['form.required.select'] + item.label + '!'
|
}
|
]
|
})(
|
<DatePicker showTime disabled={item.readonly === 'true'} />
|
)}
|
</Form.Item>
|
</Col>
|
)
|
} else if (item.type === 'fileupload') {
|
fields.push(
|
<Col span={24 / cols} key={index}>
|
<Form.Item label={item.label}>
|
{getFieldDecorator(item.field, {
|
initialValue: item.initval,
|
rules: [
|
{
|
required: item.required === 'true',
|
message: this.props.dict['form.required.select'] + item.label + '!'
|
}
|
]
|
})(
|
<FileUpload config={item}/>
|
)}
|
</Form.Item>
|
</Col>
|
)
|
} else if (item.type === 'funcvar') {
|
fields.push(
|
<Col span={24 / cols} key={index}>
|
<Form.Item label={item.label}>
|
{getFieldDecorator(item.field, {
|
initialValue: '系统自动生成',
|
})(<Input placeholder="" autoComplete="off" disabled={true} />)}
|
</Form.Item>
|
</Col>
|
)
|
} else if (item.type === 'textarea') {
|
let _labelcol = cols !== 3 ? 8 / cols : 3
|
let _wrapcol = cols !== 3 ? 16 + (cols - 1) * 4 : 21
|
let _style = {}
|
if (cols === 2 || cols === 4) {
|
_style.paddingLeft = '7px'
|
}
|
fields.push(
|
<Col span={24} key={index} className="textarea-row" style={{..._style}}>
|
<Form.Item label={item.label} labelCol={{xs: { span: 24 }, sm: { span: _labelcol }}} wrapperCol={ {xs: { span: 24 }, sm: { span: _wrapcol }} }>
|
{getFieldDecorator(item.field, {
|
initialValue: item.initval || '',
|
rules: [
|
{
|
required: item.required === 'true',
|
message: this.props.dict['form.required.input'] + item.label + '!'
|
},
|
{
|
max: formRule.textarea.max,
|
message: formRule.textarea.message
|
}
|
]
|
})(<TextArea autoSize={{ minRows: 2, maxRows: item.maxRows || 6 }} disabled={item.readonly === 'true'} />)}
|
</Form.Item>
|
</Col>
|
)
|
}
|
})
|
|
return fields
|
}
|
|
handleConfirm = () => {
|
const { record, encrypts, intercepts } = this.state
|
// 表单提交时检查输入值是否正确
|
return new Promise((resolve, reject) => {
|
this.props.form.validateFieldsAndScroll((err, values) => {
|
if (!err) {
|
let search = []
|
// 隐藏表单
|
this.state.formlist.forEach(item => {
|
if (!item.field) return
|
|
if (item.type === 'funcvar') {
|
let _val = item.initval
|
if (values.hasOwnProperty(item.field)) {
|
_val = values[item.field] === '系统自动生成' ? '' : values[item.field]
|
} else if (record.hasOwnProperty(item.field)) {
|
_val = record[item.field]
|
}
|
search.push({
|
type: 'funcvar',
|
readonly: 'true',
|
readin: false,
|
fieldlen: this.state.fieldlen[item.field],
|
key: item.field,
|
value: _val
|
})
|
} else if (item.hidden === 'true' && item.field !== this.props.setting.primaryKey) {
|
let _val = item.initval
|
if (record.hasOwnProperty(item.field)) {
|
_val = record[item.field]
|
}
|
|
search.push({
|
type: this.state.datatype[item.field],
|
readonly: this.state.readtype[item.field],
|
readin: this.state.readin[item.field],
|
fieldlen: this.state.fieldlen[item.field],
|
key: item.field,
|
value: _val
|
})
|
} else if (item.supField && !item.supvalue.includes(this.props.form.getFieldValue(item.supField))) {
|
search.push({
|
type: this.state.datatype[item.field],
|
readonly: this.state.readtype[item.field],
|
readin: this.state.readin[item.field],
|
fieldlen: this.state.fieldlen[item.field],
|
key: item.field,
|
value: item.initVal
|
})
|
}
|
})
|
|
Object.keys(values).forEach(key => {
|
if (this.state.datatype[key] === 'funcvar') return
|
|
let _value = ''
|
if (this.state.datatype[key] === 'datetime') {
|
if (values[key]) {
|
_value = moment(values[key]).format('YYYY-MM-DD HH:mm:ss')
|
}
|
} else if (this.state.datatype[key] === 'datemonth') {
|
if (values[key]) {
|
_value = moment(values[key]).format('YYYY-MM')
|
}
|
} else if (this.state.datatype[key] === 'date') {
|
if (values[key]) {
|
_value = moment(values[key]).format('YYYY-MM-DD')
|
}
|
} else if (this.state.datatype[key] === 'number') {
|
_value = values[key]
|
|
} else if (this.state.datatype[key] === 'multiselect') {
|
_value = values[key] ? values[key].join(',') : ''
|
|
} else if (this.state.datatype[key] === 'fileupload') {
|
_value = values[key]
|
|
} else if (this.state.datatype[key] === 'text' || this.state.datatype[key] === 'textarea') {
|
_value = values[key].replace(/\t*|\v*/g, '') // 去除制表符
|
|
if (intercepts.includes(key)) { // 去除首尾空格
|
_value = _value.replace(/(^\s*|\s*$)/g, '')
|
}
|
} else {
|
_value = values[key]
|
|
}
|
|
search.push({
|
type: this.state.datatype[key],
|
readonly: this.state.readtype[key],
|
readin: this.state.readin[key],
|
fieldlen: this.state.fieldlen[key],
|
key: key,
|
value: _value
|
})
|
})
|
|
if (encrypts && encrypts.length > 0) {
|
search = search.map(item => {
|
let _value = item.value
|
if (encrypts.includes(item.key)) {
|
try {
|
_value = window.btoa(window.encodeURIComponent(_value))
|
} catch (e) {
|
console.warn(e)
|
}
|
}
|
item.value = _value
|
|
return item
|
})
|
}
|
resolve(search)
|
} else {
|
reject(err)
|
}
|
})
|
})
|
}
|
|
handleSubmit = (e) => {
|
e.preventDefault()
|
this.props.inputSubmit()
|
}
|
|
render() {
|
const { setting } = this.props
|
const { groups } = this.state
|
const formItemLayout = {
|
labelCol: {
|
xs: { span: 24 },
|
sm: { span: 8 }
|
},
|
wrapperCol: {
|
xs: { span: 24 },
|
sm: { span: 16 }
|
}
|
}
|
|
let _width = (setting && setting.width) || 100
|
|
let keys = groups.map(group => group.uuid)
|
|
return (
|
<Form {...formItemLayout} className="form-tab-form-field">
|
<Collapse
|
defaultActiveKey={keys}
|
expandIconPosition='right'
|
>
|
{groups.map(group =>
|
<Panel header={group.label} key={group.uuid}>
|
<Row style={{margin: '0 auto', width: _width + '%'}} gutter={24}>{this.getFields(group.sublist)}</Row>
|
</Panel>
|
)}
|
</Collapse>
|
</Form>
|
)
|
}
|
}
|
|
export default Form.create()(MainSearch)
|