package.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/assets/img/normaltable.jpg | 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/sidemenu/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/sidemenu/index.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/sidemenu/menuform/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/locales/en-US/header.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/locales/en-US/role.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/locales/zh-CN/header.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/locales/zh-CN/role.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/tabviews/rolemanage/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/tabviews/rolemanage/index.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/login/index.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
package.json
@@ -77,7 +77,7 @@ "workbox-webpack-plugin": "4.3.1" }, "scripts": { "dev": "set PORT=3001 && node scripts/start.js", "dev": "set PORT=3001 && node scripts/start.js --host 192.168.8.106", "build": "node scripts/build.js", "test": "node scripts/test.js" }, src/assets/img/normaltable.jpg
src/components/sidemenu/index.jsx
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types' import {connect} from 'react-redux' import { is, fromJS } from 'immutable' import { Menu, Icon, Button, notification, Modal, Spin} from 'antd' import { Menu, Icon, Button, notification, Modal, Spin, Tabs, Radio, Card, Row, Col} from 'antd' import HTML5Backend from 'react-dnd-html5-backend' import { DndProvider } from 'react-dnd' import {modifyTabview, resetEditLevel} from '@/store/action' @@ -14,9 +14,11 @@ import enUS from '@/locales/en-US/header.js' import Api from '@/api' import './index.scss' import nortable from '@/assets/img/normaltable.jpg' const { SubMenu } = Menu const { confirm } = Modal const { TabPane } = Tabs let previewList = null class Sidemenu extends Component { @@ -29,8 +31,9 @@ } state = { mainMenuList: null, subMenulist: null, mainMenuList: null, // 一级菜单,编辑调整上级菜单时获取 subMenulist: null, // 二级菜单 editMenu: null, // 编辑三级菜单时设置 rootSubmenuKeys: null, modalOptions: { visible: false, @@ -43,6 +46,7 @@ menuLoading: false, thawMvisible: false, thawmenulist: null, createThirdMenu: false, dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS, openKeys: null } @@ -66,32 +70,43 @@ this.setState({ menuLoading: false, subMenulist: result.data.map((item, i) => { item.id = i item.text = item.MenuNameP let _smenu = {} _smenu.id = i _smenu.MenuID = item.ParentID _smenu.text = item.MenuNameP try { item.PageParam = JSON.parse(item.PageParamP) _smenu.PageParam = JSON.parse(item.PageParamP) } catch (e) { item.PageParam = {Icon: 'folder'} _smenu.PageParam = {Icon: 'folder'} } if (item.FunMenu) { item.children = item.FunMenu.map((child, n) => { _smenu.children = item.FunMenu.map((child, n) => { let _tmenu = {} let _msg = window.btoa(menu.MenuID + '&' + i + '&' + n + '&' + msg) // 待完善 child.src = '#/main/' + _msg _tmenu.src = '#/main/' + _msg if (child.LinkUrl === 'CommonTable') { child.type = 'CommonTable' _tmenu.type = 'CommonTable' } else if (child.LinkUrl === 'DataManage') { child.type = 'DataManage' _tmenu.type = 'DataManage' } else if (child.LinkUrl === 'bda/rdt?pageno=rolemenus&MenuNo=RoleMenuM') { child.type = 'RoleManage' _tmenu.type = 'RoleManage' } else if (child.LinkUrl.split('?')[0] === 'Main/Index' || child.LinkUrl.split('?')[0] === 'bda/rdt') { child.type = 'iframe' _tmenu.type = 'iframe' } child.id = n child.text = item.MenuName return child try { _tmenu.PageParam = JSON.parse(child.PageParam) } catch (e) { _tmenu.PageParam = {} } _tmenu.id = n _tmenu.MenuID = child.MenuID _tmenu.MenuNo = child.MenuNo _tmenu.MenuName = child.MenuName _tmenu.text = child.MenuName return _tmenu }) } return item return _smenu }), rootSubmenuKeys: result.data.map(item => item.ParentID), openKeys: (this.props.collapse || !parentID) ? [] : [parentID] @@ -102,6 +117,20 @@ opentab.selected = true this.props.modifyTabview([opentab]) } // this.props.modifyTabview([{ // Action: 'Index', // Icon: 'Content/icons/L32X32/RoleM.png', // LinkUrl: 'bda/rdt?pageno=rolemenus&MenuNo=RoleMenuM', // MenuID: 'MMenu14002DBD0010', // MenuName: '角色权限分配', // MenuNo: 'RoleMenuM', // Ot: '空', // PageParam: '', // SortSub: '720', // id: 3, // selected: true, // type: 'RoleManage' // }]) } } @@ -167,12 +196,20 @@ this.setState({ mainMenuList: res.data.map(item => { return { id: item.MenuID, MenuID: item.MenuID, text: item.MenuName } }) }) }) } enterThrEdit = (e, menu) => { // 编辑三级菜单 e.stopPropagation() previewList = null this.props.resetEditLevel('level3') this.setState({editMenu: menu}) } handlePreviewList = (List) => { @@ -198,7 +235,7 @@ onOk() { let param = { func: 'sPC_MainMenu_Del', MenuID: menu.card.ParentID MenuID: menu.card.MenuID } return Api.submitInterface(param).then(res => { if (res.status) { @@ -214,7 +251,7 @@ }, onCancel() {} }) } else if (menu.type === 'edit') { } else if (menu.type === 'edit' && this.props.editLevel === 'level2') { this.setState({ modalOptions: { visible: true, @@ -226,11 +263,38 @@ menu: menu.card } }) } else if (menu.type === 'edit' && this.props.editLevel === 'level3') { this.setState({ modalOptions: { visible: true, title: this.state.dict['header.menu.editTitle'], level: 'tlevel', type: 'edit', parentMenu: this.state.editMenu, supMenuList: this.state.subMenulist, menu: menu.card } }) } } createThMenu = () => { this.setState({ modalOptions: { visible: true, title: this.state.dict['header.menu.addtitle'], level: 'tlevel', type: 'add', parentMenu: this.state.editMenu, supMenuList: this.state.subMenulist, menu: null } }) } handleSubBtn = (type) => { // 操作按钮 if (this.props.editLevel === 'level2') { if (type === 'add') { this.setState({ modalOptions: { @@ -304,6 +368,83 @@ } } else if (type === 'close') { this.props.resetEditLevel(false) } } else { if (type === 'add') { this.setState({ createThirdMenu: true // modalOptions: { // visible: true, // title: this.state.dict['header.menu.addtitle'], // level: 'tlevel', // type: 'add', // parentMenu: this.state.editMenu, // supMenuList: this.state.subMenulist, // menu: null // } }) } else if (type === 'thaw') { this.setState({ thawMvisible: true }) Api.submitInterface({ func: 'sPC_Get_FrozenMenu', ParentID: this.state.editMenu.MenuID, TYPE: 30 }).then(res => { if (res.status) { this.setState({ thawmenulist: res.data.map(menu => { return { key: menu.MenuID, title: menu.MenuName } }) }) } else { notification.warning({ top: 92, message: res.message, duration: 10 }) } }) } else if (type === 'confirm') { if (previewList && !is(fromJS(previewList), fromJS(this.state.editMenu.children))) { 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.loadsubmenu(_this.props.mainMenu) } else { notification.warning({ top: 92, message: res.message, duration: 10 }) } }) }, onCancel() {} }) } else { this.props.resetEditLevel(false) } } else if (type === 'close') { this.props.resetEditLevel(false) } } } @@ -451,22 +592,25 @@ <aside className={"side-menu ant-menu-dark" + (this.props.collapse ? ' side-menu-collapsed' : '') + (this.props.isiframe ? ' iframe' : '')}> {this.state.subMenulist && (!this.props.editLevel || this.props.editLevel === 'level1') && <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark" inlineCollapsed={this.props.collapse}> {editShow && <li className="sup-menu"><Icon onClick={this.enterSubEdit} className="edit-check" type="edit" /></li>} {this.state.subMenulist.map((item, index) => { return ( <SubMenu key={item.ParentID} key={item.MenuID} title={ <span className={editShow && index === 0 ? 'edit-control' : ''}> <Icon type={item.PageParam.Icon} /> {editShow && index === 0 && <Icon onClick={this.enterSubEdit} className="edit-check" type="edit" />} <span>{item.MenuNameP}</span> <span>{item.text}</span> </span> } > {editShow && <li className={'ant-menu-item ' + (item.children.length > 0 ? 'sub-menu' : '')}> <Icon onClick={(e) => {this.enterThrEdit(e, item)}} className="edit-check" type="edit" /> </li>} {item.children.map(cell => { return ( <Menu.Item key={cell.MenuID}> <a href={cell.src} id={cell.MenuID} data-item={JSON.stringify(cell)} onClick={this.changemenu.bind(this)}>{cell.MenuName}</a> <a href={cell.src} id={cell.MenuID} data-item={JSON.stringify(cell)} onClick={this.changemenu.bind(this)}>{cell.text}</a> </Menu.Item> ) })} @@ -479,6 +623,29 @@ <DndProvider className="header-drag-menu" backend={HTML5Backend}> <DragElement list={this.state.subMenulist} handlePreviewList={this.handlePreviewList} handleMenu={this.handleMenu} /> </DndProvider> <div className="menu-add" onClick={() => {this.handleSubBtn('add')}}> <Icon type="plus" /> </div> <div className="menu-btn"> <Button type="primary" onClick={() => {this.handleSubBtn('thaw')}}>{this.state.dict['header.thawmenu']}</Button> <Button type="primary" onClick={() => {this.handleSubBtn('confirm')}}>{this.state.dict['header.confirm']}</Button> <Button onClick={() => {this.handleSubBtn('close')}}>{this.state.dict['header.close']}</Button> </div> </div> } {this.props.editLevel === 'level3' && this.state.editMenu && !this.state.menuLoading && <div> <div className="cus-submenu-title"> <Icon type={this.state.editMenu.PageParam.Icon} /> <span>{this.state.editMenu.text}</span> </div> <DndProvider className="header-drag-menu" backend={HTML5Backend}> <DragElement list={this.state.editMenu.children} handlePreviewList={this.handlePreviewList} handleMenu={this.handleMenu} /> @@ -520,39 +687,55 @@ {!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> {/* {this.props.editLevel === 'level2' && <div className="editboard"> {this.props.editLevel === 'level3' && this.state.createThirdMenu && <div className="editboard"> <div className="workplace"> <Tabs defaultActiveKey="1" onChange={this.callback}> <TabPane tab="二级菜单" key="1"> <div className="ant-card ant-card-bordered level2-left"> <div className="ant-card-head"> <div className="ant-card-head-wrapper"> <div className="ant-card-head-title"> <TabPane tab="新建菜单" key="1"> <Row> <Col span={8}> <Card title={ '基础表格' }> <img src={nortable} alt=""/> <div className="card-operation"> <Button type="primary">预览</Button> <Button type="primary" onClick={() => {this.createThMenu()}}>使用模板</Button> </div> </Card> </Col> <Col span={8}> <Card title={ '数据表格' }> <img src={nortable} alt=""/> <div className="card-operation"> <Button type="primary">预览</Button> <Button type="primary" onClick={() => {this.createThMenu()}}>使用模板</Button> </div> </Card> </Col> </Row> </TabPane> {/* <TabPane tab="三级菜单" key="2"> <Card // className="level2-left" title={ <div> <Radio.Group name="radiogroup" defaultValue={1}> <Radio value={1}>排序</Radio> <Radio value={2}>编辑</Radio> </Radio.Group> <Icon onClick={this.enterEdit} className="edit-check" type="plus" /> </div> </div> </div> <div className="ant-card-body"> <p>Card content</p> <p>Card content</p> <p>Card content</p> </div> </div> </TabPane> <TabPane tab="三级菜单" key="2"> <Card title="df" style={{ width: 300 }}> <p>Card content</p> <p>Card content</p> <p>Card content</p> }> <img src={nortable} alt=""/> </Card> </TabPane> </TabPane> */} </Tabs> </div> </div>} */} </div>} </aside> ) } src/components/sidemenu/index.scss
@@ -13,9 +13,15 @@ padding-left: 48px; } } .ant-menu-sub.ant-menu-inline { position: relative; } .ant-menu-sub.ant-menu-inline > .ant-menu-item { // 重置三级菜单行高 height: 30px; line-height: 30px; .edit-check { top: -5px; } } .ant-menu-inline .ant-menu-item { font-size: 1.5rem; @@ -36,6 +42,9 @@ margin-right: 0px; right: 0px; top: 0px; :hover { color: #ffffff; } } .edit-control + .ant-menu-submenu-arrow { display: none; @@ -60,29 +69,86 @@ margin-left: 5px; } } // .editboard { // position: fixed; // top: 48px; // left: 0px; // right: 0px; // bottom: 0px; // background: rgba(0, 0, 0, 0.15); // .workplace { // position: relative; // width: calc(100vw - 235px); // height: 100%; // overflow-y: auto; // left: 235px; // background: #ffffff; .editboard { position: fixed; z-index: 10; top: 48px; left: 0px; right: 0px; bottom: 0px; background: rgba(0, 0, 0, 0.15); .workplace { position: relative; width: calc(100vw - 235px); height: 100%; overflow-y: auto; left: 235px; background: #ffffff; // .level2-left { // width: 350px; // margin-left: 20px; // float: left; // height: calc(100vh - 125px); // } // } // } .ant-col { padding: 10px; } .ant-card-body { padding: 2px; position: relative; text-align: center; overflow: hidden; .card-operation { position: absolute; left: 0px; right: 0px; bottom: 0px; top: 100%; background: rgba(0, 0, 0, 0.35); padding-top: 0; transition: top 0.3s, padding-top 0.3s; button:first-child { margin-right: 10px; } button { display: none; } } } .ant-card-body:hover { .card-operation { top: 0; padding-top: 24%; button { display: inline-block; } } } img { max-width: 100%; } } } .sup-menu { position: relative; z-index: 1; } .ant-menu-sub.ant-menu-inline .sub-menu { position: absolute; z-index: 1; width: 30px; left: 205px; } .cus-submenu-title { padding: 0px 24px; background: #364150; margin: 0; height: 48px; line-height: 48px; width: 100%; overflow: hidden; font-size: 14px; white-space: nowrap; text-overflow: ellipsis; i { margin-right: 10px; } } } .side-menu.iframe { // tab页中为iframe时 max-height: 100vh; src/components/sidemenu/menuform/index.jsx
@@ -38,12 +38,38 @@ initVal: 'folder', required: true, options: [{ id: 'folder', MenuID: 'folder', text: 'folder' }, { id: 'api', MenuID: 'api', text: 'api' }] } ], tlevel: [ { type: 'select', key: 'parentId', label: this.props.dict['header.menu.supMenu'], initVal: '', required: true, options: [] }, { type: 'text', key: 'menuName', label: this.props.dict['header.menu.menuName'], initVal: '', required: true, readonly: false }, { type: 'text', key: 'menuNo', label: this.props.dict['header.menu.menuNo'], initVal: '', required: true, readonly: false } ] } @@ -55,7 +81,6 @@ UNSAFE_componentWillReceiveProps (nextProps) { if (nextProps.options.visible && !is(fromJS(this.props.options), fromJS(nextProps.options))) { console.log(nextProps.options) this.resetform(nextProps.options) } } @@ -64,8 +89,7 @@ if (!options.visible) return let formlist = JSON.parse(JSON.stringify(this.state.menuform[options.level])) if (options.type === 'add') { if (options.type === 'add' && options.level === 'slevel') { this.setState({ formlist: formlist.map(item =>{ if (item.key === 'parentId') { @@ -75,16 +99,40 @@ return item }) }) } else { } else if (options.type === 'add' && options.level === 'tlevel') { this.setState({ formlist: formlist.map(item =>{ if (item.key === 'parentId') { item.initVal = options.parentMenu.MenuID item.options = options.supMenuList } return item }) }) } else if (options.type === 'edit' && options.level === 'slevel') { this.setState({ formlist: formlist.map(item => { if (item.key === 'parentId') { item.initVal = options.parentMenu.MenuID item.options = options.supMenuList } else if (item.key === 'menuName') { item.initVal = options.menu.MenuNameP item.initVal = options.menu.text } else if (item.key === 'icon') { item.initVal = options.menu.PageParam.Icon } return item }) }) } else if (options.type === 'edit' && options.level === 'tlevel') { this.setState({ formlist: formlist.map(item => { if (item.key === 'parentId') { item.initVal = options.parentMenu.MenuID item.options = options.supMenuList } else if (item.key === 'menuName') { item.initVal = options.menu.text } else if (item.key === 'menuNo') { item.initVal = options.menu.MenuNo } return item }) @@ -150,12 +198,12 @@ })( <Select showSearch filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} filterOption={(input, option) => option.props.children[2].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}> <Select.Option id={option.MenuID} title={option.text} key={option.MenuID} value={option.MenuID}> {item.key === 'icon' && <Icon type={option.text} />} {option.text} </Select.Option> )} @@ -185,15 +233,34 @@ Icon: values.icon }) }) } else { } else if (this.props.options.type === 'edit' && this.props.options.level === 'slevel') { resolve({ ParentID: values.parentId, MenuID: this.props.options.menu.ParentID, MenuID: this.props.options.menu.MenuID, MenuName: values.menuName, PageParam: JSON.stringify({ Icon: values.icon }) }) } else if (this.props.options.type === 'add' && this.props.options.level === 'tlevel') { resolve({ ParentID: values.parentId, MenuID: this.props.options.menu.MenuID, MenuName: values.menuName, PageParam: JSON.stringify({ Icon: values.icon }) }) } else if (this.props.options.type === 'edit' && this.props.options.level === 'tlevel') { resolve({ ParentID: values.parentId, MenuID: this.props.options.menu.MenuID, MenuName: values.menuName, MenuNo: values.menuNo, PageParam: JSON.stringify({ Icon: values.icon }) }) } } else { reject(err) src/locales/en-US/header.js
@@ -26,6 +26,7 @@ 'header.menu.editTitle': 'The edit menu', 'header.menu.menuID': 'Menu ID', 'header.menu.menuName': 'Menu Name', 'header.menu.menuNo': 'Menu Parameter', 'header.menu.supMenu': 'Superior Menu', 'header.menu.icon': 'Icon', 'header.menu.openType': 'Open With', src/locales/en-US/role.js
New file @@ -0,0 +1,3 @@ export default { 'role.title': 'The role list', } src/locales/zh-CN/header.js
@@ -26,6 +26,7 @@ 'header.menu.editTitle': '编辑菜单', 'header.menu.menuID': '菜单ID', 'header.menu.menuName': '菜单名称', 'header.menu.menuNo': '菜单参数', 'header.menu.supMenu': '上级菜单', 'header.menu.icon': '图标', 'header.menu.openType': '打开方式', src/locales/zh-CN/role.js
New file @@ -0,0 +1,3 @@ export default { 'role.title': '角色列表', } src/tabviews/rolemanage/index.jsx
@@ -1,11 +1,11 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' import { BackTop, Card, Col, Row } from 'antd' import { BackTop, Card, Col, Row, Icon } from 'antd' import Api from '@/api' import Loading from '@/components/loading' import zhCN from '@/locales/zh-CN/main.js' import enUS from '@/locales/en-US/main.js' // import Loading from '@/components/loading' import zhCN from '@/locales/zh-CN/role.js' import enUS from '@/locales/en-US/role.js' import './index.scss' export default class RoleManage extends Component { @@ -72,10 +72,12 @@ render() { return ( <div className="rolemanage"> {!this.state.searchlist && <Loading />} {/* {!this.state.searchlist && <Loading />} */} <Row gutter={16}> <Col span={6}> <Card title="Card title" bordered={false}> <Card title={<span className="role-title"><Icon type="bank" /> {this.state.dict['role.title']}</span>} bordered={false}> Card content </Card> </Col> src/tabviews/rolemanage/index.scss
@@ -4,6 +4,9 @@ position: relative; background: #fafafa; padding: 15px; .role-title { color: #36c6d3; } } .ant-back-top { bottom: 30px; src/views/login/index.scss
@@ -22,7 +22,8 @@ float: right; margin-top: 5%; margin-right: 20%; padding: 15px; // padding: 15px; padding: 1.6vw; background: #ffffff; width: 22vw; min-width: 300px; @@ -36,7 +37,7 @@ } .ant-form-item { font-size: 16px; margin-bottom: 4vh; margin-bottom: 3vh; } .btn-login { margin-bottom: 3vh; @@ -47,8 +48,9 @@ } button { width: 100%; height: 40px; line-height: 40px; // height: 40px; height: calc(2vw + 10px); line-height: 1; } .ant-dropdown-link { float: right; @@ -64,7 +66,8 @@ } .ant-input { font-size: 16px; height: 36px; // height: 36px; height: calc(2vw + 5px); } .ant-form label { font-size: 16px;