king
2020-09-16 2e5908bf05c200e12aa0fdfe5db5e21cbe7d014a
2020-09-16
8个文件已修改
6个文件已添加
672 ■■■■ 已修改文件
src/menu/components/chart/antv-bar/chartcompile/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.jsx 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.scss 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/tabcomponents/card.jsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/tabcomponents/index.jsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/tabcomponents/index.scss 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/card.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/index.jsx 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/shellcomponent/card.jsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/shellcomponent/index.jsx 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/shellcomponent/index.scss 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/loginform.jsx 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/index.scss
@@ -25,6 +25,9 @@
        .ant-input-number {
          width: 100%;
        }
        .ant-tabs-nav-wrap {
          text-align: center;
        }
      }
    }
  }
src/menu/components/chart/antv-bar/index.jsx
@@ -18,7 +18,7 @@
class antvBarLineChart extends Component {
  static propTpyes = {
    config: PropTypes.object,
    menu: PropTypes.object,
    card: PropTypes.object,
    updateConfig: PropTypes.func,
  }
@@ -29,7 +29,7 @@
  }
  UNSAFE_componentWillMount () {
    const { card, config } = this.props
    const { card, menu } = this.props
    if (card.isNew) {
      let _plot = {
@@ -51,27 +51,14 @@
        _plot.shape = 'hv'
      }
      let name = ''
      let names = {
        bar: '柱状图',
        line: '折线图',
      }
      let i = 1
      while (!name) {
        let _name = names[card.type] + i
        if (config.components.filter(com => com.setting && com.setting.name === _name).length === 0) {
          name = _name
        }
        i++
      }
      let dataName = ''
      while (!dataName) {
        let _dataName = Utils.getdataName()
        if (config.components.filter(com => com.dataName === _dataName).length === 0) {
          dataName = _dataName
      if (card.floor === 1) {
        while (!dataName) {
          let _dataName = Utils.getdataName()
          if (menu.components.filter(com => com.dataName === _dataName).length === 0) {
            dataName = _dataName
          }
        }
      }
@@ -84,7 +71,7 @@
        switchable: false, // 组件属性 - 数据是否可切换
        dataName: dataName,
        subtype: card.subtype,
        setting: {span: 12, height: 400, interType: 'system', name},
        setting: {span: card.floor === 1 ? 12 : 24, height: 400, interType: 'system', name: card.name},
        columns: [],
        scripts: [],
        search: [],
@@ -510,33 +497,8 @@
    }
  }
  plotChange = (_plot) => {
    const { config } = this.props
    if (_plot.datatype === 'statistics') {
      _plot.Yaxis = [_plot.InfoValue]
    }
    let _charts = fromJS(config.charts).toJS()
    _charts = _charts.map(item => {
      if (item.uuid === _plot.uuid) {
        if (!is(fromJS(item), fromJS(_plot))) {
          let _element = document.getElementById(_plot.uuid)
          if (_element) {
            _element.innerHTML = ''
          }
        }
        return _plot
      }
      return item
    })
    this.props.plotchange({...config, charts: _charts})
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState))
  }
  updateComponent = (component) => {
@@ -564,28 +526,28 @@
  render() {
    const { card } = this.state
    const { config } = this.props
    const { menu } = this.props
    return (
      <div className="menu-line-chart-edit-box" style={{height: card.setting.height || 400}}>
        <SettingComponent
          config={card}
          menu={config}
          menu={menu}
          updateConfig={this.updateComponent}
        />
        <div className="chart-header">
          <span className="chart-title">{card.setting.title || ''}</span>
          <SearchComponent
            menu={config}
            menu={menu}
            config={card}
            sysRoles={config.sysRoles}
            sysRoles={menu.sysRoles}
            optionLibs={null}
            updatesearch={this.updateComponent}
          />
        </div>
        <ActionComponent
          type="chart"
          menu={config}
          menu={menu}
          config={card}
          tabs={[]}
          // setSubConfig={(_btn) => this.setSubConfig(_btn, 'button')}
src/menu/components/tabs/antv-tabs/index.jsx
@@ -12,13 +12,14 @@
const SettingComponent = asyncComponent(() => import('../tabsetting'))
const TabLabelComponent = asyncComponent(() => import('../tablabelform'))
const TabComponents = asyncComponent(() => import('../tabcomponents'))
const { TabPane } = Tabs
const { confirm } = Modal
class antvBarLineChart extends Component {
  static propTpyes = {
    config: PropTypes.object,
    menu: PropTypes.object,
    tabs: PropTypes.object,
    updateConfig: PropTypes.func,
  }
@@ -31,41 +32,30 @@
  }
  UNSAFE_componentWillMount () {
    const { tabs, config } = this.props
    const { tabs } = this.props
    if (tabs.isNew) {
      let name = ''
      let i = 1
      while (!name) {
        let _name = '标签页' + i
        if (config.components.filter(com => com.setting && com.setting.name === _name).length === 0) {
          name = _name
        }
        i++
      }
      let _tabs = {
        uuid: tabs.uuid,
        type: tabs.type,
        floor: tabs.floor,
        subtype: tabs.subtype,
        setting: {span: 12, position: 'top', tabStyle: 'line', name},
        setting: {span: 12, position: 'top', tabStyle: 'line', name: tabs.name},
        subtabs: [{
          uuid: Utils.getuuid(),
          label: 'Tab 1',
          icon: '',
          subcomponents: [],
          components: [],
        }, {
          uuid: Utils.getuuid(),
          label: 'Tab 2',
          icon: '',
          subcomponents: [],
          components: [],
        }, {
          uuid: Utils.getuuid(),
          label: 'Tab 3',
          icon: '',
          subcomponents: [],
          components: [],
        }]
      }
      this.setState({
@@ -79,24 +69,30 @@
    }
  }
  componentDidMount () { }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!is(fromJS(this.props.plot), fromJS(nextProps.plot))) {
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState))
  }
  updateComponent = (component) => {
    this.setState({
      tabs: component
    })
    this.props.updateConfig(component)
  }
  updateTabComponent = (tab) => {
    let tabs = fromJS(this.state.tabs).toJS()
    tabs.subtabs = tabs.subtabs.map(t => {
      if (t.uuid === tab.uuid) {
        return tab
      } else {
        return t
      }
    })
    this.setState({tabs})
    this.props.updateConfig(tabs)
  }
  tabAdd = (e) => {
@@ -106,7 +102,7 @@
        uuid: '',
        label: '',
        icon: '',
        subcomponents: []
        components: []
      },
      labelvisible: true
    })
@@ -175,6 +171,7 @@
  }
  render() {
    const { menu } = this.props
    const { tabs, dict, labelvisible, editab } = this.state
    return (
@@ -194,7 +191,8 @@
                <span>{tab.icon ? <Icon type={tab.icon} /> : null}{tab.label}</span>
              </Popover>
            } key={tab.uuid}>
              Content of Tab Pane {tab.label}
              {/* Content of Tab Pane {tab.label} */}
              <TabComponents menu={menu} config={tab} handleList={this.updateTabComponent} deleteCard={this.deleteCard} />
            </TabPane>
          ))}
          <TabPane className="tab-add" disabled tab={<Icon onClick={this.tabAdd} type="plus" />} key="add"></TabPane>
src/menu/components/tabs/antv-tabs/index.scss
@@ -46,12 +46,36 @@
    top: 0px;
  }
  .ant-tabs-card {
    .ant-tabs-card-bar .ant-tabs-tab:last-child {
      padding: 0px;
      border: 0px;
      background: transparent;
      .anticon-plus {
        padding: 12px 16px;
    .ant-tabs-left-bar, .ant-tabs-right-bar {
      .ant-tabs-tab {
        > span {
          padding: 0px 16px;
        }
        .anticon-plus {
          padding: 0px 16px;
        }
      }
      .ant-tabs-tab-active {
        padding-left: 0px!important;
        padding-right: 0px!important;
      }
    }
    .ant-tabs-card-bar {
      .ant-tabs-tab {
        padding: 0px;
        > span {
          display: inline-block;
          padding: 0px 16px;
        }
      }
      .ant-tabs-tab:last-child {
        padding: 0px;
        border: 0px;
        background: transparent;
        .anticon-plus {
          padding: 12px 16px;
        }
      }
    }
  }
src/menu/components/tabs/tabcomponents/card.jsx
New file
@@ -0,0 +1,56 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Icon } from 'antd'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar'))
const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs'))
const Card = ({ id, menu, card, moveCard, findCard, delCard, hasDrop, doubleClickCard, updateConfig }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: 'menu', id, originalIndex },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })
  const [, drop] = useDrop({
    accept: 'menu',
    canDrop: () => true,
    drop: (item) => {
      if (!item.hasOwnProperty('originalIndex')) {
        hasDrop(card)
      }
    },
    hover({ id: draggedId }) {
      if (!draggedId) return
      if (draggedId !== id) {
        const { index: overIndex } = findCard(id)
        moveCard(draggedId, overIndex)
      }
    },
  })
  let style = { opacity: 1}
  if (isDragging) {
    style = { opacity: 0.3}
  }
  const getCardComponent = () => {
    if (card.type === 'bar' || card.type === 'line') {
      return (<AntvBar menu={menu} card={card} updateConfig={updateConfig} />)
    } else if (card.type === 'tabs') {
      return (<AntvTabs menu={menu} tabs={card} updateConfig={updateConfig} />)
    }
  }
  return (
    <div className={'ant-col mk-component-card ant-col-' + (card.setting ? card.setting.span : 24)} ref={node => drag(drop(node))} style={style}>
      {getCardComponent()}
      <Icon className="remove-component" title="delete" type="delete" onClick={() => delCard(id)} />
    </div>
  )
}
export default Card
src/menu/components/tabs/tabcomponents/index.jsx
New file
@@ -0,0 +1,108 @@
import React, { useState } from 'react'
import { useDrop } from 'react-dnd'
import { is, fromJS } from 'immutable'
import update from 'immutability-helper'
import { Empty, notification } from 'antd'
import Utils from '@/utils/utils.js'
import Card from './card'
import './index.scss'
const Container = ({menu, config, handleList, deleteCard, doubleClickCard }) => {
  let target = null
  const [cards, setCards] = useState(config.components)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    handleList({...config, components: _cards})
  }
  if (!is(fromJS(cards), fromJS(config.components))) {
    setCards(config.components)
  }
  const findCard = id => {
    const card = cards.filter(c => `${c.uuid}` === id)[0]
    return {
      card,
      index: cards.indexOf(card),
    }
  }
  const hasDrop = (item) => {
    target = item
  }
  const updateConfig = (element) => {
    handleList({...config, components: cards.map(item => item.uuid === element.uuid ? element : item)})
  }
  const [, drop] = useDrop({
    accept: 'menu',
    drop(item) {
      if (item.hasOwnProperty('originalIndex') || item.added) {
        return
      }
      item.added = true
      if (item.component === 'search') { // 搜索组件不可重复添加
        if (cards.filter(card => card.type === 'search').length > 0) {
          notification.warning({
            top: 92,
            message: '搜索条件不可重复添加!',
            duration: 5
          })
          return
        }
      }
      let newcard = {
        uuid: Utils.getuuid(),
        type: item.component,
        subtype: item.subtype,
        floor: 2,   // 组件的层级
        isNew: true // 新添加标志,用于初始化
      }
      let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0
      if (target) {
        targetId = target.uuid
      }
      const { index: overIndex } = findCard(`${targetId}`)
      let targetIndex = overIndex
      targetIndex++
      const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
      handleList({...config, components: _cards})
      target = null
    }
  })
  return (
    <div ref={drop} className="ant-row tab-shell-inner">
      {cards.map(card => (
        <Card
          id={card.uuid}
          key={card.uuid}
          menu={menu}
          config={config}
          card={card}
          moveCard={moveCard}
          delCard={deleteCard}
          findCard={findCard}
          hasDrop={hasDrop}
          updateConfig={updateConfig}
          doubleClickCard={doubleClickCard}
        />
      ))}
      {cards.length === 0 ?
        <Empty description="请添加组件" /> : null
      }
    </div>
  )
}
export default Container
src/menu/components/tabs/tabcomponents/index.scss
New file
@@ -0,0 +1,48 @@
.tab-shell-inner {
  margin: -8px;
  >.ant-col {
    padding: 8px;
  }
  .anticon {
    cursor: unset;
  }
  .mk-component-card {
    position: relative;
    .remove-component {
      position: absolute;
      right: 42px;
      top: -16px;
      color: #ff4d4f;
      border-radius: 2px;
      font-size: 16px;
      padding: 5px;
      cursor: pointer;
      opacity: 0;
      transition: opacity 0.2s;
    }
  }
  .mk-component-card:hover {
    .remove-component {
      opacity: 1;
    }
    .model-datasource > .anticon-setting, .model-menu-tabs-setting > .anticon-setting {
      opacity: 1;
    }
  }
  >.ant-empty {
    padding: 60px 0px 70px;
  }
  .model-datasource > .anticon-setting, .model-menu-tabs-setting > .anticon-setting {
    font-size: 16px;
    padding: 5px;
    position: absolute;
    right: 0px;
    top: -30px;
    opacity: 0;
    cursor: pointer;
    transition: opacity 0.2s;
  }
}
src/menu/menushell/card.jsx
@@ -8,7 +8,7 @@
const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar'))
const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs'))
const Card = ({ id, config, card, moveCard, findCard, delCard, hasDrop, doubleClickCard, updateConfig }) => {
const Card = ({ id, menu, card, moveCard, findCard, delCard, hasDrop, doubleClickCard, updateConfig }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: 'menu', id, originalIndex },
@@ -40,9 +40,9 @@
  const getCardComponent = () => {
    if (card.type === 'bar' || card.type === 'line') {
      return (<AntvBar config={config} card={card} updateConfig={updateConfig} />)
      return (<AntvBar menu={menu} card={card} updateConfig={updateConfig} />)
    } else if (card.type === 'tabs') {
      return (<AntvTabs config={config} tabs={card} updateConfig={updateConfig} />)
      return (<AntvTabs menu={menu} tabs={card} updateConfig={updateConfig} />)
    }
  }
src/menu/menushell/index.jsx
@@ -8,18 +8,18 @@
import Card from './card'
import './index.scss'
const Container = ({config, handleList, deleteCard, doubleClickCard }) => {
const Container = ({menu, handleList, deleteCard, doubleClickCard }) => {
  let target = null
  const [cards, setCards] = useState(config.components)
  const [cards, setCards] = useState(menu.components)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    handleList({...config, components: _cards})
    handleList({...menu, components: _cards})
  }
  if (!is(fromJS(cards), fromJS(config.components))) {
    setCards(config.components)
  if (!is(fromJS(cards), fromJS(menu.components))) {
    setCards(menu.components)
  }
  
  const findCard = id => {
@@ -35,16 +35,15 @@
  }
  const updateConfig = (element) => {
    handleList({...config, components: cards.map(item => item.uuid === element.uuid ? element : item)})
    handleList({...menu, components: cards.map(item => item.uuid === element.uuid ? element : item)})
  }
  const [, drop] = useDrop({
    accept: 'menu',
    drop(item) {
      if (item.hasOwnProperty('originalIndex')) {
      if (item.hasOwnProperty('originalIndex') || item.added) {
        return
      }
      if (item.component === 'search') { // 搜索组件不可重复添加
        if (cards.filter(card => card.type === 'search').length > 0) {
          notification.warning({
@@ -54,6 +53,22 @@
          })
          return
        }
      }
      let name = ''
      let names = {
        bar: '柱状图',
        line: '折线图',
        tabs: '标签组'
      }
      let i = 1
      while (!name && names[item.component]) {
        let _name = names[item.component] + i
        if (menu.components.filter(com => com.setting && com.setting.name === _name).length === 0) {
          name = _name
        }
        i++
      }
      let newcard = {
@@ -76,7 +91,7 @@
      const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
      handleList({...config, components: _cards})
      handleList({...menu, components: _cards})
      target = null
    }
  })
@@ -87,7 +102,7 @@
        <Card
          id={card.uuid}
          key={card.uuid}
          config={config}
          menu={menu}
          card={card}
          moveCard={moveCard}
          delCard={deleteCard}
src/menu/shellcomponent/card.jsx
New file
@@ -0,0 +1,56 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Icon } from 'antd'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar'))
const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs'))
const Card = ({ id, menu, card, moveCard, findCard, delCard, hasDrop, doubleClickCard, updateConfig }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: 'menu', id, originalIndex },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })
  const [, drop] = useDrop({
    accept: 'menu',
    canDrop: () => true,
    drop: (item) => {
      if (!item.hasOwnProperty('originalIndex')) {
        hasDrop(card)
      }
    },
    hover({ id: draggedId }) {
      if (!draggedId) return
      if (draggedId !== id) {
        const { index: overIndex } = findCard(id)
        moveCard(draggedId, overIndex)
      }
    },
  })
  let style = { opacity: 1}
  if (isDragging) {
    style = { opacity: 0.3}
  }
  const getCardComponent = () => {
    if (card.type === 'bar' || card.type === 'line') {
      return (<AntvBar menu={menu} card={card} updateConfig={updateConfig} />)
    } else if (card.type === 'tabs') {
      return (<AntvTabs menu={menu} tabs={card} updateConfig={updateConfig} />)
    }
  }
  return (
    <div className={'ant-col mk-component-card ant-col-' + (card.setting ? card.setting.span : 12)} ref={node => drag(drop(node))} style={style}>
      {getCardComponent()}
      <Icon className="remove-component" title="delete" type="delete" onClick={() => delCard(id)} />
    </div>
  )
}
export default Card
src/menu/shellcomponent/index.jsx
New file
@@ -0,0 +1,121 @@
import React, { useState } from 'react'
import { useDrop } from 'react-dnd'
import { is, fromJS } from 'immutable'
import update from 'immutability-helper'
import { Empty, notification } from 'antd'
import Utils from '@/utils/utils.js'
import Card from './card'
import './index.scss'
const Container = ({menu, handleList, deleteCard, doubleClickCard }) => {
  let target = null
  const [cards, setCards] = useState(menu.components)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    handleList({...menu, components: _cards})
  }
  if (!is(fromJS(cards), fromJS(menu.components))) {
    setCards(menu.components)
  }
  const findCard = id => {
    const card = cards.filter(c => `${c.uuid}` === id)[0]
    return {
      card,
      index: cards.indexOf(card),
    }
  }
  const hasDrop = (item) => {
    target = item
  }
  const updateConfig = (element) => {
    handleList({...menu, components: cards.map(item => item.uuid === element.uuid ? element : item)})
  }
  const [, drop] = useDrop({
    accept: 'menu',
    drop(item) {
      if (item.hasOwnProperty('originalIndex') || item.added) {
        return
      }
      if (item.component === 'search') { // 搜索组件不可重复添加
        if (cards.filter(card => card.type === 'search').length > 0) {
          notification.warning({
            top: 92,
            message: '搜索条件不可重复添加!',
            duration: 5
          })
          return
        }
      }
      let name = ''
      let names = {
        bar: '柱状图',
        line: '折线图',
        tabs: '标签组'
      }
      let i = 1
      while (!name && names[item.component]) {
        let _name = names[item.component] + i
        if (menu.components.filter(com => com.setting && com.setting.name === _name).length === 0) {
          name = _name
        }
        i++
      }
      let newcard = {
        uuid: Utils.getuuid(),
        type: item.component,
        subtype: item.subtype,
        floor: 1,   // 组件的层级
        isNew: true // 新添加标志,用于初始化
      }
      let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0
      if (target) {
        targetId = target.uuid
      }
      const { index: overIndex } = findCard(`${targetId}`)
      let targetIndex = overIndex
      targetIndex++
      const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
      handleList({...menu, components: _cards})
      target = null
    }
  })
  return (
    <div ref={drop} className="ant-row menu-shell-inner">
      {cards.map(card => (
        <Card
          id={card.uuid}
          key={card.uuid}
          menu={menu}
          card={card}
          moveCard={moveCard}
          delCard={deleteCard}
          findCard={findCard}
          hasDrop={hasDrop}
          updateConfig={updateConfig}
          doubleClickCard={doubleClickCard}
        />
      ))}
      {cards.length === 0 ?
        <Empty description="请添加组件" /> : null
      }
    </div>
  )
}
export default Container
src/menu/shellcomponent/index.scss
New file
@@ -0,0 +1,49 @@
.menu-shell-inner {
  min-height: calc(100vh - 150px);
  margin: -8px;
  >.ant-col {
    padding: 8px;
  }
  .anticon {
    cursor: unset;
  }
  .mk-component-card {
    position: relative;
    .remove-component {
      position: absolute;
      right: 42px;
      top: -16px;
      color: #ff4d4f;
      border-radius: 2px;
      font-size: 16px;
      padding: 5px;
      cursor: pointer;
      opacity: 0;
      transition: opacity 0.2s;
    }
  }
  .mk-component-card:hover {
    .remove-component {
      opacity: 1;
    }
    .model-datasource > .anticon-setting, .model-menu-tabs-setting > .anticon-setting {
      opacity: 1;
    }
  }
  >.ant-empty {
    padding-top: 150px;
  }
  .model-datasource > .anticon-setting, .model-menu-tabs-setting > .anticon-setting {
    font-size: 16px;
    padding: 5px;
    position: absolute;
    right: 0px;
    top: -30px;
    opacity: 0;
    cursor: pointer;
    transition: opacity 0.2s;
  }
}
src/views/login/loginform.jsx
@@ -31,6 +31,7 @@
    activeKey: 'uname_pwd',
    username: '',
    password: '',
    remember: true,
    delay: null,
    loginWays: [],
    smsId: '',
@@ -39,6 +40,12 @@
  UNSAFE_componentWillMount () {
    const { loginWays } = this.props
    let remember = true
    let _url = window.location.href.split('#')[0]
    if (localStorage.getItem(_url + 'remember') === 'false') {
      remember = false
    }
    let smsId = ''
    let _loginWays = []
@@ -54,7 +61,8 @@
    this.setState({
      smsId: smsId,
      loginWays: _loginWays,
      activeKey: _loginWays[0].type
      activeKey: _loginWays[0].type,
      remember
    })
  }
@@ -246,6 +254,13 @@
    }
  }
  rememberChange = (e) => {
    let val = e.target.checked
    let _url = window.location.href.split('#')[0]
    localStorage.setItem(_url + 'remember', val)
  }
  /**
   * @description 组件销毁,清除state更新
   */
@@ -257,7 +272,7 @@
  render() {
    const { getFieldDecorator } = this.props.form
    const { activeKey, verdisabled, delay, loginWays } = this.state
    const { activeKey, verdisabled, delay, loginWays, remember } = this.state
    return (
      <Form className={`login-form login-form-${loginWays.length}`} id="login-form" onSubmit={this.handleSubmit}>
@@ -323,8 +338,8 @@
          {activeKey === 'uname_pwd' ? <Form.Item className="minline">
            {getFieldDecorator('remember', {
              valuePropName: 'checked',
              initialValue: true,
            })(<Checkbox>{this.props.dict['login.remember']}</Checkbox>)}
              initialValue: remember,
            })(<Checkbox onChange={this.rememberChange}>{this.props.dict['login.remember']}</Checkbox>)}
          </Form.Item> : null}
          {this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right">
            {getFieldDecorator('lang', {
src/views/menudesign/index.jsx
@@ -45,9 +45,12 @@
  }
  UNSAFE_componentWillMount() {
    this.getMenuParam()
    // this.testFunc()
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  /**
@@ -403,7 +406,7 @@
                    <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{dict['mob.save']}</Button>
                  </div>
                } style={{ width: '100%' }}>
                  {config && config.components ? <MenuShell config={config} handleList={this.updateConfig} deleteCard={this.deleteCard} /> : null}
                  {config && config.components ? <MenuShell menu={config} handleList={this.updateConfig} deleteCard={this.deleteCard} /> : null}
                </Card>
              </div>
            </div>