import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { is, fromJS } from 'immutable'
|
import { DndProvider } from 'react-dnd'
|
import HTML5Backend from 'react-dnd-html5-backend'
|
import moment from 'moment'
|
import { Button, Modal, Collapse, notification, Switch } from 'antd'
|
import { LeftOutlined } from '@ant-design/icons'
|
|
import Api from '@/api'
|
import Utils from '@/utils/utils.js'
|
import zhCN from '@/locales/zh-CN/model.js'
|
import enUS from '@/locales/en-US/model.js'
|
import { getModalForm } from '@/templates/zshare/formconfig'
|
|
import SourceElement from '@/templates/modalconfig/dragelement/source'
|
import SettingForm from '@/templates/modalconfig/settingform'
|
import asyncComponent from '@/utils/asyncComponent'
|
import MKEmitter from '@/utils/events.js'
|
import { SearchItems } from './source'
|
import './index.scss'
|
|
const { Panel } = Collapse
|
const { confirm } = Modal
|
const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
|
const PasteComponent = asyncComponent(() => import('./pastecomponent'))
|
const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
|
const DragElement = asyncComponent(() => import('@/mob/components/formdragelement'))
|
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
|
|
class ComModalConfig extends Component {
|
static propTpyes = {
|
btn: PropTypes.object,
|
handleSave: PropTypes.func,
|
handleBack: PropTypes.func
|
}
|
|
state = {
|
dict: CommonDict, // 字典
|
config: null, // 页面配置,包括模板类型、模态框设置、添加表名、表单列表
|
visible: false, // 表单编辑模态框,显示控制
|
formlist: null, // 表单编辑模态框,可编辑字段
|
card: null, // 编辑元素
|
settingVisible: false, // 全局配置模态框
|
originConfig: null, // 原始菜单
|
sqlVerifing: false, // sql验证
|
showField: false, // 显示表单字段值
|
standardform: null,
|
saving: false
|
}
|
|
/**
|
* @description 数据预处理
|
*/
|
UNSAFE_componentWillMount () {
|
const { btn } = this.props
|
|
let _config = btn.modal
|
_config.version = '1.0'
|
|
this.setState({
|
config: _config,
|
originConfig: fromJS(_config).toJS()
|
})
|
}
|
|
componentDidMount () {
|
MKEmitter.addListener('completeSave', this.completeSave)
|
}
|
|
/**
|
* @description 组件销毁,清除state更新
|
*/
|
componentWillUnmount () {
|
this.setState = () => {
|
return
|
}
|
MKEmitter.removeListener('completeSave', this.completeSave)
|
}
|
|
completeSave = () => {
|
this.setState({saving: false})
|
}
|
|
/**
|
* @description 表单变化
|
* 1、表单拖拽添加时,检查是否存在示例表单,如存在则去除示例
|
* 2、表单移动后,保存移动后的顺序
|
* 3、新增表单时,直接打开编辑框
|
*/
|
handleList = (list, newcard) => {
|
let _config = fromJS(this.state.config).toJS()
|
|
if (list.length > _config.fields.length) {
|
_config.fields = list
|
this.setState({
|
config: _config
|
}, () => {
|
this.handleForm(newcard)
|
})
|
} else {
|
_config.fields = list
|
this.setState({config: _config})
|
}
|
}
|
|
/**
|
* @description 表单编辑
|
* 1、显示编辑弹窗-visible
|
* 2、保存编辑项-card
|
* 3、设置编辑参数项-formlist
|
*/
|
handleForm = (_card) => {
|
const { componentConfig } = this.props
|
const { config } = this.state
|
let card = fromJS(_card).toJS()
|
let _inputfields = []
|
let _tabfields = []
|
let _linkableFields = []
|
let _linksupFields = []
|
let standardform = null
|
|
let uniq = new Map()
|
let index = null
|
uniq.set(card.field, true)
|
|
let _inputIndex = 1
|
let _tabIndex = 1
|
let _linkIndex = 1
|
config.fields.forEach((item, i) => {
|
if (card.uuid === item.uuid) {
|
index = i
|
}
|
|
if (['text', 'number', 'textarea', 'color'].includes(item.type) && card.field !== item.field) {
|
_inputfields.push({
|
field: item.field,
|
label: _inputIndex + '、' + item.label
|
})
|
_inputIndex++
|
}
|
if (card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
|
_tabfields.push({
|
field: item.field,
|
label: _tabIndex + '、' + item.label
|
})
|
_tabIndex++
|
}
|
|
if (item.type === 'switch') {
|
_linksupFields.push({
|
field: item.field,
|
label: _linkIndex + '、' + item.label
|
})
|
}
|
|
if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
|
if (item.type === 'checkcard' && item.multiple === 'true') return // 选项卡多选
|
if (item.field && !uniq.has(item.field)) {
|
uniq.set(item.field, true)
|
|
_linkableFields.push({
|
field: item.field,
|
label: _linkIndex + '、' + item.label + ' (表单)'
|
})
|
_linksupFields.push({
|
field: item.field,
|
label: _linkIndex + '、' + item.label
|
})
|
_linkIndex++
|
}
|
})
|
|
_tabfields.unshift({field: '', label: '原表单'})
|
|
if (index !== null) {
|
if (index === 0) {
|
standardform = config.fields[index + 1] || null
|
} else {
|
standardform = config.fields[index - 1] || null
|
}
|
}
|
|
componentConfig.columns.forEach(col => {
|
if (col.field && !uniq.has(col.field)) {
|
uniq.set(col.field, true)
|
|
_linkableFields.push({
|
field: col.field,
|
label: _linkIndex + '、' + col.label + ' (显示列)'
|
})
|
_linkIndex++
|
}
|
})
|
|
if (card.linkSubField && card.linkSubField.length > 0) {
|
let fields = _inputfields.map(item => item.field)
|
card.linkSubField = card.linkSubField.filter(item => fields.includes(item))
|
}
|
|
if (!card.span && standardform && standardform.span) {
|
card.span = standardform.span
|
card.labelwidth = standardform.labelwidth
|
}
|
|
this.setState({
|
standardform,
|
visible: true,
|
card: card,
|
formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields)
|
})
|
}
|
|
/**
|
* @description 编辑后提交
|
* 1、获取编辑后的表单信息
|
* 2、去除可能存在的示例表单
|
* 3、通过loading刷新
|
*/
|
handleSubmit = () => {
|
this.formRef.handleConfirm().then(res => {
|
let _config = fromJS(this.state.config).toJS()
|
let fieldrepet = false // 字段重复
|
|
_config.fields = _config.fields.map(item => {
|
if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
|
fieldrepet = true
|
}
|
|
if (item.uuid === res.uuid) {
|
return res
|
} else {
|
return item
|
}
|
})
|
|
if (fieldrepet) {
|
notification.warning({
|
top: 92,
|
message: '字段已存在!',
|
duration: 10
|
})
|
return
|
}
|
|
if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
|
this.setState({
|
sqlVerifing: true
|
})
|
|
let param = {
|
func: 's_debug_sql',
|
exec_type: 'y',
|
LText: res.dataSource
|
}
|
|
param.LText = param.LText.replace(/@\$|\$@/ig, '')
|
|
param.LText = Utils.formatOptions(param.LText)
|
param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
|
param.secretkey = Utils.encrypt('', param.timestamp)
|
|
if (window.GLOB.mainSystemApi && res.database === 'sso') {
|
param.rduri = window.GLOB.mainSystemApi
|
}
|
|
Api.getLocalConfig(param).then(result => {
|
if (result.status) {
|
this.setState({
|
sqlVerifing: false,
|
config: _config,
|
card: null,
|
visible: false
|
})
|
} else {
|
this.setState({sqlVerifing: false})
|
|
Modal.error({
|
title: result.message
|
})
|
}
|
})
|
} else {
|
this.setState({
|
config: _config,
|
card: null,
|
visible: false
|
})
|
}
|
})
|
}
|
|
/**
|
* @description 表单删除并刷新
|
*/
|
closeForm = (card) => {
|
let _this = this
|
|
confirm({
|
content: `确定删除${card.label ? `<<${card.label}>>` : ''}吗?`,
|
onOk() {
|
let _config = fromJS(_this.state.config).toJS()
|
_config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
|
|
_this.setState({
|
config: _config,
|
})
|
},
|
onCancel() {}
|
})
|
}
|
|
submitConfig = () => {
|
const { config } = this.state
|
|
this.setState({originConfig: fromJS(config).toJS(), saving: true})
|
this.props.handleSave(config)
|
|
setTimeout(() => {
|
MKEmitter.emit('triggerMenuSave')
|
}, 100)
|
}
|
|
cancelConfig = () => {
|
const { config, originConfig } = this.state
|
|
if (!is(fromJS(config), fromJS(originConfig))) {
|
let _this = this
|
confirm({
|
content: '配置信息未保存,确定返回吗?',
|
onOk() {
|
_this.props.handleBack()
|
},
|
onCancel() {}
|
})
|
} else {
|
this.props.handleBack()
|
}
|
}
|
|
/**
|
* @description 全局设置模态框
|
*/
|
changeSetting = () => {
|
this.setState({
|
settingVisible: true
|
})
|
}
|
|
/**
|
* @description 保存全局设置
|
*/
|
settingSave = () => {
|
const {config} = this.state
|
this.settingRef.handleConfirm().then(res => {
|
this.setState({
|
config: {...config, setting: res},
|
settingVisible: false
|
})
|
})
|
}
|
|
editModalCancel = () => {
|
const { config, card } = this.state
|
|
if (card.focus) {
|
let _fields = config.fields.filter(item => item.uuid !== card.uuid)
|
let _config = {...config, fields: _fields}
|
|
this.setState({
|
card: null,
|
config: _config,
|
visible: false
|
})
|
} else {
|
this.setState({
|
card: null,
|
visible: false
|
})
|
}
|
}
|
|
/**
|
* @description 更新
|
*/
|
plusFields = (items) => {
|
let _config = fromJS(this.state.config).toJS()
|
|
_config.fields.push(...items)
|
|
this.setState({
|
config: _config
|
}, () => {
|
if (items.length === 1 && items[0].focus) {
|
this.handleForm(items[0])
|
}
|
})
|
}
|
|
insert = (config) => {
|
this.setState({
|
config
|
}, () => {
|
this.handleForm(config.fields[config.fields.length - 1])
|
})
|
}
|
|
clearConfig = () => {
|
const _this = this
|
let _config = {...this.state.config, fields: []}
|
|
confirm({
|
content: '确定清空表单吗?',
|
onOk() {
|
_this.setState({ config: _config })
|
},
|
onCancel() {}
|
})
|
}
|
|
render () {
|
const { config, dict, saving } = this.state
|
|
return (
|
<div className="mob-form-board">
|
<DndProvider backend={HTML5Backend}>
|
<div className="tools">
|
<Collapse accordion defaultActiveKey="1" bordered={false}>
|
<Panel header={dict['header.menu.form']} key="1">
|
<div className="search-element">
|
{SearchItems.map((item, index) => {
|
return (<SourceElement key={index} content={item}/>)
|
})}
|
</div>
|
<FieldsComponent config={config} type="form" plusFields={this.plusFields}/>
|
</Panel>
|
</Collapse>
|
</div>
|
<div className="modal-control">
|
<Button icon="setting" onClick={this.changeSetting}>设置</Button>
|
<Button type="primary" id="save-modal-config" loading={saving} onClick={this.submitConfig}>保存</Button>
|
<Button onClick={this.cancelConfig}>返回</Button>
|
<PasteComponent config={config} updateConfig={this.insert} />
|
<Button type="danger" onClick={this.clearConfig}>清空</Button>
|
<Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
|
</div>
|
<div className="setting">
|
<div className="mob-shell" style={{width: window.GLOB.shellWidth, height: window.GLOB.shellHeight}}>
|
<div className="mob-shell-inner">
|
<div className="am-navbar">
|
<LeftOutlined />
|
<div className="am-navbar-title">{config.setting.title}</div>
|
{config.setting.btnPosition === 'top' ? <Button className="modal-submit-top">{config.setting.btnName || '确定'}</Button> : null}
|
</div>
|
<DragElement
|
list={config.fields}
|
setting={config.setting}
|
showField={this.state.showField}
|
placeholder={this.state.dict['header.form.modal.placeholder']}
|
handleList={this.handleList}
|
handleForm={this.handleForm}
|
closeForm={this.closeForm}
|
/>
|
{config.setting.btnPosition !== 'top' ?
|
<Button className="modal-submit" type="primary">{config.setting.btnName || '确定'}</Button> : null}
|
</div>
|
</div>
|
</div>
|
</DndProvider>
|
<Modal
|
title={this.state.dict['model.edit']}
|
visible={this.state.visible}
|
width={850}
|
onCancel={this.editModalCancel}
|
onOk={this.handleSubmit}
|
confirmLoading={this.state.sqlVerifing}
|
destroyOnClose
|
>
|
<ModalForm
|
dict={this.state.dict}
|
card={this.state.card}
|
formlist={this.state.formlist}
|
inputSubmit={this.handleSubmit}
|
standardform={this.state.standardform}
|
wrappedComponentRef={(inst) => this.formRef = inst}
|
/>
|
</Modal>
|
<Modal
|
title={this.state.dict['model.edit']}
|
visible={this.state.settingVisible}
|
width={900}
|
maskClosable={false}
|
onOk={this.settingSave}
|
onCancel={() => { this.setState({ settingVisible: false }) }}
|
destroyOnClose
|
>
|
<SettingForm
|
config={config}
|
dict={this.state.dict}
|
isSubTab={!!this.props.editTab}
|
inputSubmit={this.settingSave}
|
wrappedComponentRef={(inst) => this.settingRef = inst}
|
/>
|
</Modal>
|
</div>
|
)
|
}
|
}
|
|
export default ComModalConfig
|