king
2021-03-05 e36eb1999794bd71e76482b92a0b0b20f49d0032
2021-03-05
26个文件已修改
4个文件已添加
1734 ■■■■ 已修改文件
package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/popview/index.jsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/index.jsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/index.scss 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/menusetting/index.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx 109 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx 462 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/quotecomponent/index.jsx 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/quotecomponent/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/quotecomponent/settingform/index.jsx 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/quotecomponent/settingform/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/excelInbutton/excelin/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/excelInbutton/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/index.jsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/fieldscomponent/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/tablecomponent/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.jsx 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 411 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/menuform/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -188,7 +188,7 @@
      ]
    ]
  },
  "homepage": ".",
  "homepage": "./build",
  "devDependencies": {
    "typescript": "^4.0.2"
  }
src/index.js
@@ -60,7 +60,7 @@
// 测试系统文件置于admin中
// fetch(process.env.NODE_ENV === 'production' ? '../options.json' : './options.json')
fetch('../options.json')
fetch('./options.json')
  .then(response => response.json())
  .catch(() => {
    document.getElementById('root').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh;">系统配置信息获取失败,请联系管理员!</div>'
src/menu/datasource/verifycard/index.jsx
@@ -655,7 +655,6 @@
            <FieldsComponent
              config={{...config, columns}}
              type="fields"
              tableFields={menu.tableFields}
              updatefield={this.updatefields}
            />
            <EditTable actions={['edit', 'move', 'copy', 'del']} type="datasourcefield" data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/>
src/menu/modalconfig/index.jsx
@@ -405,10 +405,9 @@
   * 3、检查表单中的已选字段,并标记已选
   */
  queryField = () => {
    const { menu } = this.props
    const { config } = this.state
    if (menu.tables.length === 0) {
    if (window.GLOB.tableFields.length === 0) {
      notification.warning({
        top: 92,
        message: '请选择表名!',
@@ -418,7 +417,7 @@
    }
    let columns = new Map()
    menu.tableFields.forEach(table => {
    window.GLOB.tableFields.forEach(table => {
      table.columns.forEach(column => {
        columns.set(column.field, column)
      })
src/menu/popview/index.jsx
@@ -42,12 +42,10 @@
    MenuType: '',
    MenuId: '',
    MenuNo: '',
    tableFields: [],
    delButtons: [],
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
    openEdition: '',
    config: null,
    customComponents: []
  }
@@ -153,11 +151,9 @@
      return
    }
    let _config = fromJS(config).toJS()
    delete _config.tableFields
    const _this = this
    if (!is(fromJS(oriConfig), fromJS(_config))) {
    if (!is(fromJS(oriConfig), fromJS(config))) {
      confirm({
        title: '配置已修改,放弃保存吗?',
        content: '',
@@ -214,10 +210,11 @@
          config.Template = 'CustomPage'
        }
        config.open_edition = result.open_edition || ''
        this.setState({
          oriConfig: config,
          config: fromJS(config).toJS(),
          openEdition: result.open_edition || '',
          config: fromJS(config).toJS()
        })
        this.props.modifyCustomMenu(config)
@@ -332,7 +329,7 @@
  submitConfig = () => {
    const { btn } = this.props
    const { openEdition, delButtons } = this.state
    const { delButtons } = this.state
    let config = fromJS(this.state.config).toJS()
    if ((config.cacheUseful === 'true' && !config.cacheTime) || !config.MenuNo || !config.MenuName) {
@@ -355,31 +352,25 @@
        config.enabled = false
      }
      let _config = fromJS(config).toJS()
      delete _config.tableFields
      let _name = (btn.component.name ? btn.component.name + '-' : '') + btn.label
      let param = {
        func: 'sPC_ButtonParam_AddUpt',
        ParentID: btn.config.uuid,
        MenuID: _config.uuid,
        MenuNo: _config.MenuNo || '',
        MenuID: config.uuid,
        MenuNo: config.MenuNo || '',
        Template: 'CustomPage',
        MenuName: _name,
        PageParam: JSON.stringify({Template: 'CustomPage'}),
        LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_config)))
      }
      if (openEdition) { // 版本管理
        param.open_edition = openEdition
        LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(config))),
        open_edition: config.open_edition
      }
      let btnParam = {             // 添加菜单按钮
        func: 'sPC_Button_AddUpt',
        Type: 60,                  // 添加菜单下的按钮type为40,按钮下的按钮type为60
        ParentID: _config.uuid,
        MenuNo: _config.MenuNo,
        ParentID: config.uuid,
        MenuNo: config.MenuNo,
        Template: 'CustomPage',
        PageParam: '',
        LongParam: '',
@@ -427,9 +418,10 @@
        if (!res) return
        if (res.status) {
          config.open_edition = res.open_edition || ''
          this.setState({
            oriConfig: fromJS(_config).toJS(),
            openEdition: res.open_edition || ''
            oriConfig: fromJS(config).toJS()
          })
          if (btnParam.LText) {
@@ -540,15 +532,8 @@
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
  updatetable = (config, fields) => {
    const { tableFields } = this.state
    config.tableFields = fields ? fields : tableFields
    this.setState({
      tableFields: fields ? fields : tableFields,
      config
    })
  updatetable = (config) => {
    this.setState({ config })
    this.props.modifyCustomMenu(config)
  }
src/pc/components/navbar/normal-navbar/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Icon, Popover } from 'antd'
import { Icon, Popover, Menu } from 'antd'
import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -18,6 +18,7 @@
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
// const { confirm } = Modal
const { SubMenu } = Menu
class NormalNavbar extends Component {
  static propTpyes = {
@@ -140,7 +141,7 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', [card.uuid], ['font', 'background', 'shadow'], card.style)
  }
  changeLogoStyle = () => {
@@ -154,6 +155,18 @@
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
    }
  }
  changeMenu = (menu) => {
    MKEmitter.emit('changeEditMenu', menu)
  }
  changeLogoMenu = () => {
    const { card } = this.state
    if (!card.wrap.logolink) return
    MKEmitter.emit('changeEditMenu', {MenuID: card.wrap.logolink})
  }
  render() {
@@ -184,9 +197,47 @@
              <Icon className="style" title="调整样式" onClick={this.changeLogoStyle} type="font-colors" />
            </div>
          } trigger="hover">
            <div className="logo" style={card.logoStyle}><img src={card.wrap.logo} alt=""/></div>
            <div className={'logo' + (card.wrap.logolink ? ' pointer' : '')} style={card.logoStyle} onDoubleClick={this.changeLogoMenu}><img src={card.wrap.logo} alt=""/></div>
          </Popover> : null}
          <div className="menu">sdf</div>
          <div className="menu">
            <Menu mode="horizontal">
              {card.menus.map(fst => {
                if (fst.property === 'classify' && fst.sublist.length > 0) {
                  return (
                    <SubMenu title={fst.name} key={fst.MenuID} popupClassName="normal-navbar-submenu">
                      {fst.sublist.map(scd => {
                        if (scd.property === 'classify' && scd.sublist.length > 0) {
                          return (
                            <Menu.ItemGroup key={scd.MenuID} title={scd.name}>
                              {scd.sublist.map(thd => {
                                return (
                                  <Menu.Item key={thd.MenuID} >
                                    <span onClick={(e) => e.stopPropagation()} onDoubleClick={() => this.changeMenu(thd)}>{thd.name}</span>
                                  </Menu.Item>
                                )
                              })}
                            </Menu.ItemGroup>
                          )
                        } else {
                          return (
                            <Menu.Item key={scd.MenuID} onClick={(e) => e.stopPropagation()}>
                              <span onClick={(e) => e.stopPropagation()} onDoubleClick={() => this.changeMenu(scd)}>{scd.name}</span>
                            </Menu.Item>
                          )
                        }
                      })}
                    </SubMenu>
                  )
                } else {
                  return (
                    <Menu.Item key={fst.MenuID} onClick={(e) => e.stopPropagation()}>
                      <span onClick={(e) => e.stopPropagation()} onDoubleClick={() => this.changeMenu(fst)}>{fst.name}</span>
                    </Menu.Item>
                  )
                }
              })}
            </Menu>
          </div>
          <div className="link">asdfds</div>
        </div>
      </div>
src/pc/components/navbar/normal-navbar/index.scss
@@ -14,6 +14,7 @@
  .navbar-wrap {
    margin: 0 auto;
    display: flex;
    max-width: 100%;
    .logo {
      display: inline-block;
@@ -22,13 +23,31 @@
        max-height: 100%;
      }
    }
    .logo.pointer {
      cursor: pointer;
    }
    .menu {
      flex: 1;
      display: inline-block;
      font-size: inherit;
      color: inherit;
      .ant-menu {
        background: transparent;
        line-height: inherit;
        font-size: inherit;
        color: inherit;
        .ant-menu-item:hover, .ant-menu-item-active, .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, .ant-menu-submenu-active, .ant-menu-submenu-title:hover {
          color: unset;
        }
      }
      .ant-menu-horizontal > .ant-menu-item:hover, .ant-menu-horizontal > .ant-menu-submenu:hover, .ant-menu-horizontal > .ant-menu-item-active, .ant-menu-horizontal > .ant-menu-submenu-active, .ant-menu-horizontal > .ant-menu-item-open, .ant-menu-horizontal > .ant-menu-submenu-open, .ant-menu-horizontal > .ant-menu-item-selected, .ant-menu-horizontal > .ant-menu-submenu-selected {
        color: unset;
      }
    }
    .link {
      flex: 1;
      display: inline-block;
      text-align: right;
    }
  }
  .card-control {
@@ -111,4 +130,23 @@
}
.top-menu-popover {
  padding-top: 0!important;
}
.normal-navbar-submenu {
  .ant-menu-item-group {
    float: left;
  }
  .ant-menu-item {
    height: 32px;
    line-height: 32px;
    span {
      display: inline-block;
      width: 100%;
      height: 100%;
      padding: 0 16px 0 28px;
    }
    padding: 0;
  }
  .ant-menu .ant-menu-item-selected {
    background-color: #ffffff;
  }
}
src/pc/components/navbar/normal-navbar/menusetting/index.jsx
@@ -19,27 +19,16 @@
    visible: false
  }
  UNSAFE_componentWillMount () {
    const { config } = this.props
    this.setState({menus: fromJS(config.menus).toJS()})
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  verifySubmit = () => {
    // const { config } = this.props
    const { config } = this.props
    let menus = this.mTable.state.data || []
    // this.verifyRef.handleConfirm().then(res => {
    //   this.setState({
    //     wrap: res,
    //     visible: false
    //   })
    //   this.props.updateConfig({...config, wrap: res})
    // })
    this.props.updateConfig({...config, menus})
    this.setState({visible: false})
  }
  render () {
@@ -53,7 +42,7 @@
          wrapClassName="popview-modal"
          title="菜单编辑"
          visible={visible}
          width={800}
          width={950}
          maskClosable={false}
          okText={dict['model.submit']}
          onOk={this.verifySubmit}
src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Radio, Tooltip, Icon } from 'antd'
import { Form, Row, Col, Input, Radio, Tooltip, Icon, Select } from 'antd'
import './index.scss'
@@ -13,11 +13,33 @@
  }
  state = {
    property: this.props.menu.property || 'menu'
    property: this.props.menu.property || 'menu',
    linkIntId: this.props.menu.linkIntId || '',
    appMenus: [],
  }
  UNSAFE_componentWillMount () {
    let appMenus = sessionStorage.getItem('appMenus')
    if (appMenus) {
      try {
        appMenus = JSON.parse(appMenus)
      } catch {
        appMenus = []
      }
    } else {
      appMenus = []
    }
    this.setState({appMenus})
  }
  componentDidMount() {
    const { menu } = this.props
    if (!menu.MenuID) {
      let _form = document.getElementById('name')
      _form && _form.select()
    }
  }
  handleConfirm = () => {
@@ -25,6 +47,9 @@
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          if (values.linkmenuid) {
            values.linkIntId = this.state.linkIntId || ''
          }
          resolve(values)
        } else {
          reject(err)
@@ -47,10 +72,14 @@
    this.setState({property: val})
  }
  changeLinkMenu = (val, { props }) => {
    this.setState({linkIntId: props.intid})
  }
  render() {
    const { menu } = this.props
    const { getFieldDecorator } = this.props.form
    const { property } = this.state
    const { property, appMenus } = this.state
    const formItemLayout = {
      labelCol: {
@@ -66,7 +95,7 @@
    return (
      <Form {...formItemLayout}>
        <Row gutter={24}>
          <Col span={24}>
          <Col span={22}>
            <Form.Item label="菜单名称">
              {getFieldDecorator('name', {
                initialValue: menu.name,
@@ -79,48 +108,76 @@
              })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
          <Col span={24}>
            <Form.Item label="属性">
          <Col span={22}>
            <Form.Item label="菜单属性">
              {getFieldDecorator('property', {
                initialValue: menu.property || 'menu'
              })(
                <Radio.Group onChange={this.changeProperty}>
                  <Radio value="menu">菜单</Radio>
                  <Radio value="link">链接</Radio>
                  <Radio value="classify">分类</Radio>
                  {menu.level === 1 || menu.level === 2 ? <Radio value="classify">分类</Radio> : null}
                  <Radio value="linkmenu">关联菜单</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          {property === 'link' ? <Col span={24}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="链接至当前系统的菜单时,可以使用 $ + 菜单ID,例如:$dsdffowejdsfi。">
                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/>
                链接地址
              </Tooltip>
            }>
          {property === 'link' ? <Col span={22}>
            <Form.Item label="链接地址">
              {getFieldDecorator('link', {
                initialValue: menu.link || '',
                rules: [
                  {
                    required: true,
                    message: '请输入链接地址!'
                  }
                ]
                rules: [{
                  required: true,
                  message: '请输入链接地址!'
                }]
              })(<TextArea rows={2} />)}
            </Form.Item>
          </Col> : null}
          {property === 'menu' ? <Col span={24}>
          {property !== 'classify' ? <Col span={22}>
            <Form.Item label="打开方式">
              {getFieldDecorator('open', {
                initialValue: menu.open || 'blank'
              })(
                <Radio.Group>
                  <Radio value="blank">新窗口</Radio>
                  <Radio value="self">当前窗口</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col> : null}
          {property === 'linkmenu' ? <Col span={22}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="复制其他菜单时,请填写对应的菜单ID。">
              <Tooltip placement="topLeft" title="关联当前app中已有的菜单。">
                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/>
                关联菜单
              </Tooltip>
            }>
              {getFieldDecorator('linkMenuId', {
                initialValue: menu.linkMenuId || '',
                rules: [{
                  required: true,
                  message: '请选择关联菜单!'
                }]
              })(
                <Select onChange={this.changeLinkMenu}>
                  {appMenus.map(item => (<Select.Option key={item.MenuID} intid={item.menuid_int} value={item.MenuID}>{item.MenuName}</Select.Option>))}
                </Select>
              )}
            </Form.Item>
          </Col> : null}
          {property === 'menu' ? <Col span={22}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="复制菜单仅在当前菜单不存在时有效。">
                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/>
                复制菜单
              </Tooltip>
            }>
              {getFieldDecorator('copyMenu', {
                initialValue: menu.copyMenu || ''
              {getFieldDecorator('copyMenuId', {
                initialValue: menu.copyMenuId || ''
              })(
                <Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />
                <Select>
                  {appMenus.map(item => (<Select.Option key={item.MenuID} value={item.MenuID}>{item.MenuName}</Select.Option>))}
                </Select>
              )}
            </Form.Item>
          </Col> : null}
src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx
@@ -1,72 +1,346 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Table, Button, Modal } from 'antd'
import { Table, Button, Modal, Icon } from 'antd'
import MenuForm from '../menuform'
import Utils from '@/utils/utils.js'
import './index.scss'
class SubTable extends Component {
const { confirm } = Modal
class ThdTable extends Component {
  static propTpyes = {
    menus: PropTypes.object,    // 卡片行信息
    menuUpdate: PropTypes.func    // 卡片行信息
  }
  state = {
    data: [],
    editMenu: null,
    columns: [
      { title: 'Date', dataIndex: 'date', key: 'date' },
      { title: 'Name', dataIndex: 'name', key: 'name' },
      {
        title: 'Status',
        key: 'state',
        render: () => (
          <span>
            Finished
          </span>
        ),
      },
      { title: 'Upgrade Status', dataIndex: 'upgradeNum', key: 'upgradeNum' },
      {
        title: 'Action',
        dataIndex: 'operation',
        key: 'operation',
        render: () => (
          <span className="table-operation">
            <a href>Pause</a>
            <a href>Stop</a>
          </span>
        ),
      },
      { title: '菜单名称', dataIndex: 'name', key: 'name' },
      { title: '菜单属性', dataIndex: 'property', key: 'property',  render: text => {
        const trans = {menu: '菜单', link: '链接', linkmenu: '关联菜单', classify: '分类'}
        return trans[text]
      }},
      { title: '打开方式', dataIndex: 'open', key: 'open',  render: (text, record) => {
        if (record.property === 'classify') return ''
        const trans = {blank: '新窗口', self: '当前窗口'}
        return trans[text]
      }},
      { title: '操作', key: 'operation', align: 'center', width: '190px', render: (text, record) =>
        (<div>
          <Button type="link" style={{padding: '0 5px', marginRight: '5px'}} onClick={() => this.editMenu(record)}>编辑</Button>
          <Button type="link" style={{color: '#ff4d4f', padding: '0 5px', marginRight: '5px'}} onClick={() => this.delMenu(record)}>删除</Button>
          <Icon type="arrow-up" style={{color: '#26C281', cursor: 'pointer', padding: '0 5px', marginRight: '5px'}} onClick={() => this.moveUp(record)}/>
          <Icon type="arrow-down" style={{color: '#ff4d4f', cursor: 'pointer', padding: '0 5px'}} onClick={() => this.moveDown(record)}/>
        </div>)
      }
    ]
  }
  UNSAFE_componentWillMount () {
    // const { data } = this.props
    const { menu } = this.props
    this.setState({data: menu.sublist ? fromJS(menu.sublist).toJS() : []})
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  handleSubmit = (e) => {
    e.preventDefault()
  moveUp = (record) => {
    const { menu } = this.props
    let data = fromJS(this.state.data).toJS()
    if (this.props.inputSubmit) {
      this.props.inputSubmit()
    let dragIndex = data.findIndex(c => c.MenuID === record.MenuID)
    let hoverIndex = dragIndex - 1
    if (hoverIndex === -1) return
    data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1))
    this.setState({data})
    this.props.menuUpdate({...menu, sublist: data})
  }
  moveDown = (record) => {
    const { menu } = this.props
    let data = fromJS(this.state.data).toJS()
    let dragIndex = data.findIndex(c => c.MenuID === record.MenuID)
    let hoverIndex = dragIndex + 1
    if (hoverIndex === data.length) return
    data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1))
    this.setState({data})
    this.props.menuUpdate({...menu, sublist: data})
  }
  delMenu = (record) => {
    const { menu } = this.props
    const _this = this
    confirm({
      title: '确定删除吗?',
      content: '',
      onOk() {
        let _data = _this.state.data.filter(item => item.MenuID !== record.MenuID)
        _this.setState({data: _data})
        _this.props.menuUpdate({...menu, sublist: _data})
      },
      onCancel() {}
    })
  }
  editMenu = (record) => {
    this.setState({editMenu: record, visible: true})
  }
  plusMenu = () => {
    let _menu = {
      name: '菜单',
      property: 'menu',
      level: 3,
      sublist: []
    }
    this.setState({editMenu: _menu, visible: true})
  }
  menuSubmit = () => {
    const { menu } = this.props
    const { editMenu } = this.state
    this.menuRef.handleConfirm().then(res => {
      let _menu = {...editMenu, ...res}
      let _data = this.state.data
      if (!_menu.MenuID) {
        _menu.MenuID = Utils.getuuid()
        _data.push(_menu)
      } else {
        _data = _data.map(item => {
          if (item.MenuID === _menu.MenuID) {
            return _menu
          } else {
            return item
          }
        })
      }
      this.setState({data: _data, editMenu: null, visible: false})
      this.props.menuUpdate({...menu, sublist: _data})
    })
  }
  render() {
    const { columns, data } = this.state
    const { columns, data, visible, editMenu } = this.state
    return (
      <Table
        className="components-table-demo-nested"
        columns={columns}
        dataSource={data}
      />
      <div className="thdmenu-control-wrap">
        <Icon type="plus" style={{color: '#26C281', padding: '5px', fontSize: '16px'}} onClick={this.plusMenu}/>
        <Table
          rowKey="MenuID"
          size="small"
          columns={columns}
          dataSource={data}
          pagination={false}
        />
        <Modal
          title="编辑"
          visible={visible}
          width={600}
          maskClosable={false}
          onOk={this.menuSubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          <MenuForm
            menu={editMenu}
            inputSubmit={this.menuSubmit}
            wrappedComponentRef={(inst) => this.menuRef = inst}
          />
        </Modal>
      </div>
    )
  }
}
class SubTable extends Component {
  static propTpyes = {
    menu: PropTypes.object,    // 卡片行信息
    menuUpdate: PropTypes.func    // 卡片行信息
  }
  state = {
    data: [],
    editMenu: null,
    columns: [
      { title: '菜单名称', dataIndex: 'name', key: 'name' },
      { title: '菜单属性', dataIndex: 'property', key: 'property',  render: text => {
        const trans = {menu: '菜单', link: '链接', linkmenu: '关联菜单', classify: '分类'}
        return trans[text]
      }},
      { title: '打开方式', dataIndex: 'open', key: 'open',  render: (text, record) => {
        if (record.property === 'classify') return ''
        const trans = {blank: '新窗口', self: '当前窗口'}
        return trans[text]
      }},
      { title: '操作', key: 'operation', align: 'center', width: '190px', render: (text, record) =>
        (<div>
          <Button type="link" style={{padding: '0 5px', marginRight: '5px'}} onClick={() => this.editMenu(record)}>编辑</Button>
          <Button type="link" style={{color: '#ff4d4f', padding: '0 5px', marginRight: '5px'}} onClick={() => this.delMenu(record)}>删除</Button>
          <Icon type="arrow-up" style={{color: '#26C281', cursor: 'pointer', padding: '0 5px', marginRight: '5px'}} onClick={() => this.moveUp(record)}/>
          <Icon type="arrow-down" style={{color: '#ff4d4f', cursor: 'pointer', padding: '0 5px'}} onClick={() => this.moveDown(record)}/>
        </div>)
      }
    ]
  }
  UNSAFE_componentWillMount () {
    const { menu } = this.props
    this.setState({data: menu.sublist ? fromJS(menu.sublist).toJS() : []})
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  moveUp = (record) => {
    const { menu } = this.props
    let data = fromJS(this.state.data).toJS()
    let dragIndex = data.findIndex(c => c.MenuID === record.MenuID)
    let hoverIndex = dragIndex - 1
    if (hoverIndex === -1) return
    data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1))
    this.setState({data})
    this.props.menuUpdate({...menu, sublist: data})
  }
  moveDown = (record) => {
    const { menu } = this.props
    let data = fromJS(this.state.data).toJS()
    let dragIndex = data.findIndex(c => c.MenuID === record.MenuID)
    let hoverIndex = dragIndex + 1
    if (hoverIndex === data.length) return
    data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1))
    this.setState({data})
    this.props.menuUpdate({...menu, sublist: data})
  }
  delMenu = (record) => {
    const { menu } = this.props
    const _this = this
    confirm({
      title: (record.property === 'classify' && record.sublist.length > 0 ? '菜单下含有子菜单,' : '') + '确定删除吗?',
      content: '',
      onOk() {
        let _data = _this.state.data.filter(item => item.MenuID !== record.MenuID)
        _this.setState({data: _data})
        _this.props.menuUpdate({...menu, sublist: _data})
      },
      onCancel() {}
    })
  }
  editMenu = (record) => {
    this.setState({editMenu: record, visible: true})
  }
  plusMenu = () => {
    let _menu = {
      name: '菜单',
      property: 'classify',
      level: 2,
      sublist: []
    }
    this.setState({editMenu: _menu, visible: true})
  }
  menuSubmit = () => {
    const { menu } = this.props
    const { editMenu } = this.state
    this.menuRef.handleConfirm().then(res => {
      let _menu = {...editMenu, ...res}
      let _data = this.state.data
      if (!_menu.MenuID) {
        _menu.MenuID = Utils.getuuid()
        _data.push(_menu)
      } else {
        _data = _data.map(item => {
          if (item.MenuID === _menu.MenuID) {
            return _menu
          } else {
            return item
          }
        })
      }
      this.setState({data: _data, editMenu: null, visible: false})
      this.props.menuUpdate({...menu, sublist: _data})
    })
  }
  menuUpdate = (res) => {
    const { menu } = this.props
    let _data = this.state.data.map(item => {
      if (item.MenuID === res.MenuID) {
        return res
      } else {
        return item
      }
    })
    this.setState({data: _data})
    this.props.menuUpdate({...menu, sublist: _data})
  }
  render() {
    const { columns, data, visible, editMenu } = this.state
    return (
      <div className="submenu-control-wrap">
        <Icon type="plus" style={{color: '#26C281', padding: '5px', fontSize: '16px'}} onClick={this.plusMenu}/>
        <Table
          size="middle"
          rowKey="MenuID"
          columns={columns}
          rowClassName={record => record.property}
          expandedRowRender={record => <ThdTable menu={record} menuUpdate={this.menuUpdate} />}
          dataSource={data}
          pagination={false}
        />
        <Modal
          title="编辑"
          visible={visible}
          width={600}
          maskClosable={false}
          onOk={this.menuSubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          <MenuForm
            menu={editMenu}
            inputSubmit={this.menuSubmit}
            wrappedComponentRef={(inst) => this.menuRef = inst}
          />
        </Modal>
      </div>
    )
  }
}
@@ -81,14 +355,26 @@
    editMenu: null,
    columns: [
      { title: '菜单名称', dataIndex: 'name', key: 'name' },
      { title: '属性', dataIndex: 'property', key: 'property',  render: text => {
        if (text === 'menu') {
          return '菜单'
        } else {
          return '分类'
        }
      { title: '菜单属性', dataIndex: 'property', key: 'property',  render: text => {
        const trans = {menu: '菜单', link: '链接', linkmenu: '关联菜单', classify: '分类'}
        return trans[text]
      }},
      { title: 'Action', key: 'operation', render: () => <a href="#d">Publish</a> },
      { title: '打开方式', dataIndex: 'open', key: 'open',  render: (text, record) => {
        if (record.property === 'classify') return ''
        const trans = {blank: '新窗口', self: '当前窗口'}
        return trans[text]
      }},
      { title: '操作', key: 'operation', align: 'center', width: '190px', render: (text, record) =>
        (<div>
          <Button type="link" style={{padding: '0 5px', marginRight: '5px'}} onClick={() => this.editMenu(record)}>编辑</Button>
          <Button type="link" style={{color: '#ff4d4f', padding: '0 5px', marginRight: '5px'}} onClick={() => this.delMenu(record)}>删除</Button>
          <Icon type="arrow-up" style={{color: '#26C281', cursor: 'pointer', padding: '0 5px', marginRight: '5px'}} onClick={() => this.moveUp(record)}/>
          <Icon type="arrow-down" style={{color: '#ff4d4f', cursor: 'pointer', padding: '0 5px'}} onClick={() => this.moveDown(record)}/>
        </div>)
      }
    ]
  }
@@ -102,12 +388,54 @@
    return !is(fromJS(this.state), fromJS(nextState))
  }
  moveUp = (record) => {
    let data = fromJS(this.state.data).toJS()
    let dragIndex = data.findIndex(c => c.MenuID === record.MenuID)
    let hoverIndex = dragIndex - 1
    if (hoverIndex === -1) return
    data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1))
    this.setState({data})
  }
  moveDown = (record) => {
    let data = fromJS(this.state.data).toJS()
    let dragIndex = data.findIndex(c => c.MenuID === record.MenuID)
    let hoverIndex = dragIndex + 1
    if (hoverIndex === data.length) return
    data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1))
    this.setState({data})
  }
  delMenu = (record) => {
    const { data } = this.state
    const _this = this
    confirm({
      title: (record.property === 'classify' && record.sublist.length > 0 ? '菜单下含有子菜单,' : '') + '确定删除吗?',
      content: '',
      onOk() {
        _this.setState({data: data.filter(item => item.MenuID !== record.MenuID)})
      },
      onCancel() {}
    })
  }
  editMenu = (record) => {
    this.setState({editMenu: record, visible: true})
  }
  plusMenu = () => {
    let _menu = {
      name: '菜单',
      property: 'classify',
      level: 1,
      children: []
      sublist: []
    }
    this.setState({editMenu: _menu, visible: true})
@@ -118,18 +446,36 @@
    this.menuRef.handleConfirm().then(res => {
      let _menu = {...editMenu, ...res}
      if (!_menu.uuid) {
        _menu.uuid = Utils.getuuid()
        this.setState({data: [...data, _menu]})
      if (!_menu.MenuID) {
        _menu.MenuID = Utils.getuuid()
        this.setState({data: [...data, _menu], editMenu: null, visible: false})
      } else {
        this.setState({data: data.map(item => {
          if (item.uuid === _menu.uuid) {
            return _menu
          } else {
            return item
          }
        })})
        this.setState({
          editMenu: null,
          visible: false,
          data: data.map(item => {
            if (item.MenuID === _menu.MenuID) {
              return _menu
            } else {
              return item
            }
          })
        })
      }
    })
  }
  menuUpdate = (res) => {
    const { data } = this.state
    this.setState({
      data: data.map(item => {
        if (item.MenuID === res.MenuID) {
          return res
        } else {
          return item
        }
      })
    })
  }
@@ -140,10 +486,12 @@
      <div className="menu-control-wrap">
        <Button className="menu-plus mk-green" onClick={this.plusMenu}>添加</Button>
        <Table
          className="components-table-demo-nested"
          rowKey="MenuID"
          columns={columns}
          expandedRowRender={<SubTable />}
          rowClassName={record => record.property}
          expandedRowRender={record => <SubTable menu={record} menuUpdate={this.menuUpdate} />}
          dataSource={data}
          pagination={false}
        />
        <Modal
          title="编辑"
src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss
@@ -7,4 +7,58 @@
    z-index: 1;
    margin-bottom: 5px;
  }
  .ant-empty {
    margin: 5px 0;
  }
  thead tr {
    background: #fbfbfb;
  }
  tbody > tr:not(.ant-table-expanded-row) {
    background: #ffffff;
  }
  tr:not(.classify) {
    > td {
      >.ant-table-row-expand-icon-cell {
        div {
          display: none;
        }
      }
      >.ant-table-row-expand-icon {
        display: none;
      }
    }
  }
  tr:not(.classify) + .ant-table-expanded-row {
    display: none;
  }
  td[colspan="4"] {
    padding: 5px 0px 5px 5px!important;
  }
  .ant-table-body {
    margin: 0!important;
  }
  .submenu-control-wrap {
    position: relative;
    .anticon-plus {
      position: absolute;
      top: 8px;
      right: 10px;
      z-index: 1;
    }
    .thdmenu-control-wrap {
      position: relative;
      .ant-table-row-indent {
        display: none;
      }
      .ant-table-row-expand-icon {
        display: none;
      }
      .ant-table-small {
        border: 0;
      }
    }
  }
}
src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Tooltip, Icon, InputNumber } from 'antd'
import { Form, Row, Col, Input, Tooltip, Icon, InputNumber, Select } from 'antd'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
@@ -16,29 +16,37 @@
  }
  state = {
    roleList: []
    appMenus: [],
    logointid: this.props.wrap.linkIntId || ''
  }
  UNSAFE_componentWillMount () {
    let roleList = sessionStorage.getItem('sysRoles')
    if (roleList) {
    let appMenus = sessionStorage.getItem('appMenus')
    if (appMenus) {
      try {
        roleList = JSON.parse(roleList)
        appMenus = JSON.parse(appMenus)
      } catch {
        roleList = []
        appMenus = []
      }
    } else {
      roleList = []
      appMenus = []
    }
    this.setState({roleList})
    this.setState({appMenus})
  }
  handleConfirm = () => {
    const { logointid } = this.state
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          values.linkIntId = ''
          if (values.logolink && logointid) {
            values.linkIntId = logointid
          }
          resolve(values)
        } else {
          reject(err)
@@ -58,6 +66,7 @@
  render() {
    const { wrap } = this.props
    const { getFieldDecorator } = this.props.form
    const { appMenus } = this.state
    const formItemLayout = {
      labelCol: {
@@ -82,6 +91,19 @@
                    {
                      required: true,
                      message: this.props.dict['form.required.input'] + '导航栏名称!'
                    }
                  ]
                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label="菜单参数">
                {getFieldDecorator('MenuNo', {
                  initialValue: wrap.MenuNo,
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.input'] + '菜单参数!'
                    }
                  ]
                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
@@ -127,6 +149,24 @@
                )}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label="logo链接">
                {getFieldDecorator('logolink', {
                  initialValue: wrap.logolink || ''
                })(
                  <Select
                    showSearch
                    onChange={(val, { props }) => this.setState({logointid: props.intid})}
                    filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  >
                    <Select.Option key="empty" intid={''} value={''}>无</Select.Option>
                    {appMenus.map(option =>
                      <Select.Option key={option.MenuID} intid={option.menuid_int} value={option.MenuID}>{option.MenuName}</Select.Option>
                    )}
                  </Select>
                )}
              </Form.Item>
            </Col>
          </Row>
        </Form>
      </div>
src/pc/quotecomponent/index.jsx
New file
@@ -0,0 +1,123 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Button, Modal, notification } from 'antd'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import SettingForm from './settingform'
import Api from '@/api'
import './index.scss'
class Quotecomponent extends Component {
  static propTpyes = {
    config: PropTypes.any,
    updateConfig: PropTypes.func
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    visible: false,
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  verifySubmit = () => {
    let config = fromJS(this.props.config).toJS()
    this.verifyRef.handleConfirm().then(res => {
      let exit = false
      config.components.forEach(item => {
        if (item.type === res.keys_type) {
          exit = true
        }
      })
      if (exit) {
        let msg = ''
        if (res.keys_type === 'navbar') {
          msg = '导航栏已存在!'
        }
        notification.warning({
          top: 92,
          message: msg,
          duration: 5
        })
        return
      }
      Api.getSystemConfig({
        func: 'sPC_Get_LongParam',
        TypeCharOne: sessionStorage.getItem('kei_no'),
        typename: 'pc',
        MenuID: res.keys_id
      }).then(result => {
        if (!result.status) {
          notification.warning({
            top: 92,
            message: result.message,
            duration: 5
          })
          return
        }
        let _config = null
        try {
          _config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
        } catch (e) {
          console.warn('Parse Failure')
          _config = null
        }
        if (!_config) {
          notification.warning({
            top: 92,
            message: '未获取到配置信息!',
            duration: 5
          })
          return
        }
        _config.open_edition = result.open_edition || ''
        window.GLOB.CacheIndependent.set(_config.uuid, fromJS(_config).toJS())
        config.components.unshift(_config)
        this.setState({
          visible: false
        })
        this.props.updateConfig(config)
      })
    })
  }
  render () {
    const { config } = this.props
    const { visible, dict } = this.state
    return (
      <div className="quote-wrap">
        <Button icon="appstore" onClick={() => {this.setState({visible: true})}}>组件引用</Button>
        <Modal
          title="组件引用"
          visible={visible}
          width={500}
          maskClosable={false}
          okText={dict['model.submit']}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          <SettingForm
            dict={dict}
            config={config}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
          />
        </Modal>
      </div>
    )
  }
}
export default Quotecomponent
src/pc/quotecomponent/index.scss
New file
@@ -0,0 +1,6 @@
.quote-wrap {
  button {
    border-color: #40a9ff;
    color: #40a9ff;
  }
}
src/pc/quotecomponent/settingform/index.jsx
New file
@@ -0,0 +1,88 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Select } from 'antd'
import './index.scss'
class SettingForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,      // 字典项
  }
  state = {
    appMenus: []
  }
  UNSAFE_componentWillMount () {
    let appMenus = sessionStorage.getItem('appViewList')
    if (appMenus) {
      try {
        appMenus = JSON.parse(appMenus)
        appMenus = appMenus.filter(item => item.keys_type !== 'index')
      } catch {
        appMenus = []
      }
    } else {
      appMenus = []
    }
    this.setState({appMenus})
  }
  handleConfirm = () => {
    const { appMenus } = this.state
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let item = appMenus.filter(_menu => _menu.keys_id === values.menu)[0]
          resolve(item)
        } else {
          reject(err)
        }
      })
    })
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const { appMenus } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    return (
      <Form {...formItemLayout}>
        <Row gutter={24}>
          <Col span={20}>
            <Form.Item label="菜单">
              {getFieldDecorator('menu', {
                initialValue: '',
                rules: [{
                  required: true,
                  message: '请选择菜单!'
                }]
              })(
                <Select>
                  {appMenus.map(option =>
                    <Select.Option key={option.keys_id} value={option.keys_id}>{option.remark}</Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        </Row>
      </Form>
    )
  }
}
export default Form.create()(SettingForm)
src/pc/quotecomponent/settingform/index.scss
New file
@@ -0,0 +1,11 @@
.model-menu-setting-form {
  position: relative;
  .anticon-question-circle {
    color: #c49f47;
    margin-right: 3px;
  }
  .ant-input-number {
    width: 100%;
  }
}
src/tabviews/zshare/actionList/excelInbutton/excelin/index.jsx
@@ -43,6 +43,7 @@
        let errors = null
        let sheetName = btn.verify.sheet
        let errDetail = ''
        if (Object.keys(workbook.Sheets).length === 1) {
          sheetName = Object.keys(workbook.Sheets)[0]
@@ -58,14 +59,15 @@
          } else {
            let iserror = false
            btn.verify.columns.forEach(op => {
              if (header[op.Column] !== op.Text) {
              let _name = typeof(header[op.Column]) === 'string' ? header[op.Column].replace(/(^\s*|\s*$)/g, '') : header[op.Column]
              let _text = op.Text ? op.Text.replace(/(^\s*|\s*$)/g, '') : op.Text
              if (_name !== _text && !iserror) {
                iserror = true
                errors = 'headerError'
                errDetail = `Excel中(${_name})与按钮列信息(${_text})不一致!`
              }
            })
            if (iserror) {
              errors = 'headerError'
            }
          }
        }
@@ -76,7 +78,7 @@
        }
        // 最终获取到并且格式化后的 json 数据
        this.props.returndata(data, errors, sheetName)
        this.props.returndata(data, errors, sheetName, errDetail)
        this.setState({
          excelId: '',
        }, () => {
src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -194,7 +194,7 @@
  /**
   * @description Excel 导入
   */
  getexceldata = (data, errors, sheetName) => {
  getexceldata = (data, errors, sheetName, errDetail) => {
    const { btn } = this.props
    if (errors) {
@@ -213,7 +213,7 @@
      } else if (errors === 'headerError') {
        notification.warning({
          top: 92,
          message: '工作表《' + sheetName + '》表头设置错误,请检查表头中的名称及顺序,与按钮Excel列信息是否一致!',
          message: `工作表《${sheetName}》表头错误,${errDetail}`,
          duration: 5
        })
      }
src/templates/calendarconfig/index.jsx
@@ -42,7 +42,6 @@
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,        // 字典
    config: null,            // 页面配置
    visible: false,          // 搜索条件、按钮、显示列,模态框显示控制
    tableFields: [],         // 已选表字段集
    fields: null,            // 搜索条件及显示列,可选字段
    formlist: null,          // 搜索条件、按钮、显示列表单字段
    menuloading: false,      // 菜单保存中
@@ -710,18 +709,6 @@
      config: config
    })
  }
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
  updatetable = (config, fields) => {
    const { tableFields } = this.state
    this.setState({
      config: config,
      tableFields: fields ? fields : tableFields
    })
  }
  // 年切换时重新生成数据
  changeDate = (year) => {
@@ -753,7 +740,7 @@
                <TableComponent
                  config={config}
                  containerId="subtable-basedata"
                  updatetable={this.updatetable}
                  updatetable={this.updateconfig}
                />
              </Panel>
              {/* 搜索条件添加 */}
@@ -766,7 +753,6 @@
                <FieldsComponent
                  config={config}
                  type="search"
                  tableFields={this.state.tableFields}
                  updatefield={this.updateconfig}
                />
              </Panel>
@@ -789,7 +775,6 @@
              <SettingComponent
                config={config}
                MenuID={menu.MenuID}
                tableFields={this.state.tableFields}
                updateConfig={this.updateconfig}
              />
              <SearchComponent
src/templates/comtableconfig/index.jsx
@@ -44,7 +44,6 @@
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    config: null,            // 页面配置
    tableFields: [],         // 已选的常用表
    formlist: null,          // 搜索条件、按钮、显示列表单字段
    menuloading: false,      // 菜单保存中
    menucloseloading: false, // 菜单关闭时,选择保存
@@ -1074,28 +1073,6 @@
  }
  
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
  updatetable = (config, fields) => {
    const { tableFields } = this.state
    this.setState({
      config: config,
      tableFields: fields ? fields : tableFields
    })
  }
  /**
   * @description 更新标签配置信息
   */
  updatetabs = (config) => {
    this.setState({
      config: config
    })
  }
  /**
   * @description 更新配置信息
   */
  updateconfig = (config) => {
@@ -1134,7 +1111,7 @@
                <TableComponent
                  config={config}
                  containerId="main-basedata"
                  updatetable={this.updatetable}
                  updatetable={this.updateconfig}
                />
              </Panel>
              {/* 搜索条件添加 */}
@@ -1145,7 +1122,6 @@
                <FieldsComponent
                  config={config}
                  type="search"
                  tableFields={this.state.tableFields}
                  updatefield={this.updateconfig}
                />
              </Panel>
@@ -1185,7 +1161,6 @@
                <FieldsComponent
                  config={config}
                  type="columns"
                  tableFields={this.state.tableFields}
                  updatefield={this.updateconfig}
                />
              </Panel>
@@ -1296,7 +1271,7 @@
                config={config}
                tabs={this.state.tabviews}
                setSubConfig={(item) => this.setSubConfig(item, 'tab')}
                updatetabs={this.updatetabs}
                updatetabs={this.updateconfig}
              />
            </Card>
          </div>
src/templates/modalconfig/index.jsx
@@ -47,7 +47,6 @@
  state = {
    menu: null,            // 上级菜单,三级菜单或标签
    dict: CommonDict,      // 字典
    tableFields: [],       // 已选的常用表
    config: null,          // 页面配置,包括模板类型、模态框设置、添加表名、表单列表
    visible: false,        // 表单编辑模态框,显示控制
    modalformlist: null,   // 基本信息表单字段
@@ -588,18 +587,6 @@
  }
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
  updatetable = (config, fields) => {
    const { tableFields } = this.state
    this.setState({
      config: config,
      tableFields: fields ? fields : tableFields
    })
  }
  /**
   * @description 全局设置模态框
   */
  changeSetting = () => {
@@ -782,7 +769,7 @@
                <TableComponent
                  config={config}
                  containerId="modal-basedata"
                  updatetable={this.updatetable}
                  updatetable={this.updateconfig}
                />
              </Panel>
              <Panel header={dict['header.menu.form']} key="1">
@@ -794,7 +781,6 @@
                <FieldsComponent
                  config={config}
                  type="form"
                  tableFields={this.state.tableFields}
                  updatefield={this.updateconfig}
                />
                <Button type="primary" block onClick={() => this.handleGroup()}>{dict['header.menu.group.add']}</Button>
src/templates/sharecomponent/fieldscomponent/index.jsx
@@ -14,7 +14,6 @@
  static propTpyes = {
    type: PropTypes.string,          // 搜索条件添加、显示列添加
    config: PropTypes.object,        // 容器Id
    tableFields: PropTypes.string,   // 已选表字段集
    updatefield: PropTypes.func
  }
@@ -25,9 +24,9 @@
  }
  queryField = () => {
    const { type, config, tableFields } = this.props
    const { type, config } = this.props
    // 判断是否已选择表名
    if (!tableFields || tableFields.length === 0) {
    if (!window.GLOB.tableFields || window.GLOB.tableFields.length === 0) {
      notification.warning({
        top: 92,
        message: '请选择表名!',
@@ -38,7 +37,7 @@
    // 表字段集转为map数据
    let columns = new Map()
    tableFields.forEach(table => {
    window.GLOB.tableFields.forEach(table => {
      table.columns.forEach(column => {
        columns.set(column.field.toLowerCase(), column)
      })
src/templates/sharecomponent/settingcalcomponent/index.jsx
@@ -12,7 +12,6 @@
  static propTpyes = {
    config: PropTypes.any,
    MenuID: PropTypes.string,
    tableFields: PropTypes.any,
    updateConfig: PropTypes.func
  }
@@ -76,7 +75,6 @@
          <VerifyCard
            dict={dict}
            config={config}
            tableFields={this.props.tableFields}
            menuId={this.props.config.uuid}
            searches={config.search}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx
@@ -21,7 +21,6 @@
class VerifyCard extends Component {
  static propTpyes = {
    dict: PropTypes.object,          // 字典项
    tableFields: PropTypes.any,      // 数据源信息
    config: PropTypes.object,        // 数据源信息
    menuId: PropTypes.string,        // 菜单Id
    searches: PropTypes.array,       // 搜索条件
@@ -353,7 +352,6 @@
            <FieldsComponent
              config={{...this.props.config, columns}}
              type="fields"
              tableFields={this.props.tableFields}
              updatefield={this.updatefields}
            />
            <Table
src/templates/sharecomponent/tablecomponent/index.jsx
@@ -153,8 +153,7 @@
      this.setState({
        tableFields: _columns
      })
      this.props.updatetable(this.props.config, _columns)
      window.GLOB.tableFields = _columns
    })
  }
@@ -209,11 +208,16 @@
              }
            })
          }
          let _columns = [...tableFields, tabmsg]
          this.setState({
            tableFields: [...tableFields, tabmsg]
            tableFields: _columns
          })
          this.props.updatetable(_config, [...tableFields, tabmsg])
          window.GLOB.tableFields = _columns
          this.props.updatetable(_config)
        } else {
          notification.warning({
            top: 92,
@@ -240,7 +244,9 @@
      tableFields: _fields
    })
    this.props.updatetable({...config, tables: _tables}, _fields)
    window.GLOB.tableFields = _fields
    this.props.updatetable({...config, tables: _tables})
  }
  /**
src/templates/subtableconfig/index.jsx
@@ -50,7 +50,6 @@
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,        // 字典
    config: null,            // 页面配置
    visible: false,          // 搜索条件、按钮、显示列,模态框显示控制
    tableFields: [],         // 已选表字段集
    menuloading: false,      // 菜单保存中
    menucloseloading: false, // 菜单关闭时,选择保存
    loading: false,          // 加载中,页面spin
@@ -916,27 +915,6 @@
      chartview: _chartview
    })
  }
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
  updatetable = (config, fields) => {
    const { tableFields } = this.state
    this.setState({
      config: config,
      tableFields: fields ? fields : tableFields
    })
  }
  /**
   * @description 批量添加,更新配置信息
   */
  updatefield = (config) => {
    this.setState({
      config: config
    })
  }
  render () {
    const { activeKey, config, chartview } = this.state
@@ -961,7 +939,7 @@
                <TableComponent
                  config={config}
                  containerId="subtable-basedata"
                  updatetable={this.updatetable}
                  updatetable={this.updateconfig}
                />
              </Panel>
              {/* 搜索条件添加 */}
@@ -974,8 +952,7 @@
                <FieldsComponent
                  config={config}
                  type="search"
                  tableFields={this.state.tableFields}
                  updatefield={this.updatefield}
                  updatefield={this.updateconfig}
                />
              </Panel>
              {/* 按钮添加 */}
@@ -1018,8 +995,7 @@
                <FieldsComponent
                  config={config}
                  type="columns"
                  tableFields={this.state.tableFields}
                  updatefield={this.updatefield}
                  updatefield={this.updateconfig}
                />
              </Panel>
            </Collapse>
src/templates/zshare/formconfig.jsx
@@ -2407,7 +2407,7 @@
    {
      type: 'radio',
      key: 'interception',
      label: '截取',
      label: '截取空格',
      initVal: card.interception || 'false',
      tooltip: '提交时,是否截取首尾的空白字符。',
      options: [{
src/views/menudesign/index.jsx
@@ -56,14 +56,12 @@
    ParentId: '',
    MenuName: '',
    MenuNo: '',
    tableFields: [],
    delButtons: [],
    copyButtons: [],
    thawButtons: [],
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
    openEdition: '',
    config: null,
    popBtn: null,             // 弹窗标签页
    visible: false,
@@ -228,10 +226,7 @@
  initPopview = (card, btn) => {
    const { oriConfig, config } = this.state
    let _config = fromJS(config).toJS()
    delete _config.tableFields
    if (!is(fromJS(oriConfig), fromJS(_config))) {
    if (!is(fromJS(oriConfig), fromJS(config))) {
      notification.warning({
        top: 92,
        message: '配置已修改,请保存!',
@@ -240,7 +235,7 @@
      return
    }
    btn.config = _config
    btn.config = fromJS(config).toJS()
    btn.component = card
    sessionStorage.setItem('editMenuType', 'popview') // 编辑弹窗标签
@@ -264,10 +259,7 @@
      return
    }
    let _config = fromJS(config).toJS()
    delete _config.tableFields
    if (!is(fromJS(oriConfig), fromJS(_config))) {
    if (!is(fromJS(oriConfig), fromJS(config))) {
      confirm({
        title: '配置已修改,放弃保存吗?',
        content: '',
@@ -341,10 +333,11 @@
          config.lastCount = config.lastCount || ''
        }
        config.open_edition = result.open_edition || ''
        this.setState({
          oriConfig: config,
          config: fromJS(config).toJS(),
          openEdition: result.open_edition || '',
          config: fromJS(config).toJS()
        })
        this.props.modifyCustomMenu(config)
@@ -458,7 +451,7 @@
  }
  submitConfig = () => {
    const { openEdition, MenuType, delButtons, copyButtons, thawButtons } = this.state
    const { MenuType, delButtons, copyButtons, thawButtons } = this.state
    let config = fromJS(this.state.config).toJS()
    if (MenuType === 'billPrint' && (!config.firstCount || !config.everyPCount)) {
@@ -495,21 +488,19 @@
        config.enabled = false
      }
      let _config = fromJS(config).toJS()
      delete _config.tableFields
      let param = {
        func: 'sPC_TrdMenu_AddUpt',
        FstID: _config.fstMenuId || '',
        SndID: _config.parentId,
        ParentID: _config.parentId,
        MenuID: _config.uuid,
        MenuNo: _config.MenuNo || '',
        EasyCode: _config.easyCode || '',
        FstID: config.fstMenuId || '',
        SndID: config.parentId,
        ParentID: config.parentId,
        MenuID: config.uuid,
        MenuNo: config.MenuNo || '',
        EasyCode: config.easyCode || '',
        Template: 'CustomPage',
        MenuName: _config.MenuName || '',
        PageParam: JSON.stringify({Template: 'CustomPage', OpenType: _config.OpenType || 'newtab'}),
        LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_config))),
        MenuName: config.MenuName || '',
        PageParam: JSON.stringify({Template: 'CustomPage', OpenType: config.OpenType || 'newtab'}),
        LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(config))),
        open_edition: config.open_edition,
        LText: '',
        LTexttb: ''
      }
@@ -518,15 +509,11 @@
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
      if (openEdition) { // 版本管理
        param.open_edition = openEdition
      }
      let btnParam = {             // 添加菜单按钮
        func: 'sPC_Button_AddUpt',
        Type: 40,                  // 添加菜单下的按钮type为40,按钮下的按钮type为60
        ParentID: _config.uuid,
        MenuNo: _config.MenuNo,
        ParentID: config.uuid,
        MenuNo: config.MenuNo,
        Template: 'CustomPage',
        PageParam: '',
        LongParam: '',
@@ -564,7 +551,7 @@
              if (result.status) {
                Api.getSystemConfig({
                  func: 's_PrintTemplateMSub',
                  ID: _config.uuid,
                  ID: config.uuid,
                  Images: Utils.getcloudurl(result.Images),
                  Remark: '',
                  temp_type: 'billprint',
@@ -646,9 +633,9 @@
        if (!res) return
        if (res.status) {
          config.open_edition = res.open_edition || ''
          this.setState({
            oriConfig: fromJS(_config).toJS(),
            openEdition: res.open_edition || ''
            oriConfig: fromJS(config).toJS()
          })
          if (btnParam.LText) {
@@ -720,7 +707,7 @@
                    let _param = {
                      func: 'sPC_ButtonParam_AddUpt',
                      ParentID: _config.uuid,
                      ParentID: config.uuid,
                      MenuID: item.uuid,
                      MenuNo: '',
                      Template: 'CustomPage',
@@ -882,22 +869,6 @@
    this.props.modifyCustomMenu(config)
  }
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
  updatetable = (config, fields) => {
    const { tableFields } = this.state
    config.tableFields = fields ? fields : tableFields
    this.setState({
      tableFields: fields ? fields : tableFields,
      config
    })
    this.props.modifyCustomMenu(config)
  }
  render () {
    const { activeKey, MenuType, popBtn, visible, dict, MenuId, config, ParentId, MenuName, MenuNo, menuloading, customComponents } = this.state
@@ -932,7 +903,7 @@
                      updateConfig={this.updateConfig}
                    /> : null}
                    {/* 表名添加 */}
                    {config ? <TableComponent config={config} updatetable={this.updatetable}/> : null}
                    {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null}
                  </Panel>
                  {/* 组件添加 */}
                  <Panel header={dict['mob.component']} key="component">
src/views/pcdesign/index.jsx
@@ -26,6 +26,7 @@
const MenuShell = asyncComponent(() => import('@/pc/menushell'))
const SourceWrap = asyncComponent(() => import('@/pc/modulesource'))
const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
const Quotecomponent = asyncComponent(() => import('@/pc/quotecomponent'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
const PaddingController = asyncComponent(() => import('@/pc/padcontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
@@ -41,6 +42,7 @@
sessionStorage.setItem('appType', 'pc')        // 应用类型
document.body.className = ''
window.GLOB.UserComponentMap = new Map() // 缓存用户自定义组件
window.GLOB.CacheIndependent = new Map()
class MenuDesign extends Component {
  state = {
@@ -49,20 +51,18 @@
    MenuId: '',
    MenuName: '',
    MenuNo: '',
    tableFields: [],
    delButtons: [],
    copyButtons: [],
    thawButtons: [],
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
    openEdition: '',
    config: null,
    popBtn: null,             // 弹窗标签页
    visible: false,
    customComponents: [],
    settingshow: true,
    controlshow: true,
    settingshow: sessionStorage.getItem('settingshow') !== 'false',
    controlshow: sessionStorage.getItem('controlshow') !== 'false',
  }
  UNSAFE_componentWillMount() {
@@ -105,6 +105,7 @@
    MKEmitter.addListener('thawButtons', this.thawButtons)
    MKEmitter.addListener('copyButtons', this.copyButtons)
    MKEmitter.addListener('changePopview', this.initPopview)
    MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
    MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
    setTimeout(() => {
@@ -124,8 +125,25 @@
    MKEmitter.removeListener('thawButtons', this.thawButtons)
    MKEmitter.removeListener('copyButtons', this.copyButtons)
    MKEmitter.removeListener('changePopview', this.initPopview)
    MKEmitter.removeListener('changeEditMenu', this.changeEditMenu)
    MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
    MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent)
  }
  changeEditMenu = (menu) => {
    const { oriConfig, config } = this.state
    if (!is(fromJS(oriConfig), fromJS(config))) {
      notification.warning({
        top: 92,
        message: '配置已修改,请保存!',
        duration: 5
      })
      return
    }
    this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: menu.MenuID, type: 'view'}))))
    window.location.reload()
  }
  getAppMessage = () => {
@@ -133,7 +151,7 @@
      func: 's_get_keyids',
      bid: sessionStorage.getItem('appId')
    }).then(res => {
      if (!res) {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
@@ -144,7 +162,11 @@
      let homeId = ''
      if (this.state.MenuId) {
        let appViewList = res.data && res.data.length > 0 ? res.data : []
        homeId = this.state.MenuId
        sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
      } else {
        let appViewList = []
        if (res.data && res.data.length > 0) {
@@ -204,6 +226,8 @@
  }
  getAppPictures = () => {
    if (sessionStorage.getItem('app_videos') || sessionStorage.getItem('app_pictures')) return
    Api.getSystemConfig({
      func: 's_url_db_adduptdel',
      PageIndex: 0,  // 0 代表全部
@@ -305,26 +329,23 @@
  }
  initPopview = (card, btn) => {
    // const { oriConfig, config } = this.state
    const { oriConfig, config } = this.state
    // let _config = fromJS(config).toJS()
    // delete _config.tableFields
    if (!is(fromJS(oriConfig), fromJS(config))) {
      notification.warning({
        top: 92,
        message: '配置已修改,请保存!',
        duration: 5
      })
      return
    }
    // if (!is(fromJS(oriConfig), fromJS(_config))) {
    //   notification.warning({
    //     top: 92,
    //     message: '配置已修改,请保存!',
    //     duration: 5
    //   })
    //   return
    // }
    btn.config = fromJS(config).toJS()
    btn.component = card
    // btn.config = _config
    // btn.component = card
    sessionStorage.setItem('editMenuType', 'popview') // 编辑弹窗标签
    // sessionStorage.setItem('editMenuType', 'popview') // 编辑弹窗标签
    // this.setState({popBtn: btn, visible: true})
    this.setState({popBtn: btn, visible: true})
  }
  closeView = () => {
@@ -335,10 +356,7 @@
      return
    }
    let _config = fromJS(config).toJS()
    delete _config.tableFields
    if (!is(fromJS(oriConfig), fromJS(_config))) {
    if (!is(fromJS(oriConfig), fromJS(config))) {
      confirm({
        title: '配置已修改,放弃保存吗?',
        content: '',
@@ -379,7 +397,6 @@
            uuid: MenuId,
            MenuID: MenuId,
            Template: 'webPage',
            easyCode: '',
            enabled: false,
            MenuName: '',
            MenuNo: '',
@@ -394,14 +411,25 @@
        
        config.uuid = MenuId
        config.MenuID = MenuId
        config.open_edition = result.open_edition || ''
        this.setState({
          oriConfig: config,
          config: fromJS(config).toJS(),
          openEdition: result.open_edition || '',
        let indeComs = []
        config.components.forEach(item => {
          if (item.type === 'navbar') {
            indeComs.push(fromJS(item).toJS())
          }
        })
        this.props.modifyCustomMenu(config)
        if (indeComs.length === 0) {
          this.setState({
            oriConfig: config,
            config: fromJS(config).toJS(),
          })
          this.props.modifyCustomMenu(config)
        } else {
          this.jointComponents(config, indeComs)
        }
      } else {
        notification.warning({
          top: 92,
@@ -409,6 +437,107 @@
          duration: 5
        })
      }
    })
    let _param = {
      func: 's_get_app_menus',
      TypeCharOne: sessionStorage.getItem('kei_no'),
      typename: 'pc',
      LText: `select '${window.GLOB.appkey}'`,
      timestamp: moment().format('YYYY-MM-DD HH:mm:ss')
    }
    _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
    Api.getSystemConfig(_param).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
      let appIndeList = sessionStorage.getItem('appViewList')
      appIndeList = JSON.parse(appIndeList)
      appIndeList = appIndeList.map(item => (item.keys_type !== 'index' ? item.keys_id : '')).join(',')
      let menus = res.menus.filter(item => appIndeList.indexOf(item.MenuID) === -1)
      sessionStorage.setItem('appMenus', JSON.stringify(menus))
    })
  }
  jointComponents = (config, indeComs) => {
    let deffers = indeComs.map(item => {
      return new Promise(resolve => {
        Api.getSystemConfig({
          func: 'sPC_Get_LongParam',
          TypeCharOne: sessionStorage.getItem('kei_no'),
          typename: 'pc',
          MenuID: item.uuid
        }).then(res => {
          res.uuid = item.uuid
          if (!res.status) {
            notification.warning({
              top: 92,
              message: res.message,
              duration: 5
            })
            return
          }
          resolve(res)
        })
      })
    })
    Promise.all(deffers).then(result => {
      let _conf = {}
      result.forEach(res => {
        let _config = null
        try {
          _config = res.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(res.LongParam))) : null
        } catch (e) {
          console.warn('Parse Failure')
          _config = null
        }
        if (_config) {
          _config.open_edition = res.open_edition || ''
          _conf[res.uuid] = _config
          window.GLOB.CacheIndependent.set(res.uuid, fromJS(_config).toJS())
        }
      })
      let _length = config.components.length
      config.components = config.components.map(item => {
        if (item.type === 'navbar') {
          if (_conf[item.uuid]) {
            item = _conf[item.uuid]
          } else {
            item = null
          }
        }
        return item
      })
      config.components = config.components.filter(Boolean)
      if (_length > config.components.length) {
        notification.warning({
          top: 92,
          message: '部分组件已删除!',
          duration: 5
        })
      }
      this.setState({
        oriConfig: fromJS(config).toJS(),
        config: config
      })
      this.props.modifyCustomMenu(config)
    })
  }
@@ -512,7 +641,7 @@
  }
  submitConfig = () => {
    const { openEdition, delButtons, copyButtons, thawButtons } = this.state
    const { delButtons, copyButtons, thawButtons } = this.state
    let config = fromJS(this.state.config).toJS()
    if (!config.MenuName || !config.MenuNo || (config.cacheUseful === 'true' && !config.cacheTime)) {
@@ -535,41 +664,33 @@
        config.enabled = false
      }
      let _config = fromJS(config).toJS()
      delete _config.tableFields
      let parMenuId = 'pc' + sessionStorage.getItem('kei_no') + sessionStorage.getItem('lang')
      let parMenuId = sessionStorage.getItem('kei_no') + 'pc' + sessionStorage.getItem('lang')
      let param = {
        func: 'sPC_TrdMenu_AddUpt',
        FstID: parMenuId,
        SndID: parMenuId,
        ParentID: parMenuId,
        MenuID: _config.uuid,
        MenuNo: _config.MenuNo || '',
        EasyCode: _config.easyCode || '',
        MenuID: config.uuid,
        MenuNo: config.MenuNo || '',
        EasyCode: '',
        Template: 'webPage',
        TypeCharOne: sessionStorage.getItem('kei_no'),
        Typename: 'pc',
        MenuName: _config.MenuName || '',
        MenuName: config.MenuName || '',
        PageParam: JSON.stringify({Template: 'webPage'}),
        LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_config))),
        open_edition: config.open_edition,
        LText: '',
        LTexttb: ''
      }
      param.LText = Utils.formatOptions(param.LText)
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
      if (!openEdition) { // 版本管理
        param.open_edition = openEdition
      }
      param.secretkey = Utils.encrypt('', param.timestamp)
      let btnParam = {             // 添加菜单按钮
        func: 'sPC_Button_AddUpt',
        Type: 40,                  // 添加菜单下的按钮type为40,按钮下的按钮type为60
        ParentID: _config.uuid,
        MenuNo: _config.MenuNo,
        ParentID: config.uuid,
        MenuNo: config.MenuNo,
        Template: 'webPage',
        PageParam: '',
        LongParam: '',
@@ -586,31 +707,129 @@
      btnParam.secretkey = Utils.encrypt(btnParam.LText, btnParam.timestamp)
      new Promise(resolve => {
        // html2canvas(document.getElementById('menu-shell-inner')).then(canvas => {
        //   let _param = {
        //     Base64Img: canvas.toDataURL('image/png') // 获取生成的图片
        //   }
        let _config = fromJS(config).toJS()
        let indeComs = []
        _config.components = _config.components.map(item => {
          if (item.type === 'navbar') {
            indeComs.push(item)
            return {
              type: 'navbar',
              uuid: item.uuid
            }
          }
          return item
        })
        //   _param.rduri = options.cloudServiceApi
        //   _param.userid = sessionStorage.getItem('CloudUserID') || ''
        //   _param.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
        param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_config)))
        //   Api.fileuploadbase64(_param).then(result => {
        //     if (result.status) {
        //       let Images = Utils.getcloudurl(result.Images)
        //       param.PageParam = JSON.stringify({Template: 'webPage', Images})
        //       resolve(true)
        //     } else {
        //       notification.warning({
        //         top: 92,
        //         message: result.ErrMesg,
        //         duration: 5
        //       })
        //       resolve(false)
        //     }
        //   })
        // })
        resolve(true)
        if (indeComs.length === 0) {
          resolve(true)
        } else {
          let new_open_edition = {}
          let deffers = indeComs.map(item => {
            return new Promise(resolve => {
              let _item = window.GLOB.CacheIndependent.get(item.uuid)
              if (_item && is(fromJS(_item), fromJS(item))) {
                new_open_edition[item.uuid] = item.open_edition || ''
                resolve()
                return
              }
              let _param = {
                func: 'sPC_TrdMenu_AddUpt',
                FstID: parMenuId,
                SndID: parMenuId,
                ParentID: parMenuId,
                MenuID: item.uuid,
                MenuNo: item.wrap.MenuNo || '',
                EasyCode: '',
                Template: item.type,
                TypeCharOne: sessionStorage.getItem('kei_no'),
                Typename: 'pc',
                MenuName: item.name || '',
                PageParam: JSON.stringify({Template: item.type}),
                open_edition: item.open_edition || '',
                LText: '',
                LTexttb: ''
              }
              _param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(item)))
              _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
              _param.secretkey = Utils.encrypt('', _param.timestamp)
              Api.getSystemConfig(_param).then(res => {
                if (!res.status) {
                  notification.warning({
                    top: 92,
                    message: res.message,
                    duration: 5
                  })
                  return
                }
                new_open_edition[item.uuid] = res.open_edition || ''
                resolve()
              })
            })
          })
          Promise.all(deffers).then(() => {
            let appViewList = sessionStorage.getItem('appViewList')
            appViewList = JSON.parse(appViewList)
            let _length = appViewList.length
            let appIndeList = appViewList.map(item => item.keys_id).join(',')
            config.components = config.components.map(item => {
              if (item.type === 'navbar') {
                item.open_edition = new_open_edition[item.uuid] || ''
                window.GLOB.CacheIndependent.set(item.uuid, fromJS(item).toJS())
                if (appIndeList.indexOf(item.uuid) === -1) {
                  appViewList.unshift({
                    appkey: window.GLOB.appkey || '',
                    bid: sessionStorage.getItem('appId') || '',
                    kei_no: sessionStorage.getItem('kei_no') || '',
                    keys_id: item.uuid,
                    keys_type: 'navbar',
                    remark: item.name
                  })
                }
              }
              return item
            })
            if (appViewList.length > _length) {
              let param = {
                func: 's_kei_link_keyids_addupt',
                BID: sessionStorage.getItem('appId'),
                exec_type: 'y',
                LText: ''
              }
              param.LText = appViewList.map(item => `select '${item.keys_id}','${item.keys_type}','${item.kei_no}','${item.appkey}','${item.bid}','${sessionStorage.getItem('CloudUserID')}','${item.remark}'`)
              param.LText = param.LText.join(' union all ')
              param.LText = Utils.formatOptions(param.LText)
              param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
              param.secretkey = Utils.encrypt('', param.timestamp)
              Api.getSystemConfig(param).then(result => {
                if (!result.status) {
                  notification.warning({
                    top: 92,
                    message: result.message,
                    duration: 5
                  })
                } else {
                  sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
                  resolve(true)
                }
              })
            } else {
              resolve(true)
            }
          })
        }
      }).then(res => { // 按钮删除
        if (!res) return
@@ -664,9 +883,10 @@
        if (!res) return
        if (res.status) {
          config.open_edition = res.open_edition || ''
          this.setState({
            oriConfig: fromJS(_config).toJS(),
            openEdition: res.open_edition || ''
            oriConfig: fromJS(config).toJS(),
          })
          if (btnParam.LText) {
@@ -738,7 +958,7 @@
                    let _param = {
                      func: 'sPC_ButtonParam_AddUpt',
                      ParentID: _config.uuid,
                      ParentID: config.uuid,
                      MenuID: item.uuid,
                      MenuNo: '',
                      Template: 'webPage',
@@ -805,6 +1025,7 @@
  }
  getRoleFields = () => {
    if (sessionStorage.getItem('sysRoles') || sessionStorage.getItem('permFuncField')) return
    Api.getSystemConfig({func: 'sPC_Get_Roles_sModular'}).then(res => {
      if (res.status) {
        let _permFuncField = []
@@ -900,20 +1121,24 @@
    this.props.modifyCustomMenu(config)
  }
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
  updatetable = (config, fields) => {
    const { tableFields } = this.state
  refreshView = () => {
    const { oriConfig, config } = this.state
    config.tableFields = fields ? fields : tableFields
    if (!is(fromJS(oriConfig), fromJS(config))) {
      notification.warning({
        top: 92,
        message: '配置已修改,请保存!',
        duration: 5
      })
      return
    }
    this.setState({
      tableFields: fields ? fields : tableFields,
      config
    })
    this.props.modifyCustomMenu(config)
    sessionStorage.removeItem('sysRoles')
    sessionStorage.removeItem('permFuncField')
    sessionStorage.removeItem('app_videos')
    sessionStorage.removeItem('app_pictures')
    window.location.reload()
  }
  render () {
@@ -925,8 +1150,8 @@
          <DndProvider backend={HTML5Backend}>
            <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}>
              <div className="draw">
                {settingshow ? <Icon onClick={() => this.setState({settingshow: false})} type="double-left" /> : null}
                {!settingshow ? <Icon onClick={() => this.setState({settingshow: true})} type="double-right" /> : null}
                {settingshow ? <Icon onClick={() => {sessionStorage.setItem('settingshow', 'false'); this.setState({settingshow: false})}} type="double-left" /> : null}
                {!settingshow ? <Icon onClick={() => {sessionStorage.setItem('settingshow', 'true'); this.setState({settingshow: true})}} type="double-right" /> : null}
              </div>
              <div className="pc-setting-tools">
                <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
@@ -940,7 +1165,7 @@
                      updateConfig={this.updateConfig}
                    /> : null}
                    {/* 表名添加 */}
                    {config ? <TableComponent config={config} updatetable={this.updatetable}/> : null}
                    {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null}
                  </Panel>
                  {/* 组件添加 */}
                  <Panel header={dict['mob.component']} key="component">
@@ -960,8 +1185,8 @@
            </div>
            <div className={'menu-control ' + (!controlshow ? 'hidden' : '')}>
              <div className="draw">
                {controlshow ? <Icon onClick={() => this.setState({controlshow: false})} type="double-right" /> : null}
                {!controlshow ? <Icon onClick={() => this.setState({controlshow: true})} type="double-left" /> : null}
                {controlshow ? <Icon onClick={() => {sessionStorage.setItem('controlshow', 'false'); this.setState({controlshow: false})}} type="double-right" /> : null}
                {!controlshow ? <Icon onClick={() => {sessionStorage.setItem('controlshow', 'true'); this.setState({controlshow: true})}} type="double-left" /> : null}
              </div>
              <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button>
              <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config && config.enabled} onChange={this.onEnabledChange} />
@@ -969,6 +1194,8 @@
              <StyleCombControlButton menu={config} />
              <SysInterface config={config} updateConfig={this.updateConfig}/>
              <PictureController/>
              <Quotecomponent config={config} updateConfig={this.updateConfig}/>
              <Button className="mk-border-danger" icon="redo" onClick={this.refreshView}>强制刷新</Button>
              <Button type="default" onClick={this.closeView}>{dict['mob.return']}</Button>
            </div>
            <div className={'menu-body ' + (menuloading ? 'saving' : '')}>
src/views/pcdesign/menuform/index.jsx
@@ -14,17 +14,6 @@
  state = {}
  UNSAFE_componentWillMount () {
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    const { config } = this.props
    if (!config && nextProps.config) {
      this.props.form.setFieldsValue({easyCode: nextProps.config.easyCode})
    }
  }
  // 一二级菜单切换
  selectChange = (key, value) => {
    const { config } = this.props
@@ -44,11 +33,6 @@
  // 菜单参数
  changeNo = (e) => {
    this.props.updateConfig({...this.props.config, MenuNo: e.target.value})
  }
  // 助记码
  changeEasyCode = (e) => {
    this.props.updateConfig({...this.props.config, easyCode: e.target.value})
  }
  changeCacheDay = (val) => {
@@ -145,13 +129,6 @@
              )}
            </Form.Item>
          </Col> : null}
          <Col span={24}>
            <Form.Item label={dict['mob.menu.easycode']}>
              {getFieldDecorator('easyCode', {
                initialValue: config.easyCode
              })(<Input placeholder="" autoComplete="off" onChange={this.changeEasyCode}/>)}
            </Form.Item>
          </Col>
        </Row>
      </Form>
    )