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 { SettingOutlined, LeftOutlined, SearchOutlined, PlusOutlined } from '@ant-design/icons'
|
|
import Api from '@/api'
|
import Utils from '@/utils/utils.js'
|
import { getSearchForm } from '@/templates/zshare/formconfig'
|
import SourceElement from '@/templates/modalconfig/dragelement/source'
|
import SettingForm from './settingform'
|
import asyncComponent from '@/utils/asyncComponent'
|
import { SearchItems } from './source'
|
import MKEmitter from '@/utils/events.js'
|
import './index.scss'
|
|
const { Panel } = Collapse
|
const { confirm } = Modal
|
const SearchForm = asyncComponent(() => import('@/templates/sharecomponent/searchcomponent/searchform'))
|
const PasteComponent = asyncComponent(() => import('./pastecomponent'))
|
const DragElement = asyncComponent(() => import('./searchdragelement'))
|
const GDragElement = asyncComponent(() => import('./groupdragelement'))
|
const GroupForm = asyncComponent(() => import('./groupform'))
|
|
class ComModalConfig extends Component {
|
static propTpyes = {
|
btn: PropTypes.object,
|
handleSave: PropTypes.func,
|
handleBack: PropTypes.func
|
}
|
|
state = {
|
config: null, // 页面配置,包括模板类型、模态框设置、添加表名、表单列表
|
visible: false, // 表单编辑模态框,显示控制
|
formlist: null, // 表单编辑模态框,可编辑字段
|
card: null, // 编辑元素
|
settingVisible: false, // 全局配置模态框
|
originConfig: null, // 原始菜单
|
sqlVerifing: false, // sql验证
|
showField: false, // 显示表单字段值
|
group: null,
|
editGroup: null,
|
saving: false
|
}
|
|
/**
|
* @description 数据预处理
|
*/
|
UNSAFE_componentWillMount () {
|
const { config } = this.props
|
|
this.setState({
|
group: fromJS(config).toJS(),
|
config: fromJS(config).toJS(),
|
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 表单变化
|
*/
|
handleList = (list, newcard) => {
|
let _group = {...this.state.group, fields: list}
|
|
this.setState({
|
group: _group
|
}, () => {
|
if (newcard) {
|
this.handleForm(newcard)
|
}
|
})
|
this.resetConfig(_group)
|
}
|
|
/**
|
* @description 分组变化
|
*/
|
handleGroupList = (list) => {
|
let _group = {...this.state.group, groups: list}
|
|
this.setState({
|
group: _group
|
})
|
this.resetConfig(_group)
|
}
|
|
/**
|
* @description 表单变化
|
*/
|
handleList = (list, newcard) => {
|
let _group = {...this.state.group, fields: list}
|
|
this.setState({
|
group: _group
|
}, () => {
|
if (newcard) {
|
this.handleForm(newcard)
|
}
|
})
|
this.resetConfig(_group)
|
}
|
|
resetConfig = (group) => {
|
let _config = fromJS(this.state.config).toJS()
|
if (group.floor === 1) {
|
_config = group
|
} else {
|
_config.groups = _config.groups.map(item => {
|
if (item.uuid === group.uuid) return group
|
return item
|
})
|
}
|
|
this.setState({
|
config: _config
|
})
|
}
|
|
/**
|
* @description 表单编辑
|
*/
|
handleForm = (_card) => {
|
const { group } = this.state
|
let card = fromJS(_card).toJS()
|
let linkableFields = []
|
|
group.fields.forEach(item => {
|
if (item.uuid === card.uuid) return
|
if (!['select', 'link', 'checkcard'].includes(item.type)) return
|
if (item.type === 'checkcard' && item.multiple === 'true') return
|
|
linkableFields.push({
|
value: item.field,
|
text: item.label
|
})
|
})
|
|
this.setState({
|
visible: true,
|
card: card,
|
formlist: getSearchForm(card, linkableFields)
|
})
|
}
|
|
/**
|
* @description 编辑后提交
|
* 1、获取编辑后的表单信息
|
* 2、去除可能存在的示例表单
|
* 3、通过loading刷新
|
*/
|
handleSubmit = () => {
|
const { config } = this.state
|
this.formRef.handleConfirm().then(res => {
|
let _group = fromJS(this.state.group).toJS()
|
|
_group.fields = _group.fields.map(item => {
|
if (item.uuid === res.uuid) {
|
return res
|
} else {
|
return item
|
}
|
})
|
|
let fieldrepet = false // 字段重复
|
let lowerField = res.field.toLowerCase()
|
|
if (config.setting.field) {
|
let m = config.setting.field.toLowerCase().split(',')
|
if (m.includes(lowerField)) {
|
fieldrepet = true
|
}
|
}
|
config.fields.forEach(item => {
|
if (item.uuid === res.uuid) return
|
if (res.type === 'date' && item.type === 'date') return
|
if (item.field.toLowerCase() === lowerField) {
|
fieldrepet = true
|
}
|
})
|
|
config.groups.forEach(group => {
|
if (group.setting.field) {
|
let m = group.setting.field.toLowerCase().split(',')
|
if (m.includes(lowerField)) {
|
fieldrepet = true
|
}
|
}
|
group.fields.forEach(item => {
|
if (item.uuid === res.uuid) return
|
if (res.type === 'date' && item.type === 'date') return
|
if (item.field.toLowerCase() === lowerField) {
|
fieldrepet = true
|
}
|
})
|
})
|
|
if (fieldrepet) {
|
notification.warning({
|
top: 92,
|
message: '字段已存在!',
|
duration: 10
|
})
|
return
|
}
|
|
if (['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.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
|
param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
|
|
param.LText = Utils.formatOptions(param.LText)
|
param.secretkey = Utils.encrypt('', param.timestamp)
|
|
if (window.GLOB.mainSystemApi && res.database === 'sso') {
|
param.rduri = window.GLOB.mainSystemApi
|
}
|
|
Api.genericInterface(param).then(result => {
|
if (result.status) {
|
this.setState({
|
sqlVerifing: false,
|
group: _group,
|
card: null,
|
visible: false
|
})
|
this.resetConfig(_group)
|
} else {
|
this.setState({sqlVerifing: false})
|
|
Modal.error({
|
title: result.message
|
})
|
}
|
})
|
} else {
|
this.setState({
|
group: _group,
|
card: null,
|
visible: false
|
})
|
this.resetConfig(_group)
|
}
|
})
|
}
|
|
/**
|
* @description 表单删除并刷新
|
*/
|
closeForm = (card) => {
|
let _this = this
|
|
confirm({
|
content: `确定删除${card.label ? `<<${card.label}>>` : ''}吗?`,
|
onOk() {
|
let _group = fromJS(_this.state.group).toJS()
|
_group.fields = _group.fields.filter(item => item.uuid !== card.uuid)
|
|
_this.setState({
|
group: _group,
|
})
|
_this.resetConfig(_group)
|
},
|
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 => {
|
let _group = {...this.state.group, setting: res}
|
let lowers = _group.setting.field ? _group.setting.field.toLowerCase() : ''
|
|
if (lowers) {
|
let fieldrepet = false // 字段重复
|
lowers = lowers.split(',')
|
let length = lowers.length
|
|
if (_group.floor !== 1 && config.setting.field) {
|
let m = config.setting.field.toLowerCase().split(',')
|
if (Array.from(new Set([...m, ...lowers])).length < m.length + length) {
|
fieldrepet = true
|
}
|
}
|
|
config.fields.forEach(item => {
|
if (lowers.includes(item.field.toLowerCase())) {
|
fieldrepet = true
|
}
|
})
|
|
config.groups.forEach(group => {
|
if (_group.uuid === group.uuid) return
|
if (group.setting.field) {
|
let m = group.setting.field.toLowerCase().split(',')
|
if (Array.from(new Set([...m, ...lowers])).length < m.length + length) {
|
fieldrepet = true
|
}
|
}
|
group.fields.forEach(item => {
|
if (lowers.includes(item.field.toLowerCase())) {
|
fieldrepet = true
|
}
|
})
|
})
|
|
if (fieldrepet) {
|
notification.warning({
|
top: 92,
|
message: '字段已存在!',
|
duration: 10
|
})
|
return
|
}
|
}
|
|
this.setState({
|
group: _group,
|
settingVisible: false
|
})
|
this.resetConfig(_group)
|
})
|
}
|
|
editModalCancel = () => {
|
const { group, card } = this.state
|
|
if (card.focus) {
|
let _fields = group.fields.filter(item => item.uuid !== card.uuid)
|
let _group = {...group, fields: _fields}
|
|
this.setState({
|
card: null,
|
group: _group,
|
visible: false
|
})
|
this.resetConfig(_group)
|
} else {
|
this.setState({
|
card: null,
|
visible: false
|
})
|
}
|
}
|
|
plusGroup = () => {
|
let config = fromJS(this.state.config).toJS()
|
let _g = {
|
uuid: Utils.getuuid(),
|
wrap: { name: 'name', icon: '' },
|
setting: { type: 'title', field: '', title: '', focus: 'true', btn: 'hidden', backgroundColor: sessionStorage.getItem('sysBgColor') },
|
fields: []
|
}
|
|
config.groups.push(_g)
|
|
this.setState({config, group: config, editGroup: _g, gVisible: true})
|
}
|
|
handleGroupForm = (_g) => {
|
this.setState({editGroup: _g, gVisible: true})
|
}
|
|
/**
|
* @description 保存分组设置
|
*/
|
groupSave = () => {
|
this.gRef.handleConfirm().then(res => {
|
let _g = {...this.state.editGroup, wrap: res}
|
|
let _group = fromJS(this.state.group).toJS()
|
_group.groups = _group.groups.map(item => {
|
if (item.uuid === _g.uuid) return _g
|
return item
|
})
|
|
this.setState({
|
editGroup: null,
|
group: _group,
|
gVisible: false
|
})
|
this.resetConfig(_group)
|
})
|
}
|
|
handleGroup = (g) => {
|
this.setState({
|
group: g
|
})
|
}
|
|
closeGroup = (g) => {
|
const _this = this
|
let _group = fromJS(this.state.group).toJS()
|
_group.groups = _group.groups.filter(item => item.uuid !== g.uuid)
|
|
confirm({
|
content: `确定删除分组《${g.wrap.name}》吗?`,
|
onOk() {
|
_this.setState({ group: _group })
|
_this.resetConfig(_group)
|
},
|
onCancel() {}
|
})
|
}
|
|
returnUp = () => {
|
const { config } = this.state
|
|
this.setState({
|
group: config
|
})
|
}
|
|
render () {
|
const { group, editGroup, saving } = this.state
|
|
return (
|
<div className="mob-search-board">
|
<DndProvider backend={HTML5Backend}>
|
<div className="tools">
|
<Collapse accordion defaultActiveKey="1" bordered={false}>
|
<Panel header="搜索条件" key="1">
|
<div className="search-element">
|
{SearchItems.map((item, index) => {
|
return (<SourceElement key={index} content={item}/>)
|
})}
|
</div>
|
</Panel>
|
</Collapse>
|
</div>
|
<div className="modal-control">
|
<Button type="primary" loading={saving} onClick={this.submitConfig}>保存</Button>
|
<Button onClick={this.cancelConfig}>关闭</Button>
|
{!group.floor ? <Button onClick={this.returnUp}>返回上级</Button> : null}
|
<PasteComponent insert={this.insert} />
|
<Switch checkedChildren="开" unCheckedChildren="关" 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" style={{backgroundColor: group.setting.backgroundColor || '#ffffff'}}>
|
<SettingOutlined className="setting-group" onClick={this.changeSetting}/>
|
{group.setting.type === 'title' ? <div className="am-navbar">
|
<LeftOutlined />
|
<div className="am-navbar-title">{group.setting.title}</div>
|
</div> : <div className="am-navbar">
|
{/* <LeftOutlined /> */}
|
<div className="search-bar"><SearchOutlined style={{marginRight: '10px'}}/>{group.setting.label || ''}</div>
|
<Button >取消</Button>
|
</div>}
|
{group.floor === 1 ? <PlusOutlined className="plus-group" onClick={this.plusGroup} /> : null}
|
<div style={{minHeight: 'calc(100% - 100px)'}}>
|
{group.floor === 1 && group.groups.length > 0 ? <GDragElement
|
list={group.groups}
|
handleList={this.handleGroupList}
|
handleForm={this.handleGroupForm}
|
handleGroup={this.handleGroup}
|
closeForm={this.closeGroup}
|
/> : null}
|
<DragElement
|
list={group.fields}
|
showField={this.state.showField}
|
handleList={this.handleList}
|
handleForm={this.handleForm}
|
closeForm={this.closeForm}
|
/>
|
</div>
|
{group.setting.btn !== 'hidden' ? <div className="search-btn">
|
<Button className="reset">重置</Button>
|
<Button className="submit" type="primary">确定</Button>
|
</div> : null}
|
</div>
|
</div>
|
</div>
|
</DndProvider>
|
<Modal
|
title="编辑"
|
visible={this.state.visible}
|
width={850}
|
onCancel={this.editModalCancel}
|
onOk={this.handleSubmit}
|
confirmLoading={this.state.sqlVerifing}
|
destroyOnClose
|
>
|
<SearchForm
|
card={this.state.card}
|
formlist={this.state.formlist}
|
inputSubmit={this.handleSubmit}
|
wrappedComponentRef={(inst) => this.formRef = inst}
|
/>
|
</Modal>
|
<Modal
|
title="编辑"
|
visible={this.state.settingVisible}
|
width={850}
|
maskClosable={false}
|
onOk={this.settingSave}
|
onCancel={() => { this.setState({ settingVisible: false }) }}
|
destroyOnClose
|
>
|
<SettingForm
|
config={group}
|
inputSubmit={this.settingSave}
|
wrappedComponentRef={(inst) => this.settingRef = inst}
|
/>
|
</Modal>
|
<Modal
|
title="编辑"
|
visible={this.state.gVisible}
|
width={600}
|
maskClosable={false}
|
onOk={this.groupSave}
|
onCancel={() => { this.setState({ gVisible: false }) }}
|
destroyOnClose
|
>
|
<GroupForm
|
config={editGroup}
|
inputSubmit={this.groupSave}
|
wrappedComponentRef={(inst) => this.gRef = inst}
|
/>
|
</Modal>
|
</div>
|
)
|
}
|
}
|
|
export default ComModalConfig
|