import React, {Component} from 'react'
|
import { is, fromJS } from 'immutable'
|
import { Menu, Popover, Modal, notification } from 'antd'
|
import { EditOutlined, PlusOutlined, SettingOutlined, ApiOutlined, SoundOutlined } from '@ant-design/icons'
|
import moment from 'moment'
|
|
import asyncComponent from '@/utils/asyncComponent'
|
import Utils from '@/utils/utils.js'
|
import Api from '@/api'
|
import MKEmitter from '@/utils/events.js'
|
import MkIcon from '@/components/mk-icon'
|
import './index.scss'
|
|
const EditSecMenu = asyncComponent(() => import('./editsecmenu'))
|
const EditThdMenu = asyncComponent(() => import('./editthdmenu'))
|
const ThawMenu = asyncComponent(() => import('@/components/thawmenu'))
|
const AddThdMenu = asyncComponent(() => import('./thdmenuplus'))
|
const ThdMenuForm = asyncComponent(() => import('./thdmenuform'))
|
const MenuForm = asyncComponent(() => import('./menuform'))
|
const { SubMenu } = Menu
|
|
class Sidemenu extends Component {
|
state = {
|
editMenu: null, // 编辑三级菜单时设置
|
rootSubmenuKeys: null,
|
openKeys: null,
|
preview: null,
|
loading: false,
|
thdVisible: false,
|
sysMenu: null,
|
formlist: []
|
}
|
|
async loadsubmenu (menu) {
|
if (!menu || !menu.MenuID) { // 没有主菜单时,清空下级菜单
|
this.setState({
|
rootSubmenuKeys: [],
|
openKeys: [],
|
editMenu: null
|
})
|
return
|
}
|
|
menu = fromJS(menu).toJS()
|
let openKey = ''
|
|
// 菜单更新时,展开原二级菜单
|
if (this.props.mainMenu && menu.MenuID === this.props.mainMenu.MenuID && this.state.openKeys && this.state.openKeys[0]) {
|
openKey = this.state.openKeys[0]
|
if (menu.children.filter(m => m.MenuID === openKey).length === 0) {
|
openKey = ''
|
}
|
}
|
if (!openKey && menu.children[0]) {
|
openKey = menu.children[0].MenuID
|
}
|
|
this.setState({
|
rootSubmenuKeys: menu.children.map(item => item.MenuID),
|
openKeys: openKey ? [openKey] : [],
|
editMenu: this.props.editLevel === 'level3' ? menu.children.filter(_menu => _menu.MenuID === this.state.editMenu.MenuID)[0] : null
|
})
|
}
|
|
shouldComponentUpdate (nextProps, nextState) {
|
return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
|
}
|
|
UNSAFE_componentWillReceiveProps (nextProps) {
|
if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu))) {
|
this.loadsubmenu(nextProps.mainMenu)
|
}
|
}
|
|
onOpenChange = openKeys => {
|
const latestOpenKey = openKeys.find(key => this.state.openKeys.indexOf(key) === -1)
|
if (this.state.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
|
this.setState({ openKeys })
|
} else {
|
this.setState({
|
openKeys: latestOpenKey ? [latestOpenKey] : []
|
})
|
}
|
}
|
|
enterSubEdit = (e) => {
|
// 编辑二级菜单
|
e.stopPropagation()
|
|
if (this.props.mainMenu.children.length === 0) return
|
|
this.props.resetEditLevel('level2')
|
}
|
|
enterThrEdit = (e, menu) => {
|
// 编辑三级菜单
|
e.stopPropagation()
|
this.props.resetEditLevel('level3')
|
this.setState({editMenu: menu})
|
}
|
|
exitEdit = () => {
|
if (this.props.editLevel === 'level3') {
|
this.setState({editMenu: null})
|
}
|
this.props.resetEditLevel(false)
|
}
|
|
editmenu = (cell) => {
|
if (window.GLOB.systemType === 'production') return
|
|
if (cell.type === 'CustomPage') {
|
let _param = {
|
MenuType: 'custom',
|
MenuId: cell.MenuID,
|
ParentId: cell.ParentId,
|
MenuName: cell.MenuName,
|
MenuNo: cell.MenuNo
|
}
|
_param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
|
window.open(`#/menudesign/${_param}`)
|
} else if (cell.type === 'BaseTable') {
|
sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
|
let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
|
|
window.open(`#/tabledesign/${_param}`)
|
} else if (['CommonTable', 'TreePage'].includes(cell.type)) {
|
sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
|
let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
|
|
window.open(`#/basedesign/${_param}`)
|
} else if (['RolePermission', 'NewPage'].includes(cell.type)) {
|
let _cell = fromJS(cell).toJS()
|
_cell.Template = _cell.PageParam.Template
|
_cell.url = _cell.PageParam.url || ''
|
_cell.proUrl = _cell.PageParam.proUrl || ''
|
|
_cell.fstMenuId = _cell.FstId
|
_cell.supMenuList = this.props.mainMenu.children
|
_cell.fstMenuList = this.props.menuTree
|
|
this.setState({
|
thdVisible: true,
|
loading: false,
|
sysMenu: _cell
|
})
|
} else {
|
notification.warning({
|
top: 92,
|
message: '当前菜单不可编辑',
|
duration: 5
|
})
|
}
|
}
|
|
addSecMenu = () => {
|
this.setState({
|
visible: true,
|
loading: false,
|
formlist: [
|
{ // 父级菜单
|
type: 'select',
|
key: 'parentId',
|
label: '上级菜单',
|
initVal: this.props.mainMenu.MenuID,
|
required: true,
|
options: this.props.menuTree
|
},
|
{ // 菜单名称
|
type: 'text',
|
key: 'menuName',
|
label: '菜单名称',
|
initVal: '',
|
required: true,
|
readonly: false
|
},
|
{ // 菜单图标
|
type: 'icon',
|
key: 'icon',
|
label: '图标',
|
initVal: 'folder',
|
required: true
|
}
|
]
|
})
|
}
|
|
secSubmit = () => {
|
this.menuFormRef.handleConfirm().then(values => {
|
let param = {
|
ParentID: values.parentId,
|
MenuID: Utils.getuuid(),
|
MenuName: values.menuName,
|
PageParam: JSON.stringify({
|
Icon: values.icon
|
})
|
}
|
param.func = 'sPC_SndMenu_Add'
|
param.Sort = (this.props.mainMenu.children.length + 1) * 10
|
|
this.setState({
|
loading: true
|
})
|
Api.getCloudConfig(param).then(res => {
|
if (res.status) {
|
this.setState({
|
loading: false,
|
visible: false
|
})
|
MKEmitter.emit('mkUpdateMenuList')
|
} else {
|
this.setState({
|
loading: false
|
})
|
notification.warning({
|
top: 92,
|
message: res.message,
|
duration: 5
|
})
|
}
|
})
|
})
|
}
|
|
/**
|
* @description 三级菜单修改
|
*/
|
thdSubmit = () => {
|
const { sysMenu } = this.state
|
|
this.menuThdFormRef.handleConfirm().then(res => {
|
let PageParam = {
|
Template: sysMenu.Template,
|
OpenType: 'newtab'
|
}
|
|
if (sysMenu.Template === 'NewPage') {
|
PageParam.OpenType = 'NewPage'
|
PageParam.url = res.url
|
if (res.proUrl) {
|
PageParam.proUrl = res.proUrl
|
}
|
}
|
|
let param = {
|
func: 'sPC_TrdMenu_AddUpt',
|
FstID: res.fstMenuId,
|
SndID: res.ParentID,
|
ParentID: res.ParentID,
|
MenuID: sysMenu.MenuID,
|
MenuNo: res.MenuNo,
|
Template: sysMenu.Template,
|
MenuName: res.MenuName,
|
PageParam: JSON.stringify(PageParam),
|
LongParam: '',
|
// LText: '',
|
// LTexttb: ''
|
}
|
|
param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
|
param.secretkey = Utils.encrypt('', param.timestamp)
|
|
this.setState({
|
loading: true
|
})
|
|
Api.getCloudConfig(param).then(response => {
|
if (response.status) {
|
this.setState({
|
loading: false,
|
thdVisible: false,
|
sysMenu: null
|
})
|
MKEmitter.emit('mkUpdateMenuList')
|
} else {
|
this.setState({
|
loading: false
|
})
|
notification.warning({
|
top: 92,
|
message: response.message,
|
duration: 5
|
})
|
}
|
})
|
})
|
}
|
|
render () {
|
const { mainMenu, editLevel } = this.props
|
const { visible, loading, thdVisible } = this.state
|
|
return (
|
<aside className="mk-sys-side-menu ant-menu-dark mk-edit">
|
{editLevel !== 'level2' && editLevel !== 'level3' && mainMenu ?
|
<Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark">
|
<li className="sup-menu">
|
<Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
|
<div className="mk-popover-control">
|
<PlusOutlined onClick={this.addSecMenu}/>
|
<EditOutlined onClick={this.enterSubEdit} className={'mk-swap' + (mainMenu.children.length === 0 ? ' disabled' : '')}/>
|
<div style={{display: 'inline-block', minWidth: '32px'}}><ThawMenu ParentId={mainMenu.MenuID} Type="20"/></div>
|
</div>
|
} trigger="hover" placement="top">
|
<SettingOutlined className="edit-check"/>
|
</Popover>
|
</li>
|
{mainMenu.children.map((item, index) => {
|
return (
|
<SubMenu
|
key={item.MenuID}
|
title={
|
<span className={!editLevel && index === 0 ? 'edit-control' : ''}>
|
<MkIcon type={item.PageParam ? item.PageParam.Icon : 'folder'} />
|
<span>{item.MenuName}</span>
|
</span>
|
}
|
>
|
<li className={'ant-menu-item ' + (item.children.length > 0 ? 'sub-menu' : '')}>
|
<Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
|
<div className="mk-popover-control">
|
<div style={{display: 'inline-block', minWidth: '32px'}}><AddThdMenu mainMenu={mainMenu} supMenu={item} menuTree={this.props.menuTree}/></div>
|
<EditOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="mk-swap"/>
|
<div style={{display: 'inline-block', minWidth: '32px'}}><ThawMenu ParentId={item.MenuID} Type="30"/></div>
|
</div>
|
} trigger="hover" placement="top">
|
<SettingOutlined className="edit-check"/>
|
</Popover>
|
</li>
|
{item.children.map(cell => {
|
return (
|
<Menu.Item key={cell.MenuID}>
|
<span className={'editable-menu-item ' + (cell.up_action ? 'unupdate' : '') + (window.backend && window.GLOB.systemType !== 'production' && cell.PageParam.backend !== 'level1' ? ' unbackend' : '')} onDoubleClick={() => this.editmenu(cell)}>{cell.PageParam.interfaces === 'true' ? <ApiOutlined title="菜单中使用了外部接口" /> : null}{cell.PageParam.msg === 'true' ? <SoundOutlined title="菜单中发送了消息" /> : null}{cell.MenuName}</span>
|
</Menu.Item>
|
)
|
})}
|
</SubMenu>
|
)
|
})}
|
</Menu> : null}
|
{editLevel === 'level2' && mainMenu ?
|
<EditSecMenu
|
menulist={mainMenu.children}
|
menuTree={this.props.menuTree}
|
supMenu={this.props.mainMenu}
|
exitEdit={this.exitEdit}
|
/> : null
|
}
|
{editLevel === 'level3' && mainMenu && this.state.editMenu ?
|
<EditThdMenu
|
menulist={this.state.editMenu.children}
|
supMenuList={mainMenu.children}
|
supMenu={this.state.editMenu}
|
menuTree={this.props.menuTree}
|
exitEdit={this.exitEdit}
|
/> : null
|
}
|
<Modal
|
title="添加菜单"
|
visible={visible}
|
onOk={this.secSubmit}
|
// confirmLoading={loading}
|
onCancel={() => this.setState({visible: false})}
|
destroyOnClose
|
>
|
<MenuForm
|
inputSubmit={this.secSubmit}
|
formlist={this.state.formlist}
|
wrappedComponentRef={(inst) => this.menuFormRef = inst}
|
/>
|
</Modal>
|
<Modal
|
title="修改菜单"
|
visible={thdVisible}
|
width={700}
|
onOk={this.thdSubmit}
|
confirmLoading={loading}
|
onCancel={() => {this.setState({thdVisible: false})}}
|
destroyOnClose
|
>
|
<ThdMenuForm
|
menu={this.state.sysMenu}
|
inputSubmit={this.thdSubmit}
|
wrappedComponentRef={(inst) => this.menuThdFormRef = inst}
|
/>
|
</Modal>
|
</aside>
|
)
|
}
|
}
|
|
export default Sidemenu
|