king
2021-03-23 a8e94242166881639cecf3809e45ca527233ebd7
2021-03-23
1 文件已重命名
42个文件已修改
9个文件已删除
9个文件已添加
5003 ■■■■ 已修改文件
src/menu/components/card/cardcellcomponent/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/cardcomponent/index.jsx 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/cardcomponent/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/cardcomponent/settingform/index.jsx 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/cardcomponent/settingform/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragelement/card.jsx 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragelement/index.jsx 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragelement/index.scss 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragelement/source.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragtitle/card.jsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragtitle/index.jsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragtitle/index.scss 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/actionform/index.jsx 362 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/actionform/index.scss 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/formconfig.jsx 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/index.jsx 290 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/normal-form/groupform/index.jsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/normal-form/groupform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/normal-form/index.jsx 463 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/normal-form/index.scss 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/wrapsetting/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/wrapsetting/settingform/index.jsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/markcomponent/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/settingform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/settingform/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.jsx 593 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.scss 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/datasource/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/menushell/card.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/modulesource/option.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/actionList/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/config.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/actionList/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/config.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 77 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/printbutton/index.jsx 77 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/card.jsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/index.jsx 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/index.scss 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/groupform/index.jsx 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 364 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.scss 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/settingform/index.jsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/source.jsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/index.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/fieldscomponent/index.jsx 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.scss 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/createinterface/index.jsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editcomponent/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-update.js 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx
@@ -663,7 +663,6 @@
          visible={profVisible}
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={dict['model.submit']}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ profVisible: false }) }}
src/menu/components/form/cardcomponent/index.jsx
File was deleted
src/menu/components/form/cardcomponent/index.scss
src/menu/components/form/cardcomponent/settingform/index.jsx
File was deleted
src/menu/components/form/cardcomponent/settingform/index.scss
File was deleted
src/menu/components/form/dragelement/card.jsx
File was deleted
src/menu/components/form/dragelement/index.jsx
File was deleted
src/menu/components/form/dragelement/index.scss
File was deleted
src/menu/components/form/dragelement/source.jsx
File was deleted
src/menu/components/form/dragtitle/card.jsx
New file
@@ -0,0 +1,59 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Icon, Popover } from 'antd'
import './index.scss'
const Card = ({ id, card, active, moveCard, findCard, editCard, closeCard, selectCard }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: 'form', id, originalIndex },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })
  const [, drop] = useDrop({
    accept: 'form',
    canDrop: () => true,
    drop: (item) => {
      const { id: draggedId, originalIndex } = item
      if (originalIndex === undefined) {
        item.dropTargetId = id
      } else if (draggedId && draggedId !== id) {
        const { index: overIndex } = findCard(id)
        moveCard(draggedId, overIndex)
      }
    }
  })
  const opacity = isDragging ? 0 : 1
  const edit = () => {
    editCard(id)
  }
  const close = () => {
    closeCard(id)
  }
  const select = () => {
    selectCard(id)
  }
  return (
    <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
      <div className="mk-popover-control">
        <Icon className="edit" type="edit" onClick={edit} />
        <Icon className="close" type="close" onClick={close} />
      </div>
    } trigger="hover">
      <div className={'page-card ' + (active ? 'active' : '')} onClick={select} style={{ opacity: opacity}}>
        <div ref={node => drag(drop(node))}>
          <span className="form-sort">{card.sort}</span>
          {card.setting.title}
        </div>
      </div>
    </Popover>
  )
}
export default Card
src/menu/components/form/dragtitle/index.jsx
New file
@@ -0,0 +1,64 @@
import React, { useState } from 'react'
import { is, fromJS } from 'immutable'
import update from 'immutability-helper'
import Card from './card'
import './index.scss'
const Container = ({list, selectId, handleList, handleGroup, closeGroup, selectGroup}) => {
  const [cards, setCards] = useState(list)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    if (!card) return
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    handleList(_cards)
  }
  if (!is(fromJS(cards), fromJS(list))) {
    setCards(list)
  }
  const findCard = id => {
    const card = cards.filter(c => `${c.uuid}` === id)[0]
    return {
      card,
      index: cards.indexOf(card),
    }
  }
  const editCard = id => {
    const { card } = findCard(id)
    handleGroup(card)
  }
  const closeCard = id => {
    const { card } = findCard(id)
    closeGroup(card)
  }
  const selectCard = id => {
    const { card } = findCard(id)
    selectGroup(card)
  }
  return (
    <div className="normal-form-titles" >
      {cards.map(card => (
        <Card
          id={card.uuid}
          key={card.uuid}
          active={card.uuid === selectId}
          card={card}
          moveCard={moveCard}
          editCard={editCard}
          closeCard={closeCard}
          findCard={findCard}
          selectCard={selectCard}
        />
      ))}
    </div>
  )
}
export default Container
src/menu/components/form/dragtitle/index.scss
New file
@@ -0,0 +1,40 @@
.normal-form-titles {
  display: flex;
  line-height: 30px;
  min-height: 50px;
  .page-card {
    position: relative;
    flex: 1;
    text-align: center;
    cursor: move;
    .form-sort {
      background: #d8d8d8;
      display: block;
      width: 20px;
      height: 20px;
      line-height: 20px;
      border-radius: 20px;
      text-align: center;
      color: #ffffff;
      margin: 10px auto 0px;
      position: relative;
      z-index: 1;
    }
  }
  .page-card:not(:first-child)::before {
    position: absolute;
    content: ' ';
    display: inline-block;
    width: 100%;
    height: 2px;
    background: #d8d8d8;
    left: -50%;
    top: 18px;
  }
  .page-card.active {
    color: #1890ff;
    .form-sort {
      background: #1890ff;
    }
  }
}
src/menu/components/form/formaction/actionform/index.jsx
New file
@@ -0,0 +1,362 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
// import { fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, Icon, Radio, Tooltip, InputNumber, Cascader } from 'antd'
import { formRule } from '@/utils/option.js'
import './index.scss'
const { TextArea } = Input
class ActionForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,      // 字典项
    formlist: PropTypes.any,     // 表单信息
    card: PropTypes.any,         // 按钮信息
    inputSubmit: PropTypes.any   // 回车提交事件
  }
  state = {
    formlist: null,  // 表单信息
    interType: null, // 接口类型:内部、外部
    procMode: null,  // 参数方式
  }
  UNSAFE_componentWillMount () {
    const { card } = this.props
    let _intertype = card.intertype || 'system'  // 接口类型
    let _procMode = card.procMode || 'system'    // 参数请求方式
    let _options = this.getOptions(_intertype, _procMode)
    this.setState({
      interType: _intertype,
      procMode: _procMode,
      formlist: this.props.formlist.map(item => {
        if (item.key === 'innerFunc' && _procMode === 'inner') {
          item.required = true
        }
        item.hidden = !_options.includes(item.key)
        return item
      })
    })
  }
  getOptions = (_intertype, _procMode) => {
    let _options = ['type', 'label', 'intertype', 'syncComponent', 'linkmenu', 'open'] // 选项列表
    if (_intertype === 'custom') {
      _options.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method', 'cross')
      if (_procMode === 'system') {
        _options.push('sql', 'sqlType')
      } else {
        _options.push('innerFunc')
      }
    } else if (_intertype === 'outer') {
      _options.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
    } else if (_intertype === 'inner') {
      _options.push('innerFunc')
    } else {
      _options.push('sql', 'sqlType')
    }
    return _options
  }
  /**
   * @description 下拉切换
   * 1、打开方式切换,重置可见表单和表单值
   * 2、显示位置切换,重置选择行
   * 3、切换标签类型,重置可选标签
   */
  optionChange = (key, value) => {
    const { procMode } = this.state
    if (key === 'intertype') {
      let _options = this.getOptions(value, procMode)
      this.setState({
        interType: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          if (item.key === 'interface') {
            item.readonly = false
          } else if (item.key === 'sysInterface') {
            item.initVal = 'false'
          }
          return item
        })
      })
    } else if (key === 'procMode') {
      let _options = this.getOptions(this.state.interType, value)
      this.setState({
        procMode: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          if (item.key === 'innerFunc') {
            item.required = true
          }
          return item
        })
      })
    } else if (key === 'sysInterface') {
      if (value === 'true') {
        this.props.form.setFieldsValue({
          interface: window.GLOB.mainSystemApi || ''
        })
      }
      this.setState({
        formlist: this.state.formlist.map(item => {
          if (item.key === 'interface' && value === 'true') {
            item.readonly = true
          } else if (item.key === 'interface') {
            item.readonly = false
          }
          return item
        })
      })
    }
  }
  handleSubmit = (e) => {
    e.preventDefault()
    if (this.props.inputSubmit) {
      this.props.inputSubmit()
    }
  }
  getFields() {
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.state.formlist.forEach((item, index) => {
      if (item.hidden || item.forbid) return
      if (item.type === 'text') { // 文本搜索
        let _rules = []
        if (item.key === 'innerFunc') {
          let str = '^(' + item.fields.join('|') + ')'
          let _patten = new RegExp(str + formRule.func.innerPattern + '$', 'g')
          _rules = [{
            pattern: _patten,
            message: formRule.func.innerMessage
          }, {
            max: formRule.func.max,
            message: formRule.func.maxMessage
          }]
        } else if (item.key === 'outerFunc' || item.key === 'callbackFunc') {
          _rules = [{
            pattern: formRule.func.pattern,
            message: formRule.func.message
          }, {
            max: formRule.func.max,
            message: formRule.func.maxMessage
          }]
        } else {
          _rules = [{
            max: formRule.input.max,
            message: formRule.input.message
          }]
        }
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  },
                  ..._rules
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'tip') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {item.initVal}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<InputNumber min={0} max={10000} precision={0} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  onChange={(value) => {this.optionChange(item.key, value)}}
                  getPopupContainer={() => document.getElementById('winter')}
                >
                  {item.options.map((option, index) =>
                    <Select.Option id={`${index}`} title={option.text} key={`${index}`} value={option.value}>
                      {option.text}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'radio') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Radio.Group onChange={(e) => {this.optionChange(item.key, e.target.value)}} disabled={item.readonly}>
                  {
                    item.options.map(option => {
                      return (
                        <Radio key={option.value} value={option.value}>{option.text}</Radio>
                      )
                    })
                  }
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'textarea') {
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label} className="textarea">
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<TextArea rows={2} readOnly={item.readonly}/>)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'cascader') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || [],
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Cascader options={item.options || []} expandTrigger="hover" placeholder=""/>
              )}
            </Form.Item>
          </Col>
        )
      }
    })
    return fields
  }
  handleConfirm = () => {
    const { card } = this.props
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          values.verify = card.verify || null
          resolve(values)
        } else {
          reject(err)
        }
      })
    })
  }
  render() {
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 7 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 17 }
      }
    }
    return (
      <Form {...formItemLayout} className="menu-action-list-form" id="winter">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
  }
}
export default Form.create()(ActionForm)
src/menu/components/form/formaction/actionform/index.scss
New file
@@ -0,0 +1,47 @@
.menu-action-list-form {
  min-height: 190px;
  .superconfig {
    color: #1890ff;
    cursor: pointer;
  }
  .textarea {
    .ant-col-sm-7 {
      width: 14%;
    }
    .ant-col-sm-17 {
      width: 86%;
    }
  }
  .ant-radio-group {
    white-space: nowrap;
    .ant-radio-wrapper {
      margin-right: 4px;
    }
  }
  .ant-input-number {
    width: 100%;
  }
  .anticon-question-circle {
    color: #c49f47;
    position: relative;
    left: -3px;
  }
  .with-button {
    .ant-form-item-control-wrapper {
      padding-right: 63px;
    }
    .ant-btn {
      position: absolute;
      right: 12px;
      top: 4.5px;
    }
  }
  .ant-input:read-only {
    background: #fafafa;
    resize: none;
  }
  .ant-input:read-only:hover, .ant-input:read-only:focus {
    border-color: #d9d9d9;
    box-shadow: none;
  }
}
src/menu/components/form/formaction/formconfig.jsx
New file
@@ -0,0 +1,278 @@
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
/**
 * @description 获取表单按钮配置信息
 * @param {*} card           编辑按钮
 * @param {*} type           按钮类型,用于区分可选的打开方式
 */
export function getActionForm (card, functip, tableName, usefulFields, modules) {
  const isApp = sessionStorage.getItem('appType') === 'pc'
  let _type = '提交'
  if (card.type === 'prev') {
    _type = '上一步'
  } else if (card.type === 'next') {
    _type = '下一步'
  }
  let menulist = []
  if (isApp) {
    menulist = sessionStorage.getItem('appMenus')
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
        menulist = menulist.map(item => ({value: item.MenuID, text: item.MenuName}))
      } catch {
        menulist = []
      }
    } else {
      menulist = []
    }
    menulist.unshift({value: '', text: '无'})
  } else {
    menulist = sessionStorage.getItem('fstMenuList')
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
      } catch {
        menulist = []
      }
    } else {
      menulist = []
    }
  }
  return [
    {
      type: 'tip',
      key: 'type',
      label: '按钮类型',
      initVal: _type
    },
    {
      type: 'text',
      key: 'label',
      label: '按钮名称',
      initVal: card.label,
      required: true,
      readonly: false
    },
    {
      type: 'radio',
      key: 'intertype',
      label: Formdict['header.form.intertype'],
      initVal: card.intertype || 'system',
      required: true,
      options: [{
        value: 'system',
        text: Formdict['model.interface.system']
      }, {
        value: 'inner',
        text: Formdict['model.interface.inner']
      }, {
        value: 'outer',
        text: Formdict['model.interface.outer']
      }, {
        value: 'custom',
        text: '自定义'
      }]
    },
    {
      type: 'radio',
      key: 'procMode',
      label: '参数处理',
      initVal: card.procMode || 'system',
      required: true,
      options: [{
        value: 'system',
        text: '系统函数'
      }, {
        value: 'inner',
        text: '内部函数'
      }]
    },
    {
      type: 'radio',
      key: 'sqlType',
      label: Formdict['header.form.action.type'],
      initVal: card.sqlType || 'update',
      required: true,
      options: [{
        value: 'insert',
        text: Formdict['header.form.action.insert']
      }, {
        value: 'update',
        text: Formdict['header.form.action.update']
      }, {
        value: 'audit',
        text: Formdict['header.form.action.audit']
      }]
    },
    {
      type: 'text',
      key: 'sql',
      label: Formdict['model.form.tablename'],
      initVal: card.sql || tableName || '',
      required: true
    },
    {
      type: 'text',
      key: 'innerFunc',
      label: Formdict['header.form.innerFunc'],
      initVal: card.innerFunc || '',
      tooltip: functip,
      fields: usefulFields,
      tooltipClass: 'middle',
      required: card.intertype === 'inner',
      readonly: false
    },
    {
      type: 'select',
      key: 'linkTab',
      label: '关联标签',
      initVal: card.linkTab || '',
      required: false,
      options: []
    },
    {
      type: 'text',
      key: 'url',
      label: Formdict['model.pageUrl'],
      initVal: card.url || '',
      required: true
    },
    {
      type: 'radio',
      key: 'sysInterface',
      label: Formdict['header.form.sysInterface'],
      initVal: card.sysInterface || 'false',
      required: true,
      options: [{
        value: 'true',
        text: Formdict['model.true']
      }, {
        value: 'false',
        text: Formdict['model.false']
      }]
    },
    {
      type: 'text',
      key: 'outerFunc',
      label: Formdict['header.form.outerFunc'],
      initVal: card.outerFunc || '',
      required: false,
      readonly: false
    },
    {
      type: 'textarea',
      key: 'interface',
      label: '测试地址',
      initVal: card.sysInterface === 'true' ? (window.GLOB.mainSystemApi || '') : (card.interface || ''),
      required: true,
      readonly: card.sysInterface === 'true'
    },
    {
      type: 'textarea',
      key: 'proInterface',
      label: '正式地址',
      initVal: card.proInterface || '',
      tooltip: '正式系统所使用的接口地址。',
      required: false
    },
    {
      type: 'radio',
      key: 'method',
      label: '请求方式',
      initVal: card.method || 'post',
      required: true,
      options: [{
        value: 'get',
        text: 'GET'
      }, {
        value: 'post',
        text: 'POST'
      }]
    },
    {
      type: 'radio',
      key: 'cross',
      label: '跨域请求',
      initVal: card.cross || 'true',
      tooltip: '如果自定义接口不支持跨域请求,会通过当前系统转发。',
      required: false,
      options: [{
        value: 'true',
        text: '支持'
      }, {
        value: 'false',
        text: '不支持'
      }]
    },
    {
      type: 'radio',
      key: 'callbackType',
      label: '回调方式',
      initVal: card.callbackType || 'script',
      tooltip: '使用后台脚本执行时,需要配合计划任务。',
      required: true,
      options: [{
        value: 'script',
        text: '自定义脚本'
      }, {
        value: 'default',
        text: '后台脚本'
      }]
    },
    {
      type: 'text',
      key: 'cbTable',
      label: '回调表名',
      initVal: card.cbTable || '',
      required: true
    },
    {
      type: 'text',
      key: 'callbackFunc',
      label: Formdict['header.form.callbackFunc'],
      initVal: card.callbackFunc || '',
      required: false,
      readonly: false
    },
    {
      type: isApp ? 'select' : 'cascader',
      key: 'linkmenu',
      label: '打开菜单',
      tooltip: '执行成功后需要打开的菜单。',
      initVal: card.linkmenu,
      required: false,
      options: menulist
    },
    {
      type: 'radio',
      key: 'open',
      label: '打开方式',
      initVal: card.open || 'blank',
      required: false,
      forbid: !isApp,
      options: [{
        value: 'blank',
        text: '新窗口'
      }, {
        value: 'self',
        text: '当前窗口'
      }]
    },
    {
      type: 'cascader',
      key: 'syncComponent',
      label: '同步刷新',
      initVal: card.syncComponent,
      tooltip: '执行成功后需要刷新的组件。',
      required: false,
      options: modules
    }
  ]
}
src/menu/components/form/formaction/index.jsx
New file
@@ -0,0 +1,290 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { connect } from 'react-redux'
import { Modal, Button, Popover, Icon } from 'antd'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import asyncComponent from '@/utils/asyncComponent'
import { getActionForm } from './formconfig'
import MKEmitter from '@/utils/events.js'
import MenuUtils from '@/utils/utils-custom.js'
import './index.scss'
const ActionForm = asyncComponent(() => import('./actionform'))
const VerifyCard = asyncComponent(() => import('@/templates/zshare/verifycard'))
class CardCellComponent extends Component {
  static propTpyes = {
    group: PropTypes.object,         // 分组信息
    updateconfig: PropTypes.func     // 菜单配置更新
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,          // 编辑中元素
    formlist: null,      // 表单信息
    elements: null,      // 按钮组
    visible: false,      // 模态框控制
    profVisible: false,  // 验证信息编辑
  }
  /**
   * @description 搜索条件初始化
   */
  UNSAFE_componentWillMount () {
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.group), fromJS(nextProps.group)) || !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  handleStyle = (element) => {
    const { group } = this.props
    let _style = element.style ? fromJS(element.style).toJS() : {}
    let options = ['font', 'border', 'padding', 'margin', 'backgroundColor']
    this.setState({
      card: element
    })
    MKEmitter.emit('changeStyle', [group.uuid, element.type], options, _style)
  }
  getStyle = (comIds, style) => {
    let group = fromJS(this.props.group).toJS()
    if (comIds.length !== 2 || comIds[0] !== group.uuid) return
    if (comIds[1] === 'prev') {
      group.prevButton.style = style
    } else if (comIds[1] === 'submit') {
      group.subButton.style = style
    } else if (comIds[1] === 'next') {
      group.nextButton.style = style
    }
    this.props.updateconfig(group)
  }
  /**
   * @description 按钮编辑,获取按钮表单信息
   */
  handleAction = (card) => {
    const { menu, config } = this.props
    let usefulFields = sessionStorage.getItem('permFuncField')
    if (usefulFields) {
      try {
        usefulFields = JSON.parse(usefulFields)
      } catch {
        usefulFields = []
      }
    } else {
      usefulFields = []
    }
    let ableField = usefulFields.join(', ')
    let functip = <div>
      <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p>
    </div>
    let modules = MenuUtils.getSubModules(menu.components, config.uuid)
    this.setState({
      visible: true,
      card: card,
      formlist: getActionForm(card, functip, config.setting.tableName, usefulFields, modules)
    })
  }
  /**
   * @description 取消保存,如果元素为新添元素,则从序列中删除
   */
  editModalCancel = () => {
    this.setState({
      card: null,
      visible: false
    })
  }
  /**
   * @description 元素修改后提交保存
   */
  handleActionSubmit = () => {
    const { elements } = this.state
    let color = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666' }
    this.actionFormRef.handleConfirm().then(res => {
      let _elements = elements.map(cell => {
        if (cell.uuid === res.uuid) {
          res = {...cell, ...res}
          delete res.focus
          let btnstyle = {}
          if (res.class !== cell.class || res.show !== cell.show || !res.btnstyle) {
            if (res.show === 'link' || res.show === 'icon') {
              btnstyle.color = color[res.class]
              btnstyle.backgroundColor = 'transparent'
            } else {
              btnstyle.color = '#ffffff'
              btnstyle.backgroundColor = color[res.class]
            }
          }
          res.btnstyle = {...res.btnstyle, ...btnstyle}
          return res
        }
        return cell
      })
      this.setState({
        elements: _elements,
        visible: false
      }, () => {
        this.props.updateElement(_elements)
      })
    })
  }
  /**
   * @description 验证信息配置
   */
  profileAction = () => {
    this.setState({
      profVisible: true
    })
  }
  /**
   * @description 验证信息保存
   */
  verifySubmit = () => {
    const { elements, card } = this.state
    this.verifyRef.handleConfirm().then(res => {
      let _elements = elements.map(cell => {
        if (cell.uuid === card.uuid) {
          cell.verify = res
        }
        return cell
      })
      this.setState({
        elements: _elements,
        profVisible: false
      }, () => {
        this.props.updateElement(_elements)
      })
    })
  }
  render() {
    const { group, config } = this.props
    const { visible, profVisible, card, dict } = this.state
    return (
      <div className="mk-form-action">
        {group.sort !== 1 ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <Icon className="edit" title="编辑" type="edit" onClick={() => this.handleAction(group.prevButton)} />
            <Icon className="style" title="调整样式" onClick={() => this.handleStyle(group.prevButton)} type="font-colors" />
          </div>
        } trigger="hover">
          <Button type="link" className="prev" style={group.prevButton.style}>{group.prevButton.label}</Button>
        </Popover> : null}
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <Icon className="edit" title="编辑" type="edit" onClick={() => this.handleAction(group.subButton)} />
            <Icon className="style" title="调整样式" onClick={() => this.handleStyle(group.subButton)} type="font-colors" />
            <Icon className="profile" title="setting" type="profile" onClick={() => this.profileAction()} />
          </div>
        } trigger="hover">
          <Button type="link" className="submit mk-primary" style={group.subButton.style}>{group.subButton.label}</Button>
        </Popover>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <Icon className="edit" title="编辑" type="edit" onClick={() => this.handleAction(group.nextButton)} />
            <Icon className="style" title="调整样式" onClick={() => this.handleStyle(group.nextButton)} type="font-colors" />
          </div>
        } trigger="hover">
          <Button type="link" className="skip" style={group.nextButton.style}>{group.nextButton.label}</Button>
        </Popover>
        {/* 编辑按钮:复制、编辑 */}
        <Modal
          title={dict['model.edit']}
          visible={visible}
          width={800}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
            <Button key="cancel" onClick={this.editModalCancel}>{dict['model.cancel']}</Button>,
            <Button key="confirm" type="primary" onClick={this.handleActionSubmit}>{dict['model.confirm']}</Button>
          ]}
          destroyOnClose
        >
          <ActionForm
            dict={dict}
            type="card"
            card={card}
            setting={config.setting}
            formlist={this.state.formlist}
            inputSubmit={this.handleActionSubmit}
            wrappedComponentRef={(inst) => this.actionFormRef = inst}
          />
        </Modal>
        {/* 按钮使用系统存储过程时,验证信息模态框 */}
        <Modal
          wrapClassName="model-table-action-verify-modal"
          title={'验证信息'}
          visible={profVisible}
          width={'75vw'}
          maskClosable={false}
          okText={dict['model.submit']}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ profVisible: false }) }}
          destroyOnClose
        >
          <VerifyCard
            card={group.subButton}
            dict={dict}
            config={config}
            columns={config.columns}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
          />
        </Modal>
      </div>
    )
  }
}
const mapStateToProps = (state) => {
  return {
    menu: state.customMenu
  }
}
const mapDispatchToProps = () => {
  return {}
}
export default connect(mapStateToProps, mapDispatchToProps)(CardCellComponent)
src/menu/components/form/formaction/index.scss
New file
@@ -0,0 +1,17 @@
.mk-form-action {
  position: relative;
  text-align: center;
  padding-bottom: 10px;
  .prev {
    margin-right: 15px;
  }
  .submit {
    min-width: 70px;
    border: none;
  }
  .skip {
    position: absolute;
    right: 5px;
  }
}
src/menu/components/form/normal-form/groupform/index.jsx
New file
@@ -0,0 +1,126 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Radio, Select } from 'antd'
import { formRule } from '@/utils/option.js'
import './index.scss'
class SettingForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,     // 字典项
    group: PropTypes.object,    // 表单配置信息
    inputSubmit: PropTypes.any  // 回车提交事件
  }
  state = {
    fields: null,
    appType: sessionStorage.getItem('appType')
  }
  UNSAFE_componentWillMount () {
    const { group } = this.props
    let fields = []
    group.fields.forEach(f => {
      if (f.field && ['select', 'link', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
      }
    })
    this.setState({
      fields: fields
    })
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          resolve(values)
        } else {
          reject(err)
        }
      })
    })
  }
  handleSubmit = (e) => {
    e.preventDefault()
    if (this.props.inputSubmit) {
      this.props.inputSubmit()
    }
  }
  render() {
    const { group, dict } = this.props
    const { getFieldDecorator } = this.props.form
    const { fields } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    return (
      <Form {...formItemLayout} className="ant-advanced-search-form modal-setting-form">
        <Row gutter={24}>
          <Col span={12}>
            <Form.Item label="标题">
              {getFieldDecorator('title', {
                initialValue: group.setting.title,
                rules: [
                  {
                    max: formRule.input.max,
                    message: formRule.input.message
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="焦点">
              {getFieldDecorator('focus', {
                initialValue: group.setting.focus || ''
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                >
                  <Select.Option value="">
                    {dict['model.empty']}
                  </Select.Option>
                  {fields.map(option =>
                    <Select.Option id={option.uuid} title={option.label} key={option.uuid} value={option.field}>
                      {option.label}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="表单排列">
              {getFieldDecorator('align', {
                initialValue: group.setting.align || 'left_right'
              })(
                <Radio.Group>
                  <Radio value="left_right">左右</Radio>
                  <Radio value="up_down">上下</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
        </Row>
      </Form>
    )
  }
}
export default Form.create()(SettingForm)
src/menu/components/form/normal-form/groupform/index.scss
src/menu/components/form/normal-form/index.jsx
@@ -2,11 +2,14 @@
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import { is, fromJS } from 'immutable'
import { Icon, Popover, Modal, Carousel } from 'antd'
import { Icon, Popover, Modal, Button, Switch, notification } from 'antd'
import moment from 'moment'
import Api from '@/api'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { getModalForm } from '@/templates/zshare/formconfig'
import ModalForm from '@/templates/zshare/modalform'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/model.js'
@@ -15,10 +18,14 @@
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const WrapComponent = asyncIconComponent(() => import('@/menu/components/form/wrapsetting'))
const CardComponent = asyncComponent(() => import('../dragelement'))
const CardComponent = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
const FormTitle = asyncComponent(() => import('../dragtitle'))
const GroupForm = asyncComponent(() => import('./groupform'))
const FormAction = asyncComponent(() => import('../formaction'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
const { confirm } = Modal
@@ -32,7 +39,13 @@
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,
    back: false
    back: false,
    group: null,
    showField: false,
    visible: false,
    editform: null,
    formlist: null,
    sqlVerifing: false
  }
  UNSAFE_componentWillMount () {
@@ -59,10 +72,14 @@
        scripts: [],
        subcards: [{
          uuid: Utils.getuuid(),
          setting: {},
          setting: {title: '第一步', align: 'left_right'},
          sort: 1,
          style: {},
          fields: [],
        }],
          prevButton: {label: '上一步', type: 'prev'},
          subButton: {label: '提交', type: 'submit'},
          nextButton: {label: '跳过', type: 'next', enable: 'false'}
        }]
      }
      if (card.config) {
@@ -82,12 +99,15 @@
        })
      }
      this.setState({
        card: _card
        card: _card,
        group: _card.subcards[0] || null
      })
      this.props.updateConfig(_card)
    } else {
      let _card = fromJS(card).toJS()
      this.setState({
        card: fromJS(card).toJS()
        card: _card,
        group: _card.subcards[0] || null
      })
    }
  }
@@ -211,46 +231,361 @@
    let newcard = {
      uuid: Utils.getuuid(),
      setting: {},
      setting: { title: `第${card.subcards.length + 1}步`, align: 'left_right' },
      sort: card.subcards.length + 1,
      style: {},
      elements: [],
    }
    if (card.subcards.length > 0) {
      newcard = fromJS(card.subcards.slice(-1)[0]).toJS()
      newcard.uuid = Utils.getuuid()
      newcard.elements = newcard.elements.map(elem => {
        elem.uuid = Utils.getuuid()
        return elem
      })
      fields: [],
      prevButton: {label: '上一步', type: 'prev'},
      subButton: {label: '提交', type: 'submit'},
      nextButton: {label: '跳过', type: 'next', enable: 'false'}
    }
    card.subcards.push(newcard)
    
    this.setState({
      card,
      group: newcard,
      groupvisible: true
    })
    this.props.updateConfig(card)
  }
  changecards = (list) => {
    let card = fromJS(this.state.card).toJS()
    card.subcards = list.map((item, index) => {
      item.sort = index + 1
      return item
    })
    this.setState({card})
    this.props.updateConfig(card)
  }
  move = (item, direction) => {
  selectGroup = (item) => {
    this.setState({
      group: item
    })
  }
  changeGroup = (item) => {
    this.setState({
      group: item,
      groupvisible: true
    })
  }
  closeGroup = (cell) => {
    const { group } = this.state
    let card = fromJS(this.state.card).toJS()
    const _this = this
    confirm({
      content: '确定删除分组吗?',
      onOk() {
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        let _group = group
        if (group.uuid === cell.uuid) {
          _group = card.subcards[0] || null
        }
        _this.setState({card, group: _group})
        _this.props.updateConfig(card)
      },
      onCancel() {}
    })
  }
  updateGroup = (group) => {
    let card = fromJS(this.state.card).toJS()
    let dragIndex = card.subcards.findIndex(c => c.uuid === item.uuid)
    let hoverIndex = null
    card.subcards = card.subcards.map(item => {
      if (item.uuid === group.uuid) {
        return group
      }
      return item
    })
    if (direction === 'left') {
      hoverIndex = dragIndex - 1
    } else {
      hoverIndex = dragIndex + 1
    this.setState({card, group})
    this.props.updateConfig(card)
  }
  handleGroupSubmit = () => {
    const { group } = this.state
    this.groupRef.handleConfirm().then(res => {
      group.setting = res
      this.setState({groupvisible: false})
      this.updateGroup(group)
    })
  }
  changecols = (type) => {
    let card = fromJS(this.state.card).toJS()
    let config = fromJS(this.state.group).toJS()
    let _this = this
    config.fields = config.fields.map(item => {
      item.labelwidth = 33.3
      item.span = 24
      if (['textarea','split','hint','checkcard','brafteditor'].includes(item.type)) {
        if (type === 2) {
          item.labelwidth = 16.3
        } else if (type === 3) {
          item.labelwidth = 10.5
        } else if (type === 4) {
          item.labelwidth = 8.3
        }
      } else if (type === 2) {
        item.span = 12
      } else if (type === 3) {
        item.span = 8
      } else if (type === 4) {
        item.span = 6
      }
      return item
    })
    confirm({
      content: `确定切换为${type}列吗?`,
      onOk() {
        card.subcards = card.subcards.map(item => {
          if (item.uuid === config.uuid) {
            return config
          }
          return item
        })
        _this.setState({group: config, card})
        _this.props.updateConfig(card)
      },
      onCancel() {}
    })
  }
  handleList = (list) => {
    let group = fromJS(this.state.group).toJS()
    let card = fromJS(this.state.card).toJS()
    group.fields = list
    card.subcards = card.subcards.map(item => {
      if (item.uuid === group.uuid) {
        return group
      }
      return item
    })
    this.setState({card, group})
    this.props.updateConfig(card)
  }
  closeForm = (cell) => {
    let group = fromJS(this.state.group).toJS()
    let card = fromJS(this.state.card).toJS()
    let _this = this
    group.fields = group.fields.filter(item => item.uuid !== cell.uuid)
    card.subcards = card.subcards.map(item => {
      if (item.uuid === group.uuid) {
        return group
      }
      return item
    })
    confirm({
      content: `确定删除<<${cell.label}>>吗?`,
      onOk() {
        _this.setState({card, group})
        _this.props.updateConfig(card)
      },
      onCancel() {}
    })
  }
  addForm = () => {
    let group = fromJS(this.state.group).toJS()
    let lastItem = group.fields[group.fields.length - 1]
    let span = lastItem ? lastItem.span : 12
    let newcard = {
      uuid: Utils.getuuid(),
      label: '',
      field: '',
      initval: '',
      type: 'text',
      resourceType: '0',
      setAll: 'false',
      span: span,
      labelwidth: 33.3,
      options: [],
      dataSource: '',
      decimal: 0,
      orderType: 'asc',
      readonly: 'false',
      required: 'true',
      focus: true
    }
    if (hoverIndex === -1 || hoverIndex === card.subcards.length) return
    group.fields.push(newcard)
    card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
    this.setState({group})
    this.handleForm(newcard)
  }
    this.setState({card: {...card, subcards: []}}, () => {
      this.setState({card})
  editModalCancel = () => {
    let group = fromJS(this.state.group).toJS()
    group.fields = group.fields.filter(item => !item.focus)
    this.setState({group, visible: false, editform: null})
  }
  /**
   * @description 表单编辑
   */
  handleForm = (_item) => {
    const { card, group } = this.state
    let _form = fromJS(_item).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = [{
      value: '',
      text: '空'
    }]
    _inputfields = group.fields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
    _tabfields = group.fields.filter(item => _form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
    _tabfields.unshift({field: '', text: '原表单'})
    let uniq = new Map()
    uniq.set(_form.field, true)
    group.fields.forEach(item => {
      if (item.type !== 'select' && item.type !== 'link' && item.type !== 'radio') return
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
        _linkableFields.push({
          value: item.field,
          text: item.label + ' (表单)'
        })
        _linksupFields.push({
          value: item.field,
          text: item.label
        })
      }
    })
    this.props.updateConfig(card)
    card.columns.forEach(col => {
      if (col.field && !uniq.has(col.field)) {
        uniq.set(col.field, true)
        _linkableFields.push({
          value: col.field,
          text: col.label + ' (显示列)'
        })
      }
    })
    if (_form.linkSubField && _form.linkSubField.length > 0) {
      let fields = _inputfields.map(item => item.field)
      _form.linkSubField = _form.linkSubField.filter(item => fields.includes(item))
    }
    this.setState({
      visible: true,
      editform: _form,
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, false)
    })
  }
  /**
   * @description 编辑后提交
   * 1、获取编辑后的表单信息
   * 2、去除可能存在的示例表单
   * 3、通过loading刷新
   */
  handleSubmit = () => {
    this.formRef.handleConfirm().then(res => {
      let _config = fromJS(this.state.group).toJS()
      let fieldrepet = false // 字段重复
      let labelrepet = false // 提示文字重复
      _config.fields = _config.fields.map(item => {
        if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
          fieldrepet = true
        } else if (res.label && item.uuid !== res.uuid && item.label === res.label) {
          labelrepet = true
        }
        if (item.uuid === res.uuid) {
          return res
        } else {
          return item
        }
      })
      if (fieldrepet) {
        notification.warning({
          top: 92,
          message: '字段已存在!',
          duration: 10
        })
        return
      } else if (labelrepet) {
        notification.warning({
          top: 92,
          message: '名称已存在!',
          duration: 10
        })
        return
      }
      if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && 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,
              editform: null,
              visible: false
            })
            this.updateGroup(_config)
          } else {
            this.setState({sqlVerifing: false})
            Modal.error({
              title: result.message
            })
          }
        })
      } else {
        this.setState({
          editform: null,
          visible: false
        })
        this.updateGroup(_config)
      }
    })
  }
  clickComponent = (e) => {
@@ -261,7 +596,7 @@
  }
  render() {
    const { card } = this.state
    const { card, dict, group } = this.state
    return (
      <div className="menu-normal-form-edit-box" style={{...card.style}} onClick={this.clickComponent} id={card.uuid}>
@@ -280,9 +615,67 @@
        } trigger="hover">
          <Icon type="tool" />
        </Popover>
        {card.subcards.length > 0 ? <Carousel dotPosition={card.wrap.dotPosition || 'bottom'} effect={card.wrap.effect || 'scrollx'}>
          {card.subcards.map((subcard) => (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        </Carousel> : null}
        <FormTitle
          list={card.subcards}
          selectId={group ? group.uuid : ''}
          handleList={this.changecards}
          handleGroup={this.changeGroup}
          closeGroup={this.closeGroup}
          selectGroup={this.selectGroup}
        />
        {group ? <div className="form-area">
          <Icon className="plus" title="添加表单" onClick={this.addForm} type="plus" />
          <FieldsComponent config={group} type="form" updatefield={this.updateGroup} />
          <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button>
          <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button>
          <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button>
          <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</Button>
          <div style={{clear: 'both'}}></div>
          <CardComponent
            list={group.fields}
            setting={group.setting}
            showField={this.state.showField}
            placeholder={dict['header.form.modal.placeholder']}
            handleList={this.handleList}
            handleForm={this.handleForm}
            closeForm={this.closeForm}
          />
          <FormAction config={card} group={group} updateconfig={this.updateGroup}/>
        </div> : null}
        <Modal
          title="分组编辑"
          visible={this.state.groupvisible}
          width={850}
          maskClosable={false}
          onCancel={() => this.setState({groupvisible: false})}
          onOk={this.handleGroupSubmit}
          destroyOnClose
        >
          <GroupForm
            dict={dict}
            group={group}
            inputSubmit={this.handleGroupSubmit}
            wrappedComponentRef={(inst) => this.groupRef = inst}
          />
        </Modal>
        <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.editform}
            formlist={this.state.formlist}
            inputSubmit={this.handleSubmit}
            wrappedComponentRef={(inst) => this.formRef = inst}
          />
        </Modal>
      </div>
    )
  }
src/menu/components/form/normal-form/index.scss
@@ -28,57 +28,43 @@
    background: rgba(255, 255, 255, 0.55);
  }
  .card-item {
    overflow: hidden;
  .page-card {
    position: relative;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    min-height: 20px;
    height: 100%;
    background: #ffffff;
    border-radius: 2px;
    margin-bottom: 15px;
  }
  .ant-carousel:not(.ant-carousel-vertical) {
    .slick-dots li button {
      height: 8px;
    }
  }
  .ant-carousel.ant-carousel-vertical {
    .slick-dots li button {
      width: 8px;
    }
  }
  .ant-carousel {
    .slick-dots li button {
      background: #1890ff;
    }
  }
  .card-item:hover {
    box-shadow: 0px 0px 2px #1890ff;
  }
  .model-menu-card-cell-list .card-detail-row > .anticon-plus {
    position: absolute;
    right: -30px;
    font-size: 16px;
  }
  .model-menu-action-list {
    line-height: 40px;
    .ant-row > .anticon-plus {
      position: absolute;
      right: -30px;
      font-size: 16px;
    }
  }
  .card-add-button {
    text-align: right;
    clear: left;
    .anticon-plus {
      font-size: 20px;
  .form-area {
    position: relative;
    >.plus {
      color: #26C281;
      padding: 5px;
      cursor: pointer;
      padding: 4px 10px;
    }
    >button {
      float: right;
      margin-right: 10px;
    }
    >.mk-cols-change {
      height: 24px;
      padding: 0 10px;
    }
    >.quickly-add {
      display: inline-block;
      margin-left: 10px;
      button {
        color: #1890ff;
        background: transparent;
        border: none;
        box-shadow: none;
        padding: 0;
        height: 24px;
      }
    }
    .modal-fields-row {
      padding-top: 10px;
      padding-bottom: 30px;
    }
  }
}
.menu-normal-form-edit-box::after {
src/menu/components/form/wrapsetting/index.jsx
@@ -58,7 +58,7 @@
        <Icon type="edit" title="编辑" onClick={() => this.editDataSource()} />
        <Modal
          wrapClassName="popview-modal"
          title={config.type === 'table' ? '表格设置' : '卡片设置'}
          title="表单设置"
          visible={visible}
          width={800}
          maskClosable={false}
src/menu/components/form/wrapsetting/settingform/index.jsx
@@ -53,7 +53,7 @@
  }
  render() {
    const { wrap, config } = this.props
    const { wrap } = this.props
    const { getFieldDecorator } = this.props.form
    const { roleList } = this.state
@@ -72,13 +72,6 @@
      <div className="model-menu-setting-form">
        <Form {...formItemLayout}>
          <Row gutter={24}>
            <Col span={12}>
              <Form.Item label="标题">
                {getFieldDecorator('title', {
                  initialValue: wrap.title || ''
                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="用于组件间的区分。">
@@ -115,11 +108,11 @@
                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col>
            {config.subtype === 'propcard' ? <Col span={12}>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="选择静态值,无需配置数据源。">
                <Tooltip placement="topLeft" title="初始值来源于数据源或表单默认值。">
                  <Icon type="question-circle" />
                  数据来源
                  初始值
                </Tooltip>
              }>
                {getFieldDecorator('datatype', {
@@ -131,101 +124,7 @@
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype === 'datacard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="数据源中选择分页时有效。">
                  <Icon type="question-circle" />
                  分页风格
                </Tooltip>
              }>
                {getFieldDecorator('pagestyle', {
                  initialValue: wrap.pagestyle || 'page'
                })(
                  <Radio.Group>
                    <Radio value="page">页码</Radio>
                    <Radio value="switch">左右切换</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype !== 'tablecard' ? <Col span={12}>
              <Form.Item label="卡片属性">
                {getFieldDecorator('cardType', {
                  initialValue: wrap.cardType || ''
                })(
                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
                    <Radio key="" value=""> 不可选 </Radio>
                    <Radio key="radio" value={'radio'}> 单选 </Radio>
                    {config.subtype !== 'propcard' ? <Radio key="checkbox" value={'checkbox'}> 多选 </Radio> : null}
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype !== 'tablecard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="设置为居中对齐或右对齐,只在卡片为1行时有效。">
                  <Icon type="question-circle" />
                  卡片排列
                </Tooltip>
              }>
                {getFieldDecorator('cardFloat', {
                  initialValue: wrap.cardFloat || 'left'
                })(
                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
                    <Radio key="left" value="left"> 左对齐 </Radio>
                    <Radio key="center" value="center"> 居中 </Radio>
                    <Radio key="right" value="right"> 右对齐 </Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype !== 'tablecard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="鼠标悬浮于卡片上方时,卡片放大1.05倍。">
                  <Icon type="question-circle" />
                  卡片放大
                </Tooltip>
              }>
                {getFieldDecorator('scale', {
                  initialValue: wrap.scale || 'false'
                })(
                  <Radio.Group>
                    <Radio key="false" value="false"> 否 </Radio>
                    <Radio key="true" value="true"> 是 </Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype === 'tablecard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="表格高度,超出时滚动,高度为空时根据内容自适应。">
                  <Icon type="question-circle" />
                  高度
                </Tooltip>
              }>
                {getFieldDecorator('height', {
                  initialValue: wrap.height
                })(<InputNumber min={100} max={2000} precision={0} onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col> : null}
            {config.subtype === 'propcard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="选择类型为《页眉/页脚》时,打印的每页里都会带有该组件。">
                  <Icon type="question-circle" />
                  组件类型
                </Tooltip>
              }>
                {getFieldDecorator('printType', {
                  initialValue: wrap.printType || 'content'
                })(
                  <Radio.Group>
                    <Radio value="content">内容</Radio>
                    <Radio value="headerOrfooter">页眉/页脚</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            </Col>
            <Col span={12}>
              <Form.Item label="黑名单">
                {getFieldDecorator('blacklist', {
src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -19,7 +19,7 @@
  funcbutton: ['label', 'OpenType', 'funcType', 'show', 'icon', 'class', 'width']
}
class MainSearch extends Component {
class ActionForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,      // 字典项
    type: PropTypes.any,         // type为"card"时,只可选单行或不选行
@@ -474,6 +474,14 @@
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'tip') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {item}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
@@ -678,4 +686,4 @@
  }
}
export default Form.create()(MainSearch)
export default Form.create()(ActionForm)
src/menu/components/share/actioncomponent/index.jsx
@@ -352,19 +352,10 @@
      }
      if (btn.OpenType === 'pop') {
        let fields = []
        if (btn.groups.length > 0) {
          btn.groups.forEach(group => {
            fields = [...fields, ...group.sublist]
          })
        } else {
          fields = btn.fields
        }
        let _param = {
          funcName: btn.innerFunc,
          name: _config.setting.tableName || '',
          fields: fields,
          fields: btn.fields,
          menuNo: menu.MenuNo
        }
        newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config))
@@ -494,7 +485,6 @@
          visible={profVisible}
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={dict['model.submit']}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ profVisible: false }) }}
src/menu/components/share/markcomponent/index.jsx
@@ -313,7 +313,6 @@
          visible={visible}
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={dict['model.submit']}
          onOk={this.markSubmit}
          onCancel={() => { this.setState({ visible: false }) }}
src/menu/datasource/index.jsx
@@ -122,7 +122,6 @@
          visible={visible}
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={dict['model.submit']}
          onOk={this.verifySubmit}
          confirmLoading={loading}
src/menu/datasource/verifycard/settingform/index.jsx
@@ -408,11 +408,11 @@
              <Form.Item label={
                <Tooltip placement="topLeft" title={'优先使用同级的搜索条件组件,同级搜索不存在时,依次向上选取,与当前组件的搜索条件一同用作数据过滤(当前组件的搜索条件优先)。'}>
                  <Icon type="question-circle" />
                  外层搜索
                  外部搜索
                </Tooltip>
              }>
                {getFieldDecorator('useMSearch', {
                  initialValue: setting.useMSearch || 'false'
                  initialValue: setting.useMSearch || 'true'
                })(
                  <Radio.Group onChange={(e) => this.setState({useMSearch: e.target.value})}>
                    <Radio value="true">使用</Radio>
src/menu/datasource/verifycard/settingform/index.scss
@@ -21,4 +21,7 @@
  .ant-input-number {
    width: 100%;
  }
  .ant-radio-group {
    white-space: nowrap;
  }
}
src/menu/modalconfig/index.jsx
@@ -5,7 +5,7 @@
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import moment from 'moment'
import { Button, Card, Modal, Collapse, notification, Icon, Empty, Popover } from 'antd'
import { Button, Card, Modal, Collapse, notification, Icon, Switch } from 'antd'
import Api from '@/api'
import Utils from '@/utils/utils.js'
@@ -14,11 +14,8 @@
import { getModalForm } from '@/templates/zshare/formconfig'
import ModalForm from '@/templates/zshare/modalform'
import DragElement from '@/templates/modalconfig/dragelement'
import SourceElement from '@/templates/modalconfig/dragelement/source'
import SettingForm from '@/templates/modalconfig/settingform'
import GroupForm from '@/templates/modalconfig/groupform'
import EditCard from '@/templates/modalconfig/editcard'
import asyncComponent from '@/utils/asyncComponent'
import { SearchItems } from '@/templates/modalconfig/source'
import './index.scss'
@@ -27,6 +24,8 @@
const { confirm } = Modal
const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
const DragElement = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
class ComModalConfig extends Component {
  static propTpyes = {
@@ -51,11 +50,10 @@
    tables: [],            // 可用表名
    selectedTables: [],    // 已选表名
    originConfig: null,    // 原始菜单
    groupVisible: false,   // 全局配置模态框
    curgroup: null,        // 当前组,新建或编辑
    sources: null,         // 表单类型
    sqlVerifing: false,    // sql验证
    openEdition: ''        // 编辑版本标记,防止多人操作
    openEdition: '',       // 编辑版本标记,防止多人操作
    showField: false       // 显示表单字段值
  }
  /**
@@ -65,20 +63,12 @@
    const { btn } = this.props
    let _config = btn.modal
    _config.version = '1.0'
    this.setState({
      config: _config,
      originConfig: fromJS(_config).toJS()
    })
  }
  /**
   * @description 获取数据表信息
   * 1、获取系统中全部表名
   * 2、根据已选表名,获取表格字段列表
   */
  componentDidMount () {
  }
  /**
@@ -96,78 +86,20 @@
   * 2、表单移动后,保存移动后的顺序
   * 3、新增表单时,直接打开编辑框
   */
  handleList = (list, group, elementId, newcard) => {
  handleList = (list, newcard) => {
    let _config = fromJS(this.state.config).toJS()
    if (!group && !elementId) {
      // 没有分组时(拖拽添加)
      if (list.length > _config.fields.length) {
        _config.fields = list.filter(item => !item.origin)
        this.setState({
          config: _config
        }, () => {
          this.handleForm(newcard)
        })
      } else {
        _config.fields = list
        this.setState({config: _config})
      }
    } else if (group && !elementId) {
      // 存在分组时,拖拽添加
      if (list.length > group.sublist.length) {
        group.sublist = list
        _config.groups = _config.groups.map(item => {
          if (item.uuid === group.uuid) {
            return group
          } else {
            return item
          }
        })
        this.setState({
          config: _config
        }, () => {
          this.handleForm(newcard)
        })
      } else {
        group.sublist = list
        _config.groups = _config.groups.map(item => {
          if (item.uuid === group.uuid) {
            return group
          } else {
            return item
          }
        })
        this.setState({config: _config})
      }
    } else if (group && elementId) {
      // 修改已有元素的分组
      let element = null
      _config.groups.forEach(item => {
        item.sublist = item.sublist.filter(cell => {
          if (cell.uuid !== elementId) {
            return true
          } else {
            element = cell
            return false
          }
        })
      })
      group.sublist.push(element)
      _config.groups = _config.groups.map(item => {
        if (item.uuid === group.uuid) {
          return group
        } else {
          return item
        }
      })
    if (list.length > _config.fields.length) {
      _config.fields = list.filter(item => !item.origin)
      this.setState({
        config: _config
      }, () => {
        this.handleForm(newcard)
      })
    } else {
      _config.fields = list
      this.setState({config: _config})
    }
  }
@@ -188,24 +120,14 @@
      value: '',
      text: '空'
    }]
    let _formfields = []
    // 设置下拉菜单可关联字段(上级与下级)
    if (config.groups.length > 0) {
      config.groups.forEach(group => {
        _formfields = [..._formfields, ...group.sublist]
      })
    } else {
      _formfields = config.fields
    }
    _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
    _tabfields = _formfields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
    _inputfields = config.fields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
    _tabfields = config.fields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
    _tabfields.unshift({field: '', text: '原表单'})
    let uniq = new Map()
    uniq.set(card.field, true)
    _formfields.forEach(item => {
    config.fields.forEach(item => {
      if (item.type !== 'select' && item.type !== 'link' && item.type !== 'radio') return
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
@@ -256,37 +178,19 @@
      let fieldrepet = false // 字段重复
      let labelrepet = false // 提示文字重复
      if (_config.groups.length > 0) {
        _config.groups.forEach(group => {
          group.sublist = group.sublist.map(item => {
            if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
              fieldrepet = true
            } else if (item.uuid !== res.uuid && item.label === res.label) {
              labelrepet = true
            }
      _config.fields = _config.fields.map(item => {
        if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
          fieldrepet = true
        } else if (res.label && item.uuid !== res.uuid && item.label === res.label) {
          labelrepet = true
        }
            if (item.uuid === res.uuid) {
              return res
            } else {
              return item
            }
          })
        })
      } else {
        _config.fields = _config.fields.map(item => {
          if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
            fieldrepet = true
          } else if (item.uuid !== res.uuid && item.label === res.label) {
            labelrepet = true
          }
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
      }
        if (item.uuid === res.uuid) {
          return res
        } else {
          return item
        }
      })
      if (fieldrepet) {
        notification.warning({
@@ -363,14 +267,7 @@
      content: `确定删除<<${card.label}>>吗?`,
      onOk() {
        let _config = fromJS(_this.state.config).toJS()
        if (_config.groups.length > 0) {
          _config.groups.forEach(group => {
            group.sublist = group.sublist.filter(item => !(item.uuid === card.uuid))
          })
        } else {
          _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
        }
        _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
        _this.setState({
          config: _config,
@@ -399,173 +296,6 @@
  }
  /**
   * @description 通过表字段添加表单
   * 1、检查是否已选表名,为选时警告提示
   * 2、表字段名通过map去重
   * 3、检查表单中的已选字段,并标记已选
   */
  queryField = () => {
    const { config } = this.state
    if (window.GLOB.tableFields.length === 0) {
      notification.warning({
        top: 92,
        message: '请选择表名!',
        duration: 10
      })
      return
    }
    let columns = new Map()
    window.GLOB.tableFields.forEach(table => {
      table.columns.forEach(column => {
        columns.set(column.field, column)
      })
    })
    if (config.groups.length > 1) {
      config.groups.forEach(group => {
        group.sublist.forEach(item => {
          if (columns.has(item.field)) {
            columns.set(item.field, {...item, selected: true})
          }
        })
      })
    } else {
      config.fields.forEach(item => {
        if (columns.has(item.field)) {
          columns.set(item.field, {...item, selected: true})
        }
      })
    }
    this.setState({
      tableVisible: true,
      fields: [...columns.values()]
    })
  }
  /**
   * @description 选择字段后提交
   * 1、没有可选字段时,直接关闭
   * 2、获取已选字段
   * 3、与已有字段对比
   * 4、添加新增字段
   */
  addFieldSubmit = () => {
    if (!this.state.fields || this.state.fields.length === 0) {
      this.setState({
        tableVisible: false
      })
    }
    let _config = fromJS(this.state.config).toJS()
    let cards = this.refs.searchcard.state.selectCards
    let columns = new Map()
    cards.forEach(card => {
      columns.set(card.field, card)
    })
    if (_config.groups.length > 1) {
      _config.groups.forEach(group => {
        let items = []
        group.sublist.forEach(item => {
          if (columns.has(item.field)) {
            let cell = columns.get(item.field)
            if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加
              items.push(item)
            } else if (cell.selected) {                     // 数据类型修改时,重置类型及初始值
              item.type = cell.type
              item.initval = ''
              items.push(item)
            }
            columns.delete(item.field)
          } else if (!item.origin) {                        // 过滤示例项
            items.push(item)
          }
        })
        group.sublist = items
      })
      let _columns = [...columns.values()]
      let _additems = _columns.map(item => { // 循环添加新增字段
        return {
          uuid: Utils.getuuid(),
          label: item.label,
          field: item.field,
          initval: '',
          type: item.type,
          resourceType: '0',
          setAll: 'false',
          options: [],
          orderType: 'asc',
          decimal: 0,
          min: '',
          max: '',
          readonly: 'false',
          required: 'true'
        }
      })
      _config.groups[_config.groups.length - 1].sublist = [..._config.groups.slice(-1)[0].sublist, ..._additems]
    } else {
      let items = []
      _config.fields.forEach(item => {
        if (columns.has(item.field)) {
          let cell = columns.get(item.field)
          if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加
            items.push(item)
          } else if (cell.selected) {                     // 数据类型修改时,重置类型及初始值
            item.type = cell.type
            item.initval = ''
            items.push(item)
          }
          columns.delete(item.field)
        } else if (!item.origin) {                        // 过滤示例项
          items.push(item)
        }
      })
      let _columns = [...columns.values()]
      _columns.forEach(item => { // 循环添加新增字段
        if (item.selected) {
          let newcard = {
            uuid: Utils.getuuid(),
            label: item.label,
            field: item.field,
            initval: '',
            type: item.type,
            resourceType: '0',
            setAll: 'false',
            options: [],
            orderType: 'asc',
            readonly: 'false',
            required: 'true'
          }
          items.push(newcard)
        }
      })
      _config.fields = items
    }
    this.setState({
      config: _config
    })
    notification.success({
      top: 92,
      message: '添加成功',
      duration: 2
    })
  }
  /**
   * @description 全局设置模态框
   */
  changeSetting = () => {
@@ -587,115 +317,12 @@
    })
  }
  handleGroup = (group) => {
    let curgroup = ''
    if (group) {
      curgroup = group
    } else {
      curgroup = {
        isnew: true,
        label: '',
        default: false,
        uuid: Utils.getuuid(),
        sublist: []
      }
    }
    this.setState({
      groupVisible: true,
      curgroup: curgroup
    })
  }
  closeGroup = (group) => {
    let _this = this
    confirm({
      content: `确定删除分组<<${group.label}>>吗?`,
      onOk() {
        let _config = fromJS(_this.state.config).toJS()
        _config.groups = _config.groups.filter(item => !(item.uuid === group.uuid))
        let _length = _config.groups.length
        if (_length === 1) {
          _config.fields = [...group.sublist, ..._config.groups[0].sublist]
          _config.groups = []
        } else {
          _config.groups[_length - 1].sublist = [...group.sublist, ..._config.groups[_length - 1].sublist]
        }
        _this.setState({
          config: _config
        })
      },
      onCancel() {}
    })
  }
  handleGroupSave = () => {
    let _group = fromJS(this.state.curgroup).toJS()
    let config = fromJS(this.state.config).toJS()
    this.groupRef.handleConfirm().then(res => {
      _group = {..._group, ...res.target}
      if (_group.isnew) {
        delete _group.isnew
        config.groups.unshift(_group)
        if (config.groups.length > 1) {
          config.groups = config.groups.map(item => {
            if (item.default) {
              return res.default
            } else {
              return item
            }
          })
        } else {
          config.groups.push(res.default)
        }
      } else {
        config.groups = config.groups.map(item => {
          if (item.uuid === _group.uuid) {
            return _group
          } else if (item.default) {
            return res.default
          } else {
            return item
          }
        })
      }
      config.fields = []
      config.groups = config.groups.sort((a, b) => {
        return a.sort - b.sort
      })
      this.setState({
        groupVisible: false,
        curgroup: '',
        config: config
      })
    })
  }
  editModalCancel = () => {
    const { config, card } = this.state
    if (card.focus) {
      let _config = null
      if (config.groups.length > 0) {
        let _groups = config.groups.map(group => {
          group.sublist = group.sublist.filter(item => item.uuid !== card.uuid)
          return group
        })
        _config = {...config, groups: _groups}
      } else {
        let _fields = config.fields.filter(item => item.uuid !== card.uuid)
        _config = {...config, fields: _fields}
      }
      let _fields = config.fields.filter(item => item.uuid !== card.uuid)
      let _config = {...config, fields: _fields}
      this.setState({
        card: null,
@@ -711,91 +338,99 @@
  }
  /**
   * @description 编辑功能完成更新,包括解冻按钮、粘贴、替换等
   * @description 更新
   */
  updateConfig = (res) => {
    if (res.type === 'paste') {
      this.setState({
        config: res.config
      })
    }
  updateConfig = (config) => {
    this.setState({
      config
    })
  }
  changecols = (type) => {
    let config = fromJS(this.state.config).toJS()
    let _this = this
    config.fields = config.fields.map(item => {
      item.labelwidth = 33.3
      item.span = 24
      if (['textarea','split','hint','checkcard','brafteditor'].includes(item.type)) {
        if (type === 2) {
          item.labelwidth = 16.3
        } else if (type === 3) {
          item.labelwidth = 10.5
        } else if (type === 4) {
          item.labelwidth = 8.3
        }
      } else if (type === 2) {
        item.span = 12
      } else if (type === 3) {
        item.span = 8
      } else if (type === 4) {
        item.span = 6
      }
      return item
    })
    confirm({
      content: `确定切换为${type}列吗?`,
      onOk() {
        _this.setState({config})
      },
      onCancel() {}
    })
  }
  render () {
    const { config } = this.state
    const { config, dict } = this.state
    return (
      <div className="modal-form-board">
        <DndProvider backend={HTML5Backend}>
          <div className="tools">
            <Collapse accordion defaultActiveKey="1" bordered={false}>
              <Panel header={this.state.dict['header.menu.form']} key="1">
              <Panel header={dict['header.menu.form']} key="1">
                <div className="search-element">
                  {SearchItems.map((item, index) => {
                    return (<SourceElement key={index} content={item}/>)
                  })}
                </div>
                <Button type="primary" block onClick={() => this.queryField()}>{this.state.dict['model.batchAdd']}</Button>
                <Button type="primary" block onClick={() => this.handleGroup()}>{this.state.dict['header.menu.group.add']}</Button>
                <FieldsComponent
                  config={config}
                  type="form"
                  updatefield={this.updateConfig}
                />
              </Panel>
            </Collapse>
          </div>
          <div className="setting">
            <Card title={this.state.dict['header.menu.form.configurable']} bordered={false} extra={
            <Card title={dict['header.menu.form.configurable']} bordered={false} extra={
              <div>
                <EditComponent dict={this.state.dict} options={['form']} config={this.state.config} refresh={this.updateConfig}/>
                <Button type="primary" onClick={this.submitConfig}>{this.state.dict['model.confirm']}</Button>
                <Button onClick={this.cancelConfig}>{this.state.dict['model.cancel']}</Button>
                <EditComponent dict={dict} options={['form']} config={this.state.config} refresh={(res) => this.updateConfig(res.config)}/>
                <Button type="primary" onClick={this.submitConfig}>{dict['model.confirm']}</Button>
                <Button onClick={this.cancelConfig}>{dict['model.cancel']}</Button>
              </div>
            } style={{ width: '100%' }}>
              <Icon type="setting" onClick={this.changeSetting} />
              <div className="ant-modal-content" style={{width: config.setting.width + '%'}}>
                <button type="button" className="ant-modal-close">
                  <span className="ant-modal-close-x"><Icon type="close"/></span>
                </button>
                <div className="ant-modal-header">
                  <div className="ant-modal-title">{config.setting.title}</div>
                  <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</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="ant-modal-body">
                  <div className="modal-form">
                    {config.groups.length > 0 &&
                      config.groups.map(group => {
                        return (
                          <div key={group.uuid}>
                            <div className="group-title">
                              {!group.default ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                                <div className="mk-popover-control">
                                  <Icon className="edit" type="edit" onClick={() => {this.handleGroup(group)}} />
                                  <Icon className="edit close" type="close" onClick={() => {this.closeGroup(group)}} />
                                </div>
                              } trigger="hover">
                                <span>{group.label}</span>
                              </Popover> : null}
                              {group.default ? <span style={{color: '#bcbcbc'}}>{group.label}</span> : null}
                            </div>
                            <DragElement
                              group={group}
                              list={group.sublist}
                              setting={config.setting}
                              placeholder={this.state.dict['header.form.modal.placeholder']}
                              handleList={this.handleList}
                              handleForm={this.handleForm}
                              closeForm={this.closeForm}
                            />
                          </div>
                        )
                      })
                    }
                    {config.groups.length === 0 ?
                      <DragElement
                        list={config.fields}
                        setting={config.setting}
                        placeholder={this.state.dict['header.form.modal.placeholder']}
                        handleList={this.handleList}
                        handleForm={this.handleForm}
                        closeForm={this.closeForm}
                      /> : null
                    }
                    <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}
                    />
                  </div>
                </div>
                <div className="ant-modal-footer">
@@ -831,25 +466,6 @@
          />
        </Modal>
        <Modal
          wrapClassName="modal-fields"
          title={this.state.dict['model.edit']}
          visible={this.state.tableVisible}
          width={'65vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          onOk={this.addFieldSubmit}
          cancelText={this.state.dict['model.close']}
          onCancel={() => { this.setState({ tableVisible: false }) }}
          destroyOnClose
        >
          {this.state.fields && this.state.fields.length > 0 ?
            <EditCard data={this.state.fields} ref="searchcard" type="search" /> : null
          }
          {(!this.state.fields || this.state.fields.length === 0) &&
            <Empty />
          }
        </Modal>
        <Modal
          title={this.state.dict['model.edit']}
          visible={this.state.settingVisible}
          width={700}
@@ -880,23 +496,6 @@
          destroyOnClose
        >
          {this.state.dict['header.menu.config.placeholder']}
        </Modal>
        <Modal
          title={this.state.dict['header.menu.group.manage']}
          visible={this.state.groupVisible}
          width={700}
          maskClosable={false}
          onOk={this.handleGroupSave}
          onCancel={() => { this.setState({ groupVisible: false }) }}
          destroyOnClose
        >
          <GroupForm
            config={config}
            dict={this.state.dict}
            group={this.state.curgroup}
            inputSubmit={this.handleGroupSave}
            wrappedComponentRef={(inst) => this.groupRef = inst}
          />
        </Modal>
      </div>
    )
src/menu/modalconfig/index.scss
@@ -136,6 +136,20 @@
          z-index: 10;
          background: transparent;
          min-height: 50px;
          padding-right: 75px;
          .ant-modal-title {
            display: inline-block;
          }
          .ant-switch {
            position: absolute;
            top: 15px;
            right: 10px;
          }
          .mk-cols-change {
            float: right;
            height: 25px;
            margin-right: 10px;
          }
        }
        .ant-modal-close {
          opacity: 0.3;
src/mob/datasource/index.jsx
@@ -139,7 +139,6 @@
          visible={visible}
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={dict['mob.submit']}
          onOk={this.verifySubmit}
          confirmLoading={loading}
src/pc/menushell/card.jsx
@@ -13,6 +13,7 @@
const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox'))
const NormalNavbar = asyncComponent(() => import('@/pc/components/navbar/normal-navbar'))
@@ -61,6 +62,8 @@
      return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'navbar') {
      return (<NormalNavbar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'form') {
      return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'search') {
      return (<MainSearch card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'pie') {
src/pc/modulesource/option.jsx
@@ -17,6 +17,7 @@
import Navbar from '@/assets/mobimg/navbar.png'
import Carousel from '@/assets/mobimg/carousel.png'
import Carousel1 from '@/assets/mobimg/carousel1.png'
import form from '@/assets/mobimg/form.png'
// 组件配置信息
export const menuOptions = [
@@ -25,6 +26,7 @@
  { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '搜索条件', width: 24 },
  { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '数据卡', width: 24 },
  { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '属性卡', width: 24 },
  { type: 'menu', url: form, component: 'form', subtype: 'form', title: '表单', width: 24 },
  { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '轮播-动态数据', width: 24 },
  { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '轮播-静态数据', width: 24 },
  { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '常用表', width: 24 },
src/tabviews/scriptmanage/actionList/index.jsx
@@ -2,13 +2,15 @@
import PropTypes from 'prop-types'
import moment from 'moment'
import { Button, Modal, notification, message } from 'antd'
import MutilForm from '@/tabviews/zshare/mutilform'
import asyncSpinComponent from '@/utils/asyncSpinComponent'
import options from '@/store/options.js'
import Utils from '@/utils/utils.js'
import Api from '@/api'
import './index.scss'
const { confirm } = Modal
const MutilForm = asyncSpinComponent(() => import('@/tabviews/zshare/mutilform'))
class MainAction extends Component {
  static propTpyes = {
src/tabviews/scriptmanage/config.jsx
@@ -58,12 +58,11 @@
    tables:[
      {"TbName":"s_custom_script","Remark":"自定义脚本"}
    ],
    groups:[],
    fields:[
      {"label":"函数","field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"funcname","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"},
      {"label":"排序","field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"15870101796149403f2pqfpviuo415m2"},
      {"label":"描述","field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"},
      {"label":"脚本","field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","encryption":"true","hidden":"false","readin":"true","fieldlength":12000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"}
      {"label":"函数",span:12,labelwidth: 33.3,"field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"funcname","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"},
      {"label":"排序",span:12,labelwidth: 33.3,"field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"15870101796149403f2pqfpviuo415m2"},
      {"label":"描述",span:24,labelwidth: 16.3,"field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"},
      {"label":"脚本",span:24,labelwidth: 16.3,"field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","encryption":"true","hidden":"false","readin":"true","fieldlength":12000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"}
    ]
  },
  '1587007258155ut4nbggg4r66t9uhut2': {
@@ -79,12 +78,11 @@
      "display":"modal"
    },
    tables: [{"TbName":"s_custom_script","Remark":"自定义脚本"}],
    groups: [],
    fields: [
      {"label":"函数","field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"funcname","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"},
      {"label":"排序","field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"1587010196675i9m6ie3tv9kg2rhgfi0"},
      {"label":"描述","field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"},
      {"label":"脚本","field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","encryption":"true","hidden":"false","readin":"true","fieldlength":12000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"}
      {"label":"函数",span:12,labelwidth: 33.3,"field":"func","type":"text","initval":"","readonly":"false","required":"true","hidden":"false","readin":"true","fieldlength":50,"regular":"funcname","supField":"","blacklist":[],"uuid":"1587006164634l397q15t49u2pfq02f5"},
      {"label":"排序",span:12,labelwidth: 33.3,"field":"Sort","type":"number","initval":0,"decimal":0,"min":"","max":"","readonly":"false","hidden":"false","readin":"true","supField":"","blacklist":[],"uuid":"1587010196675i9m6ie3tv9kg2rhgfi0"},
      {"label":"描述",span:24,labelwidth: 16.3,"field":"Remark","type":"textarea","initval":"","readonly":"false","required":"false","hidden":"false","readin":"true","fieldlength":512,"maxRows":6,"supField":"","blacklist":[],"uuid":"1587006199263k8hm45cmtomgu6hd881"},
      {"label":"脚本",span:24,labelwidth: 16.3,"field":"LongParam","type":"textarea","initval":"","readonly":"false","required":"true","encryption":"true","hidden":"false","readin":"true","fieldlength":12000,"maxRows":20,"supField":"","blacklist":[],"uuid":"1587006209935qbkle15h4d9i9lg9tcu"}
    ]
  }
}
src/tabviews/verupmanage/actionList/index.jsx
@@ -2,13 +2,16 @@
import PropTypes from 'prop-types'
import moment from 'moment'
import { Button, Modal, notification, message } from 'antd'
import MutilForm from '@/tabviews/zshare/mutilform'
import asyncSpinComponent from '@/utils/asyncSpinComponent'
import Utils, { getSysDefaultSql } from '@/utils/utils.js'
import options from '@/store/options.js'
import { updateForm } from '@/utils/utils-update.js'
import Api from '@/api'
import './index.scss'
const { confirm } = Modal
const MutilForm = asyncSpinComponent(() => import('@/tabviews/zshare/mutilform'))
class MainAction extends Component {
  static propTpyes = {
@@ -109,6 +112,7 @@
        this.setState({loadingUuid: ''})
      })
    } else if (item.OpenType === 'pop') {
      item = updateForm(item)
      if (item.setting.display === 'prompt') { // 如果表单以是否框展示,不请求下拉菜单信息
        this.setState({
          execAction: item,
@@ -648,17 +652,10 @@
    const { BData } = this.props
    const { execAction, tabledata } = this.state
    let _this = this
    let _fields = []
    if (execAction.groups.length > 0) {
      execAction.groups.forEach(group => {
        _fields = [..._fields, ...group.sublist]
      })
    } else {
      _fields = execAction.fields
    }
    let result = _fields.map(item => {
    let result = []
    execAction.fields.forEach(item => {
      if (!item.field) return
      let _readin = item.readin !== 'false'
      let _initval = item.initval
@@ -679,14 +676,14 @@
        _fieldlen = item.decimal ? item.decimal : 0
      }
      return {
      result.push({
        key: item.field,
        readonly: item.readonly === 'true',
        readin: _readin,
        fieldlen: _fieldlen,
        type: item.type,
        value: _initval
      }
      })
    })
    confirm({
src/tabviews/verupmanage/config.jsx
@@ -55,11 +55,11 @@
export const buttonConfig = {
  '1583979660949vpssdb2p2lsqff9abkr': {
    type: 'Modal',
    setting:{title: '添加',width:45,focus:'VersionName',cols:'1',finish:'close',clickouter:'unclose',container:'tab',display:'modal'},
    version: '1.0',
    setting:{title: '添加',width:45,focus:'VersionName',finish:'close',clickouter:'unclose',container:'tab',display:'modal'},
    tables:[],
    groups:[],
    fields:[
      {label:'传输号',field:'VersionName',type:'text',initval:'',regular:'letter&number',readonly:'false',required:'true',hidden:'false',fieldlength:20,readin:'true',uuid:'1581738428097qgoe876i5u0866373uu'}
      {label:'传输号',field:'VersionName',span:24,labelwidth: 33.3,type:'text',initval:'',regular:'letter&number',readonly:'false',required:'true',hidden:'false',fieldlength:20,readin:'true',uuid:'1581738428097qgoe876i5u0866373uu'}
    ]
  },
  '1583983849299g1qfd28g3c9n9e0e57a': {
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -11,6 +11,7 @@
import zhCN from '@/locales/zh-CN/main.js'
import enUS from '@/locales/en-US/main.js'
import asyncSpinComponent from '@/utils/asyncSpinComponent'
import { updateForm } from '@/utils/utils-update.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
@@ -1404,52 +1405,24 @@
  handleModelConfig = (config) => {
    let roleId = sessionStorage.getItem('role_id') || '' // 角色ID
    if (config.groups.length > 0) {
      config.groups.forEach(group => {
        group.sublist = group.sublist.map(cell => {
          // 数据源sql语句,预处理, 权限黑名单字段设置为隐藏表单
          if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
            let _option = Utils.getSelectQueryOptions(cell)
    config.fields = config.fields.map(cell => {
      // 数据源sql语句,预处理,权限黑名单字段设置为隐藏表单
      if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
        let _option = Utils.getSelectQueryOptions(cell)
            // 外联数据库替换
            if (window.GLOB.externalDatabase !== null) {
              _option.sql = _option.sql.replace(/@db@/ig, window.GLOB.externalDatabase)
            }
        cell.data_sql = Utils.formatOptions(_option.sql)
        cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
        cell.arr_field = _option.field
      }
            cell.data_sql = Utils.formatOptions(_option.sql)
            cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
            cell.arr_field = _option.field
          }
      // 字段权限黑名单
      if (!cell.blacklist || cell.blacklist.length === 0) return cell
      if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
        cell.hidden = 'true'
      }
          // 字段权限黑名单
          if (!cell.blacklist || cell.blacklist.length === 0) return cell
          if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
            cell.hidden = 'true'
          }
          return cell
        })
      })
    } else {
      config.fields = config.fields.map(cell => {
        // 数据源sql语句,预处理,权限黑名单字段设置为隐藏表单
        if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
          let _option = Utils.getSelectQueryOptions(cell)
          cell.data_sql = Utils.formatOptions(_option.sql)
          cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
          cell.arr_field = _option.field
        }
        // 字段权限黑名单
        if (!cell.blacklist || cell.blacklist.length === 0) return cell
        if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
          cell.hidden = 'true'
        }
        return cell
      })
    }
      return cell
    })
    return config
  }
@@ -1499,6 +1472,7 @@
          })
          this.updateStatus('over')
        } else {
          _LongParam = updateForm(_LongParam)
          _LongParam = this.handleModelConfig(_LongParam)
          
          this.setState({
@@ -1549,17 +1523,10 @@
    const { BData } = this.props
    const { btnconfig, tabledata } = this.state
    let _this = this
    let _fields = []
    if (btnconfig.groups.length > 0) {
      btnconfig.groups.forEach(group => {
        _fields = [..._fields, ...group.sublist]
      })
    } else {
      _fields = btnconfig.fields
    }
    let result = _fields.map(item => {
    let result = []
    btnconfig.fields.forEach(item => {
      if (!item.field) return
      let _readin = item.readin !== 'false'
      let _initval = item.initval
@@ -1590,7 +1557,7 @@
        _initval = ''
      }
      return {
      result.push({
        key: item.field,
        readonly: item.readonly === 'true',
        readin: _readin,
@@ -1598,7 +1565,7 @@
        writein: item.writein !== 'false',
        type: item.type,
        value: _initval
      }
      })
    })
    confirm({
src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -11,6 +11,7 @@
import zhCN from '@/locales/zh-CN/main.js'
import enUS from '@/locales/en-US/main.js'
import asyncSpinComponent from '@/utils/asyncSpinComponent'
import { updateForm } from '@/utils/utils-update.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
@@ -1029,52 +1030,24 @@
  handleModelConfig = (config) => {
    let roleId = sessionStorage.getItem('role_id') || '' // 角色ID
    if (config.groups.length > 0) {
      config.groups.forEach(group => {
        group.sublist = group.sublist.map(cell => {
          // 数据源sql语句,预处理, 权限黑名单字段设置为隐藏表单
          if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
            let _option = Utils.getSelectQueryOptions(cell)
    config.fields = config.fields.map(cell => {
      // 数据源sql语句,预处理,权限黑名单字段设置为隐藏表单
      if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
        let _option = Utils.getSelectQueryOptions(cell)
            // 外联数据库替换
            if (window.GLOB.externalDatabase !== null) {
              _option.sql = _option.sql.replace(/@db@/ig, window.GLOB.externalDatabase)
            }
        cell.data_sql = Utils.formatOptions(_option.sql)
        cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
        cell.arr_field = _option.field
      }
            cell.data_sql = Utils.formatOptions(_option.sql)
            cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
            cell.arr_field = _option.field
          }
      // 字段权限黑名单
      if (!cell.blacklist || cell.blacklist.length === 0) return cell
      if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
        cell.hidden = 'true'
      }
          // 字段权限黑名单
          if (!cell.blacklist || cell.blacklist.length === 0) return cell
          if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
            cell.hidden = 'true'
          }
          return cell
        })
      })
    } else {
      config.fields = config.fields.map(cell => {
        // 数据源sql语句,预处理,权限黑名单字段设置为隐藏表单
        if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
          let _option = Utils.getSelectQueryOptions(cell)
          cell.data_sql = Utils.formatOptions(_option.sql)
          cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
          cell.arr_field = _option.field
        }
        // 字段权限黑名单
        if (!cell.blacklist || cell.blacklist.length === 0) return cell
        if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
          cell.hidden = 'true'
        }
        return cell
      })
    }
      return cell
    })
    return config
  }
@@ -1124,6 +1097,7 @@
          })
          this.updateStatus('over')
        } else {
          _LongParam = updateForm(_LongParam)
          _LongParam = this.handleModelConfig(_LongParam)
          this.setState({
@@ -1168,17 +1142,10 @@
    const { BData } = this.props
    const { btnconfig, tabledata } = this.state
    let _this = this
    let _fields = []
    let result = []
    
    if (btnconfig.groups.length > 0) {
      btnconfig.groups.forEach(group => {
        _fields = [..._fields, ...group.sublist]
      })
    } else {
      _fields = btnconfig.fields
    }
    let result = _fields.map(item => {
    btnconfig.fields.forEach(item => {
      if (!item.field) return
      let _readin = item.readin !== 'false'
      let _initval = item.initval
@@ -1209,14 +1176,14 @@
        _initval = ''
      }
      return {
      result.push({
        key: item.field,
        readonly: item.readonly === 'true',
        readin: _readin,
        fieldlen: _fieldlen,
        type: item.type,
        value: _initval
      }
      })
    })
    confirm({
src/tabviews/zshare/mutilform/index.jsx
@@ -33,7 +33,6 @@
  }
  state = {
    cols: 2,         // 显示为多少列
    datatype: null,  // 数据类型
    readtype: null,  // 是否只读
    readin: null,    // 行数据是否写入
@@ -44,20 +43,6 @@
    record: {}       // 记录下拉表单关联字段,用于数据写入
  }
  UNSAFE_componentWillMount () {
    let cols = 2
    if (this.props.action.setting && this.props.action.setting.cols) {
      cols = parseInt(this.props.action.setting.cols)
      if (cols > 4 || cols < 1) {
        cols = 2
      }
    }
    this.setState({
      cols: cols
    })
  }
  componentDidMount () {
    const { data, BData, action } = this.props
    
@@ -66,34 +51,13 @@
    let readin = {}
    let writein = {}
    let fieldlen = {}
    let formlist = []
    let intercepts = []
    let _inputfields = []
    if (action.groups && action.groups.length > 0) {
      let groups = fromJS(action.groups).toJS()
      groups.forEach(group => {
        if (group.sublist.length === 0) return
        if (!group.default) {
          formlist.push({
            type: 'title',
            label: group.label,
            uuid: group.uuid
          })
        }
        formlist.push(...group.sublist)
      })
    } else {
      formlist = fromJS(action.fields).toJS()
    }
    let linkFields = {} // 关联菜单
    let supItemVal = {} // 上级菜单初始值
    let deForms = []    // 需要动态获取下拉菜单的表单
    formlist.forEach(item => {
    action.fields.forEach(item => {
      if (item.type === 'text' || item.type === 'number') {              // 用于过滤下拉菜单关联表单
        _inputfields.push(item.field)
      } else if (item.type === 'textarea') {
@@ -107,8 +71,11 @@
      }
    })
    formlist = formlist.map(item => {
      if (item.type === 'title') return item
    let formlist = action.fields.map(item => {
      if (item.labelwidth) {
        item.labelCol = {style: {width: item.labelwidth + '%'}}
      }
      if (item.type === 'split' || item.type === 'hint') return item
      // 数据自动填充
      let _readin = item.readin !== 'false'
@@ -716,13 +683,13 @@
  getFields() {
    const { getFieldDecorator } = this.props.form
    const { cols, formlist } = this.state
    const { formlist } = this.state
    const fields = []
    let filtration = {}
    formlist.forEach((item, index) => {
      if ((!item.field && item.type !== 'title' && item.type !== 'hint') || item.hidden === 'true' || item.type === 'funcvar') return
      if ((!item.field && item.type !== 'split' && item.type !== 'hint') || item.hidden === 'true' || item.type === 'funcvar') return
      if (item.supField) { // 多层表单控制
        let _supVal = this.props.form.getFieldValue(item.supField)
@@ -738,12 +705,7 @@
        }
      }
      let _colspan = 24 / cols
      if (item.entireLine === 'true') {
        _colspan = 24
      }
      if (item.type === 'title') {
      if (item.type === 'split') {
        fields.push(
          <Col span={24} key={index}>
            <p>{item.label}</p>
@@ -751,8 +713,8 @@
        )
      } else if (item.type === 'hint') {
        fields.push(
          <Col span={24} key={index}>
            <Form.Item colon={!!item.label} label={item.label || ' '} className="hint">
          <Col span={item.span || 24} key={index}>
            <Form.Item colon={!!item.label} label={item.label || ' '} labelCol={item.labelCol} className="hint">
              <div className="message">{item.message}</div>
            </Form.Item>
          </Col>
@@ -789,8 +751,8 @@
        }
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -817,8 +779,8 @@
        let precision = (item.decimal || item.decimal === 0) ? item.decimal : null
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -845,8 +807,8 @@
        )
      } else if (item.type === 'color') { // 颜色选择
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -868,8 +830,8 @@
        )
      } else if (item.type === 'checkcard') { // 多选框
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -889,8 +851,8 @@
        )
      } else if (item.type === 'switch') { // 多选框
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -912,8 +874,8 @@
        let _initval = item.initval ? item.initval.split(',').filter(Boolean) : []
        
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -937,8 +899,8 @@
        )
      } else if (item.type === 'radio') { // 单选框
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -962,8 +924,8 @@
        )
      } else if (item.type === 'select' || item.type === 'link') { // 下拉搜索
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -996,8 +958,8 @@
      } else if (item.type === 'multiselect') { // 多选
        let _initval = item.initval ? item.initval.split(',').filter(Boolean) : []
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -1028,8 +990,8 @@
        )
      } else if (item.type === 'date') { // 时间搜索
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -1051,8 +1013,8 @@
        )
      } else if (item.type === 'datemonth') {
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -1074,8 +1036,8 @@
        )
      } else if (item.type === 'datetime') {
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -1116,8 +1078,8 @@
        }
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -1139,8 +1101,8 @@
        )
      } else if (item.type === 'linkMain') {
        fields.push(
          <Col span={_colspan} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -1170,8 +1132,8 @@
          }]
        }
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -1198,8 +1160,8 @@
        let _max = item.fieldlength || 512
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.hidelabel !== 'true' && item.tooltip ?
          <Col span={item.span || 24} key={index}>
            <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.hidelabel !== 'true' && item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
@@ -1389,21 +1351,9 @@
  }
  render() {
    const { cols } = this.state
    const formItemLayout = {
      // labelCol: {
      //   xs: { span: 24 },
      //   sm: { span: 8 }
      // },
      // wrapperCol: {
      //   xs: { span: 24 },
      //   sm: { span: 16 }
      // }
    }
    return (
      <Form {...formItemLayout} className="main-form-field" id="main-form-box">
        <Row className={'cols' + cols} gutter={24}>{this.getFields()}</Row>
      <Form className="main-form-field" id="main-form-box">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
  }
src/templates/formtabconfig/index.jsx
@@ -2013,7 +2013,6 @@
          visible={this.state.tableVisible}
          width={'65vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          cancelText={this.state.dict['model.close']}
          onOk={this.addFieldSubmit}
          onCancel={() => { // 取消添加
@@ -2037,7 +2036,6 @@
          visible={this.state.profileVisible}
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={this.state.dict['model.submit']}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ profileVisible: false }) }}
src/templates/modalconfig/dragelement/card.jsx
@@ -1,6 +1,6 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Icon, Select, DatePicker, Input, InputNumber, Button, Popover, Switch, Radio, Checkbox } from 'antd'
import { Icon, Select, DatePicker, Input, InputNumber, Button, Popover, Switch, Radio, Checkbox, Form } from 'antd'
import moment from 'moment'
import asyncComponent from '@/utils/asyncComponent'
@@ -62,29 +62,29 @@
      selectval = card.emptyText || '空'
    }
  }
  let labelCol = 'ant-col-sm-8'
  let wrapCol = 'ant-col-sm-16'
  let isEntireLine = false
  // let labelCol = 'ant-col-sm-8'
  // let wrapCol = 'ant-col-sm-16'
  // let isEntireLine = false
  if (card.entireLine === 'true' || ['textarea', 'hint', 'checkcard', 'brafteditor'].includes(card.type)) {
    isEntireLine = true
  }
  // if (card.entireLine === 'true' || ['textarea', 'hint', 'checkcard', 'brafteditor'].includes(card.type)) {
  //   isEntireLine = true
  // }
  if (isEntireLine) {
    if (cols === '2') {
      labelCol = 'ant-col-sm-4'
      wrapCol = 'ant-col-sm-20'
    } else if (cols === '3') {
      labelCol = 'ant-col-cuslabel'
      wrapCol = 'ant-col-cuswrap'
    } else if (cols === '4') {
      labelCol = 'ant-col-sm-2'
      wrapCol = 'ant-col-sm-22'
    }
    if (card.hidelabel === 'true') {
      wrapCol = 'ant-col-sm-24'
    }
  }
  // if (isEntireLine) {
  //   if (cols === '2') {
  //     labelCol = 'ant-col-sm-4'
  //     wrapCol = 'ant-col-sm-20'
  //   } else if (cols === '3') {
  //     labelCol = 'ant-col-cuslabel'
  //     wrapCol = 'ant-col-cuswrap'
  //   } else if (cols === '4') {
  //     labelCol = 'ant-col-sm-2'
  //     wrapCol = 'ant-col-sm-22'
  //   }
  //   if (card.hidelabel === 'true') {
  //     wrapCol = 'ant-col-sm-24'
  //   }
  // }
  let formItem = null
  if (card.type === 'text') {
@@ -134,6 +134,8 @@
    </Checkbox.Group>)
  } else if (card.type === 'hint') {
    formItem = <div style={{marginTop: '10px', color: 'rgba(0, 0, 0, 0.85)'}}>{card.message}</div>
  } else if (card.type === 'split') {
    formItem = <div className="split-line">{card.label}</div>
  } else if (card.type === 'checkcard') {
    formItem = <CheckCard width={card.width} ratio={card.ratio} display={card.display} fields={card.fields} options={card.options} />
  }
@@ -148,7 +150,18 @@
    } trigger="hover">
      <div className="page-card" style={{ opacity: opacity}}>
        <div ref={node => drag(drop(node))}>
          {<div className="ant-row ant-form-item">
          {card.type === 'split' ? formItem : <Form.Item
            className="ant-form-item"
            colon={!!card.label}
            label={card.tooltip ? <span><Icon type="question-circle" />{card.label}</span> : card.label}
            required={card.required === 'true'}
            extra={card.extra || null}
            labelCol={card.labelwidth ? {style: {width: card.labelwidth + '%'}} : null}
          >
            {formItem}
            {showField ? <div className="field-name">{card.field}</div> : ''}
          </Form.Item>}
          {/* <div className="ant-row ant-form-item">
            {card.hidelabel !== 'true' ? <div className={'ant-col ant-form-item-label ant-col-xs-24 ' + labelCol}>
              {card.label ? <label className={card.required === 'true' ? 'required' : ''}>{card.tooltip ? 
                <Icon type="question-circle" /> : null}
@@ -158,7 +171,7 @@
              {formItem}
              {showField ? card.field : ''}
            </div>
          </div>}
          </div> */}
        </div>
      </div>
    </Popover>
src/templates/modalconfig/dragelement/index.jsx
@@ -7,7 +7,7 @@
import Card from './card'
import './index.scss'
const Container = ({list, group, setting, placeholder, handleList, handleForm, closeForm, showField }) => {
const Container = ({list, setting, placeholder, handleList, handleForm, closeForm, showField }) => {
  const [cards, setCards] = useState(list)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
@@ -16,11 +16,7 @@
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    if (!group) {
      handleList(_cards)
    } else {
      handleList(_cards, group)
    }
    handleList(_cards)
  }
  if (!is(fromJS(cards), fromJS(list))) {
@@ -69,22 +65,12 @@
    setCards(_cards)
    if (!group) {
      handleList(_cards, null, null, _card)
    } else {
      handleList(_cards, group, null, _card)
    }
    handleList(_cards, _card)
  }
  const [, drop] = useDrop({
    accept: 'form',
    drop(item) {
      if (item.hasOwnProperty('originalIndex') && group) {
        const { card } = findCard(item.id)
        if (!card) {
          handleList(cards, group, item.id)
        }
      }
      if (item.hasOwnProperty('originalIndex')) {
        return
      }
@@ -113,26 +99,14 @@
      setCards(_cards)
      if (!group) {
        handleList(_cards, null, null, newcard)
      } else {
        handleList(_cards, group, null, newcard)
      }
      handleList(_cards, newcard)
    }
  })
  let _cols = 24 / (setting.cols || 2)
  return (
    <div ref={drop} className="ant-row modal-fields-row">
    <div ref={drop} className={'ant-row modal-fields-row ' + (setting.align || 'left_right')} >
      {cards.map(card => {
        let isEntireLine = false
        if (card.entireLine === 'true' || ['textarea', 'hint', 'checkcard', 'brafteditor'].includes(card.type)) {
          isEntireLine = true
        }
        return <Col key={card.uuid} className={isEntireLine ? 'textarea' + setting.cols : ''} span={isEntireLine ? 24 : _cols}>
        return <Col key={card.uuid} span={card.span || 24}>
          <Card
            id={card.uuid}
            cols={setting.cols}
src/templates/modalconfig/dragelement/index.scss
@@ -24,4 +24,97 @@
    float: none;
    vertical-align: top;
  }
  .ant-form-item {
    cursor: move;
    display: flex;
    margin-bottom: 0px;
    .ant-form-item-label {
      overflow: visible;
      position: relative;
      cursor: move;
      height: 40px;
      width: 33.3%;
      label {
        width: 100%;
        cursor: move;
        overflow: hidden;
        display: inline-block;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      .anticon-question-circle {
        color: #c49f47;
        margin-right: 3px;
        line-height: 40px;
      }
    }
    .ant-form-item-control-wrapper {
      position: relative;
      flex: 1;
      .ant-select {
        width: 100%;
        margin-top: 4px;
      }
      .field-name {
        line-height: 1.3;
        float: left;
      }
      .ant-checkbox-group {
        line-height: 40px;
        .ant-checkbox-wrapper {
          margin-right: 8px;
        }
        .ant-checkbox-wrapper + .ant-checkbox-wrapper {
          margin-left: 0px;
        }
      }
      .ant-radio-group {
        line-height: 40px;
      }
      .ant-calendar-picker {
        width: 100%;
        margin-top: 4px;
      }
      .ant-input-number {
        width: 100%;
        margin-top: 4px;
      }
      .color-sketch-block {
        margin-top: 7px;
        overflow: hidden;
        .color-sketch-block-box {
          min-width: 100px;
        }
      }
      .normal-braft-editor {
        border: 1px solid #d9d9d9;
        border-radius: 4px;
      }
    }
    .ant-form-item-control-wrapper::after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      opacity: 0;
      z-index: 1;
    }
    .ant-col-cuslabel {
      width: 10.5%;
    }
    .ant-col-cuswrap {
      width: 89.5%;
    }
  }
}
.modal-fields-row.up_down {
  .ant-form-item {
    display: block;
    .ant-form-item-label {
      width: 100%!important;
      text-align: left;
    }
  }
}
src/templates/modalconfig/groupform/index.jsx
File was deleted
src/templates/modalconfig/index.jsx
@@ -5,7 +5,7 @@
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import moment from 'moment'
import { Button, Card, Modal, Collapse, notification, Icon, Popover, Switch } from 'antd'
import { Button, Card, Modal, Collapse, notification, Icon, Switch } from 'antd'
import Api from '@/api'
import Utils from '@/utils/utils.js'
@@ -14,19 +14,19 @@
import { getModalForm } from '@/templates/zshare/formconfig'
import ModalForm from '@/templates/zshare/modalform'
import DragElement from './dragelement'
import SourceElement from './dragelement/source'
import SettingForm from './settingform'
import GroupForm from './groupform'
import MenuForm from './menuform'
import asyncComponent from '@/utils/asyncComponent'
import { BaseConfig, SearchItems } from './source'
import { updateForm } from '@/utils/utils-update.js'
import './index.scss'
const { Panel } = Collapse
const { confirm } = Modal
const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
const DragElement = asyncComponent(() => import('./dragelement'))
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
@@ -57,8 +57,6 @@
    settingVisible: false, // 全局配置模态框
    closeVisible: false,   // 关闭模态框
    originConfig: null,    // 原始菜单
    groupVisible: false,   // 全局配置模态框
    curgroup: null,        // 当前组,新建或编辑
    sqlVerifing: false,    // sql验证
    openEdition: '',       // 编辑版本标记,防止多人操作
    showField: false       // 显示表单字段值
@@ -107,6 +105,7 @@
        url: ''
      })
    }
    _config = updateForm(_config)
    this.setState({
      openEdition: editAction.open_edition || '',
@@ -172,78 +171,20 @@
   * 2、表单移动后,保存移动后的顺序
   * 3、新增表单时,直接打开编辑框
   */
  handleList = (list, group, elementId, newcard) => {
  handleList = (list, newcard) => {
    let _config = fromJS(this.state.config).toJS()
    if (!group && !elementId) {
      // 没有分组时(拖拽添加)
      if (list.length > _config.fields.length) {
        _config.fields = list.filter(item => !item.origin)
        this.setState({
          config: _config
        }, () => {
          this.handleForm(newcard)
        })
      } else {
        _config.fields = list
        this.setState({config: _config})
      }
    } else if (group && !elementId) {
      // 存在分组时,拖拽添加
      if (list.length > group.sublist.length) {
        group.sublist = list
        _config.groups = _config.groups.map(item => {
          if (item.uuid === group.uuid) {
            return group
          } else {
            return item
          }
        })
        this.setState({
          config: _config
        }, () => {
          this.handleForm(newcard)
        })
      } else {
        group.sublist = list
        _config.groups = _config.groups.map(item => {
          if (item.uuid === group.uuid) {
            return group
          } else {
            return item
          }
        })
        this.setState({config: _config})
      }
    } else if (group && elementId) {
      // 修改已有元素的分组
      let element = null
      _config.groups.forEach(item => {
        item.sublist = item.sublist.filter(cell => {
          if (cell.uuid !== elementId) {
            return true
          } else {
            element = cell
            return false
          }
        })
      })
      group.sublist.push(element)
      _config.groups = _config.groups.map(item => {
        if (item.uuid === group.uuid) {
          return group
        } else {
          return item
        }
      })
    if (list.length > _config.fields.length) {
      _config.fields = list.filter(item => !item.origin)
      this.setState({
        config: _config
      }, () => {
        this.handleForm(newcard)
      })
    } else {
      _config.fields = list
      this.setState({config: _config})
    }
  }
@@ -255,8 +196,8 @@
   */
  handleForm = (_card) => {
    const { menu, tabConfig, subTabConfig } = this.props
    let card = fromJS(_card).toJS()
    const { config } = this.state
    let card = fromJS(_card).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
@@ -264,24 +205,14 @@
      value: '',
      text: '空'
    }]
    let _formfields = []
    // 设置下拉菜单可关联字段(上级与下级)
    if (config.groups.length > 0) {
      config.groups.forEach(group => {
        _formfields = [..._formfields, ...group.sublist]
      })
    } else {
      _formfields = config.fields
    }
    _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
    _tabfields = _formfields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
    _inputfields = config.fields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
    _tabfields = config.fields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
    _tabfields.unshift({field: '', text: '原表单'})
    let uniq = new Map()
    uniq.set(card.field, true)
    _formfields.forEach(item => {
    config.fields.forEach(item => {
      if (item.type !== 'select' && item.type !== 'link' && item.type !== 'radio') return
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
@@ -356,37 +287,19 @@
      let fieldrepet = false // 字段重复
      let labelrepet = false // 提示文字重复
      if (_config.groups.length > 0) {
        _config.groups.forEach(group => {
          group.sublist = group.sublist.map(item => {
            if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
              fieldrepet = true
            } else if (item.uuid !== res.uuid && item.label === res.label) {
              labelrepet = true
            }
      _config.fields = _config.fields.map(item => {
        if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
          fieldrepet = true
        } else if (res.label && item.uuid !== res.uuid && item.label === res.label) {
          labelrepet = true
        }
            if (item.uuid === res.uuid) {
              return res
            } else {
              return item
            }
          })
        })
      } else {
        _config.fields = _config.fields.map(item => {
          if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
            fieldrepet = true
          } else if (item.uuid !== res.uuid && item.label === res.label) {
            labelrepet = true
          }
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
      }
        if (item.uuid === res.uuid) {
          return res
        } else {
          return item
        }
      })
      if (fieldrepet) {
        notification.warning({
@@ -463,14 +376,7 @@
      content: `确定删除<<${card.label}>>吗?`,
      onOk() {
        let _config = fromJS(_this.state.config).toJS()
        if (_config.groups.length > 0) {
          _config.groups.forEach(group => {
            group.sublist = group.sublist.filter(item => !(item.uuid === card.uuid))
          })
        } else {
          _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
        }
        _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
        _this.setState({
          config: _config,
@@ -608,115 +514,12 @@
    })
  }
  handleGroup = (group) => {
    let curgroup = ''
    if (group) {
      curgroup = group
    } else {
      curgroup = {
        isnew: true,
        label: '',
        default: false,
        uuid: Utils.getuuid(),
        sublist: []
      }
    }
    this.setState({
      groupVisible: true,
      curgroup: curgroup
    })
  }
  closeGroup = (group) => {
    let _this = this
    confirm({
      content: `确定删除分组<<${group.label}>>吗?`,
      onOk() {
        let _config = fromJS(_this.state.config).toJS()
        _config.groups = _config.groups.filter(item => !(item.uuid === group.uuid))
        let _length = _config.groups.length
        if (_length === 1) {
          _config.fields = [...group.sublist, ..._config.groups[0].sublist]
          _config.groups = []
        } else {
          _config.groups[_length - 1].sublist = [...group.sublist, ..._config.groups[_length - 1].sublist]
        }
        _this.setState({
          config: _config
        })
      },
      onCancel() {}
    })
  }
  handleGroupSave = () => {
    let _group = fromJS(this.state.curgroup).toJS()
    let config = fromJS(this.state.config).toJS()
    this.groupRef.handleConfirm().then(res => {
      _group = {..._group, ...res.target}
      if (_group.isnew) {
        delete _group.isnew
        config.groups.unshift(_group)
        if (config.groups.length > 1) {
          config.groups = config.groups.map(item => {
            if (item.default) {
              return res.default
            } else {
              return item
            }
          })
        } else {
          config.groups.push(res.default)
        }
      } else {
        config.groups = config.groups.map(item => {
          if (item.uuid === _group.uuid) {
            return _group
          } else if (item.default) {
            return res.default
          } else {
            return item
          }
        })
      }
      config.fields = []
      config.groups = config.groups.sort((a, b) => {
        return a.sort - b.sort
      })
      this.setState({
        groupVisible: false,
        curgroup: '',
        config: config
      })
    })
  }
  editModalCancel = () => {
    const { config, card } = this.state
    if (card.focus) {
      let _config = null
      if (config.groups.length > 0) {
        let _groups = config.groups.map(group => {
          group.sublist = group.sublist.filter(item => item.uuid !== card.uuid)
          return group
        })
        _config = {...config, groups: _groups}
      } else {
        let _fields = config.fields.filter(item => item.uuid !== card.uuid)
        _config = {...config, fields: _fields}
      }
      let _fields = config.fields.filter(item => item.uuid !== card.uuid)
      let _config = {...config, fields: _fields}
      this.setState({
        card: null,
@@ -752,6 +555,40 @@
    })
  }
  changecols = (type) => {
    let config = fromJS(this.state.config).toJS()
    let _this = this
    config.fields = config.fields.map(item => {
      item.labelwidth = 33.3
      item.span = 24
      if (['textarea','split','hint','checkcard','brafteditor'].includes(item.type)) {
        if (type === 2) {
          item.labelwidth = 16.3
        } else if (type === 3) {
          item.labelwidth = 10.5
        } else if (type === 4) {
          item.labelwidth = 8.3
        }
      } else if (type === 2) {
        item.span = 12
      } else if (type === 3) {
        item.span = 8
      } else if (type === 4) {
        item.span = 6
      }
      return item
    })
    confirm({
      content: `确定切换为${type}列吗?`,
      onOk() {
        _this.setState({config})
      },
      onCancel() {}
    })
  }
  render () {
    const { config, source, dict } = this.state
@@ -783,7 +620,6 @@
                  type="form"
                  updatefield={this.updateconfig}
                />
                <Button type="primary" block onClick={() => this.handleGroup()}>{dict['header.menu.group.add']}</Button>
              </Panel>
            </Collapse>
          </div>
@@ -799,50 +635,23 @@
              <div className="ant-modal-content" style={{width: config.setting.width + '%'}}>
                <div className="ant-modal-header">
                  <div className="ant-modal-title">{config.setting.title}</div>
                  <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</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="ant-modal-body">
                  <div className="modal-form">
                    {config.groups.length > 0 &&
                      config.groups.map(group => {
                        return (
                          <div key={group.uuid}>
                            <div className="group-title">
                              {!group.default ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                                <div className="mk-popover-control">
                                  <Icon className="edit" type="edit" onClick={() => {this.handleGroup(group)}} />
                                  <Icon className="edit close" type="close" onClick={() => {this.closeGroup(group)}} />
                                </div>
                              } trigger="hover">
                                <span>{group.label}</span>
                              </Popover> : null}
                              {group.default ? <span style={{color: '#bcbcbc'}}>{group.label}</span> : null}
                            </div>
                            <DragElement
                              group={group}
                              list={group.sublist}
                              setting={config.setting}
                              showField={this.state.showField}
                              placeholder={dict['header.form.modal.placeholder']}
                              handleList={this.handleList}
                              handleForm={this.handleForm}
                              closeForm={this.closeForm}
                            />
                          </div>
                        )
                      })
                    }
                    {config.groups.length === 0 ?
                      <DragElement
                        list={config.fields}
                        setting={config.setting}
                        showField={this.state.showField}
                        placeholder={dict['header.form.modal.placeholder']}
                        handleList={this.handleList}
                        handleForm={this.handleForm}
                        closeForm={this.closeForm}
                      /> : null
                    }
                    <DragElement
                      list={config.fields}
                      setting={config.setting}
                      showField={this.state.showField}
                      placeholder={dict['header.form.modal.placeholder']}
                      handleList={this.handleList}
                      handleForm={this.handleForm}
                      closeForm={this.closeForm}
                    />
                  </div>
                </div>
                <div className="ant-modal-footer">
@@ -909,23 +718,6 @@
          destroyOnClose
        >
          {dict['header.menu.config.placeholder']}
        </Modal>
        <Modal
          title={dict['header.menu.group.manage']}
          visible={this.state.groupVisible}
          width={700}
          maskClosable={false}
          onOk={this.handleGroupSave}
          onCancel={() => { this.setState({ groupVisible: false }) }}
          destroyOnClose
        >
          <GroupForm
            dict={dict}
            config={config}
            group={this.state.curgroup}
            inputSubmit={this.handleGroupSave}
            wrappedComponentRef={(inst) => this.groupRef = inst}
          />
        </Modal>
      </div>
    )
src/templates/modalconfig/index.scss
@@ -136,10 +136,19 @@
          z-index: 10;
          background: transparent;
          min-height: 50px;
          padding-right: 75px;
          .ant-modal-title {
            display: inline-block;
          }
          .ant-switch {
            position: absolute;
            top: 15px;
            right: 10px;
          }
          .mk-cols-change {
            float: right;
            height: 25px;
            margin-right: 10px;
          }
        }
        .ant-modal-footer {
@@ -188,92 +197,6 @@
          background: #ffffff;
          border-radius: 2px;
          margin-bottom: 15px;
          .ant-form-item {
            cursor: move;
            display: flex;
            margin-bottom: 0px;
            .ant-form-item-label {
              overflow: visible;
              position: relative;
              height: 40px;
              label {
                width: 100%;
                cursor: move;
                overflow: hidden;
                display: inline-block;
                text-overflow: ellipsis;
                white-space: nowrap;
              }
              label.required::before {
                display: inline-block;
                margin-right: 4px;
                color: #f5222d;
                font-size: 14px;
                font-family: SimSun, sans-serif;
                line-height: 1;
                content: '*';
              }
              .anticon-question-circle {
                color: #c49f47;
                margin-right: 3px;
                line-height: 40px;
              }
            }
            .ant-form-item-control-wrapper {
              position: relative;
              .ant-select {
                width: 100%;
                margin-top: 4px;
              }
              .ant-checkbox-group {
                line-height: 40px;
                .ant-checkbox-wrapper {
                  margin-right: 8px;
                }
                .ant-checkbox-wrapper + .ant-checkbox-wrapper {
                  margin-left: 0px;
                }
              }
              .ant-radio-group {
                line-height: 40px;
              }
              .ant-calendar-picker {
                width: 100%;
                margin-top: 4px;
              }
              .ant-input-number {
                width: 100%;
                margin-top: 4px;
              }
              .color-sketch-block {
                margin-top: 7px;
                overflow: hidden;
                .color-sketch-block-box {
                  min-width: 100px;
                }
              }
              .normal-braft-editor {
                border: 1px solid #d9d9d9;
                border-radius: 4px;
              }
            }
            .ant-form-item-control-wrapper::after {
              content: '';
              position: absolute;
              top: 0;
              left: 0;
              right: 0;
              bottom: 0;
              opacity: 0;
              z-index: 1;
            }
            .ant-col-cuslabel {
              width: 10.5%;
            }
            .ant-col-cuswrap {
              width: 89.5%;
            }
          }
        }
        .ant-calendar-picker {
          min-width: 100px!important;
src/templates/modalconfig/settingform/index.jsx
@@ -21,21 +21,11 @@
    const { config } = this.props
    let fields = []
    if (config.groups.length > 0) {
      config.groups.forEach(group => {
        group.sublist.forEach(item => {
          if (item.field && ['select', 'link', 'text', 'number'].includes(item.type) && item.hidden !== 'true' && item.readonly !== 'true') {
            fields.push(item)
          }
        })
      })
    } else if (config.fields.length > 0) {
      config.fields.forEach(f => {
        if (f.field && ['select', 'link', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
          fields.push(f)
        }
      })
    }
    config.fields.forEach(f => {
      if (f.field && ['select', 'link', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
      }
    })
    this.setState({
      fields: fields
@@ -125,16 +115,14 @@
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="列数">
              {getFieldDecorator('cols', {
                initialValue: config.setting.cols || '2'
            <Form.Item label="表单排列">
              {getFieldDecorator('align', {
                initialValue: config.setting.align || 'left_right'
              })(
                <Select>
                  <Select.Option value="1">1列</Select.Option>
                  <Select.Option value="2">2列</Select.Option>
                  <Select.Option value="3">3列</Select.Option>
                  <Select.Option value="4">4列</Select.Option>
                </Select>
                <Radio.Group>
                  <Radio value="left_right">左右</Radio>
                  <Radio value="up_down">上下</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
src/templates/modalconfig/source.jsx
@@ -17,7 +17,6 @@
    display: 'modal'
  },
  tables: [],
  groups: [],
  fields: [
    {
      origin: true,
@@ -158,12 +157,6 @@
  },
  {
    type: 'form',
    label: '提示',
    subType: 'hint',
    url: ''
  },
  {
    type: 'form',
    label: CommonDict['model.form.color'],
    subType: 'color',
    url: ''
@@ -179,6 +172,18 @@
    label: CommonDict['header.form.funcvar'],
    subType: 'funcvar',
    url: ''
  },
  {
    type: 'form',
    label: '提示',
    subType: 'hint',
    url: ''
  },
  {
    type: 'form',
    label: '分割线',
    subType: 'split',
    url: ''
  }
]
src/templates/sharecomponent/actioncomponent/index.jsx
@@ -14,6 +14,7 @@
import ActionForm from './actionform'
import CreateFunc from '@/templates/zshare/createfunc'
import CreateInterface from '@/templates/zshare/createinterface'
import { updateForm } from '@/utils/utils-update.js'
import DragElement from './dragaction'
import './index.scss'
@@ -744,19 +745,12 @@
            }
            if (_LongParam) {
              let fields = []
              if (_LongParam.groups.length > 0) {
                _LongParam.groups.forEach(group => {
                  fields = [...fields, ...group.sublist]
                })
              } else {
                fields = _LongParam.fields
              }
              _LongParam = updateForm(_LongParam)
              let _param = {
                funcName: btn.innerFunc,
                name: _config.setting.tableName || '',
                fields: fields,
                fields: _LongParam.fields,
                menuNo: menu.MenuNo
              }
              newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config))
@@ -915,7 +909,6 @@
          visible={profVisible}
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={dict['model.submit']}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ profVisible: false }) }}
src/templates/sharecomponent/columncomponent/index.jsx
@@ -549,7 +549,6 @@
          visible={modaltype === 'mark'}
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={dict['model.submit']}
          onOk={this.markSubmit}
          onCancel={() => { this.setState({ modaltype: '' }) }}
src/templates/sharecomponent/fieldscomponent/index.jsx
@@ -67,23 +67,12 @@
        }
      })
    } else if (type === 'form') {
      if (config.groups.length > 1) {
        config.groups.forEach(group => {
          group.sublist.forEach(item => {
            if (item.field && columns.has(item.field.toLowerCase())) {
              let _datatype = columns.get(item.field.toLowerCase()).datatype
              columns.set(item.field.toLowerCase(), {...item, selected: true, datatype: _datatype})
            }
          })
        })
      } else {
        config.fields.forEach(item => {
          if (item.field && columns.has(item.field.toLowerCase())) {
            let _datatype = columns.get(item.field.toLowerCase()).datatype
            columns.set(item.field.toLowerCase(), {...item, selected: true, datatype: _datatype})
          }
        })
      }
      config.fields.forEach(item => {
        if (item.field && columns.has(item.field.toLowerCase())) {
          let _datatype = columns.get(item.field.toLowerCase()).datatype
          columns.set(item.field.toLowerCase(), {...item, selected: true, datatype: _datatype})
        }
      })
    }
    // 显示字段集弹窗
@@ -239,32 +228,30 @@
        }
      })
    } else if (type === 'form') {
      if (config.groups.length > 1) {
        config.groups.forEach(group => {
          let _items = []
          group.sublist.forEach(item => {
            if (item.field && columnsMap.has(item.field.toLowerCase())) {
              let cell = columnsMap.get(item.field.toLowerCase())
              if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加
                _items.push(item)
              } else if (cell.selected) {                     // 数据类型修改时,重置类型及初始值
                item.type = cell.type
                item.initval = ''
                _items.push(item)
              }
              columnsMap.delete(item.field.toLowerCase())
            } else if (!item.origin) {                        // 过滤示例项
              _items.push(item)
            }
          })
          group.sublist = _items
        })
        let _columns = [...columnsMap.values()]
        let _additems = _columns.map(item => { // 循环添加新增字段
          return {
      config.fields.forEach(item => {
        if (item.field && columnsMap.has(item.field.toLowerCase())) {
          let cell = columnsMap.get(item.field.toLowerCase())
          if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加
            items.push(item)
          } else if (cell.selected) {                     // 数据类型修改时,重置类型及初始值
            item.type = cell.type
            item.initval = ''
            items.push(item)
          }
          columnsMap.delete(item.field.toLowerCase())
        } else if (!item.origin) {                        // 过滤示例项
          items.push(item)
        }
      })
      let _columns = [...columnsMap.values()]
      let lastItem = config.fields[config.fields.length - 1]
      let span = lastItem ? lastItem.span : 12
      _columns.forEach(item => { // 循环添加新增字段
        if (item.selected) {
          let newcard = {
            uuid: Utils.getuuid(),
            label: item.label,
            field: item.field,
@@ -272,59 +259,21 @@
            type: item.type,
            resourceType: '0',
            setAll: 'false',
            span: span,
            labelwidth: 33.3,
            options: [],
            dataSource: '',
            orderType: 'asc',
            decimal: item.decimal,
            orderType: 'asc',
            readonly: 'false',
            required: 'true'
          }
        })
        config.groups[config.groups.length - 1].sublist = [...config.groups.slice(-1)[0].sublist, ..._additems]
      } else {
        config.fields.forEach(item => {
          if (item.field && columnsMap.has(item.field.toLowerCase())) {
            let cell = columnsMap.get(item.field.toLowerCase())
            if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加
              items.push(item)
            } else if (cell.selected) {                     // 数据类型修改时,重置类型及初始值
              item.type = cell.type
              item.initval = ''
              items.push(item)
            }
            columnsMap.delete(item.field.toLowerCase())
          } else if (!item.origin) {                        // 过滤示例项
            items.push(item)
          }
        })
        let _columns = [...columnsMap.values()]
        _columns.forEach(item => { // 循环添加新增字段
          if (item.selected) {
            let newcard = {
              uuid: Utils.getuuid(),
              label: item.label,
              field: item.field,
              initval: '',
              type: item.type,
              resourceType: '0',
              setAll: 'false',
              options: [],
              dataSource: '',
              decimal: item.decimal,
              orderType: 'asc',
              readonly: 'false',
              required: 'true'
            }
            items.push(newcard)
          }
        })
        config.fields = items
      }
          items.push(newcard)
        }
      })
      config.fields = items
    }
    if (type === 'search' || type === 'columns' || type === 'form') {
@@ -373,7 +322,6 @@
          visible={this.state.tableVisible}
          width={'65vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          cancelText={dict['model.close']}
          onOk={this.addFieldSubmit}
          onCancel={() => { // 取消添加
src/templates/sharecomponent/settingcalcomponent/index.jsx
@@ -65,7 +65,6 @@
          visible={visible}
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={dict['model.submit']}
          onOk={this.verifySubmit}
          confirmLoading={loading}
src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.scss
@@ -18,5 +18,7 @@
      margin-right: 3px;
    }
  }
  .ant-radio-group {
    white-space: nowrap;
  }
}
src/templates/zshare/createinterface/index.jsx
@@ -7,6 +7,7 @@
import MutilForm from './mutilform'
import Utils from '@/utils/utils.js'
import options from '@/store/options.js'
import { updateForm } from '@/utils/utils-update.js'
import Api from '@/api'
import './index.scss'
@@ -422,20 +423,14 @@
                _LongParam = ''
              }
            }
            let fields = []
            if (_LongParam && _LongParam.type === 'Modal') {
              if (_LongParam.groups.length > 0) {
                _LongParam.groups.forEach(group => {
                  fields = [...fields, ...group.sublist]
                })
              } else {
                fields = _LongParam.fields
              }
              _LongParam = updateForm(_LongParam)
            }
            if (fields && fields.length > 0) {
              formlist = fields.map(cell => {
            if (_LongParam && _LongParam.fields.length > 0) {
              _LongParam.fields.forEach(cell => {
                if (!cell.field) return
                let _fieldlen = cell.fieldlength || 50
                if (cell.type === 'textarea' || cell.type === 'fileupload' || cell.type === 'multiselect') {
@@ -471,7 +466,7 @@
                  _field.value = ''
                }
                return _field
                formlist.push(_field)
              })
            }
            resolve(true)
src/templates/zshare/editcomponent/index.jsx
@@ -221,23 +221,11 @@
        }
        res.copyType = 'form'
        if (_config.groups.length > 0) {
          _config.groups.forEach(group => {
            group.sublist.forEach(item => {
              item.field && fields.push(item.field.toLowerCase())
              labels.push(item.label)
            })
            if (group.default) {
              group.sublist.push(res)
            }
          })
        } else {
          _config.fields.forEach(item => {
            item.field && fields.push(item.field.toLowerCase())
            labels.push(item.label)
          })
          _config.fields.push(res)
        }
        _config.fields.forEach(item => {
          item.field && fields.push(item.field.toLowerCase())
          labels.push(item.label)
        })
        _config.fields.push(res)
        if (res.field && fields.includes(res.field.toLowerCase())) {
          notification.warning({
src/templates/zshare/formconfig.jsx
@@ -1985,9 +1985,6 @@
        value: 'textarea',
        text: Formdict['model.form.textarea']
      }, {
        value: 'hint',
        text: '提示'
      }, {
        value: 'color',
        text: Formdict['model.form.color']
      }, {
@@ -1996,6 +1993,12 @@
      }, {
        value: 'funcvar',
        text: Formdict['header.form.funcvar']
      }, {
        value: 'hint',
        text: '提示'
      }, {
        value: 'split',
        text: '分隔线'
      },
      ..._openType]
    },
@@ -2074,6 +2077,9 @@
    {
      type: 'number',
      key: 'width',
      min: 1,
      max: 24,
      precision: 0,
      label: '卡片宽度',
      initVal: card.width || 4,
      tooltip: '栅格布局,每行等分为24列。',
@@ -2215,6 +2221,9 @@
    {
      type: 'number',
      key: 'decimal',
      min: 0,
      max: 18,
      precision: 0,
      label: Formdict['header.form.decimal'],
      initVal: card.decimal || 0,
      required: true
@@ -2236,6 +2245,9 @@
    {
      type: 'number',
      key: 'fieldlength',
      min: 1,
      max: 1000000,
      precision: 0,
      label: Formdict['model.form.field'] + Formdict['model.length'],
      tooltip: '文本、下拉框、日期等字段默认长度为50,多行文本与文件上传字段默认长度为512',
      initVal: card.fieldlength || _fieldlength,
@@ -2244,6 +2256,9 @@
    {
      type: 'number',
      key: 'maxRows',
      min: 2,
      max: 100,
      precision: 0,
      label: Formdict['header.form.maxRows'],
      initVal: card.maxRows || 6,
      required: false
@@ -2286,6 +2301,9 @@
    {
      type: 'number',
      key: 'maxfile',
      min: 1,
      max: 1000000,
      precision: 0,
      label: '最大文件数',
      initVal: card.maxfile || '',
      required: false
@@ -2384,18 +2402,26 @@
      }]
    },
    {
      type: 'radio',
      key: 'entireLine',
      label: '占据整行',
      initVal: card.entireLine || 'false',
      required: false,
      options: [{
        value: 'true',
        text: '是'
      }, {
        value: 'false',
        text: '否'
      }]
      type: 'number',
      key: 'span',
      min: 1,
      max: 24,
      precision: 0,
      label: '表单宽度',
      initVal: card.span || ('textarea,hint,checkcard,brafteditor'.indexOf(card.type) > -1 ? 24 : 12),
      tooltip: '栅格布局整行24等分。',
      required: true
    },
    {
      type: 'number',
      key: 'labelwidth',
      min: 1,
      max: 100,
      precision: 1,
      label: '名称宽度',
      initVal: card.labelwidth || 33.3,
      tooltip: '名称占据表单宽度的百分比。注:存在多列表单时,当前表单如果想要占据整行可参照以下比例,两列(16.3)、三列(10.5)、四列(8.3)',
      required: true
    },
    {
      type: 'text',
@@ -2462,6 +2488,14 @@
    },
    {
      type: 'text',
      key: 'extra',
      label: '底部提示',
      tooltip: '显示于表单底部。',
      initVal: card.extra || '',
      required: false
    },
    {
      type: 'text',
      key: 'emptyText',
      label: '空值文本',
      tooltip: '空值的提示文本,选择设置空值时有效,默认值为《空》。',
src/templates/zshare/modalform/index.jsx
@@ -14,25 +14,26 @@
const { TextArea } = Input
const modalTypeOptions = {
  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'entireLine', 'tooltip', 'enter'],
  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'entireLine', 'tooltip', 'enter'],
  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'entireLine', 'tooltip', 'emptyText', 'enter'],
  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'entireLine', 'tooltip'],
  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine', 'tooltip', 'setAll', 'emptyText'],
  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'fieldlength', 'display', 'tooltip', 'width', 'multiple'],
  multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'entireLine', 'tooltip'],
  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine', 'tooltip', 'emptyText', 'enter'],
  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'entireLine', 'tooltip', 'suffix'],
  switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'entireLine', 'tooltip'],
  date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
  datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
  datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
  textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxRows', 'encryption', 'interception', 'tooltip'],
  color: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
  hint: ['label', 'type', 'blacklist', 'message'],
  brafteditor: ['required', 'hidelabel', 'hidden', 'readin', 'fieldlength', 'readonly', 'tooltip', 'encryption'],
  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'tooltip', 'extra', 'enter'],
  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter'],
  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter'],
  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'span', 'labelwidth', 'tooltip', 'extra'],
  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'setAll', 'emptyText'],
  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'fieldlength', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'width', 'multiple'],
  multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra'],
  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter'],
  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'tooltip', 'extra', 'suffix'],
  switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra'],
  date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra'],
  datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra'],
  datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra'],
  textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'span', 'labelwidth', 'maxRows', 'encryption', 'interception', 'tooltip', 'extra'],
  color: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra'],
  hint: ['label', 'type', 'blacklist', 'message', 'span', 'labelwidth'],
  split: ['label', 'type'],
  brafteditor: ['required', 'hidelabel', 'hidden', 'readin', 'fieldlength', 'readonly', 'span', 'labelwidth', 'tooltip', 'extra', 'encryption'],
  funcvar: [],
  linkMain: ['readonly', 'required', 'hidden', 'fieldlength', 'entireLine', 'tooltip']
  linkMain: ['readonly', 'required', 'hidden', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra']
}
class MainSearch extends Component {
@@ -147,6 +148,8 @@
    if (type === 'hint') {
      _options = fromJS(modalTypeOptions[type]).toJS()
    } else if (type === 'split') {
      return fromJS(modalTypeOptions[type]).toJS()
    } else if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(type)) {
      if (resourceType === '0') {        // 自定义资源
        _options.push('options')
@@ -417,10 +420,15 @@
          </Col>
        )
      } else if (item.type === 'number') {
        if (item.key === 'decimal') {
        if (item.max) {
          fields.push(
            <Col span={12} key={index}>
              <Form.Item label={item.label}>
              <Form.Item label={item.tooltip ?
                <Tooltip placement="topLeft" title={item.tooltip}>
                  <Icon type="question-circle" />
                  {item.label}
                </Tooltip> : item.label
              }>
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal || 0,
                  rules: [
@@ -429,50 +437,18 @@
                      message: this.props.dict['form.required.input'] + item.label + '!'
                    }
                  ]
                })(<InputNumber min={0} max={18} precision={0} />)}
                })(<InputNumber min={item.min} max={item.max} precision={item.precision} onPressEnter={this.handleSubmit}/>)}
              </Form.Item>
            </Col>
          )
        } else if (item.key === 'fieldlength' || item.key === 'maxfile') {
        } else {
          fields.push(
            <Col span={12} key={index}>
              <Form.Item label={item.label}>
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal,
                  rules: [
                    {
                      required: !!item.required,
                      message: this.props.dict['form.required.input'] + item.label + '!'
                    }
                  ]
                })(<InputNumber min={1} precision={0} />)}
              </Form.Item>
            </Col>
          )
        } else if (item.key === 'maxRows') {
          fields.push(
            <Col span={12} key={index}>
              <Form.Item label={item.label}>
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal,
                  rules: [
                    {
                      required: !!item.required,
                      message: this.props.dict['form.required.input'] + item.label + '!'
                    }
                  ]
                })(<InputNumber min={2} max={100} precision={0} />)}
              </Form.Item>
            </Col>
          )
        } else if (item.key === 'width') {
          fields.push(
            <Col span={12} key={index}>
              <Form.Item label={
              <Form.Item label={item.tooltip ?
                <Tooltip placement="topLeft" title={item.tooltip}>
                  <Icon type="question-circle" />
                  {item.label}
                </Tooltip>
                </Tooltip> : item.label
              }>
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal,
@@ -482,23 +458,7 @@
                      message: this.props.dict['form.required.input'] + item.label + '!'
                    }
                  ]
                })(<InputNumber min={1} max={24} precision={0} />)}
              </Form.Item>
            </Col>
          )
        } else {
          fields.push(
            <Col span={12} key={index}>
              <Form.Item label={item.label}>
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal,
                  rules: [
                    {
                      required: !!item.required,
                      message: this.props.dict['form.required.input'] + item.label + '!'
                    }
                  ]
                })(<InputNumber />)}
                })(<InputNumber onPressEnter={this.handleSubmit}/>)}
              </Form.Item>
            </Col>
          )
@@ -710,6 +670,8 @@
            }
          } else if (values.type === 'linkMain') {
            values.initval = ''
          } else if (values.type === 'split') {
            values.span = 24
          }
          ['linkField', 'valueField', 'valueText', 'orderBy'].forEach(item => {
src/templates/zshare/verifycard/index.jsx
@@ -15,6 +15,7 @@
import BillcodeForm from './billcodeform'
import VoucherForm from './voucherform'
import asyncComponent from '@/utils/asyncComponent'
import { updateForm } from '@/utils/utils-update.js'
import './index.scss'
const { TabPane } = Tabs
@@ -571,13 +572,7 @@
        })
        resolve(_fields)
      } else if (card.modal) {
        if (card.modal.groups && card.modal.groups.length > 0) {
          card.modal.groups.forEach(group => {
            _fields.push(...group.sublist)
          })
        } else {
          _fields = card.modal.fields || []
        }
        _fields = card.modal.fields || []
        resolve(_fields)
      } else if (card.OpenType === 'pop') {
        Api.getSystemConfig({
@@ -598,13 +593,8 @@
            if (!_LongParam) {
              message.warning('未获取到表单信息,部分验证将无法设置!')
            } else {
              if (_LongParam.groups.length > 0) {
                _LongParam.groups.forEach(group => {
                  _fields.push(...group.sublist)
                })
              } else {
                _fields = _LongParam.fields || []
              }
              _LongParam = updateForm(_LongParam)
              _fields = _LongParam.fields || []
            }
          } else {
            notification.warning({
src/utils/utils-update.js
@@ -1,4 +1,59 @@
/**
 * @description 升级表单信息
 * @param {Object}   config      表单配置信息
 * @return {Object}  config
 */
export function updateForm (config) {
  if (!config.version && config.groups) {
    config.version = '1.0'
    if (config.groups && config.groups.length > 0) {
      let fields = []
      config.groups.forEach(group => {
        if (group.sublist.length === 0) return
        if (!group.default) {
          fields.push({
            type: 'split',
            label: group.label,
            uuid: group.uuid,
            span: 24
          })
        }
        fields.push(...group.sublist)
      })
      config.fields = fields
    }
    delete config.groups
    let _col = config.setting.cols || '2'
    config.fields = config.fields.map(item => {
      item.labelwidth = 33.3
      if (_col === '1' || item.entireLine === 'true' || ['textarea','hint','checkcard','brafteditor'].includes(item.type)) {
        item.span = 24
        if (_col === '2') {
          item.labelwidth = 16.3
        } else if (_col === '3') {
          item.labelwidth = 10.5
        } else if (_col === '4') {
          item.labelwidth = 8.3
        }
      } else if (_col === '2') {
        item.span = 12
      } else if (_col === '3') {
        item.span = 8
      } else if (_col === '4') {
        item.span = 6
      }
      return item
    })
  }
  return config
}
/**
 * @description 升级主表信息
 * @param {Object}   config      页面配置信息
 * @return {Object}  config