king
2019-10-29 d4f4804aeedb44d81b7518cd5469abcb0c215d6b
level1 menu
13个文件已修改
4个文件已添加
798 ■■■■ 已修改文件
src/api/index.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/dragelement/card.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/dragelement/index.jsx 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/dragelement/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 300 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.scss 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/menuform/index.jsx 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/menuform/index.scss 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/transferform/index.jsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/transferform/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/header.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/header.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action-type.js 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/reducer.js 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -9,7 +9,7 @@
axios.interceptors.request.use((config) => {
  config.method = 'post'
  if (config.url.includes('LoginAndRedirect')) {
  if (config.url.includes('LoginAndRedirect') || config.url.includes('getjsonresult')) {
    config.data = qs.stringify(config.data)
  } else {
    config.headers.token = sessionStorage.getItem('TOKEN') || ''
@@ -64,6 +64,20 @@
      }
    })
  }
  /**
   * @description 登录系统
   */
  getusermsg (username, password) {
    return axios({
      url: 'webapi/getjsonresult',
      data: {
        DBT: 'proc',
        DBS: 'webapi_login',
        DBP: JSON.stringify({ 'UserName': username, 'Password': password })
      }
    })
  }
  
  /**
   * @description 登出系统
src/components/dragelement/card.jsx
@@ -24,9 +24,9 @@
  })
  const opacity = isDragging ? 0 : 1
  const close = () => {
    closeCard(id)
  }
  // const close = () => {
  //   closeCard(id)
  // }
  const edit = () => {
    editCard(id)
@@ -36,7 +36,6 @@
      <div ref={node => drag(drop(node))}>
        {text}
      </div>
      <Icon className="close" type="close" onClick={close} />
      <Icon className="edit" type="edit" onClick={edit} />
    </div>
  )
src/components/dragelement/index.jsx
@@ -52,28 +52,32 @@
  const cancel = () => {
    handleButton('cancel')
  }
  const thawmenu = () => {
    handleButton('thawmenu')
  }
  const [, drop] = useDrop({ accept: ItemTypes.CARD })
  return (
    <>
      <div ref={drop} className="dragdashboard">
        {cards.map(card => (
          <Card
            key={card.id}
            id={`${card.id}`}
            text={card.text}
            moveCard={moveCard}
            closeCard={closeCard}
            editCard={editCard}
            findCard={findCard}
          />
        ))}
        <div className="card-add" onClick={add}>
          <Icon type="plus" />
        </div>
        <Button type="primary" onClick={confirm}>{dict['header.confirm']}</Button>
        <Button onClick={cancel}>{dict['header.return']}</Button>
    <div ref={drop} className="dragdashboard">
      {cards.map(card => (
        <Card
          key={card.id}
          id={`${card.id}`}
          text={card.text}
          moveCard={moveCard}
          closeCard={closeCard}
          editCard={editCard}
          findCard={findCard}
        />
      ))}
      <div className="card-add" onClick={add}>
        <Icon type="plus" />
      </div>
    </>
      <Button type="primary" onClick={thawmenu}>{dict['header.thawmenu']}</Button>
      <Button type="primary" onClick={confirm}>{dict['header.confirm']}</Button>
      <Button onClick={cancel}>{dict['header.close']}</Button>
    </div>
  )
}
export default Container
src/components/dragelement/index.scss
@@ -1,11 +1,14 @@
.dragdashboard {
  position: relative;
  z-index: 1;
  width: calc(100vw - 400px);
  float: left;
  background: #001529;
  padding-bottom: 5px;
  .card-add {
    border: 1px dashed gray;
    padding: 2px;
    margin-top: 10px;
    margin-top: 13px;
    margin-left: 10px;
    width: 50px;
    float: left;
@@ -13,7 +16,7 @@
    cursor: pointer;
  }
  button {
    margin-top: 10px;
    margin-top: 14px;
    margin-left: 10px;
    padding: 0 10px;
    height: 26px;
@@ -22,15 +25,14 @@
.card {
  position: relative;
  border: 1px dashed gray;
  padding-right: 15px;
  margin-top: 7px;
  margin-right: 10px;
  float: left;
  div {
    padding: 5px;
    padding: 5px 20px 5px 5px;
    cursor: move;
    min-width: 43px;
    max-width: 70px;
    max-width: 85px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
src/components/header/index.jsx
@@ -3,12 +3,13 @@
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import { is, fromJS } from 'immutable'
import {Dropdown, Menu, Icon, Modal, message, Form, notification } from 'antd'
import {Dropdown, Menu, Icon, Modal, message, Form, notification, Button, Switch, Spin } from 'antd'
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import md5 from 'md5'
import SimpleForm from '@/components/simpleform'
import {toggleCollapse, modifyMainMenu, resetState, resetDebug, resetEditState} from '@/store/action'
import MenuForm from './menuform'
import TransferForm from './transferform'
import {toggleCollapse, modifyMainMenu, resetState, resetDebug, resetEditState, resetEditLevel} from '@/store/action'
import Resetpwd from '@/components/resetpwd'
import DragElement from '@/components/dragelement'
import Api from '@/api'
@@ -18,9 +19,9 @@
import logourl from '../../assets/img/mlogo.png'
import avatar from '../../assets/img/avatar.jpg'
import './index.scss'
import { Promise } from 'q';
const { confirm } = Modal
const { SubMenu } = Menu
let previewList = null
class Header extends Component {
@@ -33,10 +34,12 @@
  }
  state = {
    menulist: null, // 一级菜单
    thawmenulist: null, // 已冻结的一级菜单
    visible: false, // 修改密码模态框
    addMvisible: false, // 添加菜单模态框
    editMenu: null, // 编辑菜单
    editMvisible: false, // 编辑菜单模态框
    thawMvisible: false, // 解除冻结模态框
    dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
    confirmLoading: false,
    userName: localStorage.getItem('username')
@@ -44,7 +47,9 @@
  handleCollapse = () => {
    // 展开、收起左侧菜单栏
    this.props.toggleCollapse(!this.props.collapse)
    if (!this.props.editState) {
      this.props.toggleCollapse(!this.props.collapse)
    }
  }
  changePassword = () => {
@@ -122,7 +127,12 @@
  changeMenu (value) {
    // 主菜单切换
    this.props.modifyMainMenu(value)
    console.log(value)
    if (value.PageParam.OpenType === 'menu') {
      this.props.modifyMainMenu(value)
    } else {
      window.open('#/' + value.PageParam.linkUrl + '/')
    }
  }
  async loadmenu () {
@@ -154,6 +164,11 @@
      previewList = result.data.map((item, index) => {
        item.id = index
        item.text = item.MenuName
        if (item.PageParam) {
          item.PageParam = JSON.parse(item.PageParam)
        } else {
          item.PageParam = {OpenType: 'menu', linkUrl: ''}
        }
        return item
      })
@@ -170,38 +185,85 @@
  handleButton = (type) => {
    // 菜单编辑:添加,确定,取消
    if (type === 'add') {
    if ((type === 'add' || type === 'thawmenu') && !is(fromJS(previewList), fromJS(this.state.menulist))) {
      notification.warning({
        top: 92,
        message: this.state.dict['header.menu.presave'],
        duration: 10
      })
    } else if (type === 'add') {
      this.setState({
        addMvisible: true
      })
    } else if (type === 'confirm' && !is(fromJS(previewList), fromJS(this.state.menulist))) {
      Api.logoutsystem().then(res => {
      let _this = this
      let param  = {}
      param.func = 'sPC_Menu_SortUpt'
      param.LText = []
      previewList.forEach((item, index) => {
        param.LText.push('selectmspace\'' + item.MenuID + '\'mspaceasmspaceMenuid,' + (index + 1) * 10 + 'mspaceasmspacesort')
      })
      param.LText = param.LText.join('mspaceunionmspace')
      confirm({
        title: this.state.dict['header.menu.resetorder'],
        content: '',
        okText: this.state.dict['header.confirm'],
        cancelText: this.state.dict['header.cancel'],
        onOk() {
          return Api.submitInterface(param).then(res => {
            if (res.status) {
              _this.setState({
                menulist: null
              })
              _this.loadmenu()
            } else {
              message.warning(res.message)
            }
          })
        },
        onCancel() {}
      })
    } else if (type === 'thawmenu') {
      this.setState({
        thawMvisible: true
      })
      Api.submitInterface({
        func: 'sPC_Get_FrozenMenu',
        ParentID: '0',
        TYPE: 10
      }).then(res => {
        if (res.status) {
          this.loadmenu()
          this.setState({
            thawmenulist: res.data.map(menu => {
              return {
                key: menu.MenuID,
                title: menu.MenuName
              }
            })
          })
        } else {
          message.warning(res.message)
        }
      })
    } else {
      previewList = this.state.menulist
      this.props.resetEditState(false)
      this.props.resetEditLevel(false)
    }
  }
  handleMenu = (Menu) => {
    // 菜单编辑:修改、删除
    const _this = this
    const menu = fromJS(Menu)
    const card = menu.get('card')
    const menu = fromJS(Menu).toJS()
    if (!is(fromJS(previewList), fromJS(this.state.menulist))) {
      notification.warning({
        top: 92,
        message: this.state.dict['header.menu.presave'],
        duration: 10
      })
    } else if (menu.get('type') === 'close') {
    } else if (menu.type === 'close') {
      confirm({
        title: this.state.dict['header.menu.close'].replace('@M', card.get('MenuName')),
        title: this.state.dict['header.menu.close'].replace('@M', menu.card.MenuName),
        content: '',
        okText: this.state.dict['header.confirm'],
        cancelText: this.state.dict['header.cancel'],
@@ -216,27 +278,10 @@
        },
        onCancel() {}
      })
    } else if (menu.get('type') === 'edit') {
    } else if (menu.type === 'edit') {
      this.setState({
        editMvisible: true,
        editMenu: [
          {
            type: 'text',
            key: 'menuID',
            label: this.state.dict['header.menu.menuID'],
            initVal: card.get('MenuID'),
            required: true,
            readonly: true
          },
          {
            type: 'text',
            key: 'menuName',
            label: this.state.dict['header.menu.menuName'],
            initVal: card.get('MenuName'),
            required: true,
            readonly: false
          }
        ]
        editMenu: menu.card
      })
    }
  }
@@ -248,17 +293,20 @@
  addMemuSubmit = () => {
    // 新建菜单:提交
    this.addMenuFormRef.handleConfirm().then(res => {
    this.addMenuFormRef.handleConfirm().then(param => {
      param.func = 'sPC_MainMenu_Add'
      param.Sort = (this.state.menulist.length + 1) * 10
      this.setState({
        confirmLoading: true
      })
      Api.logoutsystem().then(res => {
      Api.submitInterface(param).then(res => {
        if (res.status) {
          this.setState({
            confirmLoading: false,
            addMvisible: false
            addMvisible: false,
            menulist: null
          })
          this.addMenuFormRef.handleReset()
          this.addMenuFormRef.handleReset('add')
          this.loadmenu()
        } else {
          this.setState({
@@ -276,21 +324,23 @@
      confirmLoading: false,
      addMvisible: false
    })
    this.addMenuFormRef.handleReset()
    this.addMenuFormRef.handleReset('add')
  }
  editMemuSubmit = () => {
    // 编辑菜单:提交
    this.editMenuFormRef.handleConfirm().then(res => {
    this.editMenuFormRef.handleConfirm().then(param => {
      param.func = 'sPC_MainMenu_Upt'
      this.setState({
        confirmLoading: true
      })
      Api.logoutsystem().then(res => {
      Api.submitInterface(param).then(res => {
        if (res.status) {
          this.setState({
            confirmLoading: false,
            editMvisible: false,
            editMenu: null
            editMenu: null,
            menulist: null
          })
          this.loadmenu()
        } else {
@@ -307,9 +357,95 @@
    // 编辑菜单:取消
    this.setState({
      confirmLoading: false,
      editMvisible: false
      editMvisible: false,
      editMenu: null
    })
    this.editMenuFormRef.handleReset()
  }
  deleteMemu = () => {
    let _this = this
    confirm({
      title: this.state.dict['header.menu.close'].replace('@M', this.state.editMenu.MenuName),
      content: '',
      okText: this.state.dict['header.confirm'],
      cancelText: this.state.dict['header.cancel'],
      onOk() {
        let param = {
          func: 'sPC_MainMenu_Del',
          MenuID: _this.state.editMenu.MenuID
        }
        return Api.submitInterface(param).then(res => {
          if (res.status) {
            _this.setState({
              editMvisible: false,
              editMenu: null,
              menulist: null
            })
            _this.loadmenu()
          } else {
            message.warning(res.message)
          }
        })
      },
      onCancel() {}
    })
  }
  thawMemuSubmit = () => {
    if (this.refs.trawmenu.state.targetKeys.length === 0) {
      notification.warning({
        top: 92,
        message: this.state.dict['header.menu.thawmenu.select'],
        duration: 10
      })
    } else {
      this.setState({
        confirmLoading: true
      })
      let defers = this.refs.trawmenu.state.targetKeys.map(item => {
        return new Promise((resolve) => {
          Api.submitInterface({
            func: 'sPC_MainMenu_ReDel',
            MenuID: item
          }).then(res => {
            if (res.status) {
              resolve('')
            } else {
              resolve(res.message)
            }
          })
        })
      })
      Promise.all(defers).then(res => {
        let msg = res.filter(Boolean)[0]
        if (msg) {
          notification.error({
            top: 92,
            message: msg,
            duration: 15
          })
        } else {
          this.setState({
            confirmLoading: false,
            thawMvisible: false,
            thawmenulist: null,
            menulist: null
          })
          this.loadmenu()
        }
      })
    }
  }
  thawMemuCancel = () => {
    this.setState({
      thawMvisible: false,
      thawmenulist: null
    })
  }
  enterEdit = () => {
    this.props.resetEditLevel('level1')
  }
  
  UNSAFE_componentWillMount () {
@@ -324,11 +460,10 @@
  render () {
    const menu = (
      <Menu overlayclassname="header-dropdown">
        {this.props.debug && <SubMenu title="编辑">
          <Menu.Item onClick={() => {this.changeEditState('level1')}}>一级菜单</Menu.Item>
          <Menu.Item>二级菜单</Menu.Item>
          <Menu.Item>三级菜单</Menu.Item>
        </SubMenu>}
        {this.props.debug && <Menu.Item key="0">
          {this.state.dict['header.edit']}
          <Switch size="small" className="edit-switch" onChange={this.changeEditState} />
        </Menu.Item>}
        <Menu.Item key="1" onClick={this.changePassword}>{this.state.dict['header.password']}</Menu.Item>
        <Menu.Item key="2" onClick={this.logout}>{this.state.dict['header.logout']}</Menu.Item>
      </Menu>
@@ -340,7 +475,8 @@
        <div className={this.props.collapse ? "collapse header-collapse" : "header-collapse"} onClick={this.handleCollapse}>
          <Icon type={this.props.collapse ? 'menu-unfold' : 'menu-fold'} />
        </div>
        {this.props.editState !== 'level1' && this.state.menulist && <ul className="header-menu">{
        {/* 正常菜单 */}
        {this.props.editLevel !== 'level1' && this.state.menulist && <ul className="header-menu">{
          this.state.menulist.map(item => {
            return (
              <li key={item.MenuID} onClick={() => {this.changeMenu(item)}} className={this.props.selectmenu.MenuID === item.MenuID ? 'active' : ''}>
@@ -349,7 +485,10 @@
            )
          })
        }</ul>}
        {this.props.editState === 'level1' && this.state.menulist && <DndProvider className="header-drag-menu" backend={HTML5Backend}>
        {/* 进入编辑按钮 */}
        {this.props.editState && !this.props.editLevel && <Icon onClick={this.enterEdit} className="edit-check" type="edit" />}
        {/* 编辑菜单 */}
        {this.props.editLevel === 'level1' && this.state.menulist && <DndProvider className="header-drag-menu" backend={HTML5Backend}>
          <DragElement
            dict={this.state.dict}
            list={this.state.menulist}
@@ -358,6 +497,8 @@
            handleButton={this.handleButton}
          />
        </DndProvider>}
        {/* 编辑mask */}
        <div className={'mask ' + (this.props.editLevel === 'level1' ? 'active' : '')}></div>
        <Dropdown className="header-setting" overlay={menu}>
          <div>
            <img src={avatar} alt=""/>
@@ -388,27 +529,10 @@
          confirmLoading={this.state.confirmLoading}
          onCancel={this.addMemuCancel}
        >
          <SimpleForm
          <MenuForm
            dict={this.state.dict}
            formlist={[
              {
                type: 'text',
                key: 'menuID',
                label: this.state.dict['header.menu.menuID'],
                initVal: '',
                required: true,
                readonly: false
              },
              {
                type: 'text',
                key: 'menuName',
                label: this.state.dict['header.menu.menuName'],
                initVal: '',
                required: true,
                readonly: false
              }
            ]}
            cols={1}
            type="add"
            menu={null}
            wrappedComponentRef={(inst) => this.addMenuFormRef = inst}
          />
        </Modal>
@@ -418,16 +542,32 @@
          okText={this.state.dict['header.confirm']}
          cancelText={this.state.dict['header.cancel']}
          visible={this.state.editMvisible}
          onOk={this.editMemuSubmit}
          confirmLoading={this.state.confirmLoading}
          onCancel={this.editMemuCancel}
          footer={null}
        >
          <SimpleForm
          {this.state.editMenu && <MenuForm
            dict={this.state.dict}
            formlist={this.state.editMenu || []}
            cols={1}
            type="edit"
            menu={this.state.editMenu}
            wrappedComponentRef={(inst) => this.editMenuFormRef = inst}
          />
          />}
          <div className="edit-modal-footer">
            <Button onClick={this.editMemuCancel}>{this.state.dict['header.cancel']}</Button>
            <Button type="primary" onClick={this.editMemuSubmit} loading={this.state.confirmLoading}>{this.state.dict['header.confirm']}</Button>
            <Button type="danger" onClick={this.deleteMemu}>{this.state.dict['header.delete']}</Button>
          </div>
        </Modal>
        {/* 解除冻结菜单模态框 */}
        <Modal
          title={this.state.dict['header.thawmenu']}
          okText={this.state.dict['header.confirm']}
          cancelText={this.state.dict['header.cancel']}
          visible={this.state.thawMvisible}
          onOk={this.thawMemuSubmit}
          confirmLoading={this.state.confirmLoading}
          onCancel={this.thawMemuCancel}
        >
          {!this.state.thawmenulist && <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" />}
          {this.state.thawmenulist && <TransferForm ref="trawmenu" dict={this.state.dict} menulist={this.state.thawmenulist}/>}
        </Modal>
      </header>
    )
@@ -439,7 +579,8 @@
    collapse: state.collapse,
    selectmenu: state.selectedMainMenu,
    debug: state.debug,
    editState: state.editState
    editState: state.editState,
    editLevel: state.editLevel
  }
}
@@ -449,7 +590,8 @@
    modifyMainMenu: (selectmenu) => dispatch(modifyMainMenu(selectmenu)),
    resetState: () => dispatch(resetState()),
    resetDebug: () => dispatch(resetDebug()),
    resetEditState: (state) => dispatch(resetEditState(state))
    resetEditState: (state) => dispatch(resetEditState(state)),
    resetEditLevel: (level) => dispatch(resetEditLevel(level))
  }
}
src/components/header/index.scss
@@ -88,9 +88,43 @@
  .header-drag-menu {
    float: left;
  }
  .edit-check {
    font-size: 18px;
    margin-top: 14px;
    margin-left: 10px;
    cursor: pointer;
  }
  .mask {
    position: fixed;
    top: 48px;
    left: 0px;
    right: 0px;
    bottom: calc(100vh - 48px);
    transition: bottom 0.2s
  }
  .mask.active {
    bottom: 0px;
    background-color: rgba(0, 0, 0, 0.15);
  }
}
.header-dropdown {
  li {
    padding: 5px 25px;
  }
}
.edit-switch {
  margin-left: 10px;
}
.edit-modal-footer{
  padding: 10px 16px;
  text-align: right;
  background: transparent;
  border-top: 1px solid #e8e8e8;
  border-radius: 0 0 4px 4px;
  margin-left: -24px;
  margin-right: -24px;
  margin-bottom: -20px;
  .ant-btn {
    margin-right: 7px;
  }
}
src/components/header/menuform/index.jsx
New file
@@ -0,0 +1,220 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Select } from 'antd'
import Utils from '@/utils/utils.js'
import './index.scss'
class MainSearch extends Component {
  static propTpyes = {
    menu: PropTypes.any, // 搜索条件列表
    dict: PropTypes.object, // 字典项
    type: PropTypes.string // 字典项
  }
  state = {
    formlist: [],
    defaultMenu: [
      {
        type: 'text',
        key: 'menuName',
        label: this.props.dict['header.menu.menuName'],
        initVal: '',
        required: true,
        readonly: false
      },
      {
        type: 'select',
        key: 'openType',
        label: this.props.dict['header.menu.openType'],
        initVal: 'menu',
        required: true,
        options: [{
          id: 'menu',
          text: this.props.dict['header.menu.openType.menu']
        }, {
          id: 'newpage',
          text: this.props.dict['header.menu.openType.newWindow']
        }]
      },
      {
        type: 'select',
        key: 'linkUrl',
        hidden: true,
        label: this.props.dict['header.menu.openType.newWindow'],
        initVal: 'service',
        required: true,
        options: [{
          id: 'service',
          text: this.props.dict['header.menu.newpage.service']
        }]
      }
    ]
  }
  UNSAFE_componentWillMount () {
    if (this.props.type === 'add') {
      this.setState({
        formlist: this.state.defaultMenu
      })
    } else {
      this.setState({
        formlist: this.state.defaultMenu.map(menu => {
          if (menu.key === 'menuName') {
            menu.initVal = this.props.menu.MenuName
          } else if (menu.key === 'openType') {
            menu.initVal = this.props.menu.PageParam.OpenType
          } else if (menu.key === 'linkUrl') {
            menu.initVal = this.props.menu.PageParam.linkUrl
            if (this.props.menu.PageParam.OpenType === 'menu') {
              menu.hidden = true
            } else if (this.props.menu.PageParam.OpenType === 'newpage') {
              menu.hidden = false
            }
          }
          return menu
        })
      })
    }
  }
  openTypeChange = (key, value) => {
    if (key === 'openType') {
      let formlist = this.state.formlist
      if (value === 'newpage') {
        formlist.forEach(item => {
          if (item.key === 'linkUrl') {
            item.hidden = false
            item.initVal = 'service'
          }
        })
      } else {
        formlist.forEach(item => {
          if (item.key === 'linkUrl') {
            item.hidden = true
          }
        })
      }
      this.setState({formlist})
    }
  }
  getFields() {
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.state.formlist.forEach((item, index) => {
      if (item.hidden) return
      if (item.type === 'text') { // 文本搜索
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  onChange={(value) => {this.openTypeChange(item.key, value)}}
                  getPopupContainer={() => document.getElementById('form-box')}
                >
                  {item.options.map(option =>
                    <Select.Option id={option.id} title={option.text} key={option.id} value={option.id}>{option.text}</Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      }
    })
    return fields
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          if (this.props.type === 'add') {
            resolve({
              MenuID: Utils.getuuid(),
              MenuName: values.menuName,
              PageParam: JSON.stringify({
                OpenType: values.openType,
                linkUrl: values.openType !== 'menu' ? values.linkUrl : ''
              })
            })
          } else {
            resolve({
              MenuID: this.props.menu.MenuID,
              MenuName: values.menuName,
              PageParam: JSON.stringify({
                OpenType: values.openType,
                linkUrl: values.openType !== 'menu' ? values.linkUrl : ''
              })
            })
          }
        } else {
          reject(err)
        }
      })
    })
  }
  handleReset = (type) => {
    // 重置
    if (type === 'add') {
      let formlist = this.state.formlist.map(item => {
        if (item.key === 'linkUrl') {
          item.hidden = true
        }
        return item
      })
      this.setState({formlist})
    }
    this.props.form.resetFields()
  }
  render() {
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 18 }
      }
    }
    return (
      <Form {...formItemLayout} className="ant-advanced-search-form" id="form-box">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
  }
}
export default Form.create()(MainSearch)
src/components/header/menuform/index.scss
New file
@@ -0,0 +1,20 @@
.ant-advanced-search-form.main-search {
  padding: 0px 24px 20px;
  border-bottom: 1px solid #d9d9d9;
  .ant-form-item {
    display: flex;
    margin-bottom: 10px;
  }
  .ant-form-item-control-wrapper {
    flex: 1;
  }
  .ant-form-item-label {
    width: 100px;
  }
}
.ant-advanced-search-form {
  position: relative;
}
.ant-advanced-search-form .ant-input-number {
  width: 100%;
}
src/components/header/transferform/index.jsx
New file
@@ -0,0 +1,44 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Transfer } from 'antd'
import './index.scss'
class TransferForm extends Component {
  static propTypes = {
    menulist: PropTypes.array,
    dict: PropTypes.object, // 字典项
  }
  state = {
    targetKeys: [],
    selectedKeys: []
  }
  handleChange = (nextTargetKeys, direction, moveKeys) => {
    this.setState({ targetKeys: nextTargetKeys })
  }
  handleSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
    this.setState({ selectedKeys: [...sourceSelectedKeys, ...targetSelectedKeys] })
  }
  render() {
    const { targetKeys, selectedKeys } = this.state
    return (
      <div className="trawmenutransfer">
        <Transfer
          dataSource={this.props.menulist}
          titles={[this.props.dict['header.menu.thawmenu.source'], this.props.dict['header.menu.thawmenu.target']]}
          targetKeys={targetKeys}
          locale={{itemUnit: this.props.dict['header.menu.thawmenu.itemUnit'], itemsUnit: this.props.dict['header.menu.thawmenu.itemsUnit']}}
          selectedKeys={selectedKeys}
          onChange={this.handleChange}
          onSelectChange={this.handleSelectChange}
          render={item => item.title}
        />
      </div>
    )
  }
}
export default TransferForm
src/components/header/transferform/index.scss
New file
@@ -0,0 +1,5 @@
.trawmenutransfer {
  .ant-transfer-list {
    width: 210px;
  }
}
src/locales/en-US/header.js
@@ -1,7 +1,11 @@
export default {
  'header.confirm': 'Ok',
  'header.delete': 'Delete',
  'header.cancel': 'Cancel',
  'header.edit': 'Edit',
  'header.return': 'Back',
  'header.close': 'Close',
  'header.thawmenu': 'Thaw the menu',
  'header.logout': 'Logout',
  'header.logout.hint': 'Are you sure you want to log out?',
  'header.password': 'Change the password',
@@ -17,9 +21,19 @@
  'header.password.resetsuccess': 'Password modified successfully!',
  'header.menu.close': 'Are you sure to delete the menu <<@M>> ?',
  'header.menu.presave': 'Menu order has been adjusted, Please save!',
  'header.menu.resetorder': 'Are you sure to adjust the menu sequence ?',
  'header.menu.addtitle': 'The new menu',
  'header.menu.edittitle': 'The edit menu',
  'header.menu.menuID': 'Menu ID',
  'header.menu.menuName': 'Menu Name',
  'header.menu.openType': 'Open With',
  'header.menu.openType.menu': 'Menu',
  'header.menu.openType.newWindow': 'A new window',
  'header.menu.newpage.service': 'Customer Service',
  'header.menu.thawmenu.select': 'Please select the menu to unfreeze !',
  'header.menu.thawmenu.source': 'Frozen',
  'header.menu.thawmenu.target': 'Unfreeze',
  'header.menu.thawmenu.itemUnit': 'item',
  'header.menu.thawmenu.itemsUnit': 'items',
  'form.required.input': 'Please enter the '
}
src/locales/zh-CN/header.js
@@ -1,7 +1,11 @@
export default {
  'header.confirm': '确定',
  'header.delete': '删除',
  'header.cancel': '取消',
  'header.edit': '编辑',
  'header.return': '返回',
  'header.close': '关闭',
  'header.thawmenu': '解冻菜单',
  'header.logout': '退出',
  'header.logout.hint': '您确定要退出吗?',
  'header.password': '修改密码',
@@ -17,10 +21,20 @@
  'header.password.resetsuccess': '密码修改成功!',
  'header.menu.close': '确定删除《@M》菜单吗?',
  'header.menu.presave': '菜单顺序已调整,请保存!',
  'header.menu.resetorder': '确认调整菜单顺序吗?',
  'header.menu.addtitle': '新建菜单',
  'header.menu.edittitle': '编辑菜单',
  'header.menu.menuID': '菜单ID',
  'header.menu.menuName': '菜单名称',
  'header.menu.openType': '打开方式',
  'header.menu.openType.menu': '菜单',
  'header.menu.openType.newWindow': '新窗口',
  'header.menu.newpage.service': '客服',
  'header.menu.thawmenu.select': '请选择要解除冻结的菜单!',
  'header.menu.thawmenu.source': '已冻结',
  'header.menu.thawmenu.target': '解除冻结',
  'header.menu.thawmenu.itemUnit': '项',
  'header.menu.thawmenu.itemsUnit': '项',
  'form.required.input': '请输入'
}
src/store/action-type.js
@@ -20,4 +20,7 @@
export const REFRESH_TABVIEW = 'REFRESH_TABVIEW'
// 重置编辑状态
export const RESET_EDITSTATE = 'RESET_EDITSTATE'
export const RESET_EDITSTATE = 'RESET_EDITSTATE'
// 重置编辑级别
export const RESET_EDITLEVEL = 'RESET_EDITLEVEL'
src/store/action.js
@@ -60,4 +60,12 @@
    type: user.RESET_EDITSTATE,
    editState
  }
}
// 重置编辑级别
export const resetEditLevel = (editLevel) => {
  return {
    type: user.RESET_EDITLEVEL,
    editLevel
  }
}
src/store/reducer.js
@@ -6,7 +6,8 @@
  collapse: false, // 是否收起侧边栏导航
  isiframe: false, // 是否为iframe窗口
  debug: false, // 知否可以复制菜单参数, 是否可进入编辑模式
  editState: false, // 是否为编辑状态,值为false、level1、level2、level3。。。
  editState: false, // 是否为编辑状态,值为false、true
  editLevel: null, // 编辑菜单级别,值为level1、level2、level3。。。
  refreshTab: null // 刷新tabview页面信息
}
@@ -56,7 +57,13 @@
    case Type.RESET_EDITSTATE:
      return {
        ...state,
        editState: action.editState
        editState: action.editState,
        collapse: false
      }
    case Type.RESET_EDITLEVEL:
      return {
        ...state,
        editLevel: action.editLevel
      }
    default:
      return state
src/utils/utils.js
@@ -10,7 +10,7 @@
    for (let i = 0; i < 19; i++) {
      uuid.push(options.substr(Math.floor(Math.random() * 0x20), 1))
    }
    uuid = uuid.join('') + timestamp
    uuid = timestamp + uuid.join('')
    return uuid
  }
src/views/login/index.jsx
@@ -83,25 +83,31 @@
    let password = param.password
    let result = await Api.loginsystem(param.username, password)
    if (!result.IsError) {
      sessionStorage.setItem('UserID', result.userid || 'U000000001')
      sessionStorage.setItem('SessionUid', Utils.getuuid())
      sessionStorage.setItem('LoginUID', '')
      localStorage.setItem('lang', this.state.selectedlang.value)
      if (param.remember) { // 记住密码时账号密码存入localStorage
        localStorage.setItem('username', param.username)
        localStorage.setItem('password', param.password)
      } else {
        localStorage.removeItem('username')
        localStorage.removeItem('password')
      }
      if (this.props.location.state && this.props.location.state.from.pathname) {
        // 查看是否为其他页面跳转,路径存在时,跳回原页面
        this.props.history.replace(this.props.location.state.from.pathname)
      } else {
        this.props.history.replace('/main')
      }
      Api.getusermsg(param.username, password).then(res => {
        if (res.status) {
          sessionStorage.setItem('UserID', res.UserID)
          sessionStorage.setItem('SessionUid', Utils.getuuid())
          sessionStorage.setItem('LoginUID', res.LoginUID)
          localStorage.setItem('lang', this.state.selectedlang.value)
          if (param.remember) { // 记住密码时账号密码存入localStorage
            localStorage.setItem('username', param.username)
            localStorage.setItem('password', param.password)
          } else {
            localStorage.removeItem('username')
            localStorage.removeItem('password')
          }
          if (this.props.location.state && this.props.location.state.from.pathname) {
            // 查看是否为其他页面跳转,路径存在时,跳回原页面
            this.props.history.replace(this.props.location.state.from.pathname)
          } else {
            this.props.history.replace('/main')
          }
        } else {
          message.warning(res.message)
        }
      })
    } else {
      message.warning(result.Message)
      this.setState({