From 6055fa01416fc57ee33b291a8103ccc1a8edce44 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期二, 20 七月 2021 23:21:14 +0800
Subject: [PATCH] 2021-07-20

---
 src/menu/components/form/formaction/index.scss             |    5 
 src/tabviews/custom/components/form/normal-form/index.scss |    4 
 src/templates/zshare/basetransferform/index.jsx            |    4 
 src/menu/components/form/formaction/actionform/index.jsx   |    4 
 src/menu/components/form/normal-form/index.jsx             |    8 
 src/templates/zshare/editcomponent/index.jsx               |   21 
 src/views/rolemanage/index.jsx                             |  490 ++++++++++++++++++++++++++++
 src/menu/components/form/formaction/index.jsx              |    2 
 src/templates/menuconfig/editthdmenu/index.jsx             |   15 
 src/views/appmanage/header/index.scss                      |   57 +++
 src/templates/sharecomponent/actioncomponent/index.scss    |    2 
 src/views/rolemanage/header/index.jsx                      |   32 +
 src/menu/components/form/formaction/formconfig.jsx         |    2 
 src/views/appmanage/index.scss                             |    9 
 src/pc/bgcontroller/index.jsx                              |   24 +
 src/menu/components/card/cardcellcomponent/index.jsx       |    2 
 src/menu/stylecontroller/index.jsx                         |   63 +++
 src/views/rolemanage/index.scss                            |   80 ++++
 src/templates/menuconfig/editfirstmenu/index.jsx           |   14 
 src/router/index.js                                        |   31 -
 src/tabviews/custom/components/form/normal-form/index.jsx  |   12 
 src/templates/menuconfig/editsecmenu/index.jsx             |   32 +
 src/views/appmanage/index.jsx                              |    9 
 src/views/appmanage/header/index.jsx                       |   31 +
 src/views/rolemanage/header/index.scss                     |   58 +++
 25 files changed, 934 insertions(+), 77 deletions(-)

diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 60d0e6f..5fa02a8 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -135,7 +135,7 @@
     const { cards, cardCell } = this.props
 
     let _style = element.style ? fromJS(element.style).toJS() : {}
-    let options = ['font', 'border', 'padding', 'margin', 'backgroundColor']
+    let options = ['font', 'border', 'padding', 'margin', 'background']
 
     if (element.eleType === 'button') {
       options.push('width', 'float')
diff --git a/src/menu/components/form/formaction/actionform/index.jsx b/src/menu/components/form/formaction/actionform/index.jsx
index 454a16e..35fb01b 100644
--- a/src/menu/components/form/formaction/actionform/index.jsx
+++ b/src/menu/components/form/formaction/actionform/index.jsx
@@ -49,11 +49,11 @@
     const { card } = this.props
 
     if (card.type === 'prev') {
-      return ['type', 'label']
+      return ['type', 'label', 'enable']
     } else if (card.type === 'next') {
       return ['type', 'label', 'enable']
     }
-    let _options = ['type', 'label', 'intertype', 'syncComponent', 'linkmenu', 'open'] // 閫夐」鍒楄〃
+    let _options = ['type', 'label', 'intertype', 'syncComponent', 'linkmenu', 'open', 'enable'] // 閫夐」鍒楄〃
     
     if (_intertype === 'custom') {
       _options.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method', 'cross')
diff --git a/src/menu/components/form/formaction/formconfig.jsx b/src/menu/components/form/formaction/formconfig.jsx
index c0e6f61..6eb2048 100644
--- a/src/menu/components/form/formaction/formconfig.jsx
+++ b/src/menu/components/form/formaction/formconfig.jsx
@@ -278,7 +278,7 @@
       type: 'radio',
       key: 'enable',
       label: '鏄惁鏄剧ず',
-      initVal: card.enable || 'false',
+      initVal: card.enable || 'true',
       required: false,
       options: [{
         value: 'true',
diff --git a/src/menu/components/form/formaction/index.jsx b/src/menu/components/form/formaction/index.jsx
index 34d1b60..8127e42 100644
--- a/src/menu/components/form/formaction/index.jsx
+++ b/src/menu/components/form/formaction/index.jsx
@@ -201,7 +201,7 @@
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={() => this.handleStyle(group.prevButton)} type="font-colors" />
           </div>
         } trigger="hover">
-          <Button type="link" className="prev" style={resetStyle(group.prevButton.style)}>{group.prevButton.label}</Button>
+          <Button type="link" className={'prev ' + group.prevButton.enable} style={resetStyle(group.prevButton.style)}>{group.prevButton.label}</Button>
         </Popover> : null}
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
diff --git a/src/menu/components/form/formaction/index.scss b/src/menu/components/form/formaction/index.scss
index 1fa18b5..b7a1cd3 100644
--- a/src/menu/components/form/formaction/index.scss
+++ b/src/menu/components/form/formaction/index.scss
@@ -6,6 +6,11 @@
   .prev {
     margin-right: 15px;
   }
+  .prev.false {
+    span {
+      text-decoration: line-through;
+    }
+  }
   .submit {
     border: none;
   }
diff --git a/src/menu/components/form/normal-form/index.jsx b/src/menu/components/form/normal-form/index.jsx
index f529207..915753b 100644
--- a/src/menu/components/form/normal-form/index.jsx
+++ b/src/menu/components/form/normal-form/index.jsx
@@ -79,8 +79,8 @@
           sort: 1,
           style: {},
           fields: [],
-          prevButton: {label: '涓婁竴姝�', type: 'prev'},
-          subButton: {label: '鎻愪氦', type: 'submit', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px'}},
+          prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'true'},
+          subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px'}},
           nextButton: {label: '璺宠繃', type: 'next', enable: 'false'}
         }]
       }
@@ -238,8 +238,8 @@
       sort: card.subcards.length + 1,
       style: {},
       fields: [],
-      prevButton: {label: '涓婁竴姝�', type: 'prev'},
-      subButton: {label: '鎻愪氦', type: 'submit', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px'}},
+      prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'true'},
+      subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px'}},
       nextButton: {label: '璺宠繃', type: 'next', enable: 'false'}
     }
 
diff --git a/src/menu/stylecontroller/index.jsx b/src/menu/stylecontroller/index.jsx
index 26bf26c..69d11e7 100644
--- a/src/menu/stylecontroller/index.jsx
+++ b/src/menu/stylecontroller/index.jsx
@@ -194,6 +194,27 @@
   }
 
   /**
+   * @description 淇敼鑳屾櫙澶у皬
+   */
+  changeBackgroundSize = (val) => {
+    this.updateStyle({backgroundSize: val})
+  }
+
+  /**
+   * @description 淇敼鑳屾櫙浣嶇疆
+   */
+  changeBackgroundPositon= (val) => {
+    this.updateStyle({backgroundPositon: val})
+  }
+
+  /**
+   * @description 淇敼鑳屾櫙閲嶅璁剧疆
+   */
+  changeBackgroundRepeat = (val) => {
+    this.updateStyle({backgroundRepeat: val})
+  }
+
+  /**
    * @description 淇敼闃村奖棰滆壊 锛岄鑹叉帶浠�
    */
   changeShadowColor = (val) => {
@@ -448,6 +469,48 @@
                     <SourceComponent value={backgroundImage} type="" placement="right" onChange={this.imgChange}/>
                   </Form.Item>
                 </Col> : null}
+                {!options.includes('backgroundColor') ? <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label="姣斾緥"
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <Select defaultValue={card.backgroundSize || 'cover'} onChange={this.changeBackgroundSize}>
+                      <Option value="100%">100%</Option>
+                      <Option value="100% 100%">100% 100%</Option>
+                      <Option value="auto 100%">auto 100%</Option>
+                      <Option value="contain">contain</Option>
+                      <Option value="cover">cover</Option>
+                    </Select>
+                  </Form.Item>
+                </Col> : null}
+                {!options.includes('backgroundColor') ? <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label="閲嶅"
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <Select defaultValue={card.backgroundRepeat || 'no-repeat'} onChange={this.changeBackgroundRepeat}>
+                      <Option value="repeat">repeat</Option>
+                      <Option value="no-repeat">no-repeat</Option>
+                      <Option value="repeat-x">repeat-x</Option>
+                      <Option value="repeat-y">repeat-y</Option>
+                    </Select>
+                  </Form.Item>
+                </Col> : null}
+                {!options.includes('backgroundColor') ? <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label="浣嶇疆"
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <Select defaultValue={card.backgroundPositon || 'center'} onChange={this.changeBackgroundPositon}>
+                      <Option value="center">center</Option>
+                      <Option value="top">top</Option>
+                      <Option value="bottom">bottom</Option>
+                    </Select>
+                  </Form.Item>
+                </Col> : null}
               </Panel> : null}
               {options.includes('border') ? <Panel header="杈规" key="border">
                 <Col span={24}>
diff --git a/src/pc/bgcontroller/index.jsx b/src/pc/bgcontroller/index.jsx
index c9fcb37..b77b775 100644
--- a/src/pc/bgcontroller/index.jsx
+++ b/src/pc/bgcontroller/index.jsx
@@ -25,6 +25,7 @@
     backgroundImage: '',
     backgroundSize: '',
     backgroundRepeat: '',
+    backgroundPositon: '',
     opacity: '',
   }
 
@@ -42,7 +43,8 @@
       backgroundColor: config.style.backgroundColor,
       backgroundImage: bgImg,
       backgroundSize: config.style.backgroundSize || '100%',
-      backgroundRepeat: config.style.backgroundRepeat || 'repeat'
+      backgroundRepeat: config.style.backgroundRepeat || 'repeat',
+      backgroundPositon: config.style.backgroundPositon || 'center'
     })
   }
 
@@ -112,9 +114,20 @@
     this.props.updateConfig(config)
   }
 
+  backgroundPositonChange = (val) => {
+    this.setState({
+      backgroundPositon: val
+    })
+
+    let config = fromJS(this.props.config).toJS()
+    config.style.backgroundPositon = val
+
+    this.props.updateConfig(config)
+  }
+
   render () {
     const { config } = this.props
-    const { backgroundColor, backgroundImage, backgroundSize, backgroundRepeat } = this.state
+    const { backgroundColor, backgroundImage, backgroundSize, backgroundRepeat, backgroundPositon } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -158,6 +171,13 @@
               <Option value="repeat-y">repeat-y</Option>
             </Select>
           </Form.Item>
+          <Form.Item colon={false} label="浣嶇疆">
+            <Select defaultValue={backgroundPositon} onChange={this.backgroundPositonChange}>
+              <Option value="center">center</Option>
+              <Option value="top">top</Option>
+              <Option value="bottom">bottom</Option>
+            </Select>
+          </Form.Item>
           <p style={{borderBottom: '1px solid #eaeaea', color: '#40a9ff'}}>鍐呰竟璺�</p>
           <Form.Item
             colon={false}
diff --git a/src/router/index.js b/src/router/index.js
index 907d84e..f496dec 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -19,6 +19,7 @@
 const BillPrint = asyncLoadComponent(() => import('@/views/billprint'))
 const PrintT = asyncLoadComponent(() => import('@/views/printTemplate'))
 const Interface = asyncLoadComponent(() => import('@/views/interface'))
+const RoleManage = asyncLoadComponent(() => import('@/views/rolemanage'))
 
 const routers = [
   {path: '/login', name: 'login', component: Login, auth: false},
@@ -33,6 +34,7 @@
   {path: '/menudesign/:param', name: 'menudesign', component: MenuDesign, auth: true},
   {path: '/billprint/:param', name: 'billprint', component: BillPrint, auth: true},
   {path: '/paramsmain/:param', name: 'pmain', component: Main, auth: true},
+  {path: '/role/:param', name: 'role', component: RoleManage, auth: true},
   {path: '/interface', name: 'interface', component: Interface, auth: true}
 ]
 
@@ -58,28 +60,13 @@
           _param.role_id && sessionStorage.setItem('role_id', _param.role_id)
           _param.dataM && sessionStorage.setItem('localRole_id', _param.dataM)
           _param.Member_Level && sessionStorage.setItem('Member_Level', _param.Member_Level)
+          _param.ThirdMenu && sessionStorage.setItem('ThirdMenu', _param.ThirdMenu)
 
-          if (_param.mainlogo) {
-            window.GLOB.mainlogo = _param.mainlogo
-          }
-          if (_param.navBar) {
-            window.GLOB.navBar = _param.navBar
-          }
+          window.GLOB.mainlogo = _param.mainlogo || ''
+          window.GLOB.navBar = _param.navBar || ''
+
           if (_param.mstyle && styles[_param.mstyle]) {
             document.body.className = styles[_param.mstyle]
-          }
-          if (_param.MainMenu) {
-            sessionStorage.setItem('MainMenu', _param.MainMenu)
-          }
-          if (_param.SubMenu) {
-            sessionStorage.setItem('SubMenu', _param.SubMenu)
-          }
-          if (_param.ThirdMenu) {
-            sessionStorage.setItem('ThirdMenu', _param.ThirdMenu)
-          }
-          if (_param.param) {
-            _param.param.ThirdMenu = _param.ThirdMenu
-            sessionStorage.setItem('MenuParam', JSON.stringify(_param.param))
           }
         }
       } catch {
@@ -107,11 +94,7 @@
     return (
       <HashRouter>
         <Switch>
-          {routers.map((item, index) => {
-            return (
-              <Route key={index} path={item.path} name={item.name} exact render={ props => this.controlRoute(item, props)}/>
-            )
-          })}
+          {routers.map((item, index) => <Route key={index} path={item.path} name={item.name} exact render={ props => this.controlRoute(item, props)}/>)}
           <Redirect exact from="/" to="login"/>
           <Route component= {NotFound}/>
         </Switch>
diff --git a/src/tabviews/custom/components/form/normal-form/index.jsx b/src/tabviews/custom/components/form/normal-form/index.jsx
index b0e13a5..f8bb190 100644
--- a/src/tabviews/custom/components/form/normal-form/index.jsx
+++ b/src/tabviews/custom/components/form/normal-form/index.jsx
@@ -77,6 +77,14 @@
       group.subButton.OpenType = 'formSubmit'
       group.subButton.execError = 'never'
 
+      if (group.subButton.enable === 'false') {
+        group.subButton.style.display = 'none'
+      }
+
+      if (group.prevButton.enable === 'false' && group.subButton.enable === 'false' && group.nextButton.enable === 'false') {
+        group.$button = 'no-button'
+      }
+
       group.fields = group.fields.map(cell => {
         // 鏁版嵁婧恠ql璇彞锛岄澶勭悊锛屾潈闄愰粦鍚嶅崟瀛楁璁剧疆涓洪殣钘忚〃鍗�
         if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
@@ -383,8 +391,8 @@
           inputSubmit={this.handleOk}
           wrappedComponentRef={(inst) => this.formRef = inst}
         /> : null}
-        {group && data ? <div className="mk-form-action">
-          {group.sort !== 1 ? <Button type="link" className="prev" onClick={this.prevStep} style={group.prevButton.style}>{group.prevButton.label}</Button> : null}
+        {group && data ? <div className={'mk-form-action ' + (group.$button || '')}>
+          {group.sort !== 1 && group.prevButton.enable !== 'false' ? <Button type="link" className="prev" onClick={this.prevStep} style={group.prevButton.style}>{group.prevButton.label}</Button> : null}
           <NormalButton
             BID={BID}
             position="form"
diff --git a/src/tabviews/custom/components/form/normal-form/index.scss b/src/tabviews/custom/components/form/normal-form/index.scss
index 285b505..7547391 100644
--- a/src/tabviews/custom/components/form/normal-form/index.scss
+++ b/src/tabviews/custom/components/form/normal-form/index.scss
@@ -78,6 +78,10 @@
       right: 5px;
     }
   }
+  .mk-form-action.no-button {
+    padding: 0;
+    height: 0;
+  }
   
   .loading-mask {
     position: absolute;
diff --git a/src/templates/menuconfig/editfirstmenu/index.jsx b/src/templates/menuconfig/editfirstmenu/index.jsx
index 3df062c..200a619 100644
--- a/src/templates/menuconfig/editfirstmenu/index.jsx
+++ b/src/templates/menuconfig/editfirstmenu/index.jsx
@@ -39,6 +39,7 @@
     thawMvisible: false, // 瑙i櫎鍐荤粨妯℃�佹
     confirmLoading: false, // 鎻愪氦涓�傘�傘��
     dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    targetKeys: [] // 瑙e喕鑿滃崟鍒楄〃
   }
 
   handlePreviewList = (List) => {
@@ -165,7 +166,9 @@
   }
 
   thawMemuSubmit = () => {
-    if (this.refs.trawmenu.state.targetKeys.length === 0) {
+    const { targetKeys } = this.state
+
+    if (targetKeys.length === 0) {
       notification.warning({
         top: 92,
         message: this.state.dict['form.required.select'] + this.state.dict['model.menu'],
@@ -175,7 +178,7 @@
       this.setState({
         confirmLoading: true
       })
-      let defers = this.refs.trawmenu.state.targetKeys.map(item => {
+      let defers = targetKeys.map(item => {
         return new Promise((resolve) => {
           Api.getSystemConfig({
             func: 'sPC_MainMenu_ReDel',
@@ -201,6 +204,7 @@
           this.setState({
             confirmLoading: false,
             thawMvisible: false,
+            targetKeys: [],
             thawmenulist: null
           })
           this.props.reload()
@@ -212,6 +216,7 @@
   thawMemuCancel = () => {
     this.setState({
       thawMvisible: false,
+      targetKeys: [],
       thawmenulist: null
     })
   }
@@ -276,7 +281,8 @@
       })
     } else if (type === 'thawmenu') {
       this.setState({
-        thawMvisible: true
+        thawMvisible: true,
+        targetKeys: []
       })
       Api.getSystemConfig({
         func: 'sPC_Get_FrozenMenu',
@@ -378,7 +384,7 @@
           destroyOnClose
         >
           {!this.state.thawmenulist && <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" />}
-          {this.state.thawmenulist && <TransferForm ref="trawmenu" menulist={this.state.thawmenulist}/>}
+          {this.state.thawmenulist && <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>}
         </Modal>
         {/* 缂栬緫鑿滃崟妯℃�佹 */}
         <Modal
diff --git a/src/templates/menuconfig/editsecmenu/index.jsx b/src/templates/menuconfig/editsecmenu/index.jsx
index 6d9733e..a30f148 100644
--- a/src/templates/menuconfig/editsecmenu/index.jsx
+++ b/src/templates/menuconfig/editsecmenu/index.jsx
@@ -33,15 +33,16 @@
 
   state = {
     dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    menulist: null,       // 鑿滃崟鍒楄〃
-    type: '',             // 缂栬緫绫诲瀷锛宎dd or edit
-    title: '',            // 妯℃�佹鏍囬
-    visible: null,        // 妯℃�佹鏄惁鍙
-    formlist: null,       // 琛ㄥ崟淇℃伅
-    editMenu: null,       // 缂栬緫鑿滃崟
-    thawmenulist: null,   // 宸插喕缁撶殑浜岀骇鑿滃崟
-    thawMvisible: false,  // 瑙i櫎鍐荤粨妯℃�佹
-    confirmLoading: false // 鎻愪氦涓�傘�傘��
+    menulist: null,        // 鑿滃崟鍒楄〃
+    type: '',              // 缂栬緫绫诲瀷锛宎dd or edit
+    title: '',             // 妯℃�佹鏍囬
+    visible: null,         // 妯℃�佹鏄惁鍙
+    formlist: null,        // 琛ㄥ崟淇℃伅
+    editMenu: null,        // 缂栬緫鑿滃崟
+    thawmenulist: null,    // 宸插喕缁撶殑浜岀骇鑿滃崟
+    thawMvisible: false,   // 瑙i櫎鍐荤粨妯℃�佹
+    confirmLoading: false, // 鎻愪氦涓�傘�傘��
+    targetKeys: []         // 瑙e喕鑿滃崟鍒楄〃 
   }
 
   handlePreviewList = (List) => {
@@ -170,7 +171,8 @@
       })
     } else if (type === 'thaw') { // 瑙e喕宸叉湁鑿滃崟
       this.setState({
-        thawMvisible: true
+        thawMvisible: true,
+        targetKeys: []
       })
       Api.getSystemConfig({
         func: 'sPC_Get_FrozenMenu',
@@ -329,7 +331,9 @@
   }
 
   thawMemuSubmit = () => { // 瑙e喕鑿滃崟锛屾彁浜わ紝瀛樺湪澶氫釜鏃讹紝寰幆鎻愪氦
-    if (this.refs.trawmenu.state.targetKeys.length === 0) {
+    const { targetKeys } = this.state
+
+    if (targetKeys.length === 0) {
       notification.warning({
         top: 92,
         message: this.state.dict['form.required.select'] + this.state.dict['model.menu'],
@@ -339,7 +343,7 @@
       this.setState({
         confirmLoading: true
       })
-      let defers = this.refs.trawmenu.state.targetKeys.map(item => {
+      let defers = targetKeys.map(item => {
         return new Promise((resolve) => {
           Api.getSystemConfig({
             func: 'sPC_MainMenu_ReDel',
@@ -365,6 +369,7 @@
           this.setState({
             confirmLoading: false,
             thawMvisible: false,
+            targetKeys: [],
             thawmenulist: null
           })
           this.props.reload()
@@ -376,6 +381,7 @@
   thawMemuCancel = () => { // 瑙e喕鑿滃崟鍙栨秷
     this.setState({
       thawMvisible: false,
+      targetKeys: [],
       thawmenulist: null
     })
   }
@@ -458,7 +464,7 @@
           onCancel={this.thawMemuCancel}
         >
           {!this.state.thawmenulist && <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" />}
-          {this.state.thawmenulist && <TransferForm ref="trawmenu" menulist={this.state.thawmenulist}/>}
+          {this.state.thawmenulist && <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>}
         </Modal>
       </div>
     )
diff --git a/src/templates/menuconfig/editthdmenu/index.jsx b/src/templates/menuconfig/editthdmenu/index.jsx
index 8cf7aa8..76cc412 100644
--- a/src/templates/menuconfig/editthdmenu/index.jsx
+++ b/src/templates/menuconfig/editthdmenu/index.jsx
@@ -79,6 +79,7 @@
     btnTabConfig: null,     // 鎵撳紑鏂版爣绛炬寜閽厤缃�
     handleMVisible: false,  // 娣诲姞鎴栦慨鏀硅彍鍗曟ā鎬佹锛堣鑹叉潈闄愬垎閰嶇瓑锛�
     sysMenu: false,         // 娣诲姞鎴栫紪杈戣彍鍗曪紙瑙掕壊鏉冮檺鍒嗛厤绛夛級
+    targetKeys: []          // 瑙e喕鑿滃崟鍒楄〃 
   }
 
   /**
@@ -268,7 +269,8 @@
         return
       }
       this.setState({
-        thawMvisible: true
+        thawMvisible: true,
+        targetKeys: []
       })
       Api.getSystemConfig({
         func: 'sPC_Get_FrozenMenu',
@@ -347,8 +349,9 @@
   }
 
   thawMemuSubmit = () => {
+    const { targetKeys } = this.state
     // 涓夌骇鑿滃崟瑙i櫎鍐荤粨
-    if (this.refs.trawmenu.state.targetKeys.length === 0) {
+    if (targetKeys.length === 0) {
       notification.warning({
         top: 92,
         message: this.state.dict['form.required.select'] + this.state.dict['model.menu'],
@@ -358,7 +361,7 @@
       this.setState({
         confirmLoading: true
       })
-      let defers = this.refs.trawmenu.state.targetKeys.map(item => {
+      let defers = targetKeys.map(item => {
         return new Promise((resolve) => {
           Api.getSystemConfig({
             func: 'sPC_MainMenu_ReDel',
@@ -384,6 +387,7 @@
           this.setState({
             confirmLoading: false,
             thawMvisible: false,
+            targetKeys: [],
             thawmenulist: null
           })
           this.props.reload()
@@ -396,7 +400,8 @@
     // 瑙i櫎鍐荤粨-鍙栨秷
     this.setState({
       thawMvisible: false,
-      thawmenulist: null
+      thawmenulist: null,
+      targetKeys: []
     })
   }
 
@@ -934,7 +939,7 @@
           destroyOnClose
         >
           {!this.state.thawmenulist && <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" />}
-          {this.state.thawmenulist && <TransferForm ref="trawmenu" menulist={this.state.thawmenulist}/>}
+          {this.state.thawmenulist && <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>}
         </Modal>
         {/* 娣诲姞绯荤粺鑿滃崟 */}
         <Modal
diff --git a/src/templates/sharecomponent/actioncomponent/index.scss b/src/templates/sharecomponent/actioncomponent/index.scss
index d5643e2..93cc1b7 100644
--- a/src/templates/sharecomponent/actioncomponent/index.scss
+++ b/src/templates/sharecomponent/actioncomponent/index.scss
@@ -16,7 +16,7 @@
   .page-card {
     display: inline-block;
     margin: 0px 0px 0px 0px;
-    padding: 0px 10px 0 0;
+    padding: 0px 10px 10px 0;
     position: relative;
     div {
       cursor: move;
diff --git a/src/templates/zshare/basetransferform/index.jsx b/src/templates/zshare/basetransferform/index.jsx
index 8dd7462..c3e3233 100644
--- a/src/templates/zshare/basetransferform/index.jsx
+++ b/src/templates/zshare/basetransferform/index.jsx
@@ -6,7 +6,8 @@
 
 class TransferForm extends Component {
   static propTypes = {
-    menulist: PropTypes.array
+    menulist: PropTypes.array,
+    onChange: PropTypes.func
   }
 
   state = {
@@ -16,6 +17,7 @@
 
   handleChange = (nextTargetKeys, direction, moveKeys) => {
     this.setState({ targetKeys: nextTargetKeys })
+    this.props.onChange(nextTargetKeys)
   }
 
   handleSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
diff --git a/src/templates/zshare/editcomponent/index.jsx b/src/templates/zshare/editcomponent/index.jsx
index 785ee7b..6fd72b8 100644
--- a/src/templates/zshare/editcomponent/index.jsx
+++ b/src/templates/zshare/editcomponent/index.jsx
@@ -25,6 +25,7 @@
     thawVisible: false,
     thawbtnlist: null,
     pasteVisible: false,
+    targetKeys: []
   }
 
   /**
@@ -34,7 +35,8 @@
     const { MenuID } = this.props
 
     this.setState({
-      thawVisible: true
+      thawVisible: true,
+      targetKeys: []
     })
 
     Api.getSystemConfig({
@@ -84,32 +86,31 @@
    */
   thawBtnSubmit = () => {
     const { thawButtons } = this.props
-    const { thawbtnlist, dict } = this.state
+    const { thawbtnlist, dict, targetKeys } = this.state
     let config = fromJS(this.props.config).toJS()
 
-    // 涓夌骇鑿滃崟瑙i櫎鍐荤粨
-    if (this.refs.trawmenu.state.targetKeys.length === 0) {
+    if (targetKeys.length === 0) {
       notification.warning({
         top: 92,
         message: dict['form.required.select'] + dict['header.form.thawbutton'],
         duration: 5
       })
     } else {
-
       thawbtnlist.forEach(item => {
-        if (this.refs.trawmenu.state.targetKeys.includes(item.key)) {
+        if (targetKeys.includes(item.key)) {
           config.action.push(item.btnParam)
         }
       })
 
       this.props.refresh({
         type: 'thaw',
-        thawButtons: [...thawButtons, ...this.refs.trawmenu.state.targetKeys],
+        thawButtons: [...thawButtons, ...targetKeys],
         config: config
       })
 
       this.setState({
-        thawVisible: false
+        thawVisible: false,
+        targetKeys: []
       })
     }
   }
@@ -249,11 +250,11 @@
           title={dict['header.form.thawbutton']}
           visible={this.state.thawVisible}
           onOk={this.thawBtnSubmit}
-          onCancel={() => {this.setState({thawVisible: false, thawbtnlist: null})}}
+          onCancel={() => {this.setState({thawVisible: false, thawbtnlist: null, targetKeys: []})}}
           destroyOnClose
         >
           {!this.state.thawbtnlist && <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" />}
-          {this.state.thawbtnlist && <TransferForm ref="trawmenu" menulist={this.state.thawbtnlist}/>}
+          {this.state.thawbtnlist && <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawbtnlist}/>}
         </Modal>
         {/* 鎸夐挳閰嶇疆淇℃伅绮樿创澶嶅埗 */}
         <Modal
diff --git a/src/views/appmanage/header/index.jsx b/src/views/appmanage/header/index.jsx
new file mode 100644
index 0000000..96bba6d
--- /dev/null
+++ b/src/views/appmanage/header/index.jsx
@@ -0,0 +1,31 @@
+import React, {Component} from 'react'
+
+import avatar from '@/assets/img/avatar.jpg'
+import MainLogo from '@/assets/img/main-logo.png'
+import './index.scss'
+
+class AppManageHeader extends Component {
+  state = {
+    avatar: sessionStorage.getItem('CloudAvatar') || avatar,
+    userName: sessionStorage.getItem('CloudUserName')
+  }
+
+  render () {
+    return (
+      <header className="app-manage-header-container">
+        <div className="header-logo"><img src={MainLogo} alt=""/></div>
+        <div className="title">
+          搴旂敤绠$悊
+        </div>
+        <div className="header-user">
+          <img src={this.state.avatar} alt=""/>
+          <span>
+            <span className="username">{this.state.userName}</span>
+          </span>
+        </div>
+      </header>
+    )
+  }
+}
+
+export default AppManageHeader
\ No newline at end of file
diff --git a/src/views/appmanage/header/index.scss b/src/views/appmanage/header/index.scss
new file mode 100644
index 0000000..fd7bb98
--- /dev/null
+++ b/src/views/appmanage/header/index.scss
@@ -0,0 +1,57 @@
+.app-manage-header-container {
+  width: 100%;
+  height: 48px;
+  color: rgba(255, 255, 255, 0.65);
+  position: fixed;
+  top: 0px;
+  z-index: 10;
+  padding-right: 0px;
+  left: 0;
+  
+  background: #001529;
+  border-bottom: 1px solid #000;
+
+  .header-logo {
+    float: left;
+    width: 180px;
+    line-height: 48px;
+    text-align: center;
+    padding-left: 5px;
+    box-sizing: border-box;
+    opacity: 1;
+    img {
+      max-width: 100%;
+      max-height: 40px;
+    }
+  }
+  .header-user {
+    float: right;
+    line-height: 48px;
+    margin-right: 10px;
+    img {
+      width: 29px;
+      height: 29px;
+      border-radius: 30px;
+      margin-right: 7px;
+    }
+    span {
+      color: #ffffff;
+      font-size: 0.95rem;
+      .username {
+        display: inline-block;
+        height: 30px;
+        max-width: 95px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+  }
+  .title {
+    position: absolute;
+    left: calc(50% - 36px);
+    top: 10px;
+    color: #ffffff;
+    font-size: 18px;
+  }
+}
\ No newline at end of file
diff --git a/src/views/appmanage/index.jsx b/src/views/appmanage/index.jsx
index 73bd849..41a56ca 100644
--- a/src/views/appmanage/index.jsx
+++ b/src/views/appmanage/index.jsx
@@ -16,7 +16,7 @@
 const { Search } = Input
 
 const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
-const Header = asyncComponent(() => import('@/mob/header'))
+const Header = asyncComponent(() => import('./header'))
 const MutilForm = asyncComponent(() => import('./mutilform'))
 const TransForm = asyncComponent(() => import('./transform'))
 const ScriptForm = asyncComponent(() => import('./scriptform'))
@@ -614,6 +614,12 @@
     window.open(window.location.href.replace(/#.+/ig, `#/${route}/${window.btoa(window.encodeURIComponent(JSON.stringify({...item, kei_no: selectApp.kei_no, remark: selectApp.remark, type: 'app'})))}`))
   }
 
+  jumpMenu = (item) => {
+    const { selectApp } = this.state
+
+    window.open(window.location.href.replace(/#.+/ig, `#/role/${window.btoa(window.encodeURIComponent(JSON.stringify({...item, kei_no: selectApp.kei_no, remark: selectApp.remark, type: 'app'})))}`))
+  }
+
   onSelectChange = selectedRowKeys => {
     const { applist } = this.state
     let selectApp = applist.filter(item => item.ID === selectedRowKeys[0])[0]
@@ -1035,6 +1041,7 @@
                       </Col>
                     </Row>
                     <div className="action">
+                      <Button type="link" onClick={() => this.jumpMenu(item)} style={{color: 'rgba(30, 228, 224, 1)'}}>鑿滃崟&鏉冮檺</Button>
                       <Button type="link" onClick={() => this.setState({ selectSubApp: item, subVisible: 'edit' })} style={{color: '#8E44AD'}}>淇敼</Button>
                       <Button type="link" onClick={() => this.deleteSubApp(item)} style={{color: '#ff4d4f'}}>鍒犻櫎</Button>
                       <Button type="link" onClick={() => this.jumpApp(item)}>缂栬緫搴旂敤</Button>
diff --git a/src/views/appmanage/index.scss b/src/views/appmanage/index.scss
index 8a72f9f..5f9cb3b 100644
--- a/src/views/appmanage/index.scss
+++ b/src/views/appmanage/index.scss
@@ -18,11 +18,6 @@
       top: 50%;
     }
   }
-  .mob-header-container {
-    padding-right: 0px;
-    z-index: 10;
-    left: 0;
-  }
   .view-wrap {
     width: 100%;
     position: relative;
@@ -98,6 +93,10 @@
           padding: 5px 20px;
           margin-top: 5px;
           border-top: 1px solid #e8e8e8;
+
+          .ant-typography-copy {
+            color: #26C281;
+          }
         }
       }
     }
diff --git a/src/views/rolemanage/header/index.jsx b/src/views/rolemanage/header/index.jsx
new file mode 100644
index 0000000..d49edb8
--- /dev/null
+++ b/src/views/rolemanage/header/index.jsx
@@ -0,0 +1,32 @@
+import React, {Component} from 'react'
+
+import avatar from '@/assets/img/avatar.jpg'
+import MainLogo from '@/assets/img/main-logo.png'
+import './index.scss'
+
+class AppManageHeader extends Component {
+  state = {
+    avatar: sessionStorage.getItem('CloudAvatar') || avatar,
+    userName: sessionStorage.getItem('CloudUserName')
+  }
+
+  render () {
+    const { app } = this.props
+    return (
+      <header className="app-manage-header-container">
+        <div className="header-logo"><img src={MainLogo} alt=""/></div>
+        <div className="title">
+          {`${app.remark} ${app.typename}`}
+        </div>
+        <div className="header-user">
+          <img src={this.state.avatar} alt=""/>
+          <span>
+            <span className="username">{this.state.userName}</span>
+          </span>
+        </div>
+      </header>
+    )
+  }
+}
+
+export default AppManageHeader
\ No newline at end of file
diff --git a/src/views/rolemanage/header/index.scss b/src/views/rolemanage/header/index.scss
new file mode 100644
index 0000000..84580f7
--- /dev/null
+++ b/src/views/rolemanage/header/index.scss
@@ -0,0 +1,58 @@
+.app-manage-header-container {
+  width: 100%;
+  height: 48px;
+  color: rgba(255, 255, 255, 0.65);
+  position: fixed;
+  top: 0px;
+  z-index: 10;
+  padding-right: 0px;
+  left: 0;
+  
+  background: #001529;
+  border-bottom: 1px solid #000;
+
+  .header-logo {
+    float: left;
+    width: 180px;
+    line-height: 48px;
+    text-align: center;
+    padding-left: 5px;
+    box-sizing: border-box;
+    opacity: 1;
+    img {
+      max-width: 100%;
+      max-height: 40px;
+    }
+  }
+  .header-user {
+    float: right;
+    line-height: 48px;
+    margin-right: 10px;
+    img {
+      width: 29px;
+      height: 29px;
+      border-radius: 30px;
+      margin-right: 7px;
+    }
+    span {
+      color: #ffffff;
+      font-size: 0.95rem;
+      .username {
+        display: inline-block;
+        height: 30px;
+        max-width: 95px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+  }
+  .title {
+    position: absolute;
+    left: 50%;
+    top: 10px;
+    color: #ffffff;
+    font-size: 18px;
+    transform: translateX(-50%);
+  }
+}
\ No newline at end of file
diff --git a/src/views/rolemanage/index.jsx b/src/views/rolemanage/index.jsx
new file mode 100644
index 0000000..0603de2
--- /dev/null
+++ b/src/views/rolemanage/index.jsx
@@ -0,0 +1,490 @@
+import React, {Component} from 'react'
+// import { fromJS } from 'immutable'
+import { Spin, notification, Button, Table, Modal, ConfigProvider, Tree } from 'antd'
+import moment from 'moment'
+// import md5 from 'md5'
+import enUS from 'antd/es/locale/en_US'
+import zhCN from 'antd/es/locale/zh_CN'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
+import asyncComponent from '@/utils/asyncComponent'
+import './index.scss'
+
+const { confirm } = Modal
+const { TreeNode } = Tree
+// const { Paragraph } = Typography
+// const { Search } = Input
+
+const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
+const Header = asyncComponent(() => import('./header'))
+const TransferForm = asyncComponent(() => import('@/templates/zshare/basetransferform'))
+
+sessionStorage.setItem('isEditState', 'true')
+
+class RoleManage extends Component {
+  state = {
+    app: null,
+    loading: false,
+    menulist: [],
+    columns: [
+      { title: '鑿滃崟鍚嶇О', dataIndex: 'MenuName', key: 'MenuName', align: 'center' },
+      {
+        title: '鎿嶄綔',
+        key: 'action',
+        align: 'center',
+        render: (text, record) => (
+          <div>
+            <Button type="link" onClick={() => this.deleteMenu(record)} style={{color: '#ff4d4f'}}>鍒犻櫎</Button>
+          </div>
+        ),
+      },
+    ],
+    selectApp: null,
+    selectSubApp: null,
+    visible: false,
+    thawmenulist: [],
+    confirmLoading: false,
+    targetKeys: [],
+    trees: [],
+    expandedKeys: []
+  }
+
+  UNSAFE_componentWillMount() {
+    let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
+
+    let expandedKeys = []
+    const data = [
+      {
+        key: Utils.getuuid(),
+        title: '瀵艰埅鏍�',
+        children: [
+          {
+            key: Utils.getuuid(),
+            title: '閲囪喘',
+            children: [
+              {
+                key: Utils.getuuid(),
+                title: '閲囪喘涓氬姟',
+                children: [
+                  {
+                    key: Utils.getuuid(),
+                    title: '閲囪喘鍗曠鐞�'
+                  },
+                  {
+                    key: Utils.getuuid(),
+                    title: '濮斿閲囪喘'
+                  }
+                ]
+              },
+              {
+                key: Utils.getuuid(),
+                title: '涓绘暟鎹�'
+              }
+            ]
+          },
+          {
+            key: Utils.getuuid(),
+            title: '搴撳瓨',
+            children: [
+              {
+                key: Utils.getuuid(),
+                title: '搴撳瓨绠$悊',
+                children: [
+                  {
+                    key: Utils.getuuid(),
+                    title: '鏀惰揣绠$悊'
+                  },
+                  {
+                    key: Utils.getuuid(),
+                    title: '閿�閫�鏀惰揣'
+                  },
+                  {
+                    key: Utils.getuuid(),
+                    title: '鍙戣揣閫氱煡鍗�'
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            key: Utils.getuuid(),
+            title: '鎶ヨ〃',
+            children: [
+              {
+                key: Utils.getuuid(),
+                title: '鎶ヨ〃鏌ヨ',
+                children: [
+                  {
+                    key: Utils.getuuid(),
+                    title: '閲囪喘鏌ヨ'
+                  },
+                  {
+                    key: Utils.getuuid(),
+                    title: '搴撳瓨鏌ヨ'
+                  },
+                  {
+                    key: Utils.getuuid(),
+                    title: '鍑哄簱鏌ヨ'
+                  }
+                ]
+              }
+            ]
+          }
+        ]
+      },
+      {
+        key: Utils.getuuid(),
+        title: '棣栭〉001'
+      },
+      {
+        key: Utils.getuuid(),
+        title: '渚涘簲鍟�'
+      }
+    ]
+
+    if (data[0]) {
+      expandedKeys.push(data[0].key)
+      if (data[0].children && data[0].children[0]) {
+        expandedKeys.push(data[0].children[0].key)
+      }
+    }
+    this.setState({app: param, trees: data, expandedKeys}, () => {
+      this.getMenuList()
+      this.getThawMenulist()
+    })
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  getMenuList = () => {
+    const { app } = this.state
+    let param = {
+      func: 's_get_app_menus',
+      TypeCharOne: app.kei_no,
+      typename: app.typename,
+      LText: `select '${window.GLOB.appkey}'`,
+      timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
+      lang: app.lang
+    }
+
+    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+
+    this.setState({
+      loading: true
+    })
+
+    Api.getCloudConfig(param).then(result => {
+      if (result.status) {
+        this.setState({
+          loading: false,
+          menulist: result.menus
+        })
+      } else {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  getThawMenulist = () => {
+    Api.getCloudConfig({
+      func: 'sPC_Get_FrozenMenu',
+      ParentID: '0',
+      TYPE: 10
+    }).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: 5
+        })
+      }
+    })
+  }
+
+  deleteMenu = (record) => {
+    // const { app } = this.state
+    const _this = this
+
+    let param = {
+      func: 'sPC_MainMenu_Del',
+      MenuID: record.MenuID,
+      // ID: app.ID,
+      // TypeCharOne: app.kei_no,
+      // typename: app.typename,
+      // lang: app.lang
+    }
+    
+    confirm({
+      content: '纭畾鍒犻櫎璇ヨ彍鍗曞悧锛�',
+      onOk() {
+        return new Promise(resolve => {
+          Api.getCloudConfig(param).then(result => {
+            if (result.status) {
+              notification.success({
+                top: 92,
+                message: '鎿嶄綔鎴愬姛锛�',
+                duration: 3
+              })
+              _this.getMenuList()
+            } else {
+              notification.warning({
+                top: 92,
+                message: result.message,
+                duration: 5
+              })
+            }
+            resolve()
+          }, () => {
+            resolve()
+          })
+        })
+      },
+      onCancel() {}
+    })
+  }
+
+  thawSubmit = () => {
+    const { targetKeys } = this.state
+
+    if (targetKeys.length === 0) {
+      notification.warning({
+        top: 92,
+        message: '璇烽�夋嫨瑙i櫎鍐荤粨鐨勮彍鍗曪紒',
+        duration: 5
+      })
+      return
+    }
+
+    this.setState({
+      confirmLoading: true
+    })
+
+    let defers = targetKeys.map(item => {
+      return new Promise((resolve) => {
+        // Api.getCloudConfig({
+        //   func: 'sPC_MainMenu_ReDel',
+        //   MenuID: item
+        // }).then(res => {
+        //   if (res.status) {
+        //     resolve('')
+        //   } else {
+        //     resolve(res.message)
+        //   }
+        // })
+        resolve('')
+      })
+    })
+    Promise.all(defers).then(res => {
+      let msg = res.filter(Boolean)[0]
+      if (msg) {
+        notification.error({
+          top: 92,
+          message: msg,
+          duration: 10
+        })
+      } else {
+        this.setState({
+          confirmLoading: false,
+          visible: false,
+          targetKeys: [],
+          thawmenulist: this.state.thawmenulist.filter(item => !targetKeys.includes(item.key))
+        })
+        this.getMenuList()
+      }
+    })
+  }
+
+  onDragEnter = info => {
+    // expandedKeys 闇�瑕佸彈鎺ф椂璁剧疆
+    // this.setState({
+    //   expandedKeys: info.expandedKeys,
+    // });
+  }
+
+  onDrop = info => {
+    const dropKey = info.node.props.eventKey;
+    const dragKey = info.dragNode.props.eventKey;
+    const dropPos = info.node.props.pos.split('-');
+    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
+
+    const loop = (data, key, callback) => {
+      data.forEach((item, index, arr) => {
+        if (item.key === key) {
+          return callback(item, index, arr)
+        }
+        if (item.children) {
+          return loop(item.children, key, callback)
+        }
+      })
+    }
+    const data = [...this.state.trees]
+
+    let dragObj
+    loop(data, dragKey, (item, index, arr) => {
+      arr.splice(index, 1)
+      dragObj = item
+    })
+
+    if (!info.dropToGap) {
+      loop(data, dropKey, item => {
+        item.children = item.children || []
+
+        item.children.push(dragObj)
+      })
+    } else if ((info.node.props.children || []).length > 0 && info.node.props.expanded && dropPosition === 1 ) {
+      loop(data, dropKey, item => {
+        item.children = item.children || []
+
+        item.children.unshift(dragObj)
+      })
+    } else {
+      let ar;
+      let i;
+
+      loop(data, dropKey, (item, index, arr) => {
+        ar = arr
+        i = index
+      })
+
+      if (dropPosition === -1) {
+        ar.splice(i, 0, dragObj)
+      } else {
+        ar.splice(i + 1, 0, dragObj)
+      }
+    }
+
+    this.setState({
+      trees: data
+    })
+  }
+
+  renderNode = data => {
+    return data.map(item => {
+      if (item.children && item.children.length) {
+        return (
+          <TreeNode key={item.key} title={item.title}>
+            {this.renderNode(item.children)}
+          </TreeNode>
+        )
+      }
+      return <TreeNode key={item.key} title={item.title} />
+    })
+  }
+
+  initTree = () => {
+    confirm({
+      content: '鍒濆鍖栦細鏍规嵁鑿滃崟閲嶇疆鏉冮檺鏍戯紝纭畾鎵ц鍚楋紵',
+      onOk() {
+        
+      },
+      onCancel() {}
+    })
+  }
+
+  syncTree = () => {
+    confirm({
+      content: '鍚屾浼氭牴鎹彍鍗曞垹闄ゆ垨鏂板鑺傜偣锛岀‘瀹氭墽琛屽悧锛�',
+      onOk() {
+        
+      },
+      onCancel() {}
+    })
+  }
+
+  saveTree = () => {
+    confirm({
+      content: '纭畾鎵ц鍚楋紵',
+      onOk() {
+        
+      },
+      onCancel() {}
+    })
+  }
+
+  render () {
+    const { app, loading, columns, menulist, trees } = this.state
+
+    return (
+      <div className="mk-role-manage">
+        <ConfigProvider locale={_locale}>
+          <Header app={app} />
+          {loading ?
+            <div className="loading-mask">
+              <Spin size="large" />
+            </div> : null
+          }
+          <div className="view-wrap">
+            <div className="left-view">
+              <div className="app-table">
+                <div className="app-action">
+                  <Button className="mk-green" onClick={() => this.setState({ visible: true, targetKeys: [] })}>瑙e喕鑿滃崟</Button>
+                </div>
+                <Table
+                  rowKey="MenuID"
+                  columns={columns}
+                  dataSource={menulist}
+                  pagination={false}
+                />
+              </div>
+            </div>
+            <div className="right-view">
+              <div className="app-action">
+                <Button className="mk-primary" onClick={this.initTree}>鍒濆鍖�</Button>
+                <Button className="mk-purple" onClick={this.syncTree}>鍚屾</Button>
+                <Button className="mk-green save" onClick={this.saveTree}>淇濆瓨</Button>
+              </div>
+              <Tree
+                className="draggable-tree"
+                defaultExpandedKeys={this.state.expandedKeys}
+                // showLine
+                draggable
+                blockNode
+                onDragEnter={this.onDragEnter}
+                onDrop={this.onDrop}
+              >
+                {this.renderNode(trees)}
+              </Tree>
+            </div>
+          </div>
+          <Modal
+            title="瑙i櫎鍐荤粨"
+            visible={this.state.visible}
+            width={600}
+            onOk={this.thawSubmit}
+            confirmLoading={this.state.confirmLoading}
+            onCancel={() => this.setState({visible: false, targetKeys: []})}
+            destroyOnClose
+          >
+            <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>
+          </Modal>
+        </ConfigProvider>
+      </div>
+    )
+  }
+}
+
+export default RoleManage
\ No newline at end of file
diff --git a/src/views/rolemanage/index.scss b/src/views/rolemanage/index.scss
new file mode 100644
index 0000000..99c4936
--- /dev/null
+++ b/src/views/rolemanage/index.scss
@@ -0,0 +1,80 @@
+.mk-role-manage {
+  background: #fff;
+  min-height: 100vh;
+  padding: 70px 30px;
+
+  .loading-mask {
+    position: fixed;
+    top: 0px;
+    bottom: 0px;
+    left: 0px;
+    right: 0px;
+    z-index: 2;
+    background: rgba(255, 255, 255, 0.35);
+
+    .ant-spin {
+      position: absolute;
+      left: 50%;
+      top: 50%;
+    }
+  }
+  .mob-header-container {
+    padding-right: 0px;
+    z-index: 10;
+    left: 0;
+  }
+  .view-wrap {
+    width: 100%;
+    position: relative;
+    display: flex;
+
+    .left-view {
+      flex: 1;
+      width: 50%;
+      padding-right: 5px;
+      .ant-table-tbody > tr > td {
+        padding: 8px 16px;
+      }
+    }
+    .right-view {
+      width: 50%;
+      padding-left: 20px;
+
+      .draggable-tree {
+        border: 1px solid #e8e8e8;
+        padding: 10px 10px 30px;
+        min-height: 400px;
+        border-radius: 4px;
+        .ant-tree-title {
+          max-width: 100%;
+          display: inline-block;
+          overflow: hidden;
+          white-space: nowrap;
+          text-overflow: ellipsis;
+        }
+      }
+    }
+  }
+  .ant-table-wrapper {
+    .ant-table-body {
+      border: 1px solid #e8e8e8;
+      border-bottom: 0;
+      border-radius: 4px;
+    }
+    .ant-table-tbody {
+      > tr.ant-table-row-selected td {
+        background: #bae7ff;
+      }
+    }
+  }
+  .app-action {
+    >button {
+      margin-bottom: 10px;
+      margin-right: 15px;
+    }
+    .save {
+      float: right;
+      margin-right: 0px;
+    }
+  }
+}

--
Gitblit v1.8.0