king
2020-10-09 8701e6928b20cc3c4af763f8e72be5396c2be99d
2020-10-09
15个文件已修改
938 ■■■■ 已修改文件
src/api/index.js 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/actioncomponent/formconfig.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.jsx 126 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecontroller/index.jsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecontroller/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/actionform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customscript/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 256 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -400,6 +400,53 @@
  }
  /**
   * @description 获取云端配置,并缓存信息
   */
  getCloudCacheConfig (param) {
    param.lang = localStorage.getItem('lang') || ''
    param.appkey = window.GLOB.appkey || ''
    param.SessionUid = localStorage.getItem('SessionUid') || ''
    if (sessionStorage.getItem('CloudUserID') && options.cloudServiceApi) { // 存在云端登录信息,且存在云端地址
      param.rduri = options.cloudServiceApi
      param.userid = sessionStorage.getItem('CloudUserID')
      param.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
    } else if (window.GLOB.mainSystemApi) {
      param.rduri = window.GLOB.mainSystemApi
      param.userid = sessionStorage.getItem('UserID')
      param.LoginUID = sessionStorage.getItem('LoginUID') || ''
    } else {
      param.userid = sessionStorage.getItem('UserID')
      param.LoginUID = sessionStorage.getItem('LoginUID') || ''
    }
    let _param = JSON.parse(JSON.stringify(param)) // 缓存校验,去除时间和加密字符
    delete _param.timestamp
    delete _param.secretkey
    delete _param.open_key
    _param = JSON.stringify(_param)
    _param  = md5(_param)
    if (window.GLOB.CacheMap.has(_param)) {
      return Promise.resolve(window.GLOB.CacheMap.get(_param))
    } else {
      param = this.encryptParam(param)
      return new Promise(resolve => {
        axios({
          url: `/webapi/dostars${param.func ? '/' + param.func : ''}`,
          data: param
        }).then(res => {
          if (res.status) {
            window.GLOB.CacheMap.set(_param, res)
          }
          resolve(res)
        })
      })
    }
  }
  /**
   * @description 获取或修改系统配置,增加appkey
   */
  getSystemConfig (param) {
src/components/header/index.jsx
@@ -740,9 +740,9 @@
        {this.props.editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>退出</Button> : null}
        {/* 进入编辑按钮 */}
        {this.props.editState && !this.props.editLevel ? <Icon onClick={this.enterEdit} className="edit-check" type="edit" /> : null}
        {this.props.editState && !this.props.editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' ?
        {/* {this.props.editState && !this.props.editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' ?
          <a href="#/mobmanage" target="_blank" className="mobile" type="edit"> 应用管理 <Icon type="arrow-right" /></a> : null
        }
        } */}
        {/* 编辑菜单 */}
        {this.props.editLevel === 'level1' ? <EditMenu menulist={this.state.menulist} reload={this.reload} exitEdit={this.exitEdit}/> : null}
        {/* 头像、用户名 */}
src/menu/actioncomponent/formconfig.jsx
@@ -391,8 +391,5 @@
    // }
  ]
  // if (type === 'chart') {
  //   return forms
  // }
  return forms
}
src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -48,7 +48,7 @@
  const getContent = () => {
    if (card.eleType === 'text' || card.eleType === 'number') {
      let val = `${card.prefix}${card.value}${card.postfix}`
      let val = `${card.prefix || ''}${card.value || ''}${card.postfix || ''}`
      return val
    } else if (card.eleType === 'icon') {
      return (<Icon type={card.icon}/>)
src/menu/components/card/cardcellcomponent/index.jsx
@@ -1,22 +1,29 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal } from 'antd'
import {connect} from 'react-redux'
import { Modal, Button, notification } from 'antd'
import Api from '@/api'
import options from '@/store/options.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import { getCardCellForm } from './formconfig'
import { getActionForm } from '@/menu/actioncomponent/formconfig'
import MKEmitter from '@/utils/events.js'
import ElementForm from './elementform'
import DragElement from './dragaction'
import ActionForm from '@/menu/actioncomponent/actionform'
import CreateFunc from '@/templates/zshare/createfunc'
import './index.scss'
const { confirm } = Modal
class CardCellComponent extends Component {
  static propTpyes = {
    config: PropTypes.object,        // 菜单配置信息
    cards: PropTypes.object,         // 菜单配置信息
    card: PropTypes.object,
    elements: PropTypes.array,       // 元素集
    updateElement: PropTypes.func    // 菜单配置更新
  }
@@ -27,6 +34,7 @@
    formlist: null,      // 表单信息
    elements: null,      // 按钮组
    visible: false,      // 模态框控制
    actvisible: false    // 按钮编辑模态框
  }
  /**
@@ -45,7 +53,7 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.config), fromJS(nextProps.config)) || !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.props.cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState))
  }
  /**
@@ -58,28 +66,31 @@
    MKEmitter.removeListener('cardAddElement', this.cardAddElement)
  }
  cardAddElement = (cardId, element) => {
    if (cardId !== this.props.config.uuid) return
  cardAddElement = (ids, element) => {
    if (!ids || ids.length !== 2 || ids[0] !== this.props.cards.uuid || ids[1] !== this.props.card.uuid) return
    const { elements } = this.state
    this.setState({elements: [...elements, element]})
    this.handleElement(element)
    if (element.eleType === 'button') {
      this.handleAction(element)
    } else {
      this.handleElement(element)
    }
  }
  /**
   * @description 按钮顺序调整
   */
  handleList = (list) => {
    const { config } = this.props
    this.setState({elements: list}, () => {
      this.props.updateElement({...config, elements: list})
      this.props.updateElement(list)
    })
  }
  /**
   * @description 按钮编辑,获取按钮表单信息
   * @description 元素编辑,获取元素表单信息
   */
  handleElement = (card) => {
    this.setState({
@@ -87,6 +98,141 @@
      card: card,
      formlist: getCardCellForm(card)
    })
  }
  /**
   * @description 按钮编辑,获取按钮表单信息
   */
  handleAction = (card) => {
    const { menu, cards } = this.props
    let ableField = menu.permFuncField ? menu.permFuncField.join(', ') : ''
    let functip = <div>
      <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p>
      <p>{this.state.dict['model.tooltip.func.outface']}</p>
    </div>
    let menulist = []
    if (menu.fstMenuList) {
      menulist = menu.fstMenuList.map(item => {
        return {
          value: item.MenuID,
          label: item.text,
          isLeaf: false
        }
      })
    }
    let modules = this.getModules(menu.components, cards.uuid)
    if (menu.fstMenuList && card.linkmenu && card.linkmenu.length > 0) {
      let _param = {
        func: 'sPC_Get_FunMenu',
        ParentID: card.linkmenu[0],
        systemType: options.sysType,
        debug: 'Y'
      }
      Api.getSystemConfig(_param).then(result => {
        if (result.status) {
          menulist = menulist.map(item => {
            if (item.value === card.linkmenu[0]) {
              item.children = result.data.map(item => {
                let submenu = {
                  value: item.ParentID,
                  label: item.MenuNameP,
                  children: item.FunMenu.map(cell => {
                    return {
                      value: cell.MenuID,
                      label: cell.MenuName,
                      MenuID: cell.MenuID,
                      MenuName: cell.MenuName,
                      MenuNo: cell.MenuNo,
                      Ot: cell.Ot,
                      PageParam: cell.PageParam,
                      LinkUrl: cell.LinkUrl,
                      disabled: cell.MenuID === menu.MenuID
                    }
                  })
                }
                return submenu
              })
            }
            return item
          })
        } else {
          notification.warning({
            top: 92,
            message: result.message,
            duration: 5
          })
        }
        this.setState({
          actvisible: true,
          card: card,
          formlist: getActionForm(card, functip, cards.setting, menu.permFuncField, '', menulist, modules)
        })
      })
    } else {
      this.setState({
        actvisible: true,
        card: card,
        formlist: getActionForm(card, functip, cards.setting, menu.permFuncField, '', menulist, modules)
      })
    }
  }
  getModules = (components, selfId) => {
    let modules = components.map(item => {
      if (item.uuid === selfId) {
        return {
          children: null
        }
      } else if (item.format) {
        return {
          value: item.uuid,
          label: item.name
        }
      } else if (item.type === 'tabs') {
        let _item = {
          value: item.uuid,
          label: item.name,
          children: item.subtabs.map(f_tab => {
            let subItem = {
              value: f_tab.uuid,
              label: f_tab.label,
              children: this.getModules(f_tab.components, selfId)
            }
            if (!subItem.children || subItem.children.length === 0) {
              return {children: null}
            }
            return subItem
          })
        }
        _item.children = _item.children.filter(t => t.children !== null)
        if (_item.children.length === 0) {
          return {children: null}
        }
        return _item
      } else {
        return {
          children: null
        }
      }
    })
    modules = modules.filter(mod => mod.children !== null)
    if (modules.length === 0) {
      return null
    }
    return modules
  }
  /**
@@ -105,19 +251,15 @@
    this.setState({
      card: null,
      elements: _elements,
      visible: false
      visible: false,
      actvisible: false
    })
  }
  /**
   * @description 搜索修改后提交保存
   * 1、去除系统默认搜索条件
   * 2、字段及提示文字重复校验
   * 3、更新下拉菜单可选集合
   * 4、下拉菜单数据源语法验证
   * @description 元素修改后提交保存
   */
  handleSubmit = () => {
    const { config } = this.props
    const { elements } = this.state
    this.elementFormRef.handleConfirm().then(ele => {
@@ -130,7 +272,28 @@
        elements: _elements,
        visible: false
      }, () => {
        this.props.updateElement({...config, elements: _elements})
        this.props.updateElement(_elements)
      })
    })
  }
  /**
   * @description 元素修改后提交保存
   */
  handleActionSubmit = () => {
    const { elements } = this.state
    this.actionFormRef.handleConfirm().then(ele => {
      let _elements = elements.map(cell => {
        if (cell.uuid === ele.uuid) return ele
        return cell
      })
      this.setState({
        elements: _elements,
        actvisible: false
      }, () => {
        this.props.updateElement(_elements)
      })
    })
  }
@@ -139,7 +302,6 @@
   * @description 按钮删除
   */
  deleteElement = (card) => {
    const { config } = this.props
    const { dict, elements } = this.state
    let _this = this
@@ -151,7 +313,7 @@
        _this.setState({
          elements: _elements
        }, () => {
          _this.props.updateElement({...config, elements: _elements})
          _this.props.updateElement(_elements)
        })
      },
      onCancel() {}
@@ -159,8 +321,8 @@
  }
  render() {
    const { config } = this.props
    const { elements, visible, card, dict } = this.state
    const { cards } = this.props
    const { elements, visible, actvisible, card, dict } = this.state
    return (
      <div className="model-menu-card-cell-list">
@@ -185,8 +347,31 @@
            card={card}
            formlist={this.state.formlist}
            inputSubmit={this.handleSubmit}
            config={config}
            config={cards}
            wrappedComponentRef={(inst) => this.elementFormRef = inst}
          />
        </Modal>
        {/* 编辑按钮:复制、编辑 */}
        <Modal
          title={dict['model.action'] + '-' + (card && card.copyType === 'action' ? dict['model.copy'] : dict['model.edit'])}
          visible={actvisible}
          width={800}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
            <CreateFunc key="create" dict={dict} ref="btnCreatFunc" trigger={this.creatFunc}/>,
            <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}
            card={card}
            formlist={this.state.formlist}
            inputSubmit={this.handleActionSubmit}
            setting={cards.setting}
            wrappedComponentRef={(inst) => this.actionFormRef = inst}
          />
        </Modal>
      </div>
@@ -194,5 +379,14 @@
  }
}
const mapStateToProps = (state) => {
  return {
    menu: state.customMenu
  }
}
export default CardCellComponent
const mapDispatchToProps = () => {
  return {}
}
export default connect(mapStateToProps, mapDispatchToProps)(CardCellComponent)
src/menu/components/card/cardcomponent/index.jsx
@@ -6,19 +6,17 @@
import asyncComponent from '@/utils/asyncComponent'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
// import { getCardCellForm } from './formconfig'
import SettingForm from './settingform'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
const { confirm } = Modal
const CardCellComponent = asyncComponent(() => import('../cardcellcomponent'))
class CardBoxComponent extends Component {
  static propTpyes = {
    config: PropTypes.object,        // 菜单配置信息
    cards: PropTypes.object,         // 卡片行配置信息
    card: PropTypes.object,          // 卡片配置信息
    deleteElement: PropTypes.func,   // 卡片删除
    updateElement: PropTypes.func    // 菜单配置更新
@@ -47,7 +45,6 @@
  }
  componentDidMount () {
    MKEmitter.addListener('cardAddElement', this.cardAddElement)
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
@@ -62,15 +59,14 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('cardAddElement', this.cardAddElement)
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { config } = this.props
    const { cards } = this.props
    const { card, side } = this.state
    if (comIds.length !== 2 || comIds[0] !== config.uuid || comIds[1] !== card.uuid) return
    if (comIds.length !== 2 || comIds[0] !== cards.uuid || comIds[1] !== card.uuid) return
    let _card = fromJS(card).toJS()
    if (side === 'back') {
@@ -86,108 +82,22 @@
    this.props.updateElement(_card)
  }
  updateCard = (cell) => {
  updateCard = (elements) => {
    const { card, side } = this.state
  }
    let _card = {}
  cardAddElement = (cardId, element) => {
    if (cardId !== this.props.config.uuid) return
    const { elements } = this.state
    this.setState({elements: [...elements, element]})
    this.handleElement(element)
  }
  /**
   * @description 按钮顺序调整
   */
  handleList = (list) => {
    const { config } = this.props
    this.setState({elements: list}, () => {
      this.props.updateElement({...config, elements: list})
    })
  }
  /**
   * @description 按钮编辑,获取按钮表单信息
   */
  handleElement = (card) => {
    this.setState({
      visible: true,
      card: card,
      // formlist: getCardCellForm(card)
    })
  }
  /**
   * @description 取消保存,如果元素为新添元素,则从序列中删除
   */
  editModalCancel = () => {
    const { card, elements } = this.state
    let _elements = null
    if (card.focus) {
      _elements = elements.filter(item => item.uuid !== card.uuid)
    if (side === 'back') {
      _card = {...card, backElements: elements}
    } else {
      _elements = elements
      _card = {...card, elements: elements}
    }
    this.setState({
      card: null,
      elements: _elements,
      visible: false
      card: _card
    })
  }
  /**
   * @description 搜索修改后提交保存
   * 1、去除系统默认搜索条件
   * 2、字段及提示文字重复校验
   * 3、更新下拉菜单可选集合
   * 4、下拉菜单数据源语法验证
   */
  handleSubmit = () => {
    const { config } = this.props
    const { elements } = this.state
    this.elementFormRef.handleConfirm().then(ele => {
      let _elements = elements.map(cell => {
        if (cell.uuid === ele.uuid) return ele
        return cell
      })
      this.setState({
        elements: _elements,
        visible: false
      }, () => {
        this.props.updateElement({...config, elements: _elements})
      })
    })
  }
  /**
   * @description 按钮删除
   */
  deleteElement = (card) => {
    const { config } = this.props
    const { dict, elements } = this.state
    let _this = this
    confirm({
      content: dict['model.confirm'] + dict['model.delete'] + '元素吗?',
      onOk() {
        let _elements = elements.filter(item => item.uuid !== card.uuid)
        _this.setState({
          elements: _elements
        }, () => {
          _this.props.updateElement({...config, elements: _elements})
        })
      },
      onCancel() {}
    })
    this.props.updateElement(_card)
  }
  changeSide = () => {
@@ -212,6 +122,7 @@
  }
  
  addElement = () => {
    const { cards } = this.props
    const { card } = this.state
    let newcard = {}
@@ -225,10 +136,11 @@
    newcard.align = 'left'
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', card.uuid, newcard)
    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard)
  }
  addButton = () => {
    const { cards } = this.props
    const { card } = this.state
    let newcard = {}
@@ -252,11 +164,11 @@
    newcard.show = 'link'
    // 注册事件-添加元素
    MKEmitter.emit('addButton', card.uuid, newcard)
    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard)
  }
  changeStyle = () => {
    const { config } = this.props
    const { cards } = this.props
    const { card, side } = this.state
    let _style = null
@@ -268,7 +180,7 @@
      options = ['background', 'border', 'padding', 'margin']
    }
    MKEmitter.emit('changeStyle', [config.uuid, card.uuid], options, _style)
    MKEmitter.emit('changeStyle', [cards.uuid, card.uuid], options, _style)
  }
  settingSubmit = () => {
@@ -292,6 +204,7 @@
  }
  render() {
    const { cards } = this.props
    const { card, elements, side, settingVisible, dict } = this.state
    let _style = card.style
@@ -301,7 +214,7 @@
    return (
      <div className={'ant-col card-item ant-col-' + (card.setting.width || 6)} style={_style}>
        <CardCellComponent config={card} elements={elements} updateElement={this.updateComponent}/>
        <CardCellComponent cards={cards} card={card} elements={elements} updateElement={this.updateCard}/>
        <div className="card-control">
          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
            <div className="mk-popover-control">
@@ -310,6 +223,7 @@
              <Icon className="edit" type="edit" onClick={() => this.setState({settingVisible: true})} />
              <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
              {card.setting.type === 'multi' ? <Switch size="small" onClick={this.changeSide} defaultChecked /> : null}
              <Icon className="close" title="删除卡片" type="delete" onClick={() => this.props.deleteElement(card)} />
            </div>
          } trigger="hover">
            <Icon type="tool" />
src/menu/components/card/data-card/index.jsx
@@ -146,7 +146,6 @@
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
    
        _this.setState({card})
        _this.props.updateConfig(card)
      },
      onCancel() {}
@@ -182,13 +181,13 @@
          <div className="mk-popover-control">
            <WrapComponent config={card} updateConfig={this.updateComponent} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
            <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
            <SettingComponent config={card} updateConfig={this.updateComponent} />
          </div>
        } trigger="hover">
          <Icon type="tool" />
        </Popover>
        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} config={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        {card.wrap.addable === 'true' ? <div className="card-add-button"><Icon type="plus" /></div> : null}
      </div>
    )
src/menu/components/card/data-card/index.scss
@@ -7,6 +7,7 @@
  background-size: cover;
  border-style: solid;
  border-width: 0;
  min-height: 50px;
  
  .card-control {
    position: absolute;
src/menu/stylecontroller/index.jsx
@@ -27,6 +27,7 @@
    bgimages: [],
    backgroundImage: '',
    options: [],
    borposition: 'outer'
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -62,6 +63,7 @@
      comIds: comIds,
      card: fromJS(style).toJS(),
      options: options,
      borposition: 'outer',
      backgroundImage
    })
  }
@@ -192,12 +194,61 @@
    this.updateStyle({backgroundImage: val})
  }
  changeBorderStyle = (val) => {
    const { borposition } = this.state
    let _style = {}
    if (borposition === 'outer') {
      _style.borderStyle = val
    } else if (borposition === 'left') {
      _style.borderLeftStyle = val
    } else if (borposition === 'right') {
      _style.borderRightStyle = val
    } else if (borposition === 'top') {
      _style.borderTopStyle = val
    } else if (borposition === 'bottom') {
      _style.borderBottomStyle = val
    }
    this.updateStyle(_style)
  }
  changeBorderWidth = (val) => {
    this.updateStyle({borderWidth: val})
    const { borposition } = this.state
    let _style = {}
    if (borposition === 'outer') {
      _style.borderWidth = val
    } else if (borposition === 'left') {
      _style.borderLeftWidth = val
    } else if (borposition === 'right') {
      _style.borderRightWidth = val
    } else if (borposition === 'top') {
      _style.borderTopWidth = val
    } else if (borposition === 'bottom') {
      _style.borderBottomWidth = val
    }
    this.updateStyle(_style)
  }
  changeBorderColor = (val) => {
    this.updateStyle({borderColor: val})
    const { borposition } = this.state
    let _style = {}
    if (borposition === 'outer') {
      _style.borderColor = val
    } else if (borposition === 'left') {
      _style.borderLeftColor = val
    } else if (borposition === 'right') {
      _style.borderRightColor = val
    } else if (borposition === 'top') {
      _style.borderTopColor = val
    } else if (borposition === 'bottom') {
      _style.borderBottomColor = val
    }
    this.updateStyle(_style)
  }
  changeHeight = (val) => {
@@ -218,7 +269,7 @@
  }
  render () {
    const { card, options, backgroundImage, bgimages } = this.state
    const { card, options, backgroundImage, bgimages, borposition } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -369,10 +420,67 @@
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="边框宽度" type="border-outer" />}
                    label={<Icon title="边框位置" type="border" />}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.borderWidth || ''} options={['px']} onChange={this.changeBorderWidth}/>
                    <Radio.Group className="border-position" defaultValue={'outer'} onChange={(e) => this.setState({borposition: e.target.value})}>
                      <Radio value="outer"><Icon title="外边框" type="border-outer" /></Radio>
                      <Radio value="left"><Icon title="左边框" type="border-left" /></Radio>
                      <Radio value="right"><Icon title="右边框" type="border-right" /></Radio>
                      <Radio value="top"><Icon title="上边框" type="border-top" /></Radio>
                      <Radio value="bottom"><Icon title="下边框" type="border-bottom" /></Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="边框样式" type="border-outer" />}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    {borposition === 'outer' ? <Select defaultValue={card.borderStyle || 'solid'} onChange={this.changeBorderStyle}>
                      <Option value="solid">实线</Option>
                      <Option value="dotted">点划线</Option>
                      <Option value="dashed">虚线</Option>
                      <Option value="double">双线</Option>
                    </Select> : null}
                    {borposition === 'left' ? <Select defaultValue={card.borderLeftStyle || 'solid'} onChange={this.changeBorderStyle}>
                      <Option value="solid">实线</Option>
                      <Option value="dotted">点划线</Option>
                      <Option value="dashed">虚线</Option>
                      <Option value="double">双线</Option>
                    </Select> : null}
                    {borposition === 'right' ? <Select defaultValue={card.borderRightStyle || 'solid'} onChange={this.changeBorderStyle}>
                      <Option value="solid">实线</Option>
                      <Option value="dotted">点划线</Option>
                      <Option value="dashed">虚线</Option>
                      <Option value="double">双线</Option>
                    </Select> : null}
                    {borposition === 'top' ? <Select defaultValue={card.borderTopStyle || 'solid'} onChange={this.changeBorderStyle}>
                      <Option value="solid">实线</Option>
                      <Option value="dotted">点划线</Option>
                      <Option value="dashed">虚线</Option>
                      <Option value="double">双线</Option>
                    </Select> : null}
                    {borposition === 'bottom' ? <Select defaultValue={card.borderBottomStyle || 'solid'} onChange={this.changeBorderStyle}>
                      <Option value="solid">实线</Option>
                      <Option value="dotted">点划线</Option>
                      <Option value="dashed">虚线</Option>
                      <Option value="double">双线</Option>
                    </Select> : null}
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="边框宽度" type="column-width" />}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    {borposition === 'outer' ? <StyleInput defaultValue={card.borderWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'left' ? <StyleInput defaultValue={card.borderLeftWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'right' ? <StyleInput defaultValue={card.borderRightWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'top' ? <StyleInput defaultValue={card.borderTopWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'bottom' ? <StyleInput defaultValue={card.borderBottomWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                  </Form.Item>
                </Col>
                <Col span={24}>
@@ -381,7 +489,11 @@
                    label={<Icon title="边框颜色" type="bg-colors" />}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <ColorSketch defaultValue={card.borderColor || 'transparent'} onChange={this.changeBorderColor} />
                    {borposition === 'outer' ? <ColorSketch defaultValue={card.borderColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'left' ? <ColorSketch defaultValue={card.borderLeftColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'right' ? <ColorSketch defaultValue={card.borderRightColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'top' ? <ColorSketch defaultValue={card.borderTopColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'bottom' ? <ColorSketch defaultValue={card.borderBottomColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                  </Form.Item>
                </Col>
                <Col span={24}>
src/menu/stylecontroller/index.scss
@@ -32,6 +32,15 @@
          }
          .ant-form-item-control-wrapper  {
            .ant-form-item-control {
              .border-position {
                .ant-radio-wrapper {
                  margin-right: 0px;
                  span.ant-radio + * {
                    padding-left: 4px;
                  }
                }
              }
              input {
                background: transparent;
                color: rgba(255, 255, 255, 0.65);
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -735,9 +735,118 @@
      _unclose = true
    }
    if (btn.verify && btn.verify.noteEnable === 'true') {
      this.sendMessage()
    }
    this.props.updateStatus('refresh', btn.execSuccess, _unclose)
  }
  sendMessage = () => {
    const { btn : { verify } } = this.props
    let param = {
      func: 's_get_sms_local',
      TypeCharOne: verify.noteTemp, // N不同内容,Y相同内容
      TypeCharTwo: verify.noteType  // N定时,Y实时
    }
    param.LText = Utils.formatOptions(Utils.getuuid())
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    Api.genericInterface(param).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
      let _param = {
        templatecode: verify.noteCode, // 模板编码
        TypeCharOne: verify.noteTemp,  // N不同内容,Y相同内容
      }
      _param.submitdate = res.submitdate
      let limit = 5 // 实时最大为5条,定时最大为100条
      let mobMap = new Map()
      if (verify.noteType === 'N') {
        _param.func = 's_get_sms_sso_timer'
        limit = 100
      } else if (verify.noteType === 'Y') {
        _param.func = 's_get_sms_sso_realtime'
      }
      let Ltext = []
      let error = false
      if (verify.noteTemp === 'Y') {
        _param.p1 = res.p1 || ''
        _param.p2 = res.p2 || ''
        _param.p3 = res.p3 || ''
        _param.p4 = res.p4 || ''
        _param.p5 = res.p5 || ''
        let _p = _param.p1 + _param.p2 + _param.p3 + _param.p4 + _param.p5
        if (/\/|\.|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信|Q/.test(_p)) {
          error = true
        }
      }
      res.send_data && res.send_data.forEach(item => {
        if (item.mob && !mobMap.has(item.mob) && Ltext.length < limit) {
          if (verify.noteTemp === 'Y') {
            Ltext.push(`'${item.mob}'`)
          } else {
            let _p = `'${item.p1 || ''}','${item.p2 || ''}','${item.p3 || ''}','${item.p4 || ''}','${item.p5 || ''}','${item.mob}'`
            if (/\/|\.|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信|Q/.test(_p)) {
              error = true
            }
            Ltext.push(_p)
          }
          mobMap.set(item.mob, true)
        }
      })
      if (error) {
        notification.warning({
          top: 92,
          message: '消息中含有非法字符',
          duration: 5
        })
        return
      }
      if (Ltext.length === 0) return
      Ltext = Ltext.join(';')
      _param.LText = window.btoa(window.encodeURIComponent(Ltext))
      _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
      _param.rduri = 'http://sso.mk9h.cn/webapi/dostar'
      _param.appkey = window.GLOB.appkey || ''
      Api.dostarInterface(_param).then(result => {
        if (!result.status) {
          notification.warning({
            top: 92,
            message: result.message,
            duration: 5
          })
        }
      })
    })
  }
  /**
   * @description 操作失败后处理
   * 1、状态码为 E、N、F、NM 时,显示相应提示信息
src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -344,7 +344,7 @@
          _fieldval.Ot = 'requiredSgl'
        } else if (value === 'audit') {
          _fieldval.label = '审核'
          _fieldval.class = 'purple'
          _fieldval.class = 'primary'
          _fieldval.Ot = 'requiredSgl'
        } else if (value === 'LogicDelete' || value === 'delete') {
          _fieldval.label = '删除'
src/templates/zshare/verifycard/customform/index.jsx
@@ -41,7 +41,7 @@
    })
    this.props.form.setFieldsValue({
      sql: '',
      sql: ' ',
      errmsg: ''
    })
  }
@@ -117,7 +117,7 @@
              this.props.customChange(values)
            })
            this.props.form.setFieldsValue({
              sql: '',
              sql: ' ',
              errmsg: ''
            })
          } else {
src/templates/zshare/verifycard/customscript/index.jsx
@@ -119,7 +119,7 @@
              this.props.scriptsChange(values)
            })
            this.props.form.setFieldsValue({
              sql: ''
              sql: ' '
            })
          } else {
            this.setState({loading: false})
@@ -139,7 +139,7 @@
    })
    this.props.form.setFieldsValue({
      sql: ''
      sql: ' '
    })
  }
src/templates/zshare/verifycard/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Tabs, Row, Col, Radio, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Tooltip, Typography } from 'antd'
import { Form, Tabs, Row, Col, Radio, Button, Table, Select, Popconfirm, Icon, notification, Modal, message, InputNumber, Tooltip, Typography } from 'antd'
import moment from 'moment'
import Api from '@/api'
@@ -30,7 +30,8 @@
  }
  state = {
    initsql: '',          // sql验证时变量声明及赋值
    initsql: '',            // sql验证时变量声明及赋值
    notes: [],              // 短信模板
    verify: {},
    fields: [],
    usefulfields: '',
@@ -451,6 +452,9 @@
    }
    _verify.default = _verify.default || 'true'
    _verify.noteEnable = _verify.noteEnable || 'false' // 短信发送是否开启
    _verify.noteType = _verify.noteType || 'N'         // 短信发送模式:Y(实时)、N(定时)
    _verify.noteTemp = _verify.noteTemp || 'Y'         // 短信发送模板:Y(相同)、N(不同)
    _verify.invalid = _invalid
    _verify.uniques = _verify.uniques || []
    _verify.contrasts = _verify.contrasts || []
@@ -983,134 +987,71 @@
  }
  componentDidMount() {
    // 获取生成单号一级菜单
    let defer1 = new Promise(resolve => {
      let _orderSql = `select distinct ModularCode as ID,ModularCode+ModularName+ModularNo as NameNO from sModular where deleted=0 and Appkey=case when Appkey='' then '' else @Appkey@ end order by ID asc`
      _orderSql = Utils.formatOptions(_orderSql)
      let orderParam = {
        func: 'sPC_Get_SelectedList',
        LText: _orderSql,
        obj_name: 'data',
        arr_field: 'ID,NameNO'
    let mutilForms = [
      {
        obj_name: 'modular',
        arr_field: 'ID,NameNO',
        LText: window.btoa(window.encodeURIComponent(`select distinct ModularCode as ID,ModularCode+ModularName+ModularNo as NameNO from sModular where deleted=0 and Appkey=case when Appkey='' then '' else @Appkey@ end order by ID asc`))
      },
      {
        obj_name: 'modularDetail',
        arr_field: 'ModularDetailCode,CodeName,BID,Type',
        LText: window.btoa(window.encodeURIComponent(`select distinct ModularDetailCode,ModularDetailCode+ModularDetailName as CodeName,ModularCode as BID,Type from sModularDetail where Deleted=0 and Appkey=case when Appkey='' then '' else @Appkey@ end order by ModularDetailCode`))
      },
      {
        obj_name: 'voucher',
        arr_field: 'ID,NameNO,TypeCharOne',
        LText: window.btoa(window.encodeURIComponent('select distinct ModularCode as ID,ModularCode+ModularName+ModularNo as NameNO,TypeCharOne from sModular where deleted=0  and Appkey=case when Appkey=\'\' then \'\' else @Appkey@ end  order by ModularCode'))
      },
      {
        obj_name: 'voucherDetail',
        arr_field: 'ModularDetailCode,CodeName,BID,VoucherTypeTwo,IDefine1',
        LText: window.btoa(window.encodeURIComponent('select distinct ModularDetailCode,ModularDetailCode+ModularDetailName as CodeName,ModularCode as BID, VoucherTypeTwo, IDefine1 from sModularDetail where Deleted=0 and VoucherTypeTwo!=\'\' and Appkey=case when Appkey=\'\' then \'\' else @Appkey@ end  order by ModularDetailCode'))
      },
      {
        obj_name: 'noteCodes',
        arr_field: 'templatecode,describe',
        LText: window.btoa(window.encodeURIComponent(`select templatecode,'['+SignName+']'+describe as describe from (select * from bd_msn_sms_temp where  deleted=0 and TypeDesc='QX' and status=20 ) t inner join (select openid from susers where uid=@userid@) u on t.openid =t.openid`))
      }
    ]
      orderParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      orderParam.secretkey = Utils.encrypt(orderParam.LText, orderParam.timestamp)
      orderParam.open_key = Utils.encryptOpenKey(orderParam.secretkey, orderParam.timestamp) // 云端数据验证
      Api.getSystemConfig(orderParam).then(res => {
        if (res.status) {
          resolve(res)
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
    mutilForms = mutilForms.map(item => `select '${item.obj_name}' as obj_name,'${item.arr_field}' as arr_field,'${item.LText}' as LText`)
    let mutilparam = {
      func: 'sPC_Get_SelectedList',
      LText: mutilForms.join(' union all '),
      obj_name: '',
      arr_field: '',
      table_type: 'Y'
    }
    mutilparam.LText = Utils.formatOptions(mutilparam.LText)
    mutilparam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    mutilparam.secretkey = Utils.encrypt(mutilparam.LText, mutilparam.timestamp)
    mutilparam.open_key = Utils.encryptOpenKey(mutilparam.secretkey, mutilparam.timestamp)
    Api.getCloudCacheConfig(mutilparam).then(res => {
      if (res.status) {
        this.setState({
          orderModular: res.modular,
          orderModularDetail: res.modularDetail,
          voucher: res.voucher,
          voucherDetail: res.voucherDetail,
          notes: res.noteCodes.map(item => {
            return {
              name: item.describe,
              value: item.templatecode
            }
          })
        }
      })
    })
    // 获取生成单号二级菜单
    let defer2 = new Promise(resolve => {
      let _orderDetailSql = `select distinct ModularDetailCode,ModularDetailCode+ModularDetailName as CodeName,ModularCode as BID,Type from sModularDetail where Deleted=0 and Appkey=case when Appkey='' then '' else @Appkey@ end order by ModularDetailCode`
      _orderDetailSql = Utils.formatOptions(_orderDetailSql)
      let orderDetailParam = {
        func: 'sPC_Get_SelectedList',
        LText: _orderDetailSql,
        obj_name: 'data',
        arr_field: 'ModularDetailCode,CodeName,BID,Type'
        })
      } else {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      }
      orderDetailParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      orderDetailParam.secretkey = Utils.encrypt(orderDetailParam.LText, orderDetailParam.timestamp)
      orderDetailParam.open_key = Utils.encryptOpenKey(orderDetailParam.secretkey, orderDetailParam.timestamp) // 云端数据验证
      Api.getSystemConfig(orderDetailParam).then(res => {
        if (res.status) {
          resolve(res)
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
        }
      })
    })
    Promise.all([defer1, defer2]).then(result => {
      this.setState({
        orderModular: result[0].data,
        orderModularDetail: result[1].data
      })
    })
    // 获取凭证二级菜单
    let defer3 = new Promise(resolve => {
      let _voucherSql = 'select distinct ModularCode as ID,ModularCode+ModularName+ModularNo as NameNO,TypeCharOne from sModular where deleted=0  and Appkey=case when Appkey=\'\' then \'\' else @Appkey@ end  order by ModularCode'
      _voucherSql = Utils.formatOptions(_voucherSql)
      let voucherParam = {
        func: 'sPC_Get_SelectedList',
        LText: _voucherSql,
        obj_name: 'data',
        arr_field: 'ID,NameNO,TypeCharOne'
      }
      voucherParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      voucherParam.secretkey = Utils.encrypt(voucherParam.LText, voucherParam.timestamp)
      voucherParam.open_key = Utils.encryptOpenKey(voucherParam.secretkey, voucherParam.timestamp) // 云端数据验证
      Api.getSystemConfig(voucherParam).then(res => {
        if (res.status) {
          resolve(res)
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
        }
      })
    })
    // 获取凭证三级菜单
    let defer4 = new Promise(resolve => {
      let _voucherDetailSql = 'select distinct ModularDetailCode,ModularDetailCode+ModularDetailName as CodeName,ModularCode as BID, VoucherTypeTwo, IDefine1 from sModularDetail where Deleted=0 and VoucherTypeTwo!=\'\' and Appkey=case when Appkey=\'\' then \'\' else @Appkey@ end  order by ModularDetailCode'
      _voucherDetailSql = Utils.formatOptions(_voucherDetailSql)
      let voucherDetailParam = {
        func: 'sPC_Get_SelectedList',
        LText: _voucherDetailSql,
        obj_name: 'data',
        arr_field: 'ModularDetailCode,CodeName,BID,VoucherTypeTwo,IDefine1'
      }
      voucherDetailParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      voucherDetailParam.secretkey = Utils.encrypt(voucherDetailParam.LText, voucherDetailParam.timestamp)
      voucherDetailParam.open_key = Utils.encryptOpenKey(voucherDetailParam.secretkey, voucherDetailParam.timestamp) // 云端数据验证
      Api.getSystemConfig(voucherDetailParam).then(res => {
        if (res.status) {
          resolve(res)
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
        }
      })
    })
    Promise.all([defer3, defer4]).then(result => {
      this.setState({
        voucher: result[0].data,
        voucherDetail: result[1].data
      })
    })
  }
@@ -1132,7 +1073,7 @@
    _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp)
    _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证
    
    Api.getSystemConfig(_sParam).then(res => {
    Api.getCloudCacheConfig(_sParam).then(res => {
      if (res.status) {
        let _scripts = []
@@ -1267,6 +1208,14 @@
    this.setState({
      verify: verify
    })
  }
  onNoteCodeChange = (val) => {
    const { verify } = this.state
    this.setState({
      verify: {...verify, noteCode: val}
    })
  }
@@ -1559,6 +1508,12 @@
        _loading = true
      }
      if (verify.noteEnable === 'true' && !verify.noteCode) { // 开启短信时,需要模板编码
        verify.noteEnable = 'false'
      } else if (verify.noteEnable !== 'true' && verify.noteCode) {
        verify.noteCode = ''
      }
      if (_loading) {
        confirm({
          content: `存在未保存项,确定提交吗?`,
@@ -1584,7 +1539,7 @@
  render() {
    const { card } = this.props
    const { verify, fields, uniqueColumns, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail } = this.state
    const { verify, fields, uniqueColumns, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail, notes } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -1631,6 +1586,51 @@
                    </Radio.Group>
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item label={
                    <Tooltip placement="bottomLeft" title={'选择发送短信时,需完善短信设置。'}>
                      <Icon type="question-circle" style={{color: '#c49f47', marginRight: '5px'}} />
                      发送短信
                    </Tooltip>
                  }>
                    <Radio.Group value={verify.noteEnable} onChange={(e) => {this.onOptionChange(e, 'noteEnable')}}>
                      <Radio value="true">开启</Radio>
                      <Radio value="false">不开启</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                {verify.noteEnable === 'true' ? <Col span={8}>
                  <Form.Item label="短信模板">
                    <Select value={verify.noteCode} onSelect={this.onNoteCodeChange}>
                      {notes.map(option =>
                        <Select.Option key={option.value} value={option.value}>
                          {option.name}
                        </Select.Option>
                      )}
                    </Select>
                  </Form.Item>
                </Col> : null}
                {verify.noteEnable === 'true' ? <Col span={8}>
                  <Form.Item label={
                    <Tooltip placement="bottomLeft" title={'实时发送最多同时发送5个用户,定时发送最多同时发送100个用户。'}>
                      <Icon type="question-circle" style={{color: '#c49f47', marginRight: '5px'}} />
                      发送方式
                    </Tooltip>
                  }>
                    <Radio.Group value={verify.noteType} onChange={(e) => {this.onOptionChange(e, 'noteType')}}>
                      <Radio value="Y">实时</Radio>
                      <Radio value="N">定时</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col> : null}
                {verify.noteEnable === 'true' ? <Col span={8}>
                  <Form.Item label="短信内容">
                    <Radio.Group value={verify.noteTemp} onChange={(e) => {this.onOptionChange(e, 'noteTemp')}}>
                      <Radio value="Y">相同</Radio>
                      <Radio value="N">不同</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col> : null}
              </Row>
            </Form>
          </TabPane>