From 4d6f55e184cabecf958f63f68002f5fd0e06f2bc Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 02 一月 2025 18:09:54 +0800
Subject: [PATCH] Merge branch 'positec' into bms

---
 src/menu/components/share/pastebasetable/index.jsx       |    7 
 src/utils/utils-custom.js                                |  110 ++-
 src/templates/zshare/verifycard/billcodeform/index.jsx   |   27 
 src/views/rolemanage/index.jsx                           |    2 
 src/tabviews/custom/popview/index.jsx                    |    7 
 src/api/index.js                                         |   12 
 src/components/paste/index.jsx                           |   53 ++
 src/views/mobdesign/index.jsx                            |    1 
 src/utils/utils.js                                       |   21 
 src/templates/zshare/verifycard/voucherform/index.jsx    |    8 
 src/menu/components/card/balcony/index.jsx               |    2 
 src/tabviews/custom/components/card/prop-card/index.jsx  |   12 
 public/index.html                                        |    6 
 src/menu/components/share/pastecomponent/index.jsx       |   22 
 src/views/rolemanage/filtermenu/index.jsx                |  523 ++++++++++++++++++++
 public/manifest.json                                     |    2 
 src/views/pcdesign/index.jsx                             |    1 
 src/views/rolemanage/filtermenu/index.scss               |    0 
 src/templates/zshare/verifycard/index.jsx                |   25 
 src/views/syscheck/index.jsx                             |  513 +++++++++++++++++++
 src/views/syscheck/index.scss                            |   52 ++
 src/router/index.js                                      |    4 
 src/menu/components/card/cardcomponent/index.jsx         |    2 
 src/menu/components/card/cardsimplecomponent/index.jsx   |    2 
 src/tabviews/zshare/mutilform/mkPopSelect/index.jsx      |    4 
 src/tabviews/zshare/mutilform/index.jsx                  |    3 
 src/tabviews/custom/index.jsx                            |    7 
 src/menu/components/table/base-table/columns/index.jsx   |    2 
 src/menu/debug/index.jsx                                 |   32 
 src/views/syscheck/header/index.scss                     |   57 ++
 src/menu/components/table/normal-table/columns/index.jsx |    2 
 src/menu/components/table/edit-table/columns/index.jsx   |    2 
 src/views/syscheck/header/index.jsx                      |   34 +
 33 files changed, 1,435 insertions(+), 122 deletions(-)

diff --git a/public/index.html b/public/index.html
index 7719992..b182d18 100644
--- a/public/index.html
+++ b/public/index.html
@@ -60,7 +60,11 @@
       }
 
       window.mkInfo = function(value, color = '') {
-        console.info(value, color)
+        if (color) {
+          console.info(value, color)
+        } else {
+          console.info(value)
+        }
       }
     </script>
   </head>
diff --git a/public/manifest.json b/public/manifest.json
index 063a1cb..cb18af8 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -6,5 +6,5 @@
   "display": "standalone",
   "theme_color": "#000000",
   "background_color": "#ffffff",
-  "mk_version": "20241202"
+  "mk_version": "20250101"
 }
diff --git a/src/api/index.js b/src/api/index.js
index 51184c4..6b6cd8c 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -791,7 +791,11 @@
           if (res.mksqls) {
             res.mksqls.forEach(n => {
               n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
-              window.mkInfo(n)
+              if (!res.status) {
+                window.mkInfo('%c' + n, 'color: #f5222d')
+              } else {
+                window.mkInfo(n)
+              }
             })
           }
           delete res.mksqls
@@ -1110,7 +1114,11 @@
           if (res.mksqls) {
             res.mksqls.forEach(n => {
               n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
-              window.mkInfo(n)
+              if (!res.status) {
+                window.mkInfo('%c' + n, 'color: #f5222d')
+              } else {
+                window.mkInfo(n)
+              }
             })
           }
           delete res.mksqls
diff --git a/src/components/paste/index.jsx b/src/components/paste/index.jsx
index ce96162..fd88a46 100644
--- a/src/components/paste/index.jsx
+++ b/src/components/paste/index.jsx
@@ -1,8 +1,10 @@
-import React, {Component} from 'react'
+import React, { Component } from 'react'
 import PropTypes from 'prop-types'
 import { Modal, notification } from 'antd'
 import { SnippetsOutlined } from '@ant-design/icons'
 
+import Utils from '@/utils/utils.js'
+import MenuUtils from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
 
 const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
@@ -17,6 +19,49 @@
     visible: false
   }
 
+  resetconfig = (item, appType) => {
+    if (item.copyType === 'action') {
+      MenuUtils.resetBtn(item, item.uuid)
+    } else if (item.copyType === 'cardcell') {
+      item.setting = item.setting || {}
+      item.setting.width = item.setting.width || 6
+      delete item.$cardType
+
+      if (item.elements) {
+        item.elements = item.elements.map(cell => {
+          cell.uuid = Utils.getuuid()
+
+          if (cell.eleType === 'button') {
+            MenuUtils.resetBtn(cell, item.uuid)
+          }
+          return cell
+        })
+        if (appType === 'mob') {
+          item.elements = item.elements.filter(cell => {
+            if (cell.eleType === 'button' && ['excelIn', 'tab'].includes(cell.OpenType)) {
+              return false
+            }
+            return true
+          })
+        }
+      }
+      if (appType === 'mob') {
+        item.backElements = []
+      } else if (item.backElements) {
+        item.backElements = item.backElements.map(cell => {
+          cell.uuid = Utils.getuuid()
+
+          if (cell.eleType === 'button') {
+            MenuUtils.resetBtn(cell, item.uuid)
+          }
+          return cell
+        })
+      }
+    }
+
+    return item
+  }
+
   pasteSubmit = () => {
     const { options } = this.props
     this.pasteFormRef.handleConfirm().then(res => {
@@ -24,6 +69,12 @@
         notification.warning({ top: 92, message: '閰嶇疆淇℃伅鏍煎紡閿欒锛�', duration: 5 })
         return
       }
+
+      let appType = sessionStorage.getItem('appType')
+      res.uuid = Utils.getuuid()
+
+      res = this.resetconfig(res, appType)
+
       this.props.updateConfig(res, (result) => {
         if (result.status) {
           notification.success({
diff --git a/src/menu/components/card/balcony/index.jsx b/src/menu/components/card/balcony/index.jsx
index e11f323..1410c94 100644
--- a/src/menu/components/card/balcony/index.jsx
+++ b/src/menu/components/card/balcony/index.jsx
@@ -213,7 +213,7 @@
       MKEmitter.emit('cardAddElement', card.uuid, res)
     } else {
       res.eleType = 'button'
-      res.width = res.width || 12
+      res.width = typeof(res.width) === 'number' ? res.width : 12
       MKEmitter.emit('cardAddElement', card.uuid, res)
     }
     resolve({status: true})
diff --git a/src/menu/components/card/cardcomponent/index.jsx b/src/menu/components/card/cardcomponent/index.jsx
index ce42f87..54f4ea0 100644
--- a/src/menu/components/card/cardcomponent/index.jsx
+++ b/src/menu/components/card/cardcomponent/index.jsx
@@ -400,7 +400,7 @@
 
     if (element.copyType === 'action') {
       element.eleType = 'button'
-      element.width = element.width || 12
+      element.width = typeof(element.width) === 'number' ? element.width : 12
     }
 
     element.uuid = _uuid
diff --git a/src/menu/components/card/cardsimplecomponent/index.jsx b/src/menu/components/card/cardsimplecomponent/index.jsx
index d7d2fe6..dce5198 100644
--- a/src/menu/components/card/cardsimplecomponent/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/index.jsx
@@ -289,7 +289,7 @@
     
     if (element.copyType === 'action') {
       element.eleType = 'button'
-      element.width = element.width || 12
+      element.width = typeof(element.width) === 'number' ? element.width : 12
     }
 
     element.uuid = _uuid
diff --git a/src/menu/components/share/pastebasetable/index.jsx b/src/menu/components/share/pastebasetable/index.jsx
index 84811f8..9204d46 100644
--- a/src/menu/components/share/pastebasetable/index.jsx
+++ b/src/menu/components/share/pastebasetable/index.jsx
@@ -4,6 +4,7 @@
 import { SnippetsOutlined } from '@ant-design/icons'
 
 import Utils from '@/utils/utils.js'
+import MenuUtils from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
 // import './index.scss'
 
@@ -52,6 +53,10 @@
           } else if (col.type === 'custom' && col.elements) {
             col.elements = col.elements.map(cell => {
               cell.uuid = Utils.getuuid()
+
+              if (cell.eleType === 'button') {
+                MenuUtils.resetBtn(cell, cell.uuid)
+              }
               return cell
             })
           }
@@ -69,6 +74,8 @@
 
         cell.uuid = _uuid
 
+        MenuUtils.resetBtn(cell, cell.uuid)
+
         return cell
       })
 
diff --git a/src/menu/components/share/pastecomponent/index.jsx b/src/menu/components/share/pastecomponent/index.jsx
index a96fa09..f0e89a1 100644
--- a/src/menu/components/share/pastecomponent/index.jsx
+++ b/src/menu/components/share/pastecomponent/index.jsx
@@ -6,6 +6,7 @@
 
 import Utils from '@/utils/utils.js'
 import MKEmitter from '@/utils/events.js'
+import MenuUtils from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
 // import './index.scss'
 
@@ -28,7 +29,9 @@
       item.uuid = _uuid
     }
 
-    if (item.copyType === 'cardcell' && config.subtype === 'datacard') {
+    if (item.copyType === 'action') {
+      MenuUtils.resetBtn(item, _uuid)
+    } else if (item.copyType === 'cardcell' && config.subtype === 'datacard') {
       item.setting = item.setting || {}
       item.$cardType = 'extendCard'
       item.setting.width = item.setting.width || 6
@@ -39,6 +42,10 @@
             cell.datatype = 'static'
           }
           cell.uuid = Utils.getuuid()
+
+          if (cell.eleType === 'button') {
+            MenuUtils.resetBtn(cell, _uuid)
+          }
           return cell
         })
       }
@@ -48,6 +55,10 @@
             cell.datatype = 'static'
           }
           cell.uuid = Utils.getuuid()
+
+          if (cell.eleType === 'button') {
+            MenuUtils.resetBtn(cell, _uuid)
+          }
           return cell
         })
       }
@@ -64,12 +75,18 @@
       if (item.elements) {
         item.elements = item.elements.map(cell => {
           cell.uuid = Utils.getuuid()
+          if (cell.eleType === 'button') {
+            MenuUtils.resetBtn(cell, _uuid)
+          }
           return cell
         })
       }
       if (item.backElements) {
         item.backElements = item.backElements.map(cell => {
           cell.uuid = Utils.getuuid()
+          if (cell.eleType === 'button') {
+            MenuUtils.resetBtn(cell, _uuid)
+          }
           return cell
         })
       }
@@ -87,6 +104,9 @@
           } else if (col.type === 'custom' && col.elements) {
             col.elements = col.elements.map(cell => {
               cell.uuid = Utils.getuuid()
+              if (cell.eleType === 'button') {
+                MenuUtils.resetBtn(cell, _uuid)
+              }
               return cell
             })
           }
diff --git a/src/menu/components/table/base-table/columns/index.jsx b/src/menu/components/table/base-table/columns/index.jsx
index 96d01c3..b824871 100644
--- a/src/menu/components/table/base-table/columns/index.jsx
+++ b/src/menu/components/table/base-table/columns/index.jsx
@@ -391,7 +391,7 @@
     if (!cell.eleType) {
       if (cell.copyType === 'action') {
         cell.eleType = 'button'
-        cell.width = cell.width || 12
+        cell.width = typeof(cell.width) === 'number' ? cell.width : 12
       } else {
         cell.eleType = 'text'
       }
diff --git a/src/menu/components/table/edit-table/columns/index.jsx b/src/menu/components/table/edit-table/columns/index.jsx
index fcf33b1..e0e95cc 100644
--- a/src/menu/components/table/edit-table/columns/index.jsx
+++ b/src/menu/components/table/edit-table/columns/index.jsx
@@ -386,7 +386,7 @@
     if (!cell.eleType) {
       if (cell.copyType === 'action') {
         cell.eleType = 'button'
-        cell.width = cell.width || 12
+        cell.width = typeof(cell.width) === 'number' ? cell.width : 12
       } else {
         cell.eleType = 'text'
       }
diff --git a/src/menu/components/table/normal-table/columns/index.jsx b/src/menu/components/table/normal-table/columns/index.jsx
index 1035dc6..bed9a9d 100644
--- a/src/menu/components/table/normal-table/columns/index.jsx
+++ b/src/menu/components/table/normal-table/columns/index.jsx
@@ -381,7 +381,7 @@
     if (!cell.eleType) {
       if (cell.copyType === 'action') {
         cell.eleType = 'button'
-        cell.width = cell.width || 12
+        cell.width = typeof(cell.width) === 'number' ? cell.width : 12
       } else {
         cell.eleType = 'text'
       }
diff --git a/src/menu/debug/index.jsx b/src/menu/debug/index.jsx
index c2bf056..aa75c46 100644
--- a/src/menu/debug/index.jsx
+++ b/src/menu/debug/index.jsx
@@ -1157,17 +1157,6 @@
   
     // 鍞竴鎬ч獙璇侊紝蹇呴』瀛樺湪琛ㄥ崟锛堣〃鍗曞瓨鍦ㄦ椂锛屼富閿潎涓哄崟鍊硷級,蹇呴』濉啓鏁版嵁婧愶紝澶氳鎷兼帴鏃朵笉鍙敤
     if (formdata && verify.uniques && verify.uniques.length > 0 && btn.Ot !== 'requiredOnce') {
-      let dateForms = []
-      let numForms = []
-      formdata.forEach(form => {
-        let _key = form.key.toLowerCase()
-        if (form.type === 'date') {
-          dateForms.push(_key)
-        } else if (form.type === 'number' || form.type === 'rate') {
-          numForms.push(_key)
-        }
-      })
-
       verify.uniques.forEach(item => {
         let _fieldValue = []                     // 琛ㄥ崟閿�煎field=value
         let _value = []                          // 琛ㄥ崟鍊硷紝鐢ㄤ簬閿欒鎻愮ず
@@ -1177,21 +1166,26 @@
         item.field.split(',').forEach((_field, index) => {
           let _key = _field.toLowerCase()
           let _val = ''
+          let _val2 = ''
   
           arr.push(_key)
-          if (_key === 'bid') { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
+          if (_key === 'bid') {
             _val = BID
-          } else if (numForms.includes(_key)) {
-            _val = '1'
-          } else if (dateForms.includes(_key)) {
-            _val = '1949-10-01'
+          } else {
+            _val = `@${_field}`
           }
 
-          _fieldValue.push(`${_key}='${_val}'`)
-          _value.push(`${_labels[index] || ''}锛�${_val || ''}`)
+          if (_key === 'bid') {
+            _val2 = `' + ${BID} + '`
+          } else {
+            _val2 = `' + @${_field} + '`
+          }
+
+          _fieldValue.push(`${_key}=${_val}`)
+          _value.push(`${_labels[index] || ''}锛�${_val2}`)
         })
   
-        if (!arr.includes(primaryKey.toLowerCase())) {
+        if (!arr.includes(primaryKey.toLowerCase()) && btn.Ot !== 'notRequired') {
           _fieldValue.push(`${primaryKey} !='${primaryId}'`)
         }
   
diff --git a/src/router/index.js b/src/router/index.js
index b66adb6..80346cf 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -24,6 +24,7 @@
 const RoleManage = asyncLoadComponent(() => import('@/views/rolemanage'))
 const SystemFunc = asyncLoadComponent(() => import('@/views/systemfunc'))
 const SystemProc = asyncLoadComponent(() => import('@/views/systemproc'))
+// const SystemCheck = asyncLoadComponent(() => import('@/views/syscheck'))
 const MkIframe = asyncLoadComponent(() => import('@/views/mkiframe'))
 
 const routers = [
@@ -53,7 +54,8 @@
   {path: '/iframe/:menuId/:loginUid/:bid', name: 'iframe', component: MkIframe},
   {path: '/view/:menuId', name: 'iframe', component: MkIframe},
   {path: '/view/:menuId/:bid', name: 'iframe', component: MkIframe},
-  {path: '/interface', name: 'interface', component: Interface}
+  {path: '/interface', name: 'interface', component: Interface},
+  // {path: '/syscheck', name: 'syscheck', component: SystemCheck}
 ]
 
 export default class RouteConfig extends Component {
diff --git a/src/tabviews/custom/components/card/prop-card/index.jsx b/src/tabviews/custom/components/card/prop-card/index.jsx
index a1e1a11..001d66e 100644
--- a/src/tabviews/custom/components/card/prop-card/index.jsx
+++ b/src/tabviews/custom/components/card/prop-card/index.jsx
@@ -399,7 +399,9 @@
 
     this.autoTimer && clearTimeout(this.autoTimer)
 
-    if (btn) {
+    if (config.setting.supModule && config.wrap.datatype === 'static' && !data.$$BID) {
+
+    } else if (btn) {
       MKEmitter.emit('triggerBtnId', config.wrap.autoExec, data.$$empty ? [] : [data])
     } else if (!times || times < 20) {
       times = times ? times + 1 : 1
@@ -526,11 +528,11 @@
 
       this.setState({
         data: _data,
+      }, () => {
+        if (!btn) {
+          this.autoExec()
+        }
       })
-
-      if (!btn) {
-        this.autoExec()
-      }
       return
     } else if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
       this.setState({
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index e1871a4..639042b 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -830,6 +830,13 @@
 
           group.subButton = this.resetButton(item, group.subButton)
 
+          if (group.subButton.linkmenu) {
+            if (Array.isArray(group.subButton.linkmenu) && group.subButton.linkmenu.length > 0) {
+              group.subButton.openmenu = group.subButton.linkmenu
+            }
+            delete group.subButton.linkmenu
+          }
+
           if (item.$cache && item.$time) { // 琛ㄥ崟缂撳瓨
             group.$cache = item.$cache
             group.$time = item.$time
diff --git a/src/tabviews/custom/popview/index.jsx b/src/tabviews/custom/popview/index.jsx
index 57197b5..778c090 100644
--- a/src/tabviews/custom/popview/index.jsx
+++ b/src/tabviews/custom/popview/index.jsx
@@ -537,6 +537,13 @@
 
           group.subButton = this.resetButton(item, group.subButton, Tab)
 
+          if (group.subButton.linkmenu) {
+            if (Array.isArray(group.subButton.linkmenu) && group.subButton.linkmenu.length > 0) {
+              group.subButton.openmenu = group.subButton.linkmenu
+            }
+            delete group.subButton.linkmenu
+          }
+
           group.fields = group.fields.map(cell => {
             // 鏁版嵁婧恠ql璇彞锛岄澶勭悊锛屾潈闄愰粦鍚嶅崟瀛楁璁剧疆涓洪殣钘忚〃鍗�
             if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index 98fa458..9a1a0c5 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -297,6 +297,9 @@
         } else {
           item.showValue = ''
         }
+        if (window.backend && action.uuid) {
+          item.formSqlId = md5(action.uuid.replace(/_pop$/, '') + item.uuid)
+        }
       } else if (item.type === 'brafteditor') {
         if (window.backend && newval && /<\/span>/.test(newval) && item.encryption === 'true') {
           try {
diff --git a/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
index 4b967e2..8b18bcf 100644
--- a/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
@@ -122,8 +122,8 @@
     })
 
     let param = null
-    if (window.backend && window.GLOB.CacheData.has('sql_' + config.uuid)) {
-      let ex = window.GLOB.CacheData.get('sql_' + config.uuid)
+    if (window.backend && window.GLOB.CacheData.has('sql_' + config.formSqlId)) {
+      let ex = window.GLOB.CacheData.get('sql_' + config.formSqlId)
       let sysvals = {
         time_id: Utils.getguid(),
         mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
diff --git a/src/templates/zshare/verifycard/billcodeform/index.jsx b/src/templates/zshare/verifycard/billcodeform/index.jsx
index cff8a6f..bf5c929 100644
--- a/src/templates/zshare/verifycard/billcodeform/index.jsx
+++ b/src/templates/zshare/verifycard/billcodeform/index.jsx
@@ -91,6 +91,7 @@
       }, () => {
         this.props.form.setFieldsValue({
           field: record.field,
+          Type: record.Type || 4,
           TypeCharOne: record.TypeCharOne,
           ModularCode: record.ModularCode,
           ModularDetailCode: _modularDetailCode,
@@ -174,7 +175,7 @@
 
           // 璁剧疆娴佹按鍙蜂綅鏁�
           let _detail = this.state.modularDetail.filter(item => item.ModularDetailCode === values.ModularDetailCode)[0]
-          values.Type = _detail.Type
+          values.Type = values.Type || _detail.Type
         } else {
           let _billField = billFields.filter(item => item.field === values.linkField)[0]
           values.linkFieldName = _billField ? _billField.label : ''
@@ -231,8 +232,8 @@
               })(
                 <Select>
                   {this.state.funFields.map(option =>
-                    <Select.Option title={option.label} id={option.uuid} key={option.uuid} value={option.field}>
-                      {option.label}
+                    <Select.Option key={option.uuid} value={option.field}>
+                      {`${option.label}锛�${option.field}锛塦}
                     </Select.Option>
                   )}
                 </Select>
@@ -240,7 +241,7 @@
             </Form.Item>
           </Col>
           <Col span={7}>
-            <Form.Item label={'绫诲瀷'}>
+            <Form.Item label="绫诲瀷">
               {getFieldDecorator('TypeCharOne', {
                 initialValue: 'Lp',
                 rules: [
@@ -260,7 +261,7 @@
             </Form.Item>
           </Col>
           {type === '1' ? <Col span={7}>
-            <Form.Item label={'鍏宠仈瀛楁'}>
+            <Form.Item label="鍏宠仈瀛楁">
               {getFieldDecorator('linkField', {
                 initialValue: '',
                 rules: [
@@ -270,10 +271,10 @@
                   }
                 ]
               })(
-                <Select>
+                <Select showSearch filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}>
                   {this.state.billFields.map(option =>
-                    <Select.Option title={option.label} id={option.uuid} key={option.uuid} value={option.field}>
-                      {option.label}
+                    <Select.Option key={option.uuid} value={option.field}>
+                      {`${option.label}锛�${option.field}锛塦}
                     </Select.Option>
                   )}
                 </Select>
@@ -281,7 +282,7 @@
             </Form.Item>
           </Col> : null}
           {type === '2' ? <Col span={7}>
-            <Form.Item label={'鍑瘉绫诲瀷'}>
+            <Form.Item label="鍑瘉绫诲瀷">
               {getFieldDecorator('ModularCode', {
                 initialValue: this.props.modular[0] ? this.props.modular[0].ID : '',
                 rules: [
@@ -297,7 +298,7 @@
                   onChange={(value) => {this.voucherChange(value)}}
                 >
                   {this.props.modular.map(option =>
-                    <Select.Option title={option.NameNO} id={option.ID} key={option.ID} value={option.ID}>
+                    <Select.Option key={option.ID} value={option.ID}>
                       {option.NameNO}
                     </Select.Option>
                   )}
@@ -310,7 +311,7 @@
               淇濆瓨
             </Button>
           </Col>
-          {type === '1' ? <Col span={7}>
+          <Col span={7}>
             <Form.Item label="浣嶆暟">
               {getFieldDecorator('Type', {
                 initialValue: 4,
@@ -322,7 +323,7 @@
                 ]
               })(<InputNumber min={1} max={10} precision={0} onPressEnter={this.handleConfirm}/>)}
             </Form.Item>
-          </Col> : null}
+          </Col>
           {type === '2' ? <Col span={7}>
             <Form.Item label="鍑瘉鏍囪瘑">
               {getFieldDecorator('ModularDetailCode', {
@@ -339,7 +340,7 @@
                   filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                 >
                   {this.state.modularDetail.map(option =>
-                    <Select.Option style={{whiteSpace: 'unset'}} title={option.CodeName} id={option.ModularDetailCode} key={option.ModularDetailCode} value={option.ModularDetailCode}>
+                    <Select.Option style={{whiteSpace: 'unset'}} key={option.ModularDetailCode} value={option.ModularDetailCode}>
                       {option.CodeName}
                     </Select.Option>
                   )}
diff --git a/src/templates/zshare/verifycard/index.jsx b/src/templates/zshare/verifycard/index.jsx
index 7d2be11..1027840 100644
--- a/src/templates/zshare/verifycard/index.jsx
+++ b/src/templates/zshare/verifycard/index.jsx
@@ -848,7 +848,7 @@
       colfields: colfields.join(', '),
       uniqueColumns: this.state.uniqueColumns.map(col => {
         if (col.dataIndex === 'field') {
-          col.options = _fields
+          col.options = unionFields
         }
         return col
       }),
@@ -1353,21 +1353,26 @@
         item.field.split(',').forEach((_field, index) => {
           let _key = _field.toLowerCase()
           let _val = ''
+          let _val2 = ''
   
           arr.push(_key)
-          if (_key === 'bid') { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
+          if (_key === 'bid') {
             _val = BID
-          } else if (numForms.includes(_key)) {
-            _val = '1'
-          } else if (dateForms.includes(_key)) {
-            _val = '1949-10-01'
+          } else {
+            _val = `@${_field}`
           }
 
-          _fieldValue.push(`${_key}='${_val}'`)
-          _value.push(`${_labels[index] || ''}锛�${_val || ''}`)
+          if (_key === 'bid') {
+            _val2 = `' + ${BID} + '`
+          } else {
+            _val2 = `' + @${_field} + '`
+          }
+
+          _fieldValue.push(`${_key}=${_val}`)
+          _value.push(`${_labels[index] || ''}锛�${_val2}`)
         })
   
-        if (!arr.includes(primaryKey.toLowerCase())) {
+        if (!arr.includes(primaryKey.toLowerCase()) && btn.Ot !== 'notRequired') {
           _fieldValue.push(`${primaryKey} !='${primaryId}'`)
         }
   
@@ -2671,7 +2676,7 @@
           } key="uniques">
             <UniqueForm
               btn={card}
-              fields={card.Ot !== 'requiredOnce' ? fields : columnsFields}
+              fields={card.Ot !== 'requiredOnce' ? unionFields : columnsFields}
               uniqueChange={this.uniqueChange}
             />
             <EditTable actions={['edit', 'move', 'del', 'status', 'sql']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
diff --git a/src/templates/zshare/verifycard/voucherform/index.jsx b/src/templates/zshare/verifycard/voucherform/index.jsx
index e0ea747..c3c4b5a 100644
--- a/src/templates/zshare/verifycard/voucherform/index.jsx
+++ b/src/templates/zshare/verifycard/voucherform/index.jsx
@@ -196,7 +196,7 @@
                   onChange={(value) => {this.voucherSChange(value)}}
                 >
                   {this.state.voucher.map(option =>
-                    <Select.Option title={option.NameNO} id={option.ID} key={option.ID} value={option.ID}>
+                    <Select.Option key={option.ID} value={option.ID}>
                       {option.NameNO}
                     </Select.Option>
                   )}
@@ -221,7 +221,7 @@
                   onChange={this.contentChange}
                 >
                   {this.state.voucherDetail.map(option =>
-                    <Select.Option title={option.CodeName} id={option.ModularDetailCode} key={option.ModularDetailCode} value={option.ModularDetailCode}>
+                    <Select.Option key={option.ModularDetailCode} value={option.ModularDetailCode}>
                       {option.CodeName}
                     </Select.Option>
                   )}
@@ -246,8 +246,8 @@
                   onChange={this.contentChange}
                 >
                   {columns.map((option, index) =>
-                    <Select.Option title={option.label} id={index + option.uuid} key={index + option.uuid} value={option.field}>
-                      {option.label}
+                    <Select.Option key={index + option.uuid} value={option.field}>
+                      {`${option.label}锛�${option.field}锛塦}
                     </Select.Option>
                   )}
                 </Select>
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index 00e48a7..db18898 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -652,7 +652,7 @@
    */
   static resetBtn (btn, commonId) {
     if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.execMode === 'pop')) {
-      if (btn.modal && btn.modal.fields.length > 0) {
+      if (btn.modal && btn.modal.fields && btn.modal.fields.length > 0) {
         btn.modal.fields = btn.modal.fields.map(m => {
           m.uuid = this.getuuid()
           return m
@@ -684,6 +684,10 @@
 
         return md5(commonId + m)
       })
+    }
+
+    if (btn.OpenType === 'popview' && btn.config && btn.config.components) {
+      btn.config.components = this.resetConfig(btn.config.components, commonId)
     }
   }
 
@@ -771,14 +775,7 @@
             if (cell.eleType === 'button') {
               cell.uuid = md5(commonId + cell.uuid)
 
-              if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-                if (cell.modal && cell.modal.fields.length > 0) {
-                  cell.modal.fields = cell.modal.fields.map(m => {
-                    m.uuid = this.getuuid()
-                    return m
-                  })
-                }
-              }
+              this.resetBtn(cell, commonId)
             } else {
               cell.uuid = this.getuuid()
             }
@@ -792,14 +789,8 @@
           card.backElements = card.backElements.map(cell => {
             if (cell.eleType === 'button') {
               cell.uuid = md5(commonId + cell.uuid)
-              if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-                if (cell.modal && cell.modal.fields.length > 0) {
-                  cell.modal.fields = cell.modal.fields.map(m => {
-                    m.uuid = this.getuuid()
-                    return m
-                  })
-                }
-              }
+
+              this.resetBtn(cell, commonId)
             } else {
               cell.uuid = this.getuuid()
             }
@@ -818,14 +809,8 @@
         item.elements = item.elements.map(cell => {
           if (cell.eleType === 'button') {
             cell.uuid = md5(commonId + cell.uuid)
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (cell.modal && cell.modal.fields.length > 0) {
-                cell.modal.fields = cell.modal.fields.map(m => {
-                  m.uuid = this.getuuid()
-                  return m
-                })
-              }
-            }
+
+            this.resetBtn(cell, commonId)
           } else {
             cell.uuid = this.getuuid()
           }
@@ -850,14 +835,7 @@
             col.elements = col.elements.map(cell => {
               cell.uuid = md5(commonId + cell.uuid)
               if (cell.eleType === 'button') {
-                if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-                  if (cell.modal && cell.modal.fields.length > 0) {
-                    cell.modal.fields = cell.modal.fields.map(m => {
-                      m.uuid = this.getuuid()
-                      return m
-                    })
-                  }
-                }
+                this.resetBtn(cell, commonId)
               }
               return cell
             })
@@ -902,14 +880,7 @@
       }
       item.action = item.action.map(cell => {
         cell.uuid = md5(commonId + cell.uuid)
-        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-          if (cell.modal && cell.modal.fields.length > 0) {
-            cell.modal.fields = cell.modal.fields.map(m => {
-              m.uuid = this.getuuid()
-              return m
-            })
-          }
-        }
+        this.resetBtn(cell, commonId)
 
         return cell
       })
@@ -1963,6 +1934,10 @@
           })
         }
         let emptys = []
+        if (cell.Ot !== 'notRequired') {
+          forms.push(...columns)
+        }
+
         cell.verify.uniques.forEach(m => {
           if (m.status === 'false') return
 
@@ -1974,7 +1949,11 @@
         })
 
         if (emptys.length) {
-          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濆敮涓�鎬ч獙璇佸瓧娈�${emptys.join('銆�')}锛屽湪琛ㄥ崟涓笉瀛樺湪锛乣})
+          if (cell.Ot === 'notRequired') {
+            errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濆敮涓�鎬ч獙璇佸瓧娈�${emptys.join('銆�')}锛屽湪琛ㄥ崟涓笉瀛樺湪锛乣})
+          } else {
+            errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濆敮涓�鎬ч獙璇佸瓧娈�${emptys.join('銆�')}锛屽湪琛ㄥ崟涓庡瓧娈甸泦涓笉瀛樺湪锛乣})
+          }
         }
       }
 
@@ -3331,7 +3310,7 @@
           } else if (form.type === 'popSelect') {
             let msg = getPopSelectSql(form)
         
-            sqls.push({uuid: form.uuid, type: 'popSource', ...msg})
+            sqls.push({uuid: md5(cell.uuid + form.uuid), type: 'popSource', ...msg})
           }
         })
       }
@@ -3374,7 +3353,7 @@
             } else if (form.type === 'popSelect') {
               let msg = getPopSelectSql(form)
           
-              sqls.push({uuid: form.uuid, type: 'popSource', ...msg})
+              sqls.push({uuid: md5(cell.uuid + form.uuid), type: 'popSource', ...msg})
             }
           })
         }
@@ -3414,7 +3393,9 @@
           })
         }
 
-        filterComponent(cell.config.components, _mainSearch, '-' + cell.label, true)
+        let label = (item.name ? '-' + item.name : '') + '-' + cell.label
+
+        filterComponent(cell.config.components, _mainSearch, label, true)
       }
     }
   }
@@ -3823,24 +3804,26 @@
           let _val2 = ''
   
           arr.push(_key)
-          if (_key === 'bid') { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
+          if (_key === 'bid') {
             _val = BID
           } else {
-            _val = `'@mk_${_key}_mk@'`
+            // _val = `'@mk_${_key}_mk@'`
+            _val = `@${_field}`
           }
 
           _fieldValue.push(`${_key}=${_val}`)
 
-          if (_key === 'bid') { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
+          if (_key === 'bid') {
             _val2 = `' + ${BID} + '`
           } else {
-            _val2 = `@mk_${_key}_mk@`
+            // _val2 = `@mk_${_key}_mk@`
+            _val2 = `' + @${_field} + '`
           }
 
           _value.push(`${_labels[index] || ''}锛�${_val2}`)
         })
   
-        if (!arr.includes(primaryKey.toLowerCase())) {
+        if (!arr.includes(primaryKey.toLowerCase()) && btn.Ot !== 'notRequired') {
           _fieldValue.push(`${primaryKey} !=${primaryId}`)
         }
   
@@ -6450,5 +6433,32 @@
 
   filterComponent(config.components, _mainSearch)
 
+  let keys = sqls.map(item => item.uuid)
+  if (keys.length > Array.from(new Set(keys)).length && !window.GLOB.syscheck) {
+    if (window.backend) {
+      let m = new Map()
+      let n = new Map()
+      sqls.forEach(item => {
+        if (m.has(item.uuid)) {
+          if (!n.has(item.uuid)) {
+            window.mkInfo(m.get(item.uuid))
+            n.set(item.uuid, true)
+          }
+          window.mkInfo(item)
+        } else {
+          m.set(item.uuid, item)
+        }
+      })
+  
+      notification.warning({
+        top: 92,
+        message: '瀛樺湪閲嶅鐨勫悗绔剼鏈琁D锛�',
+        duration: 5
+      })
+    }
+
+    return []
+  }
+
   return sqls
 }
\ No newline at end of file
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 0235f91..94e75c9 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -2176,18 +2176,27 @@
 
       item.field.split(',').forEach((_field, index) => {
         let _key = _field.toLowerCase()
-        let _val = datavars[_key] !== undefined ? datavars[_key] : ''
+        let _val = ''
+        let _val2 = ''
 
         arr.push(_key)
-        if (_key === 'bid' && !_val) { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
+        if (_key === 'bid') {
           _val = BID
+        } else {
+          _val = `@${_field}`
         }
-
-        _fieldValue.push(`${_key}='${_val}'`)
-        _value.push(`${_labels[index] || ''}锛�${_val || ''}`)
+        
+        if (_key === 'bid') {
+          _val2 = `' + ${BID} + '`
+        } else {
+          _val2 = `' + @${_field} + '`
+        }
+        
+        _fieldValue.push(`${_key}=${_val}`)
+        _value.push(`${_labels[index] || ''}锛�${_val2}`)
       })
 
-      if (!arr.includes(primaryKey.toLowerCase())) {
+      if (!arr.includes(primaryKey.toLowerCase()) && btn.Ot !== 'notRequired') {
         _fieldValue.push(`${primaryKey} !='${primaryId}'`)
       }
 
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index dab7a68..b15aa97 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -1616,6 +1616,7 @@
       }
 
       let subMenus = this.getSubMenus()
+      subMenus = subMenus.filter(item => item.MenuID !== config.uuid)
       let menus_used_list = subMenus.map(m => `'${config.uuid}','${config.MenuName || ''}','${config.MenuNo || ''}','${m.MenuID}','${m.MenuName}'`).join(';')
       menus_used_list = window.btoa(window.encodeURIComponent(menus_used_list || 'del'))
 
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index d3a7101..f4dd5f0 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -1263,6 +1263,7 @@
       let roleParam = this.getMenuMessage(tbs)
 
       let subMenus = this.getSubMenus()
+      subMenus = subMenus.filter(item => item.MenuID !== config.uuid)
       let menus_used_list = subMenus.map(m => `'${config.uuid}','${config.MenuName || ''}','${config.MenuNo || ''}','${m.MenuID}','${m.MenuName}'`).join(';')
       menus_used_list = window.btoa(window.encodeURIComponent(menus_used_list || 'del'))
 
diff --git a/src/views/rolemanage/filtermenu/index.jsx b/src/views/rolemanage/filtermenu/index.jsx
new file mode 100644
index 0000000..788a7d7
--- /dev/null
+++ b/src/views/rolemanage/filtermenu/index.jsx
@@ -0,0 +1,523 @@
+import React, { Component } from 'react'
+import { Button, notification, Modal, Table } from 'antd'
+import moment from 'moment'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
+
+// import './index.scss'
+
+const { confirm } = Modal
+
+class AppMenuFilter extends Component {
+  state = {
+    visible: false,
+    loading: false,
+    unUseMenus: [],
+    selectedRowKeys: [],
+    columns: [
+      {
+        title: '鑿滃崟鍚嶇О', dataIndex: 'MenuName', key: 'MenuName', align: 'center'
+      },
+      {
+        title: '鑿滃崟鍙傛暟', dataIndex: 'MenuNo', key: 'MenuNo', align: 'center'
+      },
+      {
+        title: '淇敼鏃堕棿', dataIndex: 'modifydate', key: 'modifydate', align: 'center'
+      },
+      {
+        title: '鎿嶄綔',
+        key: 'action',
+        align: 'center',
+        render: (text, record) => (
+          <Button type="link" onClick={() => this.jumpApp(record)} style={{color: '#1890ff', marginLeft: '5px'}}>鏌ョ湅</Button>
+        ),
+      },
+    ]
+  }
+
+  menus = []
+  unchecks = []
+  allmenus = []
+
+  trigger = () => {
+    this.menus = []
+    this.unchecks = []
+    this.allmenus = []
+
+    this.setState({
+      visible: true,
+      loading: true,
+      unUseMenus: [],
+      selectedRowKeys: []
+    })
+
+    this.getAppViewList()
+  }
+
+  jumpApp = (item) => {
+    const { app } = this.props
+
+    let route = 'mobdesign'
+    if (app.typename === 'pc') {
+      route = 'pcdesign'
+    }
+
+    if (item.menus_rolelist) {
+      item.type = 'view'
+      try {
+        let pageParam = JSON.parse(window.decodeURIComponent(window.atob(item.menus_rolelist)))
+        if (pageParam.type === 'navbar') {
+          item.type = 'navbar'
+        }
+      } catch(e) {
+
+      }
+    }
+
+    if (item.type === 'navbar') {
+      notification.warning({
+        top: 92,
+        message: '瀵艰埅鏍忎笉鍙崟鐙墦寮�锛岃鍦ㄥ惈鏈夊鑸爮鐨勯〉闈腑鏌ョ湅銆�',
+        duration: 5
+      })
+      return
+    }
+
+    window.open(window.location.href.replace(/#.+/ig, `#/${route}/${window.btoa(window.encodeURIComponent(JSON.stringify({...app, MenuID: item.MenuID, type: 'app'})))}`))
+  }
+
+  getAppViewList = () => {
+    const { app } = this.props
+
+    Api.getCloudConfig({
+      func: 's_get_keyids',
+      bid: app.ID
+    }).then(result => {
+      if (!result.status) {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+        return
+      }
+
+      let indexPage = ''
+
+      result.data.forEach(item => {
+        if (item.keys_type === 'index') {
+          indexPage = item.keys_id
+        }
+      })
+      
+      if (!indexPage) {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: '搴旂敤鏈缃椤碉紒',
+          duration: 5
+        })
+        return
+      }
+
+      this.unchecks.push(indexPage)
+
+      if (app.user_binding === 'true' && app.userbind && indexPage !== app.userbind) {
+        this.unchecks.push(app.userbind)
+      }
+
+      this.getMenuList()
+    })
+  }
+
+  getMenuList = () => {
+    const { app } = this.props
+
+    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)
+
+    Api.getCloudConfig(param).then(result => {
+      if (result.status) {
+        this.setState({
+          menulist: result.menus
+        })
+
+        this.allmenus = result.menus.map(item => item.MenuID)
+
+        if (result.menus.length === 0) {
+          this.setState({
+            loading: false
+          })
+          notification.warning({
+            top: 92,
+            message: '瀛愬簲鐢ㄨ彍鍗曚负绌猴紒',
+            duration: 5
+          })
+        } else if (result.menus.findIndex(item => item.MenuID === this.unchecks[0]) === -1) {
+          this.setState({
+            loading: false
+          })
+          notification.warning({
+            top: 92,
+            message: '璇疯缃簲鐢ㄩ椤碉紒',
+            duration: 5
+          })
+        } else {
+          this.getMenuParam()
+        }
+      } else {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  getMenuParam = () => {
+    const { app } = this.props
+    const { visible } = this.state
+
+    if (!visible) return
+
+    let MenuID = this.unchecks.shift()
+
+    let param = {
+      func: 'sPC_Get_LongParam',
+      MenuID: MenuID,
+      TypeCharOne: app.kei_no,
+      typename: app.typename,
+      lang: app.lang,
+    }
+
+    Api.getCloudConfig(param).then(result => {
+      if (result.status) {
+        let config = null
+
+        try {
+          config = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : null
+        } catch (e) {
+          console.warn('Parse Failure')
+          config = null
+        }
+
+        this.menus.push(MenuID)
+        if (config) {
+          let menus = []
+
+          if (config.type === 'navbar') {
+            config.menus.forEach(k => {
+              if (k.property === 'classify') {
+                k.sublist && k.sublist.forEach(m => {
+                  if (m.property === 'classify') {
+                    m.sublist && m.sublist.forEach(n => {
+                      if (n.property === 'menu') {
+                        menus.push(n.MenuID)
+                      } else if (n.property === 'linkmenu') {
+                        menus.push(n.linkMenuId)
+                      }
+                    })
+                  } else if (m.property === 'menu') {
+                    menus.push(m.MenuID)
+                  } else if (m.property === 'linkmenu') {
+                    menus.push(m.linkMenuId)
+                  }
+                })
+              } else if (k.property === 'menu') {
+                menus.push(k.MenuID)
+              } else if (k.property === 'linkmenu') {
+                menus.push(k.linkMenuId)
+              }
+            })
+          }
+          config.components && this.resetConfig(config.components, menus)
+
+          menus = Array.from(new Set(menus))
+
+          menus.forEach(n => {
+            if (this.allmenus.includes(n) && !this.menus.includes(n)) {
+              this.unchecks.push(n)
+            }
+          })
+        }
+
+        if (this.unchecks.length > 0) {
+          setTimeout(() => {
+            this.getMenuParam()
+          }, 200)
+        } else {
+          this.setState({
+            loading: false
+          })
+
+          this.getUseMenus()
+        }
+      } else {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  resetConfig = (components, menus) => {
+    components.forEach(item => {
+      if (item.subtype === 'tablecard') { // 鍏煎
+        item.type = 'card'
+      }
+
+      if (item.type === 'navbar') {
+        menus.push(item.uuid)
+      } else if (item.type === 'tabs') {
+        item.subtabs.forEach(tab => {
+          this.resetConfig(tab.components, menus)
+        })
+      } else if (item.type === 'group') {
+        this.resetConfig(item.components, menus)
+      } else if (item.type === 'menubar') {
+        item.subMenus.forEach(cell => {
+          if (cell.setting.type === 'linkmenu' && cell.setting.linkMenuId && typeof(cell.setting.linkMenuId) === 'string') {
+            menus.push(cell.setting.linkMenuId)
+          } else if (cell.setting.type === 'menu') {
+            menus.push(cell.uuid)
+          }
+        })
+      } else if (['card', 'carousel', 'timeline'].includes(item.type)) {
+        if (item.subtype === 'propcard') {
+          if (item.wrap.jump === 'menu' && item.wrap.menu) {
+            menus.push(item.wrap.menu)
+          }
+        }
+        item.subcards.forEach(card => {
+          if (card.setting.click === 'menu' && typeof(card.setting.menu) === 'string') {
+            menus.push(card.setting.menu)
+          } else if (card.setting.click === 'menus') {
+            card.menus && card.menus.forEach(n => {
+              if (n.menu && typeof(n.menu) === 'string') {
+                menus.push(n.menu)
+              }
+            })
+          }
+
+          card.elements && card.elements.forEach(cell => {
+            if (cell.eleType === 'button') {
+              if (cell.linkmenu && typeof(cell.linkmenu) === 'string') {
+                menus.push(cell.linkmenu)
+              } else if (cell.openmenu && typeof(cell.openmenu) === 'string') {
+                menus.push(cell.openmenu)
+              }
+            }
+          })
+          card.backElements && card.backElements.forEach(cell => {
+            if (cell.eleType === 'button') {
+              if (cell.linkmenu && typeof(cell.linkmenu) === 'string') {
+                menus.push(cell.linkmenu)
+              } else if (cell.openmenu && typeof(cell.openmenu) === 'string') {
+                menus.push(cell.openmenu)
+              }
+            }
+          })
+        })
+      } else if (item.type === 'balcony') {
+        item.elements && item.elements.forEach(cell => {
+          if (cell.eleType === 'button') {
+            if (cell.linkmenu && typeof(cell.linkmenu) === 'string') {
+              menus.push(cell.linkmenu)
+            } else if (cell.openmenu && typeof(cell.openmenu) === 'string') {
+              menus.push(cell.openmenu)
+            }
+          }
+        })
+      } else if (item.type === 'table') {
+        let loopCol = (cols) => {
+          cols.forEach(col => {
+            if (col.type === 'action') {
+              col.type = 'custom'
+            }
+
+            if (col.type === 'colspan' && col.subcols) {
+              loopCol(col.subcols)
+            } else if (col.type === 'custom') {
+              col.elements && col.elements.forEach(cell => {
+                if (cell.eleType === 'button') {
+                  if (cell.linkmenu && typeof(cell.linkmenu) === 'string') {
+                    menus.push(cell.linkmenu)
+                  } else if (cell.openmenu && typeof(cell.openmenu) === 'string') {
+                    menus.push(cell.openmenu)
+                  }
+                }
+              })
+            }
+          })
+        }
+
+        item.cols && loopCol(item.cols)
+      } else if (item.type === 'form') {
+        item.subcards.forEach(cell => {
+          if (cell.subButton && cell.subButton.linkmenu && typeof(cell.subButton.linkmenu) === 'string') {
+            menus.push(cell.subButton.linkmenu)
+          }
+        })
+      } else if (item.type === 'login') {
+        if (item.wrap.linkmenu && typeof(item.wrap.linkmenu) === 'string') {
+          menus.push(item.wrap.linkmenu)
+        }
+      } else if (item.type === 'topbar') {
+        if (item.wrap.linkmenu && typeof(item.wrap.linkmenu) === 'string') {
+          menus.push(item.wrap.linkmenu)
+        }
+        
+        item.wrap.menus && item.wrap.menus.forEach(cell => {
+          if (cell.menu && typeof(cell.menu) === 'string') {
+            menus.push(cell.menu)
+          }
+        })
+      }
+  
+      item.action && item.action.forEach(cell => {
+        if (cell.linkmenu && typeof(cell.linkmenu) === 'string') {
+          menus.push(cell.linkmenu)
+        } else if (cell.openmenu && typeof(cell.openmenu) === 'string') {
+          menus.push(cell.openmenu)
+        }
+      })
+    })
+  }
+
+  getUseMenus = () => {
+    const { menulist } = this.state
+
+    let unmenus = []
+
+    menulist.forEach(m => {
+      if (!this.menus.includes(m.MenuID)) {
+        unmenus.push(m)
+      }
+    })
+
+    this.setState({
+      unUseMenus: unmenus
+    })
+  }
+
+  deletemenu = () => {
+    const { app, getMenuList } = this.props
+    const { selectedRowKeys, unUseMenus, loading } = this.state
+
+    if (loading) {
+      notification.warning({
+        top: 92,
+        message: '鑿滃崟瑙f瀽涓紝璇风◢鍚庯紒',
+        duration: 5
+      })
+      return
+    }
+
+    if (unUseMenus.length === 0) {
+      this.setState({visible: false})
+    } else if (selectedRowKeys.length === 0) {
+      notification.warning({
+        top: 92,
+        message: '璇烽�夋嫨闇�瑕佸垹闄ょ殑鑿滃崟锛�',
+        duration: 5
+      })
+    } else {
+      let param = {
+        func: 'sPC_MainMenu_Del',
+        MenuID: selectedRowKeys.join(','),
+        TypeCharOne: app.kei_no,
+        typename: app.typename,
+        lang: app.lang
+      }
+
+      const that = this
+
+      confirm({
+        content: '纭畾鍒犻櫎鑿滃崟鍚楋紵',
+        onOk() {
+          return new Promise(resolve => {
+            Api.getCloudConfig(param).then(result => {
+              if (result.status) {
+                notification.success({
+                  top: 92,
+                  message: '鍒犻櫎鎴愬姛锛�',
+                  duration: 3
+                })
+
+                that.setState({visible: false})
+                getMenuList()
+              } else {
+                notification.warning({
+                  top: 92,
+                  message: result.message,
+                  duration: 5
+                })
+              }
+              resolve()
+            }, () => {
+              resolve()
+            })
+          })
+        },
+        onCancel() {}
+      })
+    }
+  }
+
+  render () {
+    const { visible, loading, columns, unUseMenus, selectedRowKeys } = this.state
+
+    return (
+      <>
+        <Button className="mk-orange" onClick={this.trigger}>杩囨护鑿滃崟</Button>
+        <Modal
+          title="杩囨护鑿滃崟"
+          visible={visible}
+          width={800}
+          onOk={this.deletemenu}
+          onCancel={() => this.setState({visible: false, loading: false})}
+          destroyOnClose
+        >
+          <div style={{fontSize: '16px', position: 'relative', top: '-15px', color: '#1890ff'}}>绯荤粺灏嗚嚜鍔ㄨ繃婊ゆ棤鍏宠仈鍏崇郴鐨勮彍鍗曪紝閫夋嫨闇�瑕佸垹闄ょ殑鑿滃崟锛岀偣鍑荤‘瀹氥��</div>
+          <Table
+            rowKey="MenuID"
+            columns={columns}
+            dataSource={unUseMenus}
+            loading={loading}
+            rowSelection={{
+              selectedRowKeys,
+              type: 'checkbox',
+              onChange: (keys) => this.setState({ selectedRowKeys: keys })
+            }}
+            pagination={false}
+          />
+        </Modal>
+      </>
+    )
+  }
+}
+
+export default AppMenuFilter
\ No newline at end of file
diff --git a/src/views/rolemanage/filtermenu/index.scss b/src/views/rolemanage/filtermenu/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/views/rolemanage/filtermenu/index.scss
diff --git a/src/views/rolemanage/index.jsx b/src/views/rolemanage/index.jsx
index 736c83f..7484a51 100644
--- a/src/views/rolemanage/index.jsx
+++ b/src/views/rolemanage/index.jsx
@@ -15,6 +15,7 @@
 const { Search } = Input
 
 const Header = asyncComponent(() => import('./header'))
+const FilterMenu = asyncComponent(() => import('./filtermenu'))
 const TransferForm = asyncComponent(() => import('@/templates/zshare/basetransferform'))
 
 class RoleManage extends Component {
@@ -925,6 +926,7 @@
             <div className="app-table">
               <div className="app-action">
                 <Button className="mk-green" onClick={this.triggerThaw}>瑙e喕鑿滃崟</Button>
+                <FilterMenu app={app} getMenuList={this.getMenuList}/>
                 <Search placeholder="缁煎悎鎼滅储" onSearch={value => this.setState({ searchkey: value })} enterButton />
               </div>
               <Table
diff --git a/src/views/syscheck/header/index.jsx b/src/views/syscheck/header/index.jsx
new file mode 100644
index 0000000..85789be
--- /dev/null
+++ b/src/views/syscheck/header/index.jsx
@@ -0,0 +1,34 @@
+import React, { Component } from 'react'
+
+import avatar from '@/assets/img/avatar.jpg'
+import MainLogo from '@/assets/img/main-logo.png'
+import './index.scss'
+
+class SysCheckHeader extends Component {
+  state = {
+    avatar: sessionStorage.getItem('CloudAvatar') || avatar,
+    userName: sessionStorage.getItem('CloudUserName'),
+    logo: sessionStorage.getItem('CloudLogo') || MainLogo
+  }
+
+  render () {
+    const { logo } = this.state
+
+    return (
+      <header className="sys-header-container">
+        <div className="header-logo"><img src={logo} 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 SysCheckHeader
\ No newline at end of file
diff --git a/src/views/syscheck/header/index.scss b/src/views/syscheck/header/index.scss
new file mode 100644
index 0000000..9c8a6aa
--- /dev/null
+++ b/src/views/syscheck/header/index.scss
@@ -0,0 +1,57 @@
+.sys-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/syscheck/index.jsx b/src/views/syscheck/index.jsx
new file mode 100644
index 0000000..d1fa395
--- /dev/null
+++ b/src/views/syscheck/index.jsx
@@ -0,0 +1,513 @@
+import React, {Component} from 'react'
+import { fromJS } from 'immutable'
+import { Spin, notification, Button, Modal } from 'antd'
+import moment from 'moment'
+import { SwapOutlined } from '@ant-design/icons'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
+import asyncComponent from '@/utils/asyncComponent'
+import { getAllSqls } from '@/utils/utils-custom.js'
+import './index.scss'
+
+const Header = asyncComponent(() => import('./header'))
+const { confirm } = Modal
+
+class SysCheck extends Component {
+  state = {
+    stop: false,
+    loading: false,
+    menulist: [],
+    activeMenu: null,
+    remain: 0,
+    lackmenus: [],
+    outmenus: [],
+    backmenus: [],
+    appbackmenus: [],
+    unablemenus: [],
+  }
+
+  sqlmap = null
+
+  // delete _val.controlField 鍒犻櫎鎸夐挳鎺у埗瀛楁
+
+  UNSAFE_componentWillMount() {
+    document.body.className = ''
+    window.GLOB.syscheck = true
+  }
+
+  componentDidMount() {
+    if (!sessionStorage.getItem('UserID')) {
+      this.props.history.replace('/login')
+      return
+    }
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  getMenus = () => {
+    this.setState({
+      stop: false,
+      activeMenu: null,
+      remain: 0,
+      menulist: [],
+      lackmenus: [],
+      outmenus: [],
+      backmenus: [],
+      appbackmenus: [],
+      unablemenus: [],
+      loading: true
+    })
+    Api.getCloudConfig({func: 's_get_pc_menus', systemType: window.GLOB.sysType, debug: 'Y'}).then(result => {
+      if (result.status) {
+        let menulist = []
+        result.fst_menu.forEach(fst => {
+          if (fst.snd_menu) {
+            fst.snd_menu.forEach(snd => {
+              if (snd.trd_menu) {
+                snd.trd_menu.forEach(trd => {
+                  if (trd.PageParam) {
+                    let pass = false
+                    try {
+                      let PageParam = JSON.parse(trd.PageParam)
+                      if (PageParam && PageParam.Template === 'RolePermission') {
+                        pass = true
+                      }
+                    } catch (e) {
+
+                    }
+                    if (pass) return
+                  }
+
+                  menulist.push({
+                    MenuID: trd.MenuID,
+                    MenuName: trd.MenuName,
+                    MenuNo: trd.MenuNo,
+                    pName: fst.MenuName + '-' + snd.MenuName,
+                  })
+                })
+              }
+            })
+          }
+        })
+
+        if (menulist.length === 0) {
+          this.setState({
+            loading: false
+          })
+          notification.warning({
+            top: 92,
+            message: '鏈煡璇㈠埌鑿滃崟淇℃伅锛�',
+            duration: 5
+          })
+        } else {
+          this.sqlmap = new Map()
+
+          let errlist = sessionStorage.getItem('syscheck_main')
+          errlist = errlist ? JSON.parse(errlist) : null
+
+          if (!errlist) {
+            this.setState({
+              menulist
+            })
+            this.getMenuParam(fromJS(menulist).toJS())
+          } else {
+            const that = this
+            confirm({
+              title: '鏄惁璺宠繃妫�鏌ュ悎鏍艰彍鍗曪紵',
+              content: '',
+              okText: '璺宠繃',
+              cancelText: '涓嶈烦杩�',
+              onOk() {
+                menulist = menulist.filter(item => errlist.includes(item.MenuID))
+
+                that.setState({
+                  menulist
+                })
+                that.getMenuParam(fromJS(menulist).toJS())
+              },
+              onCancel() {
+                that.setState({
+                  menulist
+                })
+                that.getMenuParam(fromJS(menulist).toJS())
+              }
+            })
+          }
+        }
+      } else {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  getAppList = () => {
+    let param = {
+      func: 's_get_kei'
+    }
+
+    this.setState({
+      stop: false,
+      activeMenu: null,
+      remain: 0,
+      menulist: [],
+      lackmenus: [],
+      outmenus: [],
+      backmenus: [],
+      appbackmenus: [],
+      unablemenus: [],
+      loading: true
+    })
+
+    Api.getCloudConfig(param).then(result => {
+      if (result.status) {
+        let applist = []
+        result.data.forEach(item => {
+          if (!item.data_detail) return
+          item.data_detail.forEach(cell => {
+            applist.push({
+              ID: cell.d_id,
+              name: item.remark,
+              typename: cell.typename,
+              kei_no: item.kei_no,
+              lang: cell.lang,
+              menus: []
+            })
+          })
+        })
+
+        if (applist.length === 0) {
+          this.setState({
+            loading: false
+          })
+          notification.warning({
+            top: 92,
+            message: '鏈煡璇㈠埌鑿滃崟淇℃伅锛�',
+            duration: 5
+          })
+        } else {
+          let deffers = applist.map((app, i) =>
+            new Promise(resolve => {
+              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)
+
+              setTimeout(() => {
+                Api.getCloudConfig(param).then(result => {
+                  if (result.status) {
+                    app.status = true
+                    app.menus = []
+
+                    result.menus.forEach(m => {
+                      if (m.menus_rolelist) {
+                        try {
+                          let pageParam = JSON.parse(window.decodeURIComponent(window.atob(m.menus_rolelist)))
+                          if (pageParam.type === 'navbar') {
+                            m.type = pageParam.type
+                          }
+                        } catch(e) {
+
+                        }
+                        if (m.type === 'navbar') return
+                      }
+                      delete m.menus_rolelist
+                      
+                      app.menus.push(m)
+                    })
+                    resolve(app)
+                  } else {
+                    resolve(result)
+                  }
+                })
+              }, 200 * i)
+            })
+          )
+
+          Promise.all(deffers).then(response => {
+            let error = response.filter(cell => !cell.status)
+            if (error[0]) {
+              notification.warning({
+                top: 92,
+                message: error[0].message,
+                duration: 5
+              })
+              this.setState({
+                loading: false
+              })
+            } else {
+              let list = []
+              response.forEach(item => {
+                item.menus.forEach(cell => {
+                  list.push({
+                    ...cell,
+                    lang: item.lang,
+                    kei_no: item.kei_no,
+                    typename: item.typename,
+                    pName: `${item.name}锛�${item.typename} / ${item.lang}锛塦,
+                  })
+                })
+              })
+
+              if (list.length === 0) {
+                this.setState({
+                  loading: false
+                })
+                notification.warning({
+                  top: 92,
+                  message: '鏈煡璇㈠埌鑿滃崟淇℃伅锛�',
+                  duration: 5
+                })
+              } else {
+                this.sqlmap = new Map()
+                
+                let errlist = sessionStorage.getItem('syscheck_app')
+                errlist = errlist ? JSON.parse(errlist) : null
+
+                if (!errlist) {
+                  this.setState({
+                    menulist: list
+                  })
+                  this.getMenuParam(fromJS(list).toJS())
+                } else {
+                  const that = this
+                  confirm({
+                    title: '鏄惁璺宠繃妫�鏌ュ悎鏍艰彍鍗曪紵',
+                    content: '',
+                    okText: '璺宠繃',
+                    cancelText: '涓嶈烦杩�',
+                    onOk() {
+                      list = list.filter(item => errlist.includes(item.MenuID))
+                      
+                      that.setState({
+                        menulist: list
+                      })
+                      that.getMenuParam(fromJS(list).toJS())
+                    },
+                    onCancel() {
+                      that.setState({
+                        menulist: list
+                      })
+                      that.getMenuParam(fromJS(list).toJS())
+                    }
+                  })
+                }
+              }
+            }
+          })
+        }
+      } else {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  getMenuParam = (menus) => {
+    const { lackmenus, outmenus, unablemenus, backmenus, appbackmenus, stop } = this.state
+
+    let menu = menus.shift()
+
+    let param = {
+      func: 'sPC_Get_LongParam',
+      MenuID: menu.MenuID
+    }
+
+    if (menu.kei_no) {
+      param.TypeCharOne = menu.kei_no
+      param.typename = menu.typename
+      param.lang = menu.lang
+    }
+
+    this.setState({
+      activeMenu: menu,
+      remain: menus.length
+    })
+
+    Api.getCloudConfig(param).then(result => {
+      if (result.status) {
+        let config = null
+
+        try {
+          config = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : null
+        } catch (e) {
+          console.warn('Parse Failure')
+          config = null
+        }
+
+        if (!config) {
+          this.setState({lackmenus: [...lackmenus, menu]})
+        } else if (!menu.kei_no && !['CustomPage', 'BaseTable'].includes(config.Template)) {
+          this.setState({outmenus: [...outmenus, menu]})
+        } else if (!menu.kei_no && config.Template === 'CustomPage' && config.version !== 2.0) {
+          menu.version = config.version
+          this.setState({outmenus: [...outmenus, menu]})
+        } else if (!config.enabled) {
+          this.setState({unablemenus: [...unablemenus, menu]})
+        } else {
+          let sqls = getAllSqls(config)
+          let keys = sqls.map(item => item.uuid)
+
+          if (keys.length > Array.from(new Set(keys)).length) {
+            this.setState({backmenus: [...backmenus, menu]})
+          } else {
+            let repeat = false
+            let premenu = null
+            sqls.forEach(item => {
+              if (this.sqlmap.has(item.uuid)) {
+                window.mkInfo(item)
+                if (repeat) return
+                repeat = true
+                premenu = this.sqlmap.get(item.uuid)
+              } else {
+                this.sqlmap.set(item.uuid, menu)
+              }
+            })
+            if (premenu) {
+              this.setState({appbackmenus: [...appbackmenus, [premenu, menu]]})
+            }
+          }
+        }
+
+        if (menus.length > 0 && !stop) {
+          setTimeout(() => {
+            this.getMenuParam(menus)
+          }, 200)
+        } else {
+          this.setState({
+            loading: false
+          }, () => {
+            this.record(menu.kei_no ? 'app' : '')
+          })
+        }
+      } else {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  record = (type) => {
+    const { lackmenus, outmenus, unablemenus, backmenus, appbackmenus } = this.state
+
+    let menus = []
+
+    lackmenus.forEach(item => {
+      menus.push(item.MenuID)
+    })
+    outmenus.forEach(item => {
+      menus.push(item.MenuID)
+    })
+    unablemenus.forEach(item => {
+      menus.push(item.MenuID)
+    })
+    backmenus.forEach(item => {
+      menus.push(item.MenuID)
+    })
+    appbackmenus.forEach(item => {
+      menus.push(item[0].MenuID)
+      menus.push(item[1].MenuID)
+    })
+
+    menus = Array.from(new Set(menus))
+
+    if (type === 'app') {
+      if (menus.length) {
+        sessionStorage.setItem('syscheck_app', JSON.stringify(menus))
+      } else {
+        sessionStorage.removeItem('syscheck_app')
+      }
+    } else {
+      if (menus.length) {
+        sessionStorage.setItem('syscheck_main', JSON.stringify(menus))
+      } else {
+        sessionStorage.removeItem('syscheck_main')
+      }
+    }
+  }
+
+  render () {
+    const { loading, activeMenu, menulist, remain, lackmenus, outmenus, unablemenus, backmenus, appbackmenus } = this.state
+
+    if (!sessionStorage.getItem('UserID')) return null
+
+    return (
+      <div className="mk-app-check">
+        <Header view="manage" />
+        {loading ? <Spin size="large" /> : null}
+        <div className="view-wrap">
+          <div className="action">
+            <Button disabled={loading} style={{marginRight: '15px'}} onClick={this.getMenus}>妫�鏌ョ鐞嗙郴缁熻彍鍗�</Button>
+            <Button disabled={loading} style={{marginRight: '15px'}} onClick={this.getAppList}>妫�鏌ュ瓙搴旂敤鑿滃崟</Button>
+            <Button onClick={() => this.setState({stop: true})}>鍋滄</Button>
+          </div>
+          {activeMenu ? <div className="menu-msg">褰撳墠鑿滃崟锛歿activeMenu.MenuName} <span></span> {activeMenu.pName} <span></span> 杩涘害锛坽menulist.length - remain} / {menulist.length}锛�</div> : null}
+          {lackmenus.length ? <div className="item-wrap">
+            <div className="title">鑿滃崟閰嶇疆涓嶅瓨鍦�</div>
+            {lackmenus.map((item, i) => {
+              return <div key={i}>{item.MenuName} <span></span> {item.pName}</div>
+            })}
+          </div> : null}
+          {outmenus.length ? <div className="item-wrap">
+            <div className="title">鑿滃崟閰嶇疆闇�瑕佸崌绾�</div>
+            {outmenus.map((item, i) => {
+              return <div key={i}>{item.MenuName} <span></span> {item.pName}</div>
+            })}
+          </div> : null}
+          {unablemenus.length ? <div className="item-wrap">
+            <div className="title">鑿滃崟鏈惎鐢�</div>
+            {unablemenus.map((item, i) => {
+              return <div key={i}>{item.MenuName} <span></span> {item.pName}</div>
+            })}
+          </div> : null}
+          {backmenus.length ? <div className="item-wrap">
+            <div className="title">鑿滃崟鍚庣鑴氭湰ID閲嶅</div>
+            {backmenus.map((item, i) => {
+              return <div key={i}>{item.MenuName} <span></span> {item.pName}</div>
+            })}
+          </div> : null}
+          {appbackmenus.length ? <div className="item-wrap">
+            <div className="title">鑿滃崟鍚庣鑴氭湰ID閲嶅锛堣彍鍗曢棿锛�</div>
+            {appbackmenus.map((item, i) => {
+              return <div key={i}>{item[0].MenuName} <span></span> {item[0].pName} <SwapOutlined /> {item[1].MenuName} <span></span> {item[1].pName}</div>
+            })}
+          </div> : null}
+        </div>
+      </div>
+    )
+  }
+}
+
+export default SysCheck
\ No newline at end of file
diff --git a/src/views/syscheck/index.scss b/src/views/syscheck/index.scss
new file mode 100644
index 0000000..d12dea7
--- /dev/null
+++ b/src/views/syscheck/index.scss
@@ -0,0 +1,52 @@
+.mk-app-check {
+  background: #fff;
+  min-height: 100vh;
+  padding: 70px 30px;
+
+  .ant-spin {
+    position: fixed;
+    z-index: 2;
+    left: calc(50% - 22px);
+    top: 50%;
+  }
+  .view-wrap {
+    width: 100%;
+    position: relative;
+
+    .action {
+      .ant-btn {
+        color: #fff!important;
+        background-color: #1890ff!important;
+        border-color: #1890ff!important;
+      }
+    }
+    .menu-msg {
+      margin-top: 15px;
+      color: #1890ff;
+      span {
+        display: inline-block;
+        width: 20px;
+        height: 15px;
+      }
+    }
+    .item-wrap {
+      width: 50%;
+      display: inline-block;
+      margin-top: 30px;
+      color: rgba(0, 0, 0, 0.85);
+      vertical-align: top;
+      .title {
+        color: #1890ff;
+        border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+        margin-bottom: 10px;
+        margin-right: 20px;
+        padding-bottom: 5px;
+      }
+      span {
+        display: inline-block;
+        width: 20px;
+        height: 15px;
+      }
+    }
+  }
+}

--
Gitblit v1.8.0