diff --git a/cmdb-ui/src/api/auth.js b/cmdb-ui/src/api/auth.js
index 4ac0a24..31aab7e 100644
--- a/cmdb-ui/src/api/auth.js
+++ b/cmdb-ui/src/api/auth.js
@@ -30,9 +30,9 @@ export function getAuthDataEnable() {
     })
 }
 
-export function testLDAP(test_type, data) {
+export function testLDAP(data) {
     return axios({
-        url: `/common-setting/v1/auth_config/LDAP/test?test_type=${test_type}`,
+        url: `/common-setting/v1/auth_config/LDAP/test`,
         method: 'post',
         data,
     })
diff --git a/cmdb-ui/src/assets/data_empty.png b/cmdb-ui/src/assets/data_empty.png
index a6529f8..562d85b 100644
Binary files a/cmdb-ui/src/assets/data_empty.png and b/cmdb-ui/src/assets/data_empty.png differ
diff --git a/cmdb-ui/src/components/CMDBFilterComp/expression.vue b/cmdb-ui/src/components/CMDBFilterComp/expression.vue
index 2b0fbef..5b43f41 100644
--- a/cmdb-ui/src/components/CMDBFilterComp/expression.vue
+++ b/cmdb-ui/src/components/CMDBFilterComp/expression.vue
@@ -178,7 +178,7 @@
       <div v-else :style="{ width: '175px' }"></div>
       <template v-if="!disabled">
         <a-tooltip :title="$t('copy')">
-          <a class="operation" @click="handleCopyRule(item)"><ops-icon type="icon-xianxing-copy"/></a>
+          <a class="operation" @click="handleCopyRule(item)"><ops-icon type="veops-copy"/></a>
         </a-tooltip>
         <a-tooltip :title="$t('delete')">
           <a class="operation" @click="handleDeleteRule(item)"><ops-icon type="icon-xianxing-delete"/></a>
diff --git a/cmdb-ui/src/components/CustomIconSelect/constants.js b/cmdb-ui/src/components/CustomIconSelect/constants.js
index cb49c52..9af14b9 100644
--- a/cmdb-ui/src/components/CustomIconSelect/constants.js
+++ b/cmdb-ui/src/components/CustomIconSelect/constants.js
@@ -759,6 +759,52 @@ export const multicolorIconList = [
       value: 'caise-redis',
       label: 'redis'
     }]
+  }, {
+    value: 'cloud',
+    label: '云',
+    list: [{
+      value: 'AWS',
+      label: 'AWS'
+    }, {
+      value: 'Azure',
+      label: 'Azure'
+    }, {
+      value: 'Google_Cloud_Platform',
+      label: 'Google Cloud Platform'
+    }, {
+      value: 'Alibaba_Cloud',
+      label: '阿里云'
+    }, {
+      value: 'Huawei_Cloud',
+      label: '华为云'
+    }, {
+      value: 'Tencent_Cloud',
+      label: '腾讯云'
+    }, {
+      value: 'UCloud',
+      label: 'UCloud'
+    }, {
+      value: 'Ctyun',
+      label: '天翼云'
+    }, {
+      value: 'ECloud',
+      label: '移动云'
+    }, {
+      value: 'JDCloud',
+      label: '京东云'
+    }, {
+      value: 'Bytecloud',
+      label: '字节云'
+    }, {
+      value: 'OpenStack',
+      label: 'OpenStack'
+    }, {
+      value: 'ZStack',
+      label: 'ZStack'
+    }, {
+      value: 'Nutanix',
+      label: 'Nutanix'
+    }]
   }, {
     value: 'system',
     label: '操作系统',
diff --git a/cmdb-ui/src/components/Menu/SideMenu.vue b/cmdb-ui/src/components/Menu/SideMenu.vue
index c05ef73..032bdf2 100644
--- a/cmdb-ui/src/components/Menu/SideMenu.vue
+++ b/cmdb-ui/src/components/Menu/SideMenu.vue
@@ -1,7 +1,7 @@
 <template>
   <a-layout-sider
     :class="['sider', isDesktop() ? null : 'shadow', theme, fixSiderbar ? 'ant-fixed-sidemenu' : null]"
-    width="200px"
+    width="220px"
     :collapsible="collapsible"
     v-model="collapsed"
     :trigger="null"
@@ -15,6 +15,7 @@
       @select="onSelect"
       style="padding: 16px 0px;"
     ></s-menu>
+    <!-- <OpsDocs :collapsed="collapsed" /> -->
   </a-layout-sider>
 </template>
 
@@ -22,10 +23,13 @@
 import Logo from '@/components/tools/Logo'
 import SMenu from './index'
 import { mixin, mixinDevice } from '@/utils/mixin'
+// import OpsDocs from '@/modules/docs/index.vue'
 
 export default {
   name: 'SideMenu',
-  components: { Logo, SMenu },
+  components: { Logo, SMenu,
+    // OpsDocs
+  },
   mixins: [mixin, mixinDevice],
   props: {
     mode: {
diff --git a/cmdb-ui/src/components/OpsTable/index.vue b/cmdb-ui/src/components/OpsTable/index.vue
index ee359c3..11fa56e 100644
--- a/cmdb-ui/src/components/OpsTable/index.vue
+++ b/cmdb-ui/src/components/OpsTable/index.vue
@@ -1,121 +1,49 @@
 <template>
-  <vxe-table v-bind="$attrs" v-on="new$listeners" ref="xTable">
-    <slot></slot>
-    <template #empty>
-      <slot name="empty">
-        <div :style="{ paddingTop: '10px' }">
-          <img :style="{ width: '100px', height: '90px' }" :src="require('@/assets/data_empty.png')" />
-          <div>{{ $t('noData') }}</div>
-        </div>
-      </slot>
-    </template>
-    <template #loading>
-      <slot name="loading"></slot>
-    </template>
-  </vxe-table>
+  <span>
+    <ops-icon :type="getPropertyIcon(attr)" />
+  </span>
 </template>
 
 <script>
-import _ from 'lodash'
-// 该组件使用方法与vxe-table一致,但调用它的方法时,需先调用getVxetableRef()获取到vxe-table实体
 export default {
-  name: 'OpsTable',
-  data() {
-    return {
-      // isShifting: false,
-      // lastIndex: -1,
-      lastSelected: [],
-      currentSelected: [],
-    }
-  },
-  computed: {
-    new$listeners() {
-      if (!Object.keys(this.$listeners).length) {
-        return this.$listeners
-      }
-      return Object.assign(this.$listeners, {
-        // 在这里覆盖原有的change事件
-        // 'checkbox-change': this.selectChangeEvent,
-        'checkbox-range-change': this.checkboxRangeChange,
-        'checkbox-range-start': this.checkboxRangeStart,
-        'checkbox-range-end': this.checkboxRangeEnd,
-      })
+  name: 'ValueTypeIcon',
+  props: {
+    attr: {
+      type: Object,
+      default: () => {},
     },
   },
-  mounted() {
-    // window.onkeydown = (e) => {
-    //   if (e.key === 'Shift') {
-    //     this.isShifting = true
-    //   }
-    // }
-    // window.onkeyup = (e) => {
-    //   if (e.key === 'Shift') {
-    //     this.isShifting = false
-    //     this.lastIndex = -1
-    //   }
-    // }
-  },
-  beforeDestroy() {
-    // window.onkeydown = ''
-    // window.onkeyup = ''
-  },
   methods: {
-    getVxetableRef() {
-      return this.$refs.xTable
-    },
-    // selectChangeEvent(e) {
-    //   const xTable = this.$refs.xTable
-    //   const { lastIndex } = this
-    //   const currentIndex = e.rowIndex
-    //   const { tableData } = xTable.getTableData()
-    //   if (lastIndex > -1 && this.isShifting) {
-    //     let start = lastIndex
-    //     let end = currentIndex
-    //     if (lastIndex > currentIndex) {
-    //       start = currentIndex
-    //       end = lastIndex
-    //     }
-    //     const rangeData = tableData.slice(start, end + 1)
-    //     xTable.setCheckboxRow(rangeData, true)
-    //   }
-    //   this.lastIndex = currentIndex
-    //   this.$emit('checkbox-change', { ...e, records: xTable.getCheckboxRecords() })
-    // },
-    checkboxRangeStart(e) {
-      const xTable = this.$refs.xTable
-      const lastSelected = xTable.getCheckboxRecords()
-      const selectedReserve = xTable.getCheckboxReserveRecords()
-      this.lastSelected = [...lastSelected, ...selectedReserve]
-      this.$emit('checkbox-range-start', e)
-    },
-    checkboxRangeChange(e) {
-      const xTable = this.$refs.xTable
-      xTable.setCheckboxRow(this.lastSelected, true)
-      this.currentSelected = e.records
-      // this.lastSelected = [...new Set([...this.lastSelected, ...e.records])]
-      this.$emit('checkbox-range-change', {
-        ...e,
-        records: [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()],
-      })
-    },
-    checkboxRangeEnd(e) {
-      const xTable = this.$refs.xTable
-      const isAllSelected = this.currentSelected.every((item) => {
-        const _idx = this.lastSelected.findIndex((ele) => _.isEqual(ele, item))
-        return _idx > -1
-      })
-      if (isAllSelected) {
-        xTable.setCheckboxRow(this.currentSelected, false)
+    getPropertyIcon(attr) {
+      switch (attr.value_type) {
+        case '0':
+          return 'duose-shishu'
+        case '1':
+          return 'duose-fudianshu'
+        case '2':
+          if (attr.is_password) {
+            return 'duose-password'
+          }
+          if (attr.is_link) {
+            return 'duose-link'
+          }
+          return 'duose-wenben'
+        case '3':
+          return 'duose-datetime'
+        case '4':
+          return 'duose-date'
+        case '5':
+          return 'duose-time'
+        case '6':
+          return 'duose-json'
+          case '7':
+            return 'duose-password'
+            case '8':
+            return 'duose-link'
       }
-      this.currentSelected = []
-      this.lastSelected = []
-      this.$emit('checkbox-range-end', {
-        ...e,
-        records: [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()],
-      })
     },
   },
 }
 </script>
 
-<style lang="less"></style>
+<style></style>
diff --git a/cmdb-ui/src/components/SplitPane/SplitPane.vue b/cmdb-ui/src/components/SplitPane/SplitPane.vue
index 8a7a21d..62a9a4e 100644
--- a/cmdb-ui/src/components/SplitPane/SplitPane.vue
+++ b/cmdb-ui/src/components/SplitPane/SplitPane.vue
@@ -64,7 +64,7 @@ export default {
     },
     triggerColor: {
       type: String,
-      default: '#f0f2f5',
+      default: '#f7f8fa',
     },
   },
   data() {
diff --git a/cmdb-ui/src/components/TwoColumnLayout/TwoColumnLayout.vue b/cmdb-ui/src/components/TwoColumnLayout/TwoColumnLayout.vue
index 351e83e..8dd4f9b 100644
--- a/cmdb-ui/src/components/TwoColumnLayout/TwoColumnLayout.vue
+++ b/cmdb-ui/src/components/TwoColumnLayout/TwoColumnLayout.vue
@@ -35,7 +35,7 @@ export default {
     },
     triggerColor: {
       type: String,
-      default: '#F0F5FF',
+      default: '#f7f8fa',
     },
   },
   data() {
@@ -52,22 +52,22 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .two-column-layout {
   margin-bottom: -24px;
   width: 100%;
   .two-column-layout-sidebar {
     height: 100%;
-    padding: 15px 7px;
     border-radius: 15px;
     overflow-y: auto;
-    background-color: #fff;
   }
   .two-column-layout-main {
     height: 100%;
     padding: 12px;
     background-color: #fff;
     overflow-y: auto;
-    border-radius: 15px;
+    border-radius: @border-radius-box;
   }
 }
 </style>
diff --git a/cmdb-ui/src/components/tools/TopMenu.vue b/cmdb-ui/src/components/tools/TopMenu.vue
index 52a66be..a84f580 100644
--- a/cmdb-ui/src/components/tools/TopMenu.vue
+++ b/cmdb-ui/src/components/tools/TopMenu.vue
@@ -11,9 +11,9 @@
       :key="route.name"
       @click="() => handleClick(route)"
     >
-      {{ route.meta.title }}
+      {{ $t(route.meta.title) }}
     </span>
-    <!-- <a-popover v-model="visible" placement="bottom" trigger="click" overlayClassName="top-menu-dropdown">
+    <a-popover v-model="visible" placement="bottom" trigger="click" overlayClassName="top-menu-dropdown">
       <template slot="content">
         <div class="title">
           更多应用
@@ -36,20 +36,31 @@
         </div>
       </template>
       <span class="top-menu-icon"><gridSvg /></span>
-    </a-popover> -->
+    </a-popover>
   </div>
 </template>
 
 <script>
 import store from '@/store'
 import { gridSvg, top_agent, top_acl } from '@/core/icons'
+import { getPreference } from '@/modules/cmdb/api/preference'
 export default {
   name: 'TopMenu',
   components: { gridSvg, top_agent, top_acl },
   data() {
     return {
-      defaultShowRouteName: ['cmdb', 'acl'],
-      defaultUnShowRouteName: [],
+      defaultShowRouteName: [
+        'dag',
+        'cmdb',
+        'itsm',
+        'ticket',
+        'monitor',
+        'calendar',
+        'datainsight',
+        'fullscreen',
+        'oneterm',
+      ],
+      defaultUnShowRouteName: ['acl', 'agent'],
       routes: store.getters.appRoutes.filter((i) => !(i.meta || {}).hiddenInTopMenu),
       current: store.getters.appRoutes[0].name,
       visible: false,
@@ -78,10 +89,20 @@ export default {
     this.current = this.$route.matched[0].name
   },
   methods: {
-    handleClick(route) {
+    async handleClick(route) {
       this.visible = false
       if (route.name !== this.current) {
-        this.$router.push(route.redirect)
+        if (route.name === 'cmdb') {
+          const preference = await getPreference()
+          const lastTypeId = window.localStorage.getItem('ops_ci_typeid') || undefined
+          if (lastTypeId && preference.some((item) => item.id === Number(lastTypeId))) {
+            this.$router.push(`/cmdb/instances/types/${lastTypeId}`)
+          } else {
+            this.$router.push('/cmdb/dashboard')
+          }
+        } else {
+          this.$router.push(route.redirect)
+        }
         // this.current = route.name
       }
     },
@@ -110,33 +131,21 @@ export default {
     line-height: @layout-header-icon-height;
     border-radius: 4px !important;
     display: inline-flex;
-    align-items: flex-end;
+    align-items: center;
   }
   > span {
     cursor: pointer;
     padding: 4px 10px;
     margin: 0 5px;
-    border-radius: 4px;
     color: @layout-header-font-color;
     height: @layout-header-height;
     display: inline-flex;
     align-items: center;
-    &:hover {
-      background: linear-gradient(0deg, rgba(0, 80, 201, 0.2) 0%, rgba(174, 207, 255, 0.06) 86.76%);
-      color: @layout-header-font-selected-color;
-      border-radius: 3px 3px 0px 0px;
-    }
   }
+  > span:hover,
   .top-menu-selected {
-    background: linear-gradient(0deg, rgba(0, 80, 201, 0.2) 0%, rgba(174, 207, 255, 0.06) 86.76%);
+    font-weight: bold;
     color: @layout-header-font-selected-color;
-    border-radius: 3px 3px 0px 0px;
-    border-bottom: 3px solid @layout-header-font-selected-color;
-    &:hover {
-      background: linear-gradient(0deg, rgba(0, 80, 201, 0.2) 0%, rgba(174, 207, 255, 0.06) 86.76%);
-      color: @layout-header-font-selected-color;
-      border-radius: 3px 3px 0px 0px;
-    }
   }
 }
 
diff --git a/cmdb-ui/src/layouts/BasicLayout.vue b/cmdb-ui/src/layouts/BasicLayout.vue
index 53fd34c..42b005e 100644
--- a/cmdb-ui/src/layouts/BasicLayout.vue
+++ b/cmdb-ui/src/layouts/BasicLayout.vue
@@ -87,21 +87,21 @@ export default {
   computed: {
     ...mapState({
       // 动态主路由
-      mainMenu: state => state.routes.appRoutes,
+      mainMenu: (state) => state.routes.appRoutes,
     }),
     contentPaddingLeft() {
       if (!this.fixSidebar || this.isMobile()) {
         return '0'
       }
       if (this.sidebarOpened) {
-        return '200px'
+        return '220px'
       }
       return '80px'
     },
     sideBarMenu() {
-      const sideMenus = this.mainMenu.filter(item => this.$route.path.startsWith(item.path))
+      const sideMenus = this.mainMenu.filter((item) => this.$route.path.startsWith(item.path))
       if (sideMenus.length > 1) {
-        return sideMenus.find(item => item.path !== '/').children
+        return sideMenus.find((item) => item.path !== '/').children
       } else {
         return sideMenus[0].children
       }
@@ -110,6 +110,9 @@ export default {
   provide() {
     return {
       reloadBoard: this.reload,
+      collapsed: () => {
+        return this.collapsed
+      },
     }
   },
   watch: {
@@ -146,15 +149,6 @@ export default {
         this.alive = true
       })
     },
-    paddingCalc() {
-      let left = ''
-      if (this.sidebarOpened) {
-        left = this.isDesktop() ? '200px' : '80px'
-      } else {
-        left = (this.isMobile() && '0') || (this.fixSidebar && '80px') || '0'
-      }
-      return left
-    },
     menuSelect() {
       if (!this.isDesktop()) {
         this.collapsed = false
diff --git a/cmdb-ui/src/modules/acl/views/history.vue b/cmdb-ui/src/modules/acl/views/history.vue
index be77b2e..386e50a 100644
--- a/cmdb-ui/src/modules/acl/views/history.vue
+++ b/cmdb-ui/src/modules/acl/views/history.vue
@@ -233,8 +233,10 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .acl-history {
-  border-radius: 15px;
+  border-radius: @border-radius-box;
   height: calc(100vh - 64px);
   margin-bottom: -24px;
   padding: 24px;
diff --git a/cmdb-ui/src/modules/acl/views/module/roleHistoryTable.vue b/cmdb-ui/src/modules/acl/views/module/roleHistoryTable.vue
index 8e7e10b..5d03ce0 100644
--- a/cmdb-ui/src/modules/acl/views/module/roleHistoryTable.vue
+++ b/cmdb-ui/src/modules/acl/views/module/roleHistoryTable.vue
@@ -290,7 +290,6 @@ export default {
                 const str = ` 【 ${key} : -> ${newVal} 】 `
                 item.description += str
               } else {
-                const str = ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
                 item.description += ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
               }
             }
diff --git a/cmdb-ui/src/modules/acl/views/module/triggerHistoryTable.vue b/cmdb-ui/src/modules/acl/views/module/triggerHistoryTable.vue
index 53a9fc6..644f61f 100644
--- a/cmdb-ui/src/modules/acl/views/module/triggerHistoryTable.vue
+++ b/cmdb-ui/src/modules/acl/views/module/triggerHistoryTable.vue
@@ -241,7 +241,6 @@ export default {
                 const str = ` 【 ${key} : -> ${newVal} 】 `
                 item.changeDescription += str
               } else {
-                const str = ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
                 item.changeDescription += ` 【 ${key} : ${oldVal} -> ${newVal} 】 `
               }
             }
diff --git a/cmdb-ui/src/modules/acl/views/operation_history/index.vue b/cmdb-ui/src/modules/acl/views/operation_history/index.vue
index 342a14c..4b6b4f2 100644
--- a/cmdb-ui/src/modules/acl/views/operation_history/index.vue
+++ b/cmdb-ui/src/modules/acl/views/operation_history/index.vue
@@ -32,8 +32,10 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .acl-operation-history {
-  border-radius: 15px;
+  border-radius: @border-radius-box;
   height: calc(100vh - 64px);
   margin-bottom: -24px;
   padding: 24px;
diff --git a/cmdb-ui/src/modules/acl/views/resource_types.vue b/cmdb-ui/src/modules/acl/views/resource_types.vue
index 15f0321..2fda663 100644
--- a/cmdb-ui/src/modules/acl/views/resource_types.vue
+++ b/cmdb-ui/src/modules/acl/views/resource_types.vue
@@ -189,8 +189,10 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .acl-resource-types {
-  border-radius: 15px;
+  border-radius: @border-radius-box;
   background-color: #fff;
   height: calc(100vh - 64px);
   margin-bottom: -24px;
diff --git a/cmdb-ui/src/modules/acl/views/resources.vue b/cmdb-ui/src/modules/acl/views/resources.vue
index 8ecd4fa..bf1a090 100644
--- a/cmdb-ui/src/modules/acl/views/resources.vue
+++ b/cmdb-ui/src/modules/acl/views/resources.vue
@@ -352,8 +352,10 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .acl-resources {
-  border-radius: 15px;
+  border-radius: @border-radius-box;
   background-color: #fff;
   height: calc(100vh - 64px);
   margin-bottom: -24px;
diff --git a/cmdb-ui/src/modules/acl/views/roles.vue b/cmdb-ui/src/modules/acl/views/roles.vue
index abf18f7..11ed56e 100644
--- a/cmdb-ui/src/modules/acl/views/roles.vue
+++ b/cmdb-ui/src/modules/acl/views/roles.vue
@@ -285,8 +285,10 @@ export default {
 </script>
 
 <style lang="less">
+@import '~@/style/static.less';
+
 .acl-roles {
-  border-radius: 15px;
+  border-radius: @border-radius-box;
   background-color: #fff;
   height: calc(100vh - 64px);
   margin-bottom: -24px;
diff --git a/cmdb-ui/src/modules/acl/views/secretKey.vue b/cmdb-ui/src/modules/acl/views/secretKey.vue
index 548ead3..3d6b622 100644
--- a/cmdb-ui/src/modules/acl/views/secretKey.vue
+++ b/cmdb-ui/src/modules/acl/views/secretKey.vue
@@ -88,10 +88,12 @@ export default {
 </script>
 
 <style lang="less">
+@import '~@/style/static.less';
+
 .acl-secret-key {
   background-color: #fff;
   padding: 24px;
-  border-radius: 15px;
+  border-radius: @border-radius-box;
   height: calc(100% + 24px);
   .ant-input[disabled] {
     color: rgba(0, 0, 0, 0.5);
diff --git a/cmdb-ui/src/modules/acl/views/trigger.vue b/cmdb-ui/src/modules/acl/views/trigger.vue
index 8724ff3..af5b698 100644
--- a/cmdb-ui/src/modules/acl/views/trigger.vue
+++ b/cmdb-ui/src/modules/acl/views/trigger.vue
@@ -320,8 +320,10 @@ export default {
 }
 </script>
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .acl-trigger {
-  border-radius: 15px;
+  border-radius: @border-radius-box;
   background-color: #fff;
   height: calc(100vh - 64px);
   margin-bottom: -24px;
diff --git a/cmdb-ui/src/modules/acl/views/users.vue b/cmdb-ui/src/modules/acl/views/users.vue
index 9e688af..f70baa3 100644
--- a/cmdb-ui/src/modules/acl/views/users.vue
+++ b/cmdb-ui/src/modules/acl/views/users.vue
@@ -188,8 +188,10 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .acl-users {
-  border-radius: 15px;
+  border-radius: @border-radius-box;
   background-color: #fff;
   height: calc(100vh - 64px);
   margin-bottom: -24px;
diff --git a/cmdb-ui/src/modules/cmdb/api/preference.js b/cmdb-ui/src/modules/cmdb/api/preference.js
index 4dcfc2b..10c7dd6 100644
--- a/cmdb-ui/src/modules/cmdb/api/preference.js
+++ b/cmdb-ui/src/modules/cmdb/api/preference.js
@@ -71,6 +71,14 @@ export function subscribeRelationView(payload) {
   })
 }
 
+export function putRelationView(id, data) {
+  return axios({
+    url: `/v0.1/preference/relation/view/${id}`,
+    method: 'put',
+    data
+  })
+}
+
 // 用户保存条件过滤选项
 export function getPreferenceSearch(payload) {
   // 参数有prv_id: 关系视图的id, ptv_id: 层级视图的id, type_id: 模型id
diff --git a/cmdb-ui/src/modules/cmdb/assets/unique_card.png b/cmdb-ui/src/modules/cmdb/assets/unique_card.png
new file mode 100644
index 0000000..124fba2
Binary files /dev/null and b/cmdb-ui/src/modules/cmdb/assets/unique_card.png differ
diff --git a/cmdb-ui/src/modules/cmdb/components/cmdbGrant/grantComp.vue b/cmdb-ui/src/modules/cmdb/components/cmdbGrant/grantComp.vue
index 848ebae..124fba2 100644
Binary files a/cmdb-ui/src/modules/cmdb/components/cmdbGrant/grantComp.vue and b/cmdb-ui/src/modules/cmdb/components/cmdbGrant/grantComp.vue differ
diff --git a/cmdb-ui/src/modules/cmdb/components/cmdbGrant/index.vue b/cmdb-ui/src/modules/cmdb/components/cmdbGrant/index.vue
index c279817..6f4c10c 100644
--- a/cmdb-ui/src/modules/cmdb/components/cmdbGrant/index.vue
+++ b/cmdb-ui/src/modules/cmdb/components/cmdbGrant/index.vue
@@ -1,5 +1,11 @@
 <template>
-  <a-modal width="800px" :visible="visible" @ok="handleOk" @cancel="handleCancel" :bodyStyle="{ padding: 0 }">
+  <a-modal
+    width="800px"
+    :visible="visible"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    :bodyStyle="{ padding: 0, paddingTop: '20px' }"
+  >
     <GrantComp
       :resourceType="resourceType"
       :app_id="app_id"
diff --git a/cmdb-ui/src/modules/cmdb/components/preferenceSearch/preferenceSearch.vue b/cmdb-ui/src/modules/cmdb/components/preferenceSearch/preferenceSearch.vue
index b1f439e..205fd99 100644
--- a/cmdb-ui/src/modules/cmdb/components/preferenceSearch/preferenceSearch.vue
+++ b/cmdb-ui/src/modules/cmdb/components/preferenceSearch/preferenceSearch.vue
@@ -11,7 +11,7 @@
         @blur="handleInputConfirm"
         @keyup.enter="handleInputConfirm"
       />
-      <a-button v-else type="primary" size="small" ghost @click="showInput">{{ $t('cmdb.components.saveQuery') }}</a-button>
+      <a v-else @click="showInput"> {{ $t('cmdb.components.saveQuery') }}</a>
     </span>
     <template v-for="(item, index) in preferenceSearchList.slice(0, 3)">
       <span
@@ -178,10 +178,10 @@ export default {
 <style lang="less" scoped>
 .preference-search-tag {
   cursor: pointer;
-  border-radius: 5px;
-  border: none;
+  border-radius: 2px;
+  border: 1px solid #d9d9d9;
   display: inline-block;
-  padding: 0 7px;
+  padding: 2px 7px;
   margin-right: 8px;
   > span {
     margin-right: 4px;
diff --git a/cmdb-ui/src/modules/cmdb/components/searchForm/SearchForm.vue b/cmdb-ui/src/modules/cmdb/components/searchForm/SearchForm.vue
index 9394345..c0545b9 100644
--- a/cmdb-ui/src/modules/cmdb/components/searchForm/SearchForm.vue
+++ b/cmdb-ui/src/modules/cmdb/components/searchForm/SearchForm.vue
@@ -5,8 +5,15 @@
         <a-space>
           <treeselect
             v-if="type === 'resourceSearch'"
-            class="custom-treeselect"
-            :style="{ width: '250px', marginRight: '10px', '--custom-height': '32px' }"
+            class="custom-treeselect custom-treeselect-bgcAndBorder"
+            :style="{
+              width: '200px',
+              marginRight: '10px',
+              '--custom-height': '32px',
+              '--custom-bg-color': '#fff',
+              '--custom-border': '1px solid #d9d9d9',
+              '--custom-multiple-lineHeight': '16px',
+            }"
             v-model="currenCiType"
             :multiple="true"
             :clearable="true"
@@ -41,15 +48,14 @@
           </treeselect>
           <a-input
             v-model="fuzzySearch"
-            :style="{ display: 'inline-block', width: '244px' }"
+            :style="{ display: 'inline-block', width: '200px' }"
             :placeholder="$t('cmdb.components.pleaseSearch')"
             @pressEnter="emitRefresh"
-            class="ops-input ops-input-radius"
           >
             <a-icon
               type="search"
               slot="suffix"
-              :style="{ color: fuzzySearch ? '#2f54eb' : '', cursor: 'pointer' }"
+              :style="{ color: fuzzySearch ? '#2f54eb' : '#d9d9d9', cursor: 'pointer' }"
               @click="emitRefresh"
             />
             <a-tooltip slot="prefix" placement="bottom" :overlayStyle="{ maxWidth: '550px', whiteSpace: 'pre-line' }">
@@ -59,6 +65,9 @@
               <a><a-icon type="question-circle"/></a>
             </a-tooltip>
           </a-input>
+          <a-tooltip :title="$t('reset')">
+            <a-button @click="reset">重置</a-button>
+          </a-tooltip>
           <FilterComp
             ref="filterComp"
             :canSearchPreferenceAttrList="canSearchPreferenceAttrList"
@@ -69,7 +78,7 @@
             <div slot="popover_item" class="search-form-bar-filter">
               <a-icon class="search-form-bar-filter-icon" type="filter" />
               {{ $t('cmdb.components.conditionFilter') }}
-              <a-icon class="search-form-bar-filter-icon" type="down" />
+              <a-icon class="search-form-bar-filter-icon" type="down" :style="{ color: '#d9d9d9' }" />
             </div>
           </FilterComp>
           <a-input
@@ -91,14 +100,13 @@
             :placeholder="placeholder"
             @keyup.enter="emitRefresh"
           >
-            <a-icon slot="suffix" type="copy" @click="handleCopyExpression" />
+            <ops-icon slot="suffix" type="veops-copy" @click="handleCopyExpression" />
           </a-input>
           <slot></slot>
         </a-space>
       </div>
       <a-space>
         <slot name="extraContent"></slot>
-        <a-button @click="reset" size="small">{{ $t('reset') }}</a-button>
         <a-tooltip :title="$t('cmdb.components.attributeDesc')" v-if="type === 'relationView'">
           <a
             @click="
@@ -237,7 +245,6 @@ export default {
       }
     },
     inputCiTypeGroup(value) {
-      console.log(value)
       if (!value || !value.length) {
         this.$emit('updateAllAttributesList', value)
       }
@@ -257,6 +264,7 @@ export default {
 }
 </script>
 <style lang="less">
+@import '~@/style/static.less';
 @import '../../views/index.less';
 .ci-searchform-expression {
   > input {
@@ -266,14 +274,14 @@ export default {
     border-right: none;
     &:hover,
     &:focus {
-      border-bottom: 2px solid #2f54eb;
+      border-bottom: 2px solid @primary-color;
     }
     &:focus {
       box-shadow: 0 2px 2px -2px #1f78d133;
     }
   }
   .ant-input-suffix {
-    color: #2f54eb;
+    color: #d9d9d9;
     cursor: pointer;
   }
 }
@@ -290,14 +298,15 @@ export default {
 @import '~@/style/static.less';
 
 .search-form-bar {
-  margin-bottom: 10px;
+  margin-bottom: 20px;
   display: flex;
   justify-content: space-between;
   align-items: center;
+  height: 32px;
   .search-form-bar-filter {
-    .ops_display_wrapper();
+    .ops_display_wrapper(transparent);
     .search-form-bar-filter-icon {
-      color: #custom_colors[color_1];
+      color: @primary-color;
       font-size: 12px;
     }
   }
diff --git a/cmdb-ui/src/modules/cmdb/lang/en.js b/cmdb-ui/src/modules/cmdb/lang/en.js
index 820ef4a..d7616a4 100644
--- a/cmdb-ui/src/modules/cmdb/lang/en.js
+++ b/cmdb-ui/src/modules/cmdb/lang/en.js
@@ -1,6 +1,7 @@
 const cmdb_en = {
     relation: 'Relation',
     attribute: 'Attributes',
+    configTable: 'Config Table',
     menu: {
         views: 'Views',
         config: 'Configuration',
@@ -182,7 +183,11 @@ const cmdb_en = {
         inheritType: 'Inherit Type',
         inheritTypePlaceholder: 'Please select inherit types',
         inheritFrom: 'inherit from {name}',
-        groupInheritFrom: 'Please go to the {name} for modification'
+        groupInheritFrom: 'Please go to the {name} for modification',
+        downloadType: 'Download CIType',
+        deleteCIType: 'Delete CIType',
+        otherGroupTips: 'Non sortable within the other group',
+        filterTips: 'click to show {name}'
     },
     components: {
         unselectAttributes: 'Unselected',
@@ -245,8 +250,10 @@ const cmdb_en = {
         unselectCIType: 'No CIType selected yet',
         pleaseUploadFile: 'Please upload files',
         batchUploadCanceled: 'Batch upload canceled',
-        selectCITypeTips: 'Please select CIType',
+        selectCIType: 'Select CIType',
+        selectCITypeTips: 'Please select a CIType and then download',
         downloadTemplate: 'Download Template',
+        clickDownload: 'Click to Download',
         drawTips: 'Click or drag files here to upload!',
         supportFileTypes: 'Supported file types: xls, xlsx',
         uploadResult: 'Upload results',
@@ -257,6 +264,16 @@ const cmdb_en = {
         errorTips: 'Error message',
         requestFailedTips: 'An error occurred with the request, please try again later',
         requestSuccessTips: 'Upload completed',
+        uploadFile: 'Upload File',
+        drawTips1: 'Please <span class="cmdb-batch-upload-tips">select a CIType</span>, and then <span class="cmdb-batch-upload-tips">download</span> ,',
+        drawTips2: '<span class="cmdb-batch-upload-tips">click or drag file</span> to upload',
+        dataPreview: 'Preview data and upload',
+        tips1: 'Kind Reminder :',
+        tips2: '1. Click to download the template, and users can customize the header of the template file, including model properties and model associations',
+        // eslint-disable-next-line no-template-curly-in-string
+        tips3: '2. The red color in the template file represents the model relationship, such as the $Product. Product Name (${Model Name}. {Attribute Name}) column, which establishes the relationship between the physical machine and the product.',
+        tips4: '3. In the download template Excel file, the predefined values of attributes will be set as dropdown options. Please note that due to the limitations of Excel itself, a single dropdown box is limited to a maximum of 255 characters. If it exceeds 255 characters, we will not set the dropdown options for this attribute',
+        tips5: '4. When using Excel templates, please ensure that a single file does not exceed 5000 lines.',
     },
     preference: {
         mySub: 'My Subscription',
@@ -274,6 +291,7 @@ const cmdb_en = {
         monthsAgo: 'month ago',
         yearsAgo: 'years ago',
         just: 'just now',
+        searchPlaceholder: 'Please search CIType',
     },
     custom_dashboard: {
         charts: 'Chart',
@@ -313,14 +331,23 @@ const cmdb_en = {
         noCustomDashboard: 'The administrator has not customized the dashboard yet',
     },
     preference_relation: {
-        newServiceTree: 'Add ServiceTree',
+        newServiceTree: 'Add Service Tree',
+        editServiceTree: 'Edit Service Tree',
         serviceTreeName: 'Name',
+        serviceTreeNamePlaceholder: 'Please enter the service tree name',
         public: 'Public',
         saveLayout: 'Save Layout',
         childNodesNotFound: 'There are no child nodes and no business relationship can be formed. Please select again!',
         tips1: 'Cannot form a view with the currently selected node, please select again!',
         tips2: 'Please enter the new serviceTree name!',
         tips3: 'Please select at least two nodes!',
+        tips4: 'Select at least one in leaf node or tree node',
+        tips5: 'Select the tree directory node and display the service tree sub nodes as a Table',
+        showLeafNode: 'Show Leaf Node',
+        showTreeNode: 'Show Tree Node',
+        sort: 'Sort',
+        sort1: 'Leaf node information comes first',
+        sort2: 'Tree node information comes first'
     },
     history: {
         ciChange: 'CI',
@@ -478,13 +505,15 @@ const cmdb_en = {
         noPermission: 'No Permission'
     },
     serviceTree: {
-        deleteNode: 'Delete Node',
+        deleteNode: 'Delete {name}',
         tips1: 'For example: q=os_version:centos&sort=os_version',
         tips2: 'Expression search',
         alert1: 'The administrator has not configured the ServiceTree(relation view), or you do not have permission to access it!',
         copyFailed: 'Copy failed',
         deleteRelationConfirm: 'Confirm to remove selected {name} from current relationship?',
         batch: 'Batch',
+        editNode: 'Edit Node',
+        editNodeName: 'Edit Node Name',
         grantTitle: 'Grant(read)',
         userPlaceholder: 'Please select users',
         rolePlaceholder: 'Please select roles',
diff --git a/cmdb-ui/src/modules/cmdb/lang/zh.js b/cmdb-ui/src/modules/cmdb/lang/zh.js
index e278f58..b336e4d 100644
--- a/cmdb-ui/src/modules/cmdb/lang/zh.js
+++ b/cmdb-ui/src/modules/cmdb/lang/zh.js
@@ -1,6 +1,7 @@
 const cmdb_zh = {
     relation: '关系',
     attribute: '属性',
+    configTable: '配置表格',
     menu: {
         views: '视图',
         config: '配置',
@@ -35,7 +36,7 @@ const cmdb_zh = {
         attributeLibray: '属性库',
         addCITypeInGroup: '在该组中新增CI模型',
         addCIType: '新增CI模型',
-        editGroupName: '编辑组名称',
+        editGroupName: '重命名分组',
         deleteGroup: '删除该组',
         CITypeName: '模型名(英文)',
         English: '英文',
@@ -182,7 +183,11 @@ const cmdb_zh = {
         inheritType: '继承模型',
         inheritTypePlaceholder: '请选择继承模型(多选)',
         inheritFrom: '属性继承自{name}',
-        groupInheritFrom: '请至{name}进行修改'
+        groupInheritFrom: '请至{name}进行修改',
+        downloadType: '下载模型',
+        deleteCIType: '删除模型',
+        otherGroupTips: '其他分组属性不可排序',
+        filterTips: '点击可仅查看{name}属性'
     },
     components: {
         unselectAttributes: '未选属性',
@@ -220,7 +225,7 @@ const cmdb_zh = {
         beforeChange: '变更前',
         afterChange: '变更后',
         noticeContentTips: '请输入通知内容',
-        saveQuery: '保存筛选条件',
+        saveQuery: '保存条件',
         pleaseSearch: '请查找',
         conditionFilter: '条件过滤',
         attributeDesc: '属性说明',
@@ -245,9 +250,10 @@ const cmdb_zh = {
         unselectCIType: '尚未选择模板类型',
         pleaseUploadFile: '请上传文件',
         batchUploadCanceled: '批量上传已取消',
-        selectCITypeTips: '请选择模板类型',
+        selectCIType: '选择模型',
+        selectCITypeTips: '请选择模型后下载模板',
         downloadTemplate: '下载模板',
-        drawTips: '点击或拖拽文件至此上传!',
+        clickDownload: '点击下载',
         supportFileTypes: '支持文件类型:xls,xlsx',
         uploadResult: '上传结果',
         total: '共',
@@ -257,6 +263,16 @@ const cmdb_zh = {
         errorTips: '错误信息',
         requestFailedTips: '请求出现错误,请稍后再试',
         requestSuccessTips: '批量上传已完成',
+        uploadFile: '文件上传',
+        drawTips1: '请先<span class="cmdb-batch-upload-tips">选择模型</span>,<span class="cmdb-batch-upload-tips">下载模板</span>后',
+        drawTips2: '<span class="cmdb-batch-upload-tips">点击或拖拽文件</span>至此上传',
+        dataPreview: '数据预览并导入',
+        tips1: '温馨提示:',
+        tips2: '1. 点击下载模板,用户可以自定义模板文件的表头,包括模型属性、模型关联',
+        // eslint-disable-next-line no-template-curly-in-string
+        tips3: '2. 模板文件中红色为模型关系,如$产品.产品名(${模型名}.{属性名})这一列就可建立物理机和产品之间的关系',
+        tips4: '3. 下载模板excel文件中会将属性的预定义值置为下拉选项,请注意,受excel本身的限制,单个下拉框限制了最多255个字符,如果超过255个字符,我们不会设置该属性的下拉选项',
+        tips5: '4. 在使用excel模板时,请确保单个文件不超过5000行',
     },
     preference: {
         mySub: '我的订阅',
@@ -274,6 +290,7 @@ const cmdb_zh = {
         monthsAgo: '月前',
         yearsAgo: '年前',
         just: '刚刚',
+        searchPlaceholder: '请搜索模型',
     },
     custom_dashboard: {
         charts: '图表',
@@ -314,13 +331,23 @@ const cmdb_zh = {
     },
     preference_relation: {
         newServiceTree: '新增服务树',
+        editServiceTree: '编辑服务树',
         serviceTreeName: '服务树名',
+        serviceTreeNamePlaceholder: '请输入服务树名',
         public: '公开',
         saveLayout: '保存布局',
         childNodesNotFound: '不存在子节点,不能形成业务关系,请重新选择!',
         tips1: '不能与当前选中节点形成视图,请重新选择!',
         tips2: '请输入新增服务树名!',
         tips3: '请选择至少两个节点!',
+        tips4: '叶子节点/树节点信息至少展示一个',
+        tips5: '选中树目录节点,服务树子节点展示成Table',
+        showLeafNode: '树的子节点展示成Table',
+        showTreeNode: '展示树节点信息',
+        sort: '顺序',
+        sort1: '树子节点信息在前',
+        sort2: '树节点信息在前'
+
     },
     history: {
         ciChange: 'CI变更',
@@ -443,7 +470,7 @@ const cmdb_zh = {
         disk: '硬盘',
     },
     ci: {
-        attributeDesc: '属性说明',
+        attributeDesc: '查看属性配置',
         selectRows: '选取:{rows} 项',
         addRelation: '添加关系',
         all: '全部',
@@ -477,13 +504,15 @@ const cmdb_zh = {
         noPermission: '暂无权限'
     },
     serviceTree: {
-        deleteNode: '删除节点',
+        deleteNode: '移除 {name}',
         tips1: '例:q=os_version:centos&sort=os_version',
         tips2: '表达式搜索',
         alert1: '管理员 还未配置业务关系, 或者你无权限访问!',
         copyFailed: '复制失败',
         deleteRelationConfirm: '确认将选中的 {name} 从当前关系中删除?',
         batch: '批量操作',
+        editNode: '编辑节点',
+        editNodeName: '修改节点名',
         grantTitle: '授权(查看权限)',
         userPlaceholder: '请选择用户',
         rolePlaceholder: '请选择角色',
diff --git a/cmdb-ui/src/modules/cmdb/router/index.js b/cmdb-ui/src/modules/cmdb/router/index.js
index 54663a9..da8909e 100644
--- a/cmdb-ui/src/modules/cmdb/router/index.js
+++ b/cmdb-ui/src/modules/cmdb/router/index.js
@@ -156,8 +156,8 @@ const genCmdbRoutes = async () => {
   const lastTypeId = window.localStorage.getItem('ops_ci_typeid') || undefined
   if (lastTypeId && preference.some(item => item.id === Number(lastTypeId))) {
     routes.redirect = `/cmdb/instances/types/${lastTypeId}`
-  } else if (routes.children[2].children.length > 0) {
-    routes.redirect = routes.children[2].children.find(item => !item.hidden).path
+  } else if (routes.children[3]?.children?.length > 0) {
+    routes.redirect = routes.children[3]?.children.find(item => !item.hidden)?.path
   } else {
     routes.redirect = '/cmdb/dashboard'
   }
diff --git a/cmdb-ui/src/modules/cmdb/utils/helper.js b/cmdb-ui/src/modules/cmdb/utils/helper.js
index f81fa2b..f4edca6 100644
--- a/cmdb-ui/src/modules/cmdb/utils/helper.js
+++ b/cmdb-ui/src/modules/cmdb/utils/helper.js
@@ -49,7 +49,6 @@ export function getCITableColumns(data, attrList, width = 1600, height) {
     const _attrList = _.orderBy(attrList, ['is_fixed'], ['desc'])
     const columns = []
     for (let attr of _attrList) {
-
         const editRender = { name: 'input' }
         switch (attr.value_type) {
             case '0':
@@ -85,7 +84,7 @@ export function getCITableColumns(data, attrList, width = 1600, height) {
 
         }
         columns.push({
-            attr_id:attr.id,
+            attr_id: attr.id,
             editRender,
             title: attr.alias || attr.name,
             field: attr.name,
@@ -135,6 +134,35 @@ export const getPropertyStyle = (attr) => {
     }
 }
 
+export const getPropertyIcon = (attr) => {
+    switch (attr.value_type) {
+        case '0':
+            return 'duose-shishu'
+        case '1':
+            return 'duose-fudianshu'
+        case '2':
+            if (attr.is_password) {
+                return 'duose-password'
+            }
+            if (attr.is_link) {
+                return 'duose-link'
+            }
+            return 'duose-wenben'
+        case '3':
+            return 'duose-datetime'
+        case '4':
+            return 'duose-date'
+        case '5':
+            return 'duose-time'
+        case '6':
+            return 'duose-json'
+        case '7':
+            return 'duose-password'
+        case '8':
+            return 'duose-link'
+    }
+}
+
 export const getLastLayout = (data, x1 = 0, y1 = 0, w1 = 0) => {
     const _tempData = _.orderBy(data, ['y', 'x'], ['asc', 'asc'])
     if (!_tempData.length) {
@@ -185,7 +213,7 @@ export const getAllParentNodesLabel = (node, label) => {
         return getAllParentNodesLabel(node.parentNode, `${node.parentNode.label}-${label}`)
     }
     return label
-  }
-  export const getTreeSelectLabel = (node) => {
+}
+export const getTreeSelectLabel = (node) => {
     return `${getAllParentNodesLabel(node, node.label)}`
-  }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/cmdb-ui/src/modules/cmdb/views/batch/index.vue b/cmdb-ui/src/modules/cmdb/views/batch/index.vue
index 17eb136..131a8b5 100644
--- a/cmdb-ui/src/modules/cmdb/views/batch/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/batch/index.vue
@@ -1,39 +1,41 @@
 <template>
   <div class="cmdb-batch-upload" :style="{ height: `${windowHeight - 64}px` }">
-    <div id="title">
-      <ci-type-choice ref="ciTypeChoice" @getCiTypeAttr="showCiType" />
+    <div class="cmdb-views-header">
+      <span>
+        <span class="cmdb-views-header-title">{{ $t('cmdb.menu.batchUpload') }}</span>
+      </span>
     </div>
-    <a-row>
-      <a-col :span="12">
-        <upload-file-form
-          :isUploading="isUploading"
-          :ciType="ciType"
-          ref="uploadFileForm"
-          @uploadDone="uploadDone"
-        ></upload-file-form>
-      </a-col>
-      <a-col :span="24" v-if="ciType && uploadData.length">
-        <CiUploadTable :ciTypeAttrs="ciTypeAttrs" ref="ciUploadTable" :uploadData="uploadData"></CiUploadTable>
-        <div class="cmdb-batch-upload-action">
-          <a-space size="large">
-            <a-button type="primary" ghost @click="handleCancel">{{ $t('cancel') }}</a-button>
-            <a-button @click="handleUpload" type="primary">{{ $t('upload') }}</a-button>
-            <a-button v-if="hasError && !isUploading" @click="downloadError" type="primary">{{ $t('cmdb.batch.downloadFailed') }}</a-button>
-          </a-space>
-        </div>
-      </a-col>
-      <a-col :span="24" v-if="ciType">
-        <upload-result
-          ref="uploadResult"
-          :upLoadData="uploadData"
-          :ciType="ciType"
-          :unique-field="uniqueField"
-          :isUploading="isUploading"
-          @uploadResultDone="uploadResultDone"
-          @uploadResultError="uploadResultError"
-        ></upload-result>
-      </a-col>
-    </a-row>
+    <CiTypeChoice ref="ciTypeChoice" @getCiTypeAttr="showCiType" />
+    <p class="cmdb-batch-upload-label"><span>*</span>3. {{ $t('cmdb.batch.uploadFile') }}</p>
+    <UploadFileForm
+      :isUploading="isUploading"
+      :ciType="ciType"
+      ref="uploadFileForm"
+      @uploadDone="uploadDone"
+    ></UploadFileForm>
+    <p class="cmdb-batch-upload-label">4. {{ $t('cmdb.batch.dataPreview') }}</p>
+    <CiUploadTable :ciTypeAttrs="ciTypeAttrs" ref="ciUploadTable" :uploadData="uploadData"></CiUploadTable>
+    <div class="cmdb-batch-upload-action">
+      <a-space size="large">
+        <a-button :disabled="!(ciType && uploadData.length)" @click="handleUpload" type="primary">{{
+          $t('upload')
+        }}</a-button>
+        <a-button @click="handleCancel">{{ $t('cancel') }}</a-button>
+        <a-button v-if="hasError && !isUploading" @click="downloadError" type="primary">{{
+          $t('cmdb.batch.downloadFailed')
+        }}</a-button>
+      </a-space>
+    </div>
+    <UploadResult
+      v-if="ciType"
+      ref="uploadResult"
+      :upLoadData="uploadData"
+      :ciType="ciType"
+      :unique-field="uniqueField"
+      :isUploading="isUploading"
+      @uploadResultDone="uploadResultDone"
+      @uploadResultError="uploadResultError"
+    ></UploadResult>
   </div>
 </template>
 
@@ -124,7 +126,7 @@ export default {
     handleCancel() {
       if (!this.isUploading) {
         this.showCiType(null)
-        this.$refs.ciTypeChoice.selectNum = null
+        this.$refs.ciTypeChoice.selectNum = undefined
         this.hasError = false
       } else {
         this.$message.warning(this.$t('cmdb.batch.batchUploadCanceled'))
@@ -144,16 +146,29 @@ export default {
   },
 }
 </script>
+<style lang="less">
+@import '~@/style/static.less';
+@import '../index.less';
+.cmdb-batch-upload-label {
+  color: @text-color_1;
+  font-weight: bold;
+  white-space: pre;
+  > span {
+    color: red;
+  }
+}
+</style>
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .cmdb-batch-upload {
   margin-bottom: -24px;
-  padding: 24px;
+  padding: 20px;
   background-color: #fff;
-  border-radius: 20px;
+  border-radius: @border-radius-box;
   overflow: auto;
   .cmdb-batch-upload-action {
     width: 50%;
-    text-align: center;
     margin: 12px 0;
   }
 }
diff --git a/cmdb-ui/src/modules/cmdb/views/batch/modules/CiTypeChoice.vue b/cmdb-ui/src/modules/cmdb/views/batch/modules/CiTypeChoice.vue
index 59c837c..0636534 100644
--- a/cmdb-ui/src/modules/cmdb/views/batch/modules/CiTypeChoice.vue
+++ b/cmdb-ui/src/modules/cmdb/views/batch/modules/CiTypeChoice.vue
@@ -1,11 +1,11 @@
 <template>
-  <a-space>
-    <span>{{ $t('cmdb.ciType.ciType') }}: </span>
+  <div>
+    <p class="cmdb-batch-upload-label"><span>*</span>1. {{ $t('cmdb.batch.selectCIType') }}</p>
     <a-select
       showSearch
       :placeholder="$t('cmdb.batch.selectCITypeTips')"
       @change="selectCiType"
-      :style="{ width: '300px' }"
+      :style="{ width: '50%', marginBottom: '1em' }"
       class="ops-select"
       :filter-option="filterOption"
       v-model="selectNum"
@@ -14,13 +14,16 @@
         ciType.alias
       }}</a-select-option>
     </a-select>
+    <p class="cmdb-batch-upload-label">&nbsp;&nbsp;2. {{ $t('cmdb.batch.downloadTemplate') }}</p>
     <a-button
+      :style="{ marginBottom: '1em' }"
       @click="openModal"
       :disabled="!selectNum"
       type="primary"
-      class="ops-button-primary"
+      ghost
+      class="ops-button-ghost"
       icon="download"
-    >{{ $t('cmdb.batch.downloadTemplate') }}</a-button
+    >{{ $t('cmdb.batch.clickDownload') }}</a-button
     >
     <a-modal
       :bodyStyle="{ paddingTop: 0 }"
@@ -88,7 +91,7 @@
         </a-row>
       </template>
     </a-modal>
-  </a-space>
+  </div>
 </template>
 
 <script>
@@ -107,7 +110,7 @@ export default {
     return {
       ciTypeList: [],
       ciTypeName: '',
-      selectNum: null,
+      selectNum: undefined,
       selectCiTypeAttrList: [],
       visible: false,
       checkedAttrs: [],
@@ -238,6 +241,7 @@ export default {
       for (let row = 2; row < 5000; row++) {
         Object.keys(choice_value_obj).forEach((key) => {
           const formulae = `"${choice_value_obj[key].choice_value.map((value) => value[0]).join(',')}"`
+          console.log(formulae)
           if (formulae.length <= 255) {
             ws.getCell(row, choice_value_obj[key].columnIdx).dataValidation = {
               type: 'list',
diff --git a/cmdb-ui/src/modules/cmdb/views/batch/modules/CiUploadTable.vue b/cmdb-ui/src/modules/cmdb/views/batch/modules/CiUploadTable.vue
index ec97359..a3670a3 100644
--- a/cmdb-ui/src/modules/cmdb/views/batch/modules/CiUploadTable.vue
+++ b/cmdb-ui/src/modules/cmdb/views/batch/modules/CiUploadTable.vue
@@ -1,13 +1,14 @@
 <template>
   <div class="cmdb-batch-upload-table">
     <vxe-table
+      v-if="uploadData && uploadData.length"
       ref="xTable"
       stripe
       show-header-overflow
       show-overflow=""
       size="small"
       class="ops-stripe-table"
-      :max-height="200"
+      height="auto"
       :data="dataSource"
       resizable
       :row-style="rowStyle"
@@ -21,6 +22,19 @@
         :min-width="100"
       ></vxe-column>
     </vxe-table>
+    <a-empty
+      v-else
+      :image-style="{
+        height: '80px',
+        marginTop: '10px',
+      }"
+    >
+      <img slot="image" :src="require('@/assets/data_empty.png')" />
+      <template slot="description">
+        <p>{{ $t('noData') }}</p>
+        <p>{{ $t('cmdb.batch.pleaseUploadFile') }}</p>
+      </template>
+    </a-empty>
   </div>
 </template>
 
@@ -99,7 +113,21 @@ export default {
 }
 </script>
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .cmdb-batch-upload-table {
-  overflow: auto;
+  height: 200px;
+  padding: 20px;
+  background: linear-gradient(90deg, @text-color_5 50%, transparent 0) repeat-x,
+    linear-gradient(90deg, @text-color_5 50%, transparent 0) repeat-x,
+    linear-gradient(0deg, @text-color_5 50%, transparent 0) repeat-y,
+    linear-gradient(0deg, @text-color_5 50%, transparent 0) repeat-y;
+  background-size: 15px 1px, 15px 1px, 1px 15px, 1px 15px;
+  background-position: 0 0, 0 100%, 0 0, 100% 0;
+  .ant-empty-description {
+    p:last-child {
+      color: @primary-color;
+    }
+  }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/batch/modules/UploadFileForm.vue b/cmdb-ui/src/modules/cmdb/views/batch/modules/UploadFileForm.vue
index d18a048..600b52f 100644
--- a/cmdb-ui/src/modules/cmdb/views/batch/modules/UploadFileForm.vue
+++ b/cmdb-ui/src/modules/cmdb/views/batch/modules/UploadFileForm.vue
@@ -9,13 +9,21 @@
       :fileList="fileList"
       :disabled="!ciType || isUploading"
     >
-      <img :style="{ width: '80px', height: '80px' }" src="@/assets/file_upload.png" />
-      <p class="ant-upload-text">{{ $t('cmdb.batch.drawTips') }}</p>
+      <ops-icon type="itsm-folder" />
       <p class="ant-upload-hint">{{ $t('cmdb.batch.supportFileTypes') }}</p>
+      <p v-html="$t('cmdb.batch.drawTips1')"></p>
+      <p v-html="$t('cmdb.batch.drawTips2')"></p>
+      <div v-for="item in fileList" :key="item.name" class="cmdb-batch-upload-dragger-file">
+        <span><a-icon type="file" :style="{ color: '#2F54EB', marginRight: '5px' }" />{{ item.name }}</span>
+        <a-progress :status="progressStatus" :percent="percent" />
+      </div>
     </a-upload-dragger>
-    <div v-for="item in fileList" :key="item.name" class="cmdb-batch-upload-dragger-file">
-      <span><a-icon type="file" :style="{ color: '#2F54EB', marginRight: '5px' }" />{{ item.name }}</span>
-      <a-progress :status="progressStatus" :percent="percent" />
+    <div class="cmdb-batch-upload-tips">
+      <p>{{ $t('cmdb.batch.tips1') }}</p>
+      <div>{{ $t('cmdb.batch.tips2') }}</div>
+      <div>{{ $t('cmdb.batch.tips3') }}</div>
+      <div>{{ $t('cmdb.batch.tips4') }}</div>
+      <div>{{ $t('cmdb.batch.tips5') }}</div>
     </div>
   </div>
 </template>
@@ -46,15 +54,13 @@ export default {
   },
   watch: {
     ciType: {
-      handler(newValue) {
-        if (!newValue) {
-          this.ciItemNum = 0
-          this.fileList = []
-          this.dataList = []
-          this.progressStatus = 'active'
-          this.percent = 0
-          this.$emit('uploadDone', this.dataList)
-        }
+      handler() {
+        this.ciItemNum = 0
+        this.fileList = []
+        this.dataList = []
+        this.progressStatus = 'active'
+        this.percent = 0
+        this.$emit('uploadDone', this.dataList)
       },
     },
   },
@@ -77,12 +83,28 @@ export default {
 </script>
 
 <style lang="less">
+@import '~@/style/static.less';
+
 .cmdb-batch-upload-dragger {
-  height: 220px;
+  height: auto;
   margin: 16px 0;
+  .ant-upload p {
+    margin-bottom: 5px;
+  }
   .ant-upload.ant-upload-drag {
-    background: rgba(240, 245, 255, 0.35);
     border: none;
+    background: linear-gradient(90deg, @text-color_5 50%, transparent 0) repeat-x,
+      linear-gradient(90deg, @text-color_5 50%, transparent 0) repeat-x,
+      linear-gradient(0deg, @text-color_5 50%, transparent 0) repeat-y,
+      linear-gradient(0deg, @text-color_5 50%, transparent 0) repeat-y;
+    background-size: 15px 1px, 15px 1px, 1px 15px, 1px 15px;
+    background-position: 0 0, 0 100%, 0 0, 100% 0;
+    .ant-upload-drag-container > i {
+      font-size: 60px;
+    }
+    .cmdb-batch-upload-tips {
+      color: @primary-color;
+    }
   }
   .ant-upload.ant-upload-drag .ant-upload-drag-container {
     vertical-align: baseline;
@@ -90,23 +112,37 @@ export default {
 }
 </style>
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .cmdb-batch-upload-dragger {
   position: relative;
+  display: flex;
+  > span {
+    display: inline-block;
+    width: 50%;
+  }
   .cmdb-batch-upload-dragger-file {
-    background-color: #fff;
-    box-shadow: 0px 2px 5px rgba(78, 94, 160, 0.2);
-    border-radius: 4px;
-    position: absolute;
+    background-color: @primary-color_7;
+    border-radius: 2px;
     width: 80%;
-    left: 50%;
-    bottom: 24px;
     padding: 2px 8px;
-    transform: translate(-50%);
     display: inline-flex;
     > span {
       white-space: nowrap;
       margin-right: 10px;
     }
   }
+  .cmdb-batch-upload-tips {
+    width: 50%;
+    padding-left: 20px;
+    color: @text-color_3;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    p:first-child {
+      color: @text-color_1;
+    }
+  }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/batch/modules/UploadResult.vue b/cmdb-ui/src/modules/cmdb/views/batch/modules/UploadResult.vue
index 1ccab2c..f6028a2 100644
--- a/cmdb-ui/src/modules/cmdb/views/batch/modules/UploadResult.vue
+++ b/cmdb-ui/src/modules/cmdb/views/batch/modules/UploadResult.vue
@@ -1,10 +1,11 @@
 <template>
   <div class="cmdb-batch-upload-result" v-if="visible">
-    <h3 class="cmdb-batch-upload-result-title">{{ $t('cmdb.batch.uploadResult') }}</h3>
+    <p class="cmdb-batch-upload-label">5. {{ $t('cmdb.batch.uploadResult') }}</p>
     <div class="cmdb-batch-upload-result-content">
       <h4>
-        {{ $t('cmdb.batch.total') }}&nbsp;<span style="color: blue">{{ total }}</span> {{ $t('cmdb.batch.successItems') }}
-        <span style="color: lightgreen">{{ success }}</span> {{ $t('cmdb.batch.failedItems') }} <span style="color: red">{{ errorNum }} </span>{{ $t('cmdb.batch.items') }}
+        {{ $t('cmdb.batch.total') }}&nbsp;<span style="color: blue">{{ total }}</span>
+        {{ $t('cmdb.batch.successItems') }} <span style="color: lightgreen">{{ success }}</span>
+        {{ $t('cmdb.batch.failedItems') }} <span style="color: red">{{ errorNum }} </span>{{ $t('cmdb.batch.items') }}
       </h4>
       <div>
         <span>{{ $t('cmdb.batch.errorTips') }}: </span>
@@ -39,7 +40,7 @@ export default {
       default: false,
     },
   },
-  data: function() {
+  data() {
     return {
       visible: false,
       complete: 0,
@@ -54,6 +55,13 @@ export default {
       return this.upLoadData.length || 0
     },
   },
+  watch: {
+    ciType: {
+      handler() {
+        this.visible = false
+      },
+    },
+  },
   methods: {
     async upload2Server() {
       this.visible = true
@@ -96,10 +104,6 @@ export default {
 @import '~@/style/static.less';
 
 .cmdb-batch-upload-result {
-  .cmdb-batch-upload-result-title {
-    border-left: 4px solid #custom_colors[color_1];
-    padding-left: 10px;
-  }
   .cmdb-batch-upload-result-content {
     background-color: rgba(240, 245, 255, 0.35);
     border-radius: 5px;
diff --git a/cmdb-ui/src/modules/cmdb/views/ci/index.vue b/cmdb-ui/src/modules/cmdb/views/ci/index.vue
index cab9c07..cd0d519 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci/index.vue
@@ -15,21 +15,35 @@
         </span>
       </span>
       <a-space>
-        <a-button size="small" icon="plus" type="primary" @click="$refs.create.handleOpen(true, 'create')">
+        <a-button
+          type="primary"
+          class="ops-button-ghost"
+          ghost
+          @click="$refs.create.handleOpen(true, 'create')"
+        ><ops-icon type="veops-increase" />
           {{ $t('create') }}
         </a-button>
-        <a-button size="small" icon="user-add" type="primary" ghost @click="handlePerm">{{ $t('grant') }}</a-button>
-        <a-popconfirm
-          :title="
-            $t('cmdb.preference.confirmcancelSub2', { name: `${this.$route.meta.title || this.$route.meta.name}` })
-          "
-          :ok-text="$t('confirm')"
-          :cancel-text="$t('cancel')"
-          @confirm="unsubscribe"
-          placement="bottomRight"
-        >
-          <a-button size="small" icon="star" type="primary" ghost>{{ $t('cmdb.preference.cancelSub') }}</a-button>
-        </a-popconfirm>
+        <EditAttrsPopover :typeId="typeId" class="operation-icon" @refresh="refreshAfterEditAttrs">
+          <a-button
+            type="primary"
+            ghost
+            class="ops-button-ghost"
+          ><ops-icon type="veops-configuration_table" />{{ $t('cmdb.configTable') }}</a-button
+          >
+        </EditAttrsPopover>
+        <a-dropdown v-model="visible">
+          <a-button type="primary" ghost class="ops-button-ghost">···</a-button>
+          <a-menu slot="overlay" @click="handleMenuClick">
+            <a-menu-item @click="handlePerm" key="grant">
+              <a-icon type="user-add" />
+              {{ $t('grant') }}
+            </a-menu-item>
+            <a-menu-item key="cancelSub" @click="unsubscribe">
+              <a-icon type="star" />
+              {{ $t('cmdb.preference.cancelSub') }}
+            </a-menu-item>
+          </a-menu>
+        </a-dropdown>
       </a-space>
     </div>
     <div class="cmdb-ci-main">
@@ -86,7 +100,6 @@
           :scroll-y="{ enabled: true, gt: 20 }"
           :scroll-x="{ enabled: true, gt: 0 }"
           class="ops-unstripe-table"
-          :style="{ margin: '0 -12px' }"
           :custom-config="{ storage: true }"
         >
           <vxe-column align="center" type="checkbox" width="60" :fixed="isCheckboxFixed ? 'left' : ''"></vxe-column>
@@ -219,11 +232,9 @@
               </template>
             </template>
           </vxe-table-column>
-          <vxe-column align="left" field="operate" fixed="right" width="120">
+          <vxe-column align="left" field="operate" fixed="right" width="80">
             <template #header>
               <span>{{ $t('operation') }}</span>
-              <EditAttrsPopover :typeId="typeId" class="operation-icon" @refresh="refreshAfterEditAttrs" />
-              <!-- <a-icon class="operation-icon" type="control" /> -->
             </template>
             <template #default="{ row }">
               <a-space>
@@ -342,7 +353,7 @@ export default {
       // if (this.selectedRowKeys && this.selectedRowKeys.length) {
       //   return this.windowHeight - 246
       // }
-      return this.windowHeight - 210
+      return this.windowHeight - 240
     },
   },
   data() {
@@ -377,6 +388,7 @@ export default {
       passwordValue: {},
       lastEditCiId: null,
       isContinueCloseEdit: true,
+      visible: false,
     }
   },
   watch: {
@@ -916,15 +928,24 @@ export default {
         })
     },
     unsubscribe(ciType, type = 'all') {
-      const promises = [subscribeCIType(this.typeId, ''), subscribeTreeView(this.typeId, '')]
-      Promise.all(promises).then(() => {
-        const lastTypeId = window.localStorage.getItem('ops_ci_typeid') || undefined
-        if (Number(ciType) === Number(lastTypeId)) {
-          localStorage.setItem('ops_ci_typeid', '')
-        }
-        this.$message.success(this.$t('cmdb.preference.cancelSubSuccess'))
-        this.resetRoute()
-        this.$router.push('/cmdb/preference')
+      const that = this
+      this.$confirm({
+        title: that.$t('warning'),
+        content: that.$t('cmdb.preference.confirmcancelSub2', {
+          name: `${that.$route.meta.title || that.$route.meta.name}`,
+        }),
+        onOk() {
+          const promises = [subscribeCIType(that.typeId, ''), subscribeTreeView(that.typeId, '')]
+          Promise.all(promises).then(() => {
+            const lastTypeId = window.localStorage.getItem('ops_ci_typeid') || undefined
+            if (Number(ciType) === Number(lastTypeId)) {
+              localStorage.setItem('ops_ci_typeid', '')
+            }
+            that.$message.success(that.$t('cmdb.preference.cancelSubSuccess'))
+            that.resetRoute()
+            that.$router.push('/cmdb/preference')
+          })
+        },
       })
     },
     resetRoute() {
@@ -957,6 +978,11 @@ export default {
         }
       })
     },
+    handleMenuClick(e) {
+      if (e.key === 'grant') {
+        this.visible = false
+      }
+    },
   },
 }
 </script>
@@ -968,11 +994,11 @@ export default {
 <style lang="less" scoped>
 @import '~@/style/static.less';
 .cmdb-ci {
+  background-color: #fff;
+  padding: 20px;
+  border-radius: @border-radius-box;
+  height: calc(100vh - 64px);
+  overflow: auto;
   margin-bottom: -24px;
-  .cmdb-ci-main {
-    background-color: #fff;
-    border-radius: 15px;
-    padding: 12px;
-  }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/CreateInstanceForm.vue b/cmdb-ui/src/modules/cmdb/views/ci/modules/CreateInstanceForm.vue
index 53f24e8..1bbbc87 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci/modules/CreateInstanceForm.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/CreateInstanceForm.vue
@@ -106,9 +106,9 @@
               <a-date-picker
                 v-decorator="[list.name, { rules: [{ required: false }] }]"
                 style="width: 100%"
-                :format="getFieldType(list.name) == 'date' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
-                v-if="getFieldType(list.name) === 'date' || getFieldType(list.name) === 'datetime'"
-                :showTime="getFieldType(list.name) === 'date' ? false : { format: 'HH:mm:ss' }"
+                :format="getFieldType(list.name) == '4' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
+                v-if="getFieldType(list.name) === '4' || getFieldType(list.name) === '3'"
+                :showTime="getFieldType(list.name) === '4' ? false : { format: 'HH:mm:ss' }"
               />
               <a-input
                 v-if="getFieldType(list.name) === 'input'"
@@ -373,7 +373,7 @@ export default {
         } else if (_find.value_type === '0' || _find.value_type === '1') {
           return 'input_number'
         } else if (_find.value_type === '4' || _find.value_type === '3') {
-          return this.valueTypeMap[_find.value_type]
+          return _find.value_type
         } else {
           return 'input'
         }
diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/editAttrsPopover.vue b/cmdb-ui/src/modules/cmdb/views/ci/modules/editAttrsPopover.vue
index 4766add..9255db8 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci/modules/editAttrsPopover.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/editAttrsPopover.vue
@@ -11,9 +11,11 @@
         @setFixedList="setFixedList"
       />
     </template>
-    <div :style="{ height: '100%', width: '30px', float: 'right', borderLeft: '1px solid #e8eaec' }">
-      <a-icon :style="{ margin: '13px 0 0 10px ' }" type="control" />
-    </div>
+    <slot>
+      <div :style="{ height: '100%', width: '30px', float: 'right', borderLeft: '1px solid #e8eaec' }">
+        <a-icon :style="{ margin: '13px 0 0 10px ' }" type="control" />
+      </div>
+    </slot>
   </a-popover>
 </template>
 
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD.vue
index ea79501..03a6563 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="attr-ad" :style="{ height: `${windowHeight - 104}px` }">
+  <div class="attr-ad" :style="{ height: `${windowHeight - 130}px` }">
     <div v-if="adCITypeList && adCITypeList.length">
       <a-tabs size="small" v-model="currentTab">
         <a-tab-pane v-for="item in adCITypeList" :key="item.id">
@@ -207,7 +207,7 @@ export default {
 @import '~@/style/static.less';
 .attr-ad {
   position: relative;
-  padding: 0 12px;
+  padding: 0 20px;
   .attr-ad-header {
     width: 100%;
     display: inline-flex;
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/attrADTabpane.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/attrADTabpane.vue
index 3fa87c6..30bf11a 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/attrADTabpane.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/attrADTabpane.vue
@@ -1,5 +1,5 @@
 <template>
-  <div :style="{ height: `${windowHeight - 156}px`, overflow: 'auto', position: 'relative' }">
+  <div :style="{ height: `${windowHeight - 187}px`, overflow: 'auto', position: 'relative' }">
     <a
       v-if="!adrIsInner"
       :style="{ position: 'absolute', right: 0, top: 0 }"
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/attributeCard.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/attributeCard.vue
index 8a390be..10f1d35 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/attributeCard.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/attributeCard.vue
@@ -1,71 +1,83 @@
 <template>
-  <div :class="{ 'attribute-card': true, 'attribute-card-inherited': inherited }">
-    <a-tooltip :title="inherited ? $t('cmdb.ciType.inheritFrom', { name: property.inherited_from }) : ''">
-      <div class="attribute-card-content">
-        <div
-          :class="{ 'attribute-card-value-type-icon': true, handle: !inherited }"
-          :style="{ ...getPropertyStyle(property) }"
-        >
-          <ValueTypeIcon :attr="property" />
-        </div>
-        <div :class="{ 'attribute-card-content-inner': true, 'attribute-card-name-required': property.is_required }">
-          <div :class="{ 'attribute-card-name': true, 'attribute-card-name-default-show': property.default_show }">
-            {{ property.alias || property.name }}
+  <div
+    @click="
+      () => {
+        if (isAdd) {
+          $emit('add')
+        }
+      }
+    "
+    :class="{ 'attribute-card': true, 'attribute-card-add': isAdd, 'attribute-card-inherited': inherited }"
+  >
+    <div class="attribute-card-uniqueKey" v-if="isUnique">{{ $t('cmdb.ciType.uniqueKey') }}</div>
+    <template v-if="!isAdd">
+      <a-tooltip :title="inherited ? $t('cmdb.ciType.inheritFrom', { name: property.inherited_from }) : ''">
+        <div class="attribute-card-content">
+          <div :class="{ 'attribute-card-value-type-icon': true, handle: !inherited }">
+            <ValueTypeIcon :attr="property" />
+          </div>
+          <div :class="{ 'attribute-card-content-inner': true, 'attribute-card-name-required': property.is_required }">
+            <div :class="{ 'attribute-card-name': true, 'attribute-card-name-default-show': property.default_show }">
+              {{ property.alias || property.name }}
+            </div>
+            <div v-if="property.is_password" class="attribute-card_value-type">{{ $t('cmdb.ciType.password') }}</div>
+            <div v-else-if="property.is_link" class="attribute-card_value-type">{{ $t('cmdb.ciType.link') }}</div>
+            <div v-else class="attribute-card_value-type">{{ valueTypeMap[property.value_type] }}</div>
+          </div>
+          <div
+            class="attribute-card-trigger"
+            v-if="(property.value_type === '3' || property.value_type === '4') && !isStore"
+          >
+            <a @click="openTrigger"><ops-icon type="ops-trigger"/></a>
           </div>
-          <div v-if="property.is_password" class="attribute-card_value-type">{{ $t('cmdb.ciType.password') }}</div>
-          <div v-else-if="property.is_link" class="attribute-card_value-type">{{ $t('cmdb.ciType.link') }}</div>
-          <div v-else class="attribute-card_value-type">{{ valueTypeMap[property.value_type] }}</div>
         </div>
-        <div
-          class="attribute-card-trigger"
-          v-if="(property.value_type === '3' || property.value_type === '4') && !isStore"
+      </a-tooltip>
+
+      <div class="attribute-card-footer">
+        <a-popover
+          trigger="click"
+          :arrowPointAtCenter="true"
+          placement="bottom"
+          overlayClassName="attribute-card-footer-popover"
         >
-          <a @click="openTrigger"><ops-icon type="ops-trigger"/></a>
-        </div>
-      </div>
-    </a-tooltip>
+          <div slot="content">
+            <h3 :style="{ textAlign: 'center', paddingTop: '0.5em' }">
+              <span>{{ property.alias }}({{ property.name }})</span>
+            </h3>
+            <a-descriptions layout="horizontal" bordered size="small" :column="2">
+              <a-descriptions-item v-for="item in propertyList" :key="item.property" :label="item.label">
+                <ops-icon
+                  :style="{ color: property[item.property] ? '#7f97fa' : '', fontSize: '10px' }"
+                  :type="`ops-${item.property}-disabled`"
+                />
+              </a-descriptions-item>
+              <a-descriptions-item label></a-descriptions-item>
+            </a-descriptions>
+          </div>
+          <a-space :style="{ cursor: 'pointer' }">
+            <ops-icon
+              v-for="item in propertyList.filter((p) => property[p.property])"
+              :key="item.property"
+              :style="{ color: '#7f97fa', fontSize: '10px' }"
+              :type="`ops-${item.property}-disabled`"
+            />
+          </a-space>
+        </a-popover>
 
-    <div class="attribute-card-footer">
-      <a-popover
-        trigger="click"
-        :arrowPointAtCenter="true"
-        placement="bottom"
-        overlayClassName="attribute-card-footer-popover"
-      >
-        <div slot="content">
-          <h3 :style="{ textAlign: 'center', paddingTop: '0.5em' }">
-            <span>{{ property.alias }}({{ property.name }})</span>
-          </h3>
-          <a-descriptions layout="horizontal" bordered size="small" :column="2">
-            <a-descriptions-item v-for="item in propertyList" :key="item.property" :label="item.label">
-              <components
-                :is="`ops_${item.property}`"
-                v-if="property[item.property]"
-                :style="{ width: '1em', height: '1em' }"
-              />
-              <ops-icon v-else :type="`ops-${item.property}-disabled`" />
-            </a-descriptions-item>
-            <a-descriptions-item label></a-descriptions-item>
-          </a-descriptions>
-        </div>
-        <a-space :style="{ cursor: 'pointer' }">
-          <components
-            v-for="item in propertyList.filter((p) => property[p.property])"
-            :key="item.property"
-            :is="`ops_${item.property}`"
-          />
+        <a-space class="attribute-card-operation" v-if="!inherited">
+          <a v-if="!isStore"><a-icon type="edit" @click="handleEdit"/></a>
+          <a-tooltip :title="$t('cmdb.ciType.computeForAllCITips')">
+            <a v-if="!isStore && property.is_computed"><a-icon type="redo" @click="handleCalcComputed"/></a>
+          </a-tooltip>
+          <a v-if="!isUnique" style="color:red;"><a-icon type="delete" @click="handleDelete"/></a>
         </a-space>
-      </a-popover>
-
-      <a-space class="attribute-card-operation" v-if="!inherited">
-        <a v-if="!isStore"><a-icon type="edit" @click="handleEdit"/></a>
-        <a-tooltip :title="$t('cmdb.ciType.computeForAllCITips')">
-          <a v-if="!isStore && property.is_computed"><a-icon type="redo" @click="handleCalcComputed"/></a>
-        </a-tooltip>
-        <a style="color:red;"><a-icon type="delete" @click="handleDelete"/></a>
-      </a-space>
-    </div>
-    <TriggerForm ref="triggerForm" :CITypeId="CITypeId" />
+      </div>
+      <TriggerForm ref="triggerForm" :CITypeId="CITypeId" />
+    </template>
+    <template v-else>
+      <a><a-icon type="plus"/></a>
+      <div>{{ $t('cmdb.ciType.addAttribute') }}</div>
+    </template>
   </div>
 </template>
 
@@ -82,10 +94,15 @@ import {
   ops_is_unique,
 } from '@/core/icons'
 import { valueTypeMap } from '../../utils/const'
-import { getPropertyStyle } from '../../utils/helper'
 import TriggerForm from './triggerForm.vue'
 export default {
   name: 'AttributeCard',
+  inject: {
+    unique: {
+      from: 'unique',
+      default: () => undefined,
+    },
+  },
   components: {
     ValueTypeIcon,
     TriggerForm,
@@ -114,11 +131,21 @@ export default {
       type: Array,
       default: () => [],
     },
+    isAdd: {
+      type: Boolean,
+      default: false,
+    },
   },
   data() {
     return {}
   },
   computed: {
+    isUnique() {
+      if (this.unique) {
+        return this.property?.name === this.unique()
+      }
+      return false
+    },
     valueTypeMap() {
       return valueTypeMap()
     },
@@ -147,11 +174,10 @@ export default {
       ]
     },
     inherited() {
-      return this.property.inherited || false
+      return this.property?.inherited || false
     },
   },
   methods: {
-    getPropertyStyle,
     handleEdit() {
       this.$emit('edit')
     },
@@ -196,11 +222,12 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
 .attribute-card {
   width: 182px;
   height: 80px;
-  background: #f8faff;
-  border-radius: 5px;
+  background: @primary-color_6;
+  border-radius: 2px;
   position: relative;
   margin-bottom: 16px;
   transition: all 0.3s;
@@ -219,7 +246,7 @@ export default {
     .attribute-card-value-type-icon {
       width: 32px;
       height: 32px;
-      font-size: 12px;
+      font-size: 16px;
       background: #ffffff !important;
       box-shadow: 0px 1px 2px rgba(47, 84, 235, 0.2);
       border-radius: 2px;
@@ -243,7 +270,7 @@ export default {
         white-space: nowrap;
       }
       .attribute-card-name-default-show {
-        color: #2f54eb;
+        color: @primary-color;
       }
       .attribute-card_value-type {
         font-size: 10px;
@@ -270,20 +297,67 @@ export default {
     position: absolute;
     bottom: 0;
     left: 0;
-    background: linear-gradient(180deg, #96abd6 0%, #ecf2ff 0.01%, #ffffff 143.33%);
-    border-radius: 0px 0px 5px 5px;
+    background: @primary-color_5;
+    border-radius: 0px 0px 2px 2px;
     display: inline-flex;
     align-items: center;
     justify-content: space-between;
+    border-top: 1px solid @primary-color_3;
     .attribute-card-operation {
       visibility: hidden;
     }
   }
+  .attribute-card-uniqueKey {
+    position: absolute;
+    right: -12px;
+    top: 0;
+    color: @func-color_2;
+    background: url('../../assets/unique_card.png');
+    font-size: 10px;
+    z-index: 1;
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+    min-width: 55px;
+    padding: 2px 0 2px 5px;
+  }
 }
 .attribute-card-inherited {
-  background: #f3f4f7;
+  background: @primary-color_7;
   .attribute-card-footer {
-    background: #eaedf3;
+    background: @text-color_7;
+  }
+}
+
+.attribute-card-add {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+  position: relative;
+  background-color: inherit;
+  &:hover {
+    box-shadow: none;
+    background-color: @primary-color_6;
+  }
+  &:after {
+    content: '';
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    top: 0;
+    left: 0;
+    z-index: 1;
+    background: linear-gradient(90deg, @text-color_5 50%, transparent 0) repeat-x,
+      linear-gradient(90deg, @text-color_5 50%, transparent 0) repeat-x,
+      linear-gradient(0deg, @text-color_5 50%, transparent 0) repeat-y,
+      linear-gradient(0deg, @text-color_5 50%, transparent 0) repeat-y;
+    background-size: 15px 1px, 15px 1px, 1px 15px, 1px 15px;
+    background-position: 0 0, 0 100%, 0 0, 100% 0;
+  }
+  div {
+    color: @text-color_4;
+    font-size: 12px;
   }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/attributeStore.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/attributeStore.vue
index f8b2876..4b19024 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/attributeStore.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/attributeStore.vue
@@ -172,8 +172,6 @@ export default {
   margin-right: 60px;
   .ant-input-group.ant-input-group-compact > *:first-child,
   .ant-input-group.ant-input-group-compact > .ant-select:first-child > .ant-select-selection {
-    border-top-left-radius: 20px !important;
-    border-bottom-left-radius: 20px !important;
     background-color: #custom_colors[color_1];
     color: #fff;
     border: none;
@@ -202,7 +200,6 @@ export default {
     .ant-input {
       background-color: #f0f5ff;
       border: none;
-      border-radius: 20px;
       &:focus {
         box-shadow: none;
       }
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/attributesTable.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/attributesTable.vue
index 4c55133..9a1a749 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/attributesTable.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/attributesTable.vue
@@ -12,14 +12,28 @@
         </a-form-item>
       </span>
     </a-modal>
-    <div class="ci-types-attributes" :style="{ maxHeight: `${windowHeight - 104}px` }">
+    <div class="ci-types-attributes" :style="{ height: `${windowHeight - 130}px` }">
       <a-space style="margin-bottom: 10px">
-        <a-button type="primary" @click="handleAddGroup" size="small" class="ops-button-primary" icon="plus">{{
-          $t('cmdb.ciType.group')
-        }}</a-button>
-        <a-button type="primary" @click="handleOpenUniqueConstraint" size="small" class="ops-button-primary">{{
-          $t('cmdb.ciType.uniqueConstraint')
-        }}</a-button>
+        <a-button @click="handleAddGroup" size="small" icon="plus">{{ $t('cmdb.ciType.group') }}</a-button>
+        <a-button @click="handleOpenUniqueConstraint" size="small">{{ $t('cmdb.ciType.uniqueConstraint') }}</a-button>
+        <div>
+          <a-tooltip
+            v-for="type in Object.keys(valueTypeMap)"
+            :key="type"
+            :title="$t('cmdb.ciType.filterTips', { name: valueTypeMap[type] })"
+          >
+            <span
+              @click="handleFilterType(type)"
+              :class="{
+                'ci-types-attributes-filter': true,
+                'ci-types-attributes-filter-selected': attrTypeFilter.includes(type),
+              }"
+            >
+              <ops-icon :type="getPropertyIcon({ value_type: type })" />
+              {{ valueTypeMap[type] }}
+            </span>
+          </a-tooltip>
+        </div>
       </a-space>
       <div :key="CITypeGroup.id" v-for="(CITypeGroup, index) in CITypeGroups">
         <div>
@@ -29,13 +43,6 @@
           >
             <span style="font-weight:700">{{ CITypeGroup.name }}</span>
             <span style="color: #c3cdd7;margin:0 5px;">({{ CITypeGroup.attributes.length }})</span>
-
-            <a v-if="!CITypeGroup.inherited" @click="handleEditGroupName(index, CITypeGroup)">
-              <a-icon type="edit" />
-            </a>
-            <a v-else :style="{ cursor: 'not-allowed', color: 'gray' }">
-              <a-icon type="edit" />
-            </a>
           </div>
           <template v-else>
             <span>
@@ -64,21 +71,24 @@
                 @click="handleMoveGroup(index, index + 1)"
               /></a>
             </a-tooltip>
-
-            <a-tooltip>
-              <template slot="title">{{ $t('cmdb.ciType.selectAttribute') }}</template>
-              <a><a-icon type="plus" @click="handleAddGroupAttr(index)"/></a>
-            </a-tooltip>
-            <a-tooltip>
-              <template slot="title">{{ $t('cmdb.ciType.deleteGroup') }}</template>
-              <a
-                :style="{ color: CITypeGroup.inherited ? 'gray' : 'red' }"
-                :disabled="CITypeGroup.inherited"
-              ><a-icon
-                type="delete"
-                @click="handleDeleteGroup(CITypeGroup)"
-              /></a>
-            </a-tooltip>
+            <a-dropdown>
+              <a><ops-icon type="veops-more"/></a>
+              <a-menu slot="overlay">
+                <a-menu-item @click="handleAddGroupAttr(index)">
+                  <template slot="title"></template>
+                  <a-icon type="plus" />
+                  {{ $t('cmdb.ciType.addAttribute') }}
+                </a-menu-item>
+                <a-menu-item @click="handleEditGroupName(index, CITypeGroup)" :disabled="CITypeGroup.inherited">
+                  <a-icon type="edit" />
+                  {{ $t('cmdb.ciType.editGroupName') }}
+                </a-menu-item>
+                <a-menu-item @click="handleDeleteGroup(CITypeGroup)" :disabled="CITypeGroup.inherited">
+                  <a-icon type="delete" />
+                  {{ $t('cmdb.ciType.deleteGroup') }}
+                </a-menu-item>
+              </a-menu>
+            </a-dropdown>
           </a-space>
         </div>
         <div class="ci-types-attributes-wrapper">
@@ -98,7 +108,9 @@
             handle=".handle"
           >
             <AttributeCard
-              v-for="item in CITypeGroup.attributes"
+              v-for="item in CITypeGroup.attributes.filter(
+                (attr) => !attrTypeFilter.length || (attrTypeFilter.length && attrTypeFilter.includes(attr.value_type))
+              )"
               :key="item.id"
               @edit="handleEditProperty(item)"
               :property="item"
@@ -106,6 +118,7 @@
               :CITypeId="CITypeId"
               :attributes="attributes"
             />
+            <AttributeCard isAdd @add="handleAddGroupAttr(index)" />
             <i></i> <i></i> <i></i> <i></i> <i></i>
           </draggable>
         </div>
@@ -114,10 +127,11 @@
         <div :style="{ height: '32px', lineHeight: '32px', display: 'inline-block', fontSize: '14px' }">
           <span style="font-weight:700">{{ $t('other') }}</span>
           <span style="color: #c3cdd7;margin-left:5px;">({{ otherGroupAttributes.length }})</span>
+          <span style="color: #c3cdd7;margin-left:5px;font-size:10px;">{{ $t('cmdb.ciType.otherGroupTips') }}</span>
         </div>
         <div style="float: right">
           <a-tooltip>
-            <template slot="title">{{ $t('cmdb.ciType.selectAttribute') }}</template>
+            <template slot="title">{{ $t('cmdb.ciType.addAttribute') }}</template>
             <a @click="handleAddGroupAttr(undefined)"><a-icon type="plus"/></a>
           </a-tooltip>
         </div>
@@ -138,7 +152,9 @@
           handle=".handle"
         >
           <AttributeCard
-            v-for="item in otherGroupAttributes"
+            v-for="item in otherGroupAttributes.filter(
+              (attr) => !attrTypeFilter.length || (attrTypeFilter.length && attrTypeFilter.includes(attr.value_type))
+            )"
             :key="item.id"
             @edit="handleEditProperty(item)"
             :property="item"
@@ -146,6 +162,7 @@
             :CITypeId="CITypeId"
             :attributes="attributes"
           />
+          <AttributeCard isAdd @add="handleAddGroupAttr(undefined)" />
           <i></i> <i></i> <i></i> <i></i> <i></i>
         </draggable>
       </div>
@@ -185,6 +202,8 @@ import AttributeCard from './attributeCard.vue'
 import AttributeEditForm from './attributeEditForm.vue'
 import NewCiTypeAttrModal from './newCiTypeAttrModal.vue'
 import UniqueConstraint from './uniqueConstraint.vue'
+import { valueTypeMap } from '../../utils/const'
+import { getPropertyIcon } from '../../utils/helper'
 
 export default {
   name: 'AttributesTable',
@@ -214,6 +233,8 @@ export default {
       otherGroupAttributes: [],
       addGroupModal: false,
       newGroupName: '',
+      attrTypeFilter: [],
+      unique: '',
     }
   },
   computed: {
@@ -223,9 +244,17 @@ export default {
     windowHeight() {
       return this.$store.state.windowHeight
     },
+    valueTypeMap() {
+      return valueTypeMap()
+    },
   },
   provide() {
-    return { refresh: this.getCITypeGroupData }
+    return {
+      refresh: this.getCITypeGroupData,
+      unique: () => {
+        return this.unique
+      },
+    }
   },
   beforeCreate() {},
   created() {},
@@ -233,6 +262,7 @@ export default {
     this.getCITypeGroupData()
   },
   methods: {
+    getPropertyIcon,
     handleEditProperty(property) {
       this.$refs.attributeEditForm.handleEdit(property, this.attributes)
     },
@@ -260,6 +290,7 @@ export default {
         group.editable = false
         group.originOrder = group.order
         group.originName = group.name
+        // group.attributes = group.attributes.sort((a, b) => a.order - b.order)
       })
 
       this.otherGroupAttributes = this.attributes
@@ -282,6 +313,7 @@ export default {
       Promise.all(promises).then((values) => {
         console.log(values)
         this.attributes = values[0].attributes
+        this.unique = values[0].unique
         const temp = {}
         this.attributes.forEach((attr) => {
           temp[attr.id] = attr
@@ -387,6 +419,7 @@ export default {
               group.attributes = group.attributes.filter((x) => !values.checkedAttributes.includes(x.id))
             }
           })
+          // this.CITypeGroups = this.CITypeGroups
 
           this.otherGroupAttributes.forEach((attributes) => {
             if (values.groupId === null) {
@@ -523,20 +556,40 @@ export default {
     handleOpenUniqueConstraint() {
       this.$refs.uniqueConstraint.open(this.attributes)
     },
+    handleFilterType(type) {
+      const _idx = this.attrTypeFilter.findIndex((item) => item === type)
+      if (_idx > -1) {
+        this.attrTypeFilter.splice(_idx, 1)
+      } else {
+        this.attrTypeFilter.push(type)
+      }
+    },
   },
-  watch: {},
 }
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .fold {
   width: calc(100% - 216px);
   display: inline-block;
 }
 
 .ci-types-attributes {
-  padding: 16px 24px 24px;
+  padding: 0 20px;
   overflow-y: auto;
+  .ci-types-attributes-filter {
+    color: @text-color_4;
+    cursor: pointer;
+    padding: 3px 8px;
+    white-space: nowrap;
+    margin-right: 5px;
+  }
+  .ci-types-attributes-filter:hover,
+  .ci-types-attributes-filter-selected {
+    background-color: @primary-color_5;
+  }
   .property-item-empty {
     color: #40a9ff;
     width: calc(100% - 20px);
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/ciTypedetail.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/ciTypedetail.vue
index 9d52aad..be8f020 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/ciTypedetail.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/ciTypedetail.vue
@@ -1,6 +1,6 @@
 <template>
   <a-card :bordered="false" :bodyStyle="{ padding: '0' }">
-    <a-tabs :activeKey="activeKey" @change="changeTab" class="ops-tab" type="card">
+    <a-tabs :activeKey="activeKey" @change="changeTab" class="ops-tab">
       <a-tab-pane key="1" :tab="$t('cmdb.ciType.attributes')">
         <AttributesTable ref="attributesTable" :CITypeId="CITypeId" :CITypeName="CITypeName"></AttributesTable>
       </a-tab-pane>
@@ -16,8 +16,10 @@
       <a-tab-pane key="5" :tab="$t('cmdb.ciType.relationAD')">
         <RelationAD :CITypeId="CITypeId"></RelationAD>
       </a-tab-pane>
-      <a-tab-pane key="6" :tab="$t('cmdb.ciType.grant')">
+      <a-tab-pane key="6" :tab="$t('cmdb.components.relationGrant')">
         <GrantComp :CITypeId="CITypeId" resourceType="CIType" :resourceTypeName="CITypeName"></GrantComp>
+        <div class="citype-detail-title">{{ $t('cmdb.ciType.relation') }}</div>
+        <RelationTable isInGrantComp :CITypeId="CITypeId" :CITypeName="CITypeName"></RelationTable>
       </a-tab-pane>
     </a-tabs>
   </a-card>
@@ -74,4 +76,13 @@ export default {
 }
 </script>
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+@import '~@/style/static.less';
+
+.citype-detail-title {
+  border-left: 4px solid @primary-color;
+  padding-left: 10px;
+  margin-left: 20px;
+  margin-bottom: 10px;
+}
+</style>
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/index.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/index.vue
index 48bd5c4..832779c 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/index.vue
@@ -8,11 +8,10 @@
     </div>
     <SplitPane
       v-else
-      :min="280"
+      :min="220"
       :max="500"
       :paneLengthPixel.sync="paneLengthPixel"
       appName="cmdb-ci-types"
-      triggerColor="#F0F5FF"
       :triggerLength="18"
     >
       <template #one>
@@ -22,22 +21,23 @@
               :disabled="!permissions.includes('admin') && !permissions.includes('cmdb_admin')"
               type="primary"
               size="small"
-              icon="plus"
+              ghost
               @click="handleClickAddGroup"
-              class="ops-button-primary"
-            >{{ $t('cmdb.ciType.group') }}</a-button
+              class="ops-button-ghost"
+            ><ops-icon type="veops-increase" />{{ $t('cmdb.ciType.group') }}</a-button
             >
             <a-space>
-              <a
+              <span
+                :style="{ cursor: 'pointer' }"
                 @click="
                   () => {
                     $refs.attributeStore.open()
                   }
                 "
-              >{{ $t('cmdb.ciType.attributeLibray') }}</a
-              >
+              >{{ $t('cmdb.ciType.attributeLibray') }}
+              </span>
               <a-dropdown v-if="permissions.includes('admin') || permissions.includes('cmdb_admin')">
-                <a><ops-icon type="ops-menu"/></a>
+                <ops-icon type="ops-menu" :style="{ cursor: 'pointer' }" />
                 <a-menu slot="overlay">
                   <a-menu-item key="0">
                     <a-upload
@@ -83,7 +83,7 @@
                 <a-space>
                   <a-tooltip>
                     <template slot="title">{{ $t('cmdb.ciType.addCITypeInGroup') }}</template>
-                    <a><a-icon type="plus" @click="handleCreate(g)"/></a>
+                    <a><ops-icon type="veops-increase" @click="handleCreate(g)"/></a>
                   </a-tooltip>
                   <template v-if="g.id !== -1">
                     <a-tooltip>
@@ -113,7 +113,7 @@
                 >
                   <div>
                     <OpsMoveIcon
-                      style="width: 17px; height: 17px; display: none; position: absolute; left: 15px; top: 5px"
+                      style="width: 17px; height: 17px; display: none; position: absolute; left: -1px; top: 8px"
                     />
                     <span class="ci-types-left-detail-icon">
                       <template v-if="ci.icon">
@@ -134,18 +134,33 @@
                     </span>
                   </div>
                   <span class="ci-types-left-detail-title">{{ ci.alias || ci.name }}</span>
-                  <a-space class="ci-types-left-detail-action">
-                    <a><a-icon type="user-add" @click="(e) => handlePerm(e, ci)"/></a>
-                    <a><a-icon type="edit" @click="(e) => handleEdit(e, ci)"/></a>
-                    <a
-                      v-if="permissions.includes('admin') || permissions.includes('cmdb_admin')"
-                      :disabled="ci.inherited"
-                      @click="(e) => handleDownloadCiType(e, ci)"
-                    >
-                      <a-icon type="download" />
+                  <a-dropdown :getPopupContainer="(trigger) => trigger">
+                    <a class="ci-types-left-detail-action">
+                      <ops-icon type="veops-more" />
                     </a>
-                    <a style="color: red" @click="(e) => handleDelete(e, ci)"><a-icon type="delete"/></a>
-                  </a-space>
+                    <a-menu slot="overlay">
+                      <a-menu-item @click="(e) => handlePerm(e, ci)">
+                        <a-icon type="user-add" />
+                        {{ $t('grant') }}
+                      </a-menu-item>
+                      <a-menu-item @click="(e) => handleEdit(e, ci)">
+                        <a-icon type="edit" />
+                        {{ $t('cmdb.ciType.editCIType') }}
+                      </a-menu-item>
+                      <a-menu-item
+                        v-if="permissions.includes('admin') || permissions.includes('cmdb_admin')"
+                        :disabled="ci.inherited"
+                        @click="(e) => handleDownloadCiType(e, ci)"
+                      >
+                        <a-icon type="download" />
+                        {{ $t('cmdb.ciType.downloadType') }}
+                      </a-menu-item>
+                      <a-menu-item @click="(e) => handleDelete(e, ci)">
+                        <a-icon type="delete" />
+                        {{ $t('cmdb.ciType.deleteCIType') }}
+                      </a-menu-item>
+                    </a-menu>
+                  </a-dropdown>
                 </div>
               </draggable>
             </div>
@@ -270,17 +285,7 @@
             </div>
           </el-select>
         </a-form-item>
-        <a-form-item>
-          <template slot="label">
-            <a-tooltip :title="$t('cmdb.ciType.uniqueKeyTips')">
-              <a-icon
-                style="position:absolute;top:3px;left:-17px;color:#2f54eb;"
-                type="question-circle"
-                theme="filled"
-              />
-            </a-tooltip>
-            <span>{{ $t('cmdb.ciType.uniqueKey') }}</span>
-          </template>
+        <a-form-item :help="$t('cmdb.ciType.uniqueKeyTips')" :label="$t('cmdb.ciType.uniqueKey')">
           <el-select
             size="small"
             filterable
@@ -456,7 +461,6 @@ export default {
     },
     currentCName() {
       if (this.currentId) {
-        console.log(this.currentId)
         if (this.currentId.split('%')[2] !== 'null') {
           return this.currentId.split('%')[2]
         }
@@ -817,8 +821,8 @@ export default {
         })
     },
     handleDelete(e, record) {
-      e.preventDefault()
-      e.stopPropagation()
+      e.domEvent.preventDefault()
+      e.domEvent.stopPropagation()
       const that = this
       this.$confirm({
         title: that.$t('warning'),
@@ -833,8 +837,8 @@ export default {
       })
     },
     handleDownloadCiType(e, ci) {
-      e.preventDefault()
-      e.stopPropagation()
+      e.domEvent.preventDefault()
+      e.domEvent.stopPropagation()
       const x = new XMLHttpRequest()
       x.open('GET', `/api/v0.1/ci_types/${ci.id}/template/export`, true)
       x.responseType = 'blob'
@@ -855,8 +859,8 @@ export default {
       })
     },
     async handleEdit(e, record) {
-      e.preventDefault()
-      e.stopPropagation()
+      e.domEvent.preventDefault()
+      e.domEvent.stopPropagation()
       this.drawerTitle = this.$t('cmdb.ciType.editCIType')
       this.drawerVisible = true
       await getCITypeAttributesById(record.id).then((res) => {
@@ -909,8 +913,8 @@ export default {
       }
     },
     handlePerm(e, ci) {
-      e.preventDefault()
-      e.stopPropagation()
+      e.domEvent.preventDefault()
+      e.domEvent.stopPropagation()
       roleHasPermissionToGrant({
         app_id: 'cmdb',
         resource_type_name: 'CIType',
@@ -942,6 +946,8 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .ci-types-wrap {
   margin: 0 0 -24px 0;
   .ci-types-empty {
@@ -955,21 +961,24 @@ export default {
     width: 100%;
     overflow: auto;
     float: left;
-    border-top-left-radius: 20px;
-    border-top-right-radius: 20px;
+
     .ci-types-left-content {
       max-height: calc(100% - 45px);
-      overflow: auto;
+      overflow: hidden;
+      &:hover {
+        overflow: auto;
+      }
     }
     .ci-types-left-title {
-      padding: 10px 15px;
+      padding: 10px 0;
       display: flex;
       flex-direction: row;
       justify-content: space-between;
+      color: @text-color_3;
     }
     .ci-types-left-group {
       position: relative;
-      padding: 8px 15px;
+      padding: 8px 0 8px 14px;
       color: rgb(99, 99, 99);
       cursor: pointer;
       font-size: 14px;
@@ -982,7 +991,7 @@ export default {
         display: none;
       }
       &:hover {
-        background-color: #e1efff;
+        background-color: @primary-color_3;
         > div:nth-child(2) {
           display: inline-flex;
         }
@@ -992,17 +1001,25 @@ export default {
       }
     }
     .ci-types-left-detail {
-      padding: 3px 14px 3px 36px;
+      padding: 3px 14px;
       cursor: pointer;
       position: relative;
       display: flex;
       flex-direction: row;
       justify-content: flex-start;
+      align-items: center;
       margin-bottom: 4px;
+      height: 32px;
+      line-height: 32px;
       .ci-types-left-detail-action {
         display: none;
         margin-left: auto;
       }
+      .ci-types-left-detail-title {
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+      }
       .ci-types-left-detail-icon {
         display: flex;
         align-items: center;
@@ -1019,7 +1036,7 @@ export default {
         }
       }
       &:hover {
-        background-color: #e1efff;
+        background-color: @primary-color_3;
         svg {
           display: inline !important;
         }
@@ -1029,7 +1046,7 @@ export default {
       }
     }
     .selected {
-      background-color: #e1efff;
+      background-color: @primary-color_3;
       .ci-types-left-detail-title {
         font-weight: 700;
       }
@@ -1038,6 +1055,7 @@ export default {
   .ci-types-right {
     width: 100%;
     position: relative;
+    background-color: #fff;
     .ci-types-right-empty {
       position: absolute;
       text-align: center;
@@ -1049,7 +1067,6 @@ export default {
   .ci-types-left,
   .ci-types-right {
     height: 100%;
-    background-color: #fff;
   }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/relationAD.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/relationAD.vue
index becf5ae..24cb511 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/relationAD.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/relationAD.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="relation-ad" :style="{ height: `${windowHeight - 104}px` }">
+  <div class="relation-ad" :style="{ height: `${windowHeight - 130}px` }">
     <div class="relation-ad-item" v-for="item in relationList" :key="item.id">
       <treeselect
         class="custom-treeselect"
@@ -253,7 +253,7 @@ export default {
 <style lang="less" scoped>
 .relation-ad {
   overflow: auto;
-  padding: 24px;
+  padding: 0 20px;
   .relation-ad-item {
     display: inline-flex;
     justify-content: flex-start;
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/relationTable.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/relationTable.vue
index 205aa16..5bbd1df 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/relationTable.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/relationTable.vue
@@ -1,6 +1,7 @@
 <template>
-  <div :style="{ padding: '16px 24px 24px' }">
+  <div :style="{ padding: '0 20px 20px' }">
     <a-button
+      v-if="!isInGrantComp"
       style="margin-bottom: 10px"
       @click="handleCreate"
       type="primary"
@@ -43,7 +44,7 @@
         <template #default="{row}">
           <a-space v-if="!row.isParent && row.source_ci_type_id">
             <a @click="handleOpenGrant(row)"><a-icon type="user-add"/></a>
-            <a-popconfirm :title="$t('cmdb.ciType.confirmDelete2')" @confirm="handleDelete(row)">
+            <a-popconfirm v-if="!isInGrantComp" :title="$t('cmdb.ciType.confirmDelete2')" @confirm="handleDelete(row)">
               <a style="color: red;"><a-icon type="delete"/></a>
             </a-popconfirm>
           </a-space>
@@ -148,6 +149,10 @@ export default {
       type: String,
       default: '',
     },
+    isInGrantComp: {
+      type: Boolean,
+      default: false,
+    },
   },
   data() {
     return {
@@ -178,7 +183,9 @@ export default {
   async mounted() {
     this.getCITypes()
     this.getRelationTypes()
-    await this.getCITypeParent()
+    if (!this.isInGrantComp) {
+      await this.getCITypeParent()
+    }
     this.getData()
   },
   methods: {
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/triggerTable.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/triggerTable.vue
index 501270b..6231930 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/triggerTable.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/triggerTable.vue
@@ -134,6 +134,6 @@ export default {
 
 <style lang="less" scoped>
 .ci-types-triggers {
-  padding: 16px 24px 24px;
+  padding: 0 20px 20px;
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartForm.vue b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartForm.vue
index 18f2276..0923545 100644
--- a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartForm.vue
+++ b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartForm.vue
@@ -165,7 +165,7 @@
                       : '#fafafa',
                 }"
               >
-                <div :style="{ color: fontColor }">{{ form.name }}</div>
+                <div v-if="chartType === 'count'" :style="{ color: fontColor }">{{ form.name }}</div>
                 <Chart
                   :ref="`chart_${item.id}`"
                   :chartId="item.id"
@@ -613,6 +613,7 @@ export default {
       } else {
         this.form.category = 1
       }
+      console.log(this.chartType)
     },
     showPreview() {
       this.$refs.chartForm.validate(async (valid) => {
diff --git a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/customLayout.vue b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/customLayout.vue
index 58b2237..861290e 100644
--- a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/customLayout.vue
+++ b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/customLayout.vue
@@ -15,7 +15,8 @@
           @click="openChartForm('add', { options: { w: 3 } })"
           type="primary"
           icon="plus-circle"
-          class="ops-button-primary"
+          ghost
+          class="ops-button-ghost"
         >{{ $t('cmdb.custom_dashboard.newChart') }}</a-button
         >
       </div>
@@ -44,7 +45,7 @@
                 ? Array.isArray(item.options.bgColor)
                   ? `linear-gradient(to bottom, ${item.options.bgColor[0]} 0%, ${item.options.bgColor[1]} 100%)`
                   : item.options.bgColor
-                : '#fafafa',
+                : '#fff',
           }"
         >
           <div class="cmdb-dashboard-grid-item-title">
@@ -78,7 +79,10 @@
             ></a>
             <a-menu slot="overlay">
               <a-menu-item>
-                <a @click="() => openChartForm('edit', item)"><a-icon style="margin-right:5px" type="edit" />{{ $t('edit') }}</a>
+                <a
+                  @click="() => openChartForm('edit', item)"
+                ><a-icon style="margin-right:5px" type="edit" />{{ $t('edit') }}</a
+                >
               </a-menu-item>
               <a-menu-item>
                 <a @click="deleteChart(item)"><a-icon style="margin-right:5px" type="delete" />{{ $t('delete') }}</a>
@@ -261,7 +265,7 @@ export default {
   text-align: center;
 }
 .cmdb-dashboard-grid-item {
-  border-radius: 8px;
+  border-radius: 2px;
   padding: 6px 12px;
   .cmdb-dashboard-grid-item-title {
     overflow: hidden;
@@ -299,6 +303,7 @@ export default {
     display: inline-block;
     width: 16px;
     height: 16px;
+    line-height: 16px;
     font-size: 16px;
     text-align: center;
     margin-right: 5px;
diff --git a/cmdb-ui/src/modules/cmdb/views/discovery/index.vue b/cmdb-ui/src/modules/cmdb/views/discovery/index.vue
index f34b1fa..03952da 100644
--- a/cmdb-ui/src/modules/cmdb/views/discovery/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/discovery/index.vue
@@ -144,6 +144,9 @@ export default {
 <style lang="less" scoped>
 @import '~@/style/static.less';
 .setting-discovery {
+  background-color: #fff;
+  padding: 20px;
+  border-radius: @border-radius-box;
   .type-header {
     width: 100%;
     display: inline-flex;
diff --git a/cmdb-ui/src/modules/cmdb/views/discoveryCI/index.vue b/cmdb-ui/src/modules/cmdb/views/discoveryCI/index.vue
index 184c98e..f2fd987 100644
--- a/cmdb-ui/src/modules/cmdb/views/discoveryCI/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/discoveryCI/index.vue
@@ -1,11 +1,11 @@
 <template>
   <TwoColumnLayout appName="cmdb-adc">
     <template #one>
-      <div v-for="group in ci_types_list" :key="group.id">
-        <div>
+      <div class="cmdb-adc-group" v-for="group in ci_types_list" :key="group.id">
+        <p>
           <strong>{{ group.name || $t('other') }}</strong
           ><span :style="{ color: 'rgb(195, 205, 215)' }">({{ group.ci_types.length }})</span>
-        </div>
+        </p>
         <div
           :class="{ 'cmdb-adc-side-item': true, 'cmdb-adc-side-item-selected': currentType === type.id }"
           v-for="type in group.ci_types"
@@ -34,7 +34,6 @@
       <div id="discovery-ci">
         <a-input-search
           :placeholder="$t('cmdb.components.pleaseSearch')"
-          class="ops-input ops-input-radius"
           :style="{ width: '200px', marginRight: '20px', marginBottom: '10px' }"
           @search="handleSearch"
           allowClear
@@ -102,7 +101,11 @@
             sortable
             v-bind="columns.length ? { width: '130px' } : { minWidth: '130px' }"
           ></vxe-column>
-          <vxe-column :title="$t('operation')" v-bind="columns.length ? { width: '60px' } : { minWidth: '60px' }" align="center">
+          <vxe-column
+            :title="$t('operation')"
+            v-bind="columns.length ? { width: '60px' } : { minWidth: '60px' }"
+            align="center"
+          >
             <template #default="{row}">
               <a-space>
                 <a-tooltip :title="$t('cmdb.ad.accept')">
@@ -312,6 +315,9 @@ export default {
 <style lang="less" scoped>
 @import '~@/style/static.less';
 .cmdb-adc {
+  .cmdb-adc-group {
+    margin-bottom: 20px;
+  }
   .cmdb-adc-side-item {
     .ops_popover_item();
     height: 32px;
@@ -343,7 +349,7 @@ export default {
   }
   .cmdb-adc-side-item-selected {
     .ops_popover_item_selected();
-    background-color: #custom_colors[color_2];
+    background-color: @primary-color_3;
   }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/index.less b/cmdb-ui/src/modules/cmdb/views/index.less
index 4182c87..36a5fa0 100644
--- a/cmdb-ui/src/modules/cmdb/views/index.less
+++ b/cmdb-ui/src/modules/cmdb/views/index.less
@@ -77,7 +77,7 @@
 }
 
 .cmdb-views-header {
-  border-left: 4px solid #custom_colors[color_1];
+  border-left: 4px solid @primary-color;
   height: 32px;
   display: flex;
   align-items: center;
@@ -85,17 +85,17 @@
   margin-bottom: 18px;
   .cmdb-views-header-title {
     font-size: 16px;
-    font-weight: 400;
-    color: rgba(0, 0, 0, 0.75);
+    font-weight: bold;
+    color: @text-color_1;
     margin-left: 10px;
   }
   .cmdb-views-header-metadata {
     cursor: pointer;
     font-size: 12px;
-    color: rgba(0, 0, 0, 0.55);
+    color: @text-color_3;
     margin-left: 20px;
     &:hover {
-      color: #custom_colors[color_1];
+      color: @primary-color;
     }
   }
 }
diff --git a/cmdb-ui/src/modules/cmdb/views/model_relation/index.vue b/cmdb-ui/src/modules/cmdb/views/model_relation/index.vue
index 4275634..d4bd8b1 100644
--- a/cmdb-ui/src/modules/cmdb/views/model_relation/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/model_relation/index.vue
@@ -242,9 +242,11 @@ export default {
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .model-relation {
   background-color: #fff;
-  border-radius: 15px;
+  border-radius: @border-radius-box;
   padding: 24px;
   height: calc(100vh - 64px);
   margin-bottom: -24px;
diff --git a/cmdb-ui/src/modules/cmdb/views/preference/index.vue b/cmdb-ui/src/modules/cmdb/views/preference/index.vue
index e42206c..bd48787 100644
--- a/cmdb-ui/src/modules/cmdb/views/preference/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/preference/index.vue
@@ -51,7 +51,6 @@
               :class="{
                 'cmdb-preference-avatar': true,
                 'cmdb-preference-avatar-noicon': !ciType.icon,
-                'cmdb-preference-avatar-noicon-is_subscribed': !ciType.icon && ciType.is_subscribed,
               }"
               :style="{ width: '30px', height: '30px', marginRight: '10px' }"
             >
@@ -94,7 +93,12 @@
       </div>
     </div>
     <div class="cmdb-preference-right">
-      <div v-for="group in citypeData" :key="group.id">
+      <a-input-search
+        v-model="searchValue"
+        :style="{ width: '300px', marginBottom: '20px' }"
+        :placeholder="$t('cmdb.preference.searchPlaceholder')"
+      />
+      <div v-for="group in filterCiTypeData" :key="group.id">
         <p @click="changeGroupExpand(group)" :style="{ display: 'inline-block', cursor: 'pointer' }">
           <a-icon :type="expandKeys.includes(group.id) ? 'caret-down' : 'caret-right'" />{{ group.name }}({{
             group.ci_types ? group.ci_types.length : 0
@@ -108,7 +112,6 @@
                   :class="{
                     'cmdb-preference-avatar': true,
                     'cmdb-preference-avatar-noicon': !item.icon,
-                    'cmdb-preference-avatar-noicon-is_subscribed': !item.icon && item.is_subscribed,
                   }"
                 >
                   <template v-if="item.icon">
@@ -188,6 +191,7 @@
 </template>
 
 <script>
+import _ from 'lodash'
 import router, { resetRouter } from '@/router'
 import store from '@/store'
 import { mapState } from 'vuex'
@@ -219,12 +223,29 @@ export default {
       },
       type_id2users: {},
       myPreferences: [],
+      searchValue: '',
     }
   },
   computed: {
     ...mapState({
       windowHeight: (state) => state.windowHeight,
     }),
+    filterCiTypeData() {
+      if (this.searchValue) {
+        const _citypeData = _.cloneDeep(this.citypeData)
+        _citypeData.forEach((group) => {
+          if (group.ci_types) {
+            group.ci_types = group.ci_types.filter(
+              (item) =>
+                item.name.toLowerCase().includes(this.searchValue.toLowerCase()) ||
+                item.alias.toLowerCase().includes(this.searchValue.toLowerCase())
+            )
+          }
+        })
+        return _citypeData
+      }
+      return this.citypeData
+    },
   },
   mounted() {
     this.getCITypes(true)
@@ -376,7 +397,6 @@ export default {
 .cmdb-preference {
   margin: -24px;
   overflow: auto;
-  background: url('../../assets/preference_background.png');
   position: relative;
   display: flex;
   flex-direction: row;
@@ -392,7 +412,7 @@ export default {
   .cmdb-preference-left {
     width: 300px;
     height: 100%;
-    padding: 12px 18px;
+    padding: 24px 18px;
     .cmdb-preference-left-card {
       background: url('../../assets/preference_card.png');
       background-repeat: no-repeat;
@@ -426,17 +446,19 @@ export default {
       .cmdb-preference-group-title {
         text-align: center;
         margin-bottom: 5px;
+        i {
+          color: @primary-color;
+        }
         > span {
           display: inline-block;
-          color: #fff;
-          background: linear-gradient(90deg, #305bec, #78cfff);
+          color: @text-color_2;
           border-radius: 16px;
           font-weight: 600;
           padding: 6px 12px;
         }
       }
       .cmdb-preference-group-content {
-        color: rgba(0, 0, 0, 0.75);
+        color: @text-color_1;
         font-weight: 400;
         display: flex;
         align-items: center;
@@ -447,7 +469,11 @@ export default {
         &:hover {
           background: #ffffff;
           box-shadow: 0px 2px 8px rgba(149, 160, 208, 0.25);
-          border-radius: 8px;
+          border-radius: @border-radius-box;
+          .cmdb-preference-avatar {
+            box-shadow: none;
+            background-color: @primary-color_5;
+          }
           .cmdb-preference-group-content-action {
             display: inline;
             white-space: nowrap;
@@ -479,7 +505,7 @@ export default {
   .cmdb-preference-right {
     flex: 1;
     height: 100%;
-    padding-top: 18px;
+    padding-top: 24px;
     .cmdb-preference-content {
       display: flex;
       flex-direction: row;
@@ -494,11 +520,11 @@ export default {
         display: inline-block;
         width: 195px;
         height: 155px;
-        border-radius: 8px;
+        border-radius: @border-radius-box;
         background-color: #fff;
         box-shadow: 0px 2px 8px rgba(149, 160, 208, 0.25);
         margin: 0 20px 20px 0;
-        padding: 8px;
+        padding: 12px;
         &:hover {
           box-shadow: 4px 25px 30px rgba(50, 89, 134, 0.25);
           transform: scale(1.1);
@@ -550,7 +576,7 @@ export default {
           .cmdb-preference-progress-gray {
             height: 5px;
             border-radius: 5px;
-            background-color: #d9d9d9;
+            background-color: @text-color_6;
             margin-top: 5px;
             width: 100%;
             position: relative;
@@ -560,7 +586,7 @@ export default {
               top: 0;
               left: 0;
               border-radius: 5px;
-              background: linear-gradient(90deg, #305bec, #78cfff);
+              background: @primary-color_8;
             }
           }
         }
@@ -592,20 +618,17 @@ export default {
     display: flex;
     align-items: center;
     justify-content: center;
-    width: 40px;
-    height: 40px;
+    width: 34px;
+    height: 34px;
     box-shadow: 0px 4px 4px rgba(129, 140, 186, 0.25);
-    border-radius: 5px;
+    border-radius: 1px;
+    background-color: #fff;
   }
   .cmdb-preference-avatar-noicon {
-    background-color: #7f97fa;
     > span {
-      font-size: 24px;
-      color: #fff;
+      font-size: 18px;
+      color: @text-color_4;
     }
   }
-  .cmdb-preference-avatar-noicon-is_subscribed {
-    background-color: #47a964;
-  }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/preference_relation/index.vue b/cmdb-ui/src/modules/cmdb/views/preference_relation/index.vue
index f0b246b..a6ecfe2 100644
--- a/cmdb-ui/src/modules/cmdb/views/preference_relation/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/preference_relation/index.vue
@@ -15,9 +15,7 @@
           >{{ $t('cmdb.preference_relation.newServiceTree') }}</a-button
           >
           <template v-else>
-            <a-input v-model="newRelationViewName" :placeholder="$t('cmdb.preference_relation.serviceTreeName')"></a-input>
-            <a-checkbox v-model="is_public">{{ $t('cmdb.preference_relation.public') }}</a-checkbox>
-            <a-button type="primary" size="small" @click="handleSaveRelationViews">{{ $t('save') }}</a-button>
+            <a-button type="primary" size="small" @click="openServiceTreeModal({}, 'add')">{{ $t('save') }}</a-button>
             <a-button
               type="primary"
               size="small"
@@ -26,13 +24,13 @@
                 () => {
                   isEdit = false
                   checkedNodes = []
-                  newRelationViewName = ''
                 }
               "
             >{{ $t('cancel') }}</a-button
             >
           </template>
-          <a-button type="primary" size="small" @click="handleSave">{{ $t('cmdb.preference_relation.saveLayout') }}</a-button>
+          <a-button size="small" @click="handleSave">{{ $t('cmdb.preference_relation.saveLayout') }}</a-button>
+          <span>{{ $t('cmdb.preference_relation.tips5') }}</span>
         </a-space>
       </div>
       <SeeksRelationGraph v-if="isPullConfig" ref="ciTypeRelationGraph" :options="graphOptions">
@@ -46,7 +44,7 @@
         </div>
       </SeeksRelationGraph>
     </div>
-    <template v-if="relationViews.views">
+    <template v-if="relationViews.views && !loading">
       <a-row :gutter="4">
         <a-col
           :xl="12"
@@ -54,11 +52,17 @@
           :md="12"
           :sm="24"
           :xs="24"
-          :key="`${view}${idx}`"
-          v-for="(view, idx) in Object.keys(relationViews.views)"
+          :key="`${view}`"
+          v-for="view in Object.keys(relationViews.views)"
         >
           <div class="relation-views">
             <h3 :style="{ padding: '10px 0 0 20px' }">{{ view }}</h3>
+            <a
+              class="relation-views-edit"
+              @click="openServiceTreeModal({ name: view }, 'edit')"
+            ><ops-icon
+              type="icon-xianxing-edit"
+            /></a>
             <a-popconfirm :title="$t('cmdb.ciType.confirmDelete', { name: `${view}` })" @confirm="confirmDelete(view)">
               <a class="relation-views-close"><a-icon type="close"/></a>
             </a-popconfirm>
@@ -69,6 +73,7 @@
         </a-col>
       </a-row>
     </template>
+    <ServiceTreeModal ref="serviceTreeModal" @submitServiceTree="submitServiceTree" />
   </div>
 </template>
 
@@ -78,11 +83,17 @@ import router, { resetRouter } from '@/router'
 import store from '@/store'
 import SeeksRelationGraph from '@/modules/cmdb/3rd/relation-graph'
 import { getCITypeRelations } from '@/modules/cmdb/api/CITypeRelation'
-import { getRelationView, deleteRelationView, subscribeRelationView } from '@/modules/cmdb/api/preference'
+import {
+  getRelationView,
+  deleteRelationView,
+  subscribeRelationView,
+  putRelationView,
+} from '@/modules/cmdb/api/preference'
 import { getSystemConfig, saveSystemConfig } from '../../api/system_config'
+import ServiceTreeModal from './serviceTreeModal.vue'
 export default {
   name: 'PreferenceRelation',
-  components: { SeeksRelationGraph },
+  components: { SeeksRelationGraph, ServiceTreeModal },
   data() {
     const defaultOptions = {
       allowShowMiniToolBar: false,
@@ -103,6 +114,7 @@ export default {
     }
     const relationViewOptions = {
       ...defaultOptions,
+      disableZoom: true,
       layouts: [
         {
           layoutName: 'tree',
@@ -116,11 +128,10 @@ export default {
       relationViewOptions,
       isEdit: false,
       relationViews: {},
-      newRelationViewName: '',
       graphJsonData: {},
       checkedNodes: [],
-      is_public: true,
       isPullConfig: false,
+      loading: false,
     }
   },
   async created() {
@@ -210,6 +221,7 @@ export default {
       return maxEle
     },
     async getViewsData() {
+      this.loading = true
       const data = await getRelationView()
       this.relationViews = data
       const { views } = data
@@ -240,6 +252,7 @@ export default {
         this.$nextTick(() => {
           this.$refs.relationViewsGraph[index].setJsonData(_graphJsonData)
         })
+        this.loading = false
       })
     },
     checked(e, node) {
@@ -288,32 +301,59 @@ export default {
         this.checkedNodes.push(node.id)
       }
     },
-    async handleSaveRelationViews() {
-      if (!this.newRelationViewName) {
-        this.$message.warning(this.$t('cmdb.preference_relation.tips2'))
-        return
-      }
-      if (this.checkedNodes.length < 2) {
+    openServiceTreeModal(treeData, type) {
+      if (type === 'add' && this.checkedNodes.length < 2) {
         this.$message.warning(this.$t('cmdb.preference_relation.tips3'))
         return
       }
-      // eslint-disable-next-line camelcase
-      const cr_ids = []
-      this.checkedNodes.forEach((item, idx) => {
-        if (idx !== this.checkedNodes.length - 1) {
-          cr_ids.push({ parent_id: Number(item), child_id: Number(this.checkedNodes[idx + 1]) })
+      let _treeData = { ...treeData }
+      if (type === 'edit') {
+        const { name } = _treeData
+        _treeData = {
+          ...treeData,
+          ...(this.relationViews?.views[name]?.option ?? {}),
+          is_public: this.relationViews?.views[name]?.is_public ?? true,
         }
-      })
-      await subscribeRelationView({
-        cr_ids,
-        name: this.newRelationViewName,
-        is_public: this.is_public,
-      })
+      }
+      this.$refs.serviceTreeModal.open(_treeData, type)
+    },
+    async submitServiceTree(treeData, type, originName) {
+      const { name, is_public, is_show_leaf_node, is_show_tree_node, sort } = treeData
+      if (type === 'add') {
+        const cr_ids = []
+        this.checkedNodes.forEach((item, idx) => {
+          if (idx !== this.checkedNodes.length - 1) {
+            cr_ids.push({ parent_id: Number(item), child_id: Number(this.checkedNodes[idx + 1]) })
+          }
+        })
+        await subscribeRelationView({
+          cr_ids,
+          name,
+          is_public,
+          option: { is_show_leaf_node, is_show_tree_node, sort, is_public },
+        })
+      } else {
+        const _name = name === originName ? name : originName
+        const topo_flatten = this.relationViews?.views[_name]?.topo_flatten ?? []
+        const name2id = this.relationViews?.name2id.find((item) => item[0] === _name)
+        const cr_ids = []
+        topo_flatten.forEach((item, idx) => {
+          if (idx !== topo_flatten.length - 1) {
+            cr_ids.push({ parent_id: Number(item), child_id: Number(topo_flatten[idx + 1]) })
+          }
+        })
+        console.log(originName, name, cr_ids, name2id)
+        await putRelationView(name2id[1], {
+          cr_ids,
+          name,
+          is_public,
+          option: { is_show_leaf_node, is_show_tree_node, sort, is_public },
+        })
+      }
       this.resetRoute()
       this.getViewsData()
       this.isEdit = false
       this.checkedNodes = []
-      this.newRelationViewName = ''
     },
     async confirmDelete(viewName) {
       await deleteRelationView(viewName)
@@ -359,7 +399,7 @@ export default {
     width: 100%;
     .ci-type-relation-header {
       position: absolute;
-      top: 10px;
+      top: 20px;
       left: 20px;
       z-index: 10;
     }
@@ -368,12 +408,19 @@ export default {
     background-color: #fff;
     margin-top: 5px;
     position: relative;
+    .relation-views-edit,
     .relation-views-close {
       position: absolute;
       z-index: 10;
-      right: 20px;
+      right: 60px;
       top: 10px;
     }
+    .relation-views-edit {
+      right: 46px;
+    }
+    .relation-views-close {
+      right: 20px;
+    }
   }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/preference_relation/serviceTreeModal.vue b/cmdb-ui/src/modules/cmdb/views/preference_relation/serviceTreeModal.vue
new file mode 100644
index 0000000..583206a
--- /dev/null
+++ b/cmdb-ui/src/modules/cmdb/views/preference_relation/serviceTreeModal.vue
@@ -0,0 +1,110 @@
+<template>
+  <a-modal width="700px" :title="title" :visible="visible" @cancel="handleCancel" @ok="handleOK">
+    <a-form-model ref="form" :model="form" :rules="rules" :label-col="{ span: 8 }" :wrapper-col="{ span: 14 }">
+      <a-form-model-item :label="$t('cmdb.preference_relation.serviceTreeName')" prop="name">
+        <a-input v-model="form.name" :placeholder="$t('cmdb.preference_relation.serviceTreeNamePlaceholder')" />
+      </a-form-model-item>
+      <a-form-model-item :label="$t('cmdb.preference_relation.public')" prop="is_public">
+        <a-checkbox v-model="form.is_public"> </a-checkbox>
+      </a-form-model-item>
+      <a-form-model-item :label="$t('cmdb.preference_relation.showLeafNode')" prop="is_show_leaf_node">
+        <a-checkbox :checked="form.is_show_leaf_node" @change="changeLeaf"> </a-checkbox>
+      </a-form-model-item>
+      <a-form-model-item :label="$t('cmdb.preference_relation.showTreeNode')" prop="is_show_tree_node">
+        <a-checkbox :checked="form.is_show_tree_node" @change="changeNode"> </a-checkbox>
+      </a-form-model-item>
+      <a-form-model-item
+        v-if="form.is_show_leaf_node && form.is_show_tree_node"
+        :label="$t('cmdb.preference_relation.sort')"
+        prop="sort"
+      >
+        <a-radio-group v-model="form.sort">
+          <a-radio :value="1">
+            {{ $t('cmdb.preference_relation.sort1') }}
+          </a-radio>
+          <a-radio :value="2">
+            {{ $t('cmdb.preference_relation.sort2') }}
+          </a-radio>
+        </a-radio-group>
+      </a-form-model-item>
+    </a-form-model>
+  </a-modal>
+</template>
+
+<script>
+export default {
+  name: 'ServiceTreeModal',
+  data() {
+    return {
+      visible: false,
+      type: 'add',
+      originTreeData: {},
+      form: {
+        name: '',
+        is_public: true,
+        is_show_leaf_node: true,
+        is_show_tree_node: false,
+        sort: 1,
+      },
+      rules: {
+        name: [{ required: true, message: this.$t('cmdb.preference_relation.serviceTreeNamePlaceholder') }],
+        is_public: [{ required: false }],
+        is_show_leaf_node: [{ required: false }],
+        is_show_tree_node: [{ required: false }],
+      },
+    }
+  },
+  computed: {
+    title() {
+      if (this.type === 'edit') {
+        return this.$t('cmdb.preference_relation.editServiceTree')
+      }
+      return this.$t('cmdb.preference_relation.newServiceTree')
+    },
+  },
+  methods: {
+    open(treeData = {}, type) {
+      this.visible = true
+      this.type = type
+      this.originTreeData = { ...treeData }
+      this.form = { name: '', is_public: true, is_show_leaf_node: true, is_show_tree_node: false, sort: 1, ...treeData }
+    },
+    handleCancel() {
+      this.$refs.form.resetFields()
+      this.visible = false
+    },
+    handleOK() {
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          this.$emit('submitServiceTree', this.form, this.type, this.originTreeData?.name ?? undefined)
+          this.handleCancel()
+        }
+      })
+    },
+    changeLeaf(e) {
+      const checked = e.target.checked
+      if (!checked && !this.form.is_show_tree_node) {
+        this.$message.warning(this.$t('cmdb.preference_relation.tips4'))
+        return
+      }
+      this.form = {
+        ...this.form,
+        is_show_leaf_node: checked,
+      }
+    },
+    changeNode(e) {
+      const checked = e.target.checked
+      if (!checked && !this.form.is_show_leaf_node) {
+        this.$message.warning(this.$t('cmdb.preference_relation.tips4'))
+        return
+      }
+      this.form = {
+        ...this.form,
+        is_show_tree_node: checked,
+      }
+    },
+  },
+}
+</script>
+
+<style></style>
diff --git a/cmdb-ui/src/modules/cmdb/views/relation_views/index.vue b/cmdb-ui/src/modules/cmdb/views/relation_views/index.vue
index 3afcc72..4facb88 100644
--- a/cmdb-ui/src/modules/cmdb/views/relation_views/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/relation_views/index.vue
@@ -1,61 +1,51 @@
 <template>
   <div :style="{ marginBottom: '-24px', overflow: 'hidden' }">
     <div v-if="relationViews.name2id && relationViews.name2id.length" class="relation-views-wrapper">
-      <div class="cmdb-views-header">
-        <span
-          class="cmdb-views-header-title"
-        >{{ $route.meta.name }}
-          <div
-            class="ops-list-batch-action"
-            :style="{ backgroundColor: '#c0ceeb' }"
-            v-if="showBatchLevel !== null && batchTreeKey && batchTreeKey.length"
-          >
-            <span
-              @click="
-                () => {
-                  $refs.grantModal.open('depart')
-                }
-              "
-            >{{ $t('grant') }}</span
-            >
-            <a-divider type="vertical" />
-            <span
-              @click="
-                () => {
-                  $refs.revokeModal.open()
-                }
-              "
-            >{{ $t('revoke') }}</span
-            >
-            <template v-if="showBatchLevel > 0">
-              <a-divider type="vertical" />
-              <span @click="batchDeleteCIRelationFromTree">{{ $t('delete') }}</span>
-            </template>
-            <a-divider type="vertical" />
-            <span
-              @click="
-                () => {
-                  showBatchLevel = null
-                  batchTreeKey = []
-                }
-              "
-            >{{ $t('cancel') }}</span
-            >
-            <span>{{ $t('selectRows', { rows: batchTreeKey.length }) }}</span>
-          </div>
-        </span>
-        <a-button size="small" icon="user-add" type="primary" ghost @click="handlePerm">{{ $t('grant') }}</a-button>
-      </div>
       <SplitPane
         :min="200"
         :max="500"
         :paneLengthPixel.sync="paneLengthPixel"
         :appName="`cmdb-relation-views-${viewId}`"
-        triggerColor="#F0F5FF"
         :triggerLength="18"
       >
         <template #one>
           <div class="relation-views-left" :style="{ height: `${windowHeight - 115}px` }">
+            <div class="relation-views-left-header" :title="$route.meta.name">{{ $route.meta.name }}</div>
+            <div
+              class="ops-list-batch-action"
+              :style="{ marginBottom: '10px' }"
+              v-if="showBatchLevel !== null && batchTreeKey && batchTreeKey.length"
+            >
+              <span
+                @click="
+                  () => {
+                    $refs.grantModal.open('depart')
+                  }
+                "
+              >{{ $t('grant') }}</span
+              >
+              <span
+                @click="
+                  () => {
+                    $refs.revokeModal.open()
+                  }
+                "
+              >{{ $t('revoke') }}</span
+              >
+              <template v-if="showBatchLevel > 0">
+                <span @click="batchDeleteCIRelationFromTree">{{ $t('delete') }}</span>
+              </template>
+              <span
+                @click="
+                  () => {
+                    showBatchLevel = null
+                    batchTreeKey = []
+                  }
+                "
+              >{{ $t('cancel') }}</span
+              >
+              <span>{{ $t('selectRows', { rows: batchTreeKey.length }) }}</span>
+            </div>
             <a-tree
               :selectedKeys="selectedKeys"
               :loadData="onLoadData"
@@ -65,9 +55,10 @@
               @drop="onDrop"
               :expandedKeys="expandedKeys"
             >
-              <template #title="{ key: treeKey, title, isLeaf }">
+              <template #title="{ key: treeKey, title,number, isLeaf }">
                 <ContextMenu
                   :title="title"
+                  :number="number"
                   :treeKey="treeKey"
                   :levels="levels"
                   :isLeaf="isLeaf"
@@ -79,51 +70,69 @@
                   :showBatchLevel="showBatchLevel"
                   :batchTreeKey="batchTreeKey"
                   @clickCheckbox="clickCheckbox"
+                  @updateTreeData="updateTreeData"
                 />
               </template>
             </a-tree>
           </div>
         </template>
         <template #two>
-          <div id="relation-views-right" class="relation-views-right" :style="{ height: `${windowHeight - 115}px` }">
-            <a-tabs :activeKey="String(currentTypeId[0])" type="card" @change="changeCIType" class="ops-tab">
-              <a-tab-pane v-for="item in showTypes" :key="`${item.id}`" :tab="item.alias || item.name"> </a-tab-pane>
+          <div id="relation-views-right" class="relation-views-right" :style="{ height: `${windowHeight - 64}px` }">
+            <a-tabs :activeKey="currentTypeId[0]" class="ops-tab" @change="changeCIType" size="small">
+              <a-tab-pane v-for="item in showTypes" :key="item.id" :tab="item.alias || item.name"> </a-tab-pane>
+              <a-space slot="tabBarExtraContent">
+                <a-button
+                  v-if="isLeaf"
+                  type="primary"
+                  class="ops-button-ghost"
+                  ghost
+                  @click="$refs.create.handleOpen(true, 'create')"
+                ><ops-icon type="veops-increase" />{{ $t('create') }}</a-button
+                >
+                <a-button icon="user-add" type="primary" ghost @click="handlePerm" class="ops-button-ghost">{{
+                  $t('grant')
+                }}</a-button>
+                <EditAttrsPopover
+                  :typeId="Number(currentTypeId[0])"
+                  class="operation-icon"
+                  @refresh="refreshAfterEditAttrs"
+                >
+                  <a-button
+                    type="primary"
+                    ghost
+                    class="ops-button-ghost"
+                  ><ops-icon type="veops-configuration_table" />{{ $t('cmdb.configTable') }}</a-button
+                  >
+                </EditAttrsPopover>
+              </a-space>
             </a-tabs>
             <SearchForm
               ref="search"
               @refresh="refreshTable"
               :preferenceAttrList="preferenceAttrList"
-              :isShowExpression="true"
+              :isShowExpression="!(isLeaf && isShowBatchIcon)"
               :typeId="Number(currentTypeId[0])"
               @copyExpression="copyExpression"
               type="relationView"
-              :style="{ padding: '0 12px', marginTop: '16px' }"
-            />
-            <div class="relation-views-right-bar">
-              <a-space>
-                <a-button v-if="isLeaf" type="primary" size="small" @click="$refs.create.handleOpen(true, 'create')">{{
-                  $t('create')
-                }}</a-button>
-
+            >
+              <PreferenceSearch
+                v-if="!(isLeaf && isShowBatchIcon)"
+                ref="preferenceSearch"
+                @getQAndSort="getQAndSort"
+                @setParamsFromPreferenceSearch="setParamsFromPreferenceSearch"
+              />
+              <a-space slot="extraContent">
                 <div class="ops-list-batch-action" v-if="isLeaf && isShowBatchIcon">
                   <template v-if="selectedRowKeys.length">
                     <span @click="$refs.create.handleOpen(true, 'update')">{{ $t('update') }}</span>
-                    <a-divider type="vertical" />
                     <span @click="openBatchDownload">{{ $t('download') }}</span>
-                    <a-divider type="vertical" />
                     <span @click="batchDelete">{{ $t('cmdb.ciType.deleteInstance') }}</span>
-                    <a-divider type="vertical" />
                     <span @click="batchDeleteCIRelation">{{ $t('cmdb.history.deleteRelation') }}</span>
                     <span>{{ $t('cmdb.ci.selectRows', { rows: selectedRowKeys.length }) }}</span>
                   </template>
                 </div>
-                <PreferenceSearch
-                  ref="preferenceSearch"
-                  @getQAndSort="getQAndSort"
-                  @setParamsFromPreferenceSearch="setParamsFromPreferenceSearch"
-                />
               </a-space>
-            </div>
+            </SearchForm>
             <vxe-table
               :id="`cmdb-relation-${viewId}-${currentTypeId}`"
               border
@@ -283,14 +292,9 @@
                   </template>
                 </template>
               </vxe-table-column>
-              <vxe-column align="left" field="operate" fixed="right" width="120">
+              <vxe-column align="left" field="operate" fixed="right" width="80">
                 <template #header>
                   <span>{{ $t('operation') }}</span>
-                  <EditAttrsPopover
-                    :typeId="Number(currentTypeId[0])"
-                    class="operation-icon"
-                    @refresh="refreshAfterEditAttrs"
-                  />
                 </template>
                 <template #default="{ row }">
                   <a-space>
@@ -482,6 +486,9 @@ export default {
       contextMenuKey: null,
       showBatchLevel: null,
       batchTreeKey: [],
+
+      statisticsObj: {},
+      viewOption: {},
     }
   },
 
@@ -490,7 +497,7 @@ export default {
       return this.$store.state.windowHeight
     },
     tableHeight() {
-      return this.windowHeight - 295
+      return this.windowHeight - 244
     },
     selectedKeys() {
       if (this.treeKeys.length <= 1) {
@@ -519,6 +526,15 @@ export default {
         .map((item) => item.split('%')[0])
         .join(',')
     },
+    is_show_leaf_node() {
+      return this.viewOption?.is_show_leaf_node ?? true
+    },
+    is_show_tree_node() {
+      return this.viewOption?.is_show_tree_node ?? false
+    },
+    leaf_tree_sort() {
+      return this.viewOption?.sort ?? 1
+    },
   },
   provide() {
     return {
@@ -638,6 +654,7 @@ export default {
       if (q && q[0] === ',') {
         q = q.slice(1)
       }
+
       if (this.treeKeys.length === 0) {
         // await this.judgeCITypes(q)
         if (!refreshType) {
@@ -684,8 +701,10 @@ export default {
             .map((item) => item.split('%')[0])
             .join(',')}`
         }
-        const typeId = parseInt(this.treeKeys[this.treeKeys.length - 1].split('%')[1])
 
+        await this.judgeCITypes()
+
+        const typeId = parseInt(this.treeKeys[this.treeKeys.length - 1].split('%')[1])
         let level = []
         if (!this.leaf.includes(typeId)) {
           let startIdx = 0
@@ -705,8 +724,8 @@ export default {
         } else {
           level = [1]
         }
-        q += `&level=${level.join(',')}`
-        await this.judgeCITypes(q)
+
+        q += `&level=${this.topo_flatten.includes(this.currentTypeId[0]) ? 1 : level.join(',')}`
         if (!refreshType) {
           this.loadNoRoot(this.treeKeys[this.treeKeys.length - 1], level)
         }
@@ -793,69 +812,106 @@ export default {
       this.selectedRowKeys = []
       this.currentTypeId = [typeId]
       this.loadColumns()
-      this.$nextTick(() => {
-        this.refreshTable()
-      })
+      // this.$nextTick(() => {
+      //   this.refreshTable()
+      // })
     },
 
-    async judgeCITypes(q) {
-      const showTypeIds = []
-      let _showTypes = []
+    async judgeCITypes() {
       let _showTypeIds = []
-
+      let _showTypes = []
       if (this.treeKeys.length) {
-        const typeId = parseInt(this.treeKeys[this.treeKeys.length - 1].split('%')[1])
-
-        _showTypes = this.node2ShowTypes[typeId + '']
-        _showTypes.forEach((item) => {
-          _showTypeIds.push(item.id)
-        })
-      } else {
-        _showTypeIds = JSON.parse(JSON.stringify(this.origShowTypeIds))
-        _showTypes = JSON.parse(JSON.stringify(this.origShowTypes))
-      }
-      const promises = _showTypeIds.map((typeId) => {
-        let _q = (`q=_type:${typeId},` + q).replace(/count=\d*/, 'count=1')
-        if (Object.values(this.level2constraint).includes('2')) {
-          _q = _q + `&has_m2m=1`
+        if (this.is_show_leaf_node) {
+          const typeId = parseInt(this.treeKeys[this.treeKeys.length - 1].split('%')[1])
+          _showTypeIds = _.cloneDeep(this.origShowTypeIds)
+          _showTypes = _.cloneDeep(this.node2ShowTypes[typeId])
         }
-        if (this.root_parent_path) {
-          _q = _q + `&root_parent_path=${this.root_parent_path}`
-        }
-        // if (this.treeKeys.length === 0) {
-        //   return searchCI2(_q).then((res) => {
-        //     if (res.numfound !== 0) {
-        //       showTypeIds.push(typeId)
-        //     }
-        //   })
-        // } else {
-        _q = _q + `&descendant_ids=${this.descendant_ids}`
-        return searchCIRelation(_q).then((res) => {
-          if (res.numfound !== 0) {
-            showTypeIds.push(typeId)
-          }
-        })
-        // }
-      })
-      await Promise.all(promises).then(async () => {
-        if (showTypeIds.length && showTypeIds.sort().join(',') !== this.showTypeIds.sort().join(',')) {
-          const showTypes = []
-          _showTypes.forEach((item) => {
-            if (showTypeIds.includes(item.id)) {
-              showTypes.push(item)
+        if (this.is_show_tree_node) {
+          const treeKeyTypeId = Number(this.treeKeys.slice(-1)[0].split('%')[1])
+          const _idx = this.topo_flatten.findIndex((item) => item === treeKeyTypeId)
+          if (_idx > -1 && _idx < this.topo_flatten.length - 1) {
+            const _showTreeTypeId = this.topo_flatten[_idx + 1]
+            const _showTreeTypes = this.relationViews.id2type[_showTreeTypeId]
+            if (this.leaf_tree_sort === 1) {
+              _showTypeIds.push(_showTreeTypeId)
+              _showTypes.push(_showTreeTypes)
+            } else {
+              _showTypeIds.unshift(_showTreeTypeId)
+              _showTypes.unshift(_showTreeTypes)
             }
-          })
-          this.showTypes = showTypes
-          this.showTypeIds = showTypeIds
-          if (
-            !this.currentTypeId.length ||
-            (this.currentTypeId.length && !this.showTypeIds.includes(this.currentTypeId[0]))
-          ) {
-            this.currentTypeId = [this.showTypeIds[0]]
-            await this.loadColumns()
           }
         }
-      })
+        this.showTypeIds = _showTypeIds
+        this.showTypes = _showTypes
+      } else {
+        this.showTypeIds = _.cloneDeep(this.origShowTypeIds)
+        this.showTypes = JSON.parse(JSON.stringify(this.origShowTypes))
+      }
+      if (
+        !this.currentTypeId.length ||
+        (this.currentTypeId.length && !this.showTypeIds.includes(this.currentTypeId[0]))
+      ) {
+        this.currentTypeId = [this.showTypeIds[0]]
+        await this.loadColumns()
+      }
+      // const showTypeIds = []
+      // let _showTypes = []
+      // let _showTypeIds = []
+
+      // if (this.treeKeys.length) {
+      //   const typeId = parseInt(this.treeKeys[this.treeKeys.length - 1].split('%')[1])
+
+      //   _showTypes = this.node2ShowTypes[typeId + '']
+      //   _showTypes.forEach((item) => {
+      //     _showTypeIds.push(item.id)
+      //   })
+      // } else {
+      //   _showTypeIds = JSON.parse(JSON.stringify(this.origShowTypeIds))
+      //   _showTypes = JSON.parse(JSON.stringify(this.origShowTypes))
+      // }
+      // const promises = _showTypeIds.map((typeId) => {
+      //   let _q = (`q=_type:${typeId},` + q).replace(/count=\d*/, 'count=1')
+      //   if (Object.values(this.level2constraint).includes('2')) {
+      //     _q = _q + `&has_m2m=1`
+      //   }
+      //   if (this.root_parent_path) {
+      //     _q = _q + `&root_parent_path=${this.root_parent_path}`
+      //   }
+      //   // if (this.treeKeys.length === 0) {
+      //   //   return searchCI2(_q).then((res) => {
+      //   //     if (res.numfound !== 0) {
+      //   //       showTypeIds.push(typeId)
+      //   //     }
+      //   //   })
+      //   // } else {
+      //   _q = _q + `&descendant_ids=${this.descendant_ids}`
+      //   return searchCIRelation(_q).then((res) => {
+      //     if (res.numfound !== 0) {
+      //       showTypeIds.push(typeId)
+      //     }
+      //   })
+      //   // }
+      // })
+      // await Promise.all(promises).then(async () => {
+      //   if (showTypeIds.length && showTypeIds.sort().join(',') !== this.showTypeIds.sort().join(',')) {
+      //     const showTypes = []
+      //     _showTypes.forEach((item) => {
+      //       if (showTypeIds.includes(item.id)) {
+      //         showTypes.push(item)
+      //       }
+      //     })
+      //     console.log(showTypes)
+      //     this.showTypes = showTypes
+      //     this.showTypeIds = showTypeIds
+      //     if (
+      //       !this.currentTypeId.length ||
+      //       (this.currentTypeId.length && !this.showTypeIds.includes(this.currentTypeId[0]))
+      //     ) {
+      //       this.currentTypeId = [this.showTypeIds[0]]
+      //       await this.loadColumns()
+      //     }
+      //   }
+      // })
     },
 
     async loadRoot() {
@@ -980,7 +1036,8 @@ export default {
       const treeData = []
       facet.forEach((item) => {
         treeData.push({
-          title: `${item[0]} (${item[1]})`,
+          title: item[0],
+          number: item[1],
           key: this.treeKeys.join('@^@') + '@^@' + item[2] + '%' + item[3] + '%' + `{"${item[4]}":"${item[0]}"}`,
           isLeaf: this.leaf.includes(item[3]),
           id: item[2],
@@ -1041,16 +1098,19 @@ export default {
           this.leaf = this.relationViews.views[this.viewName].leaf
           this.currentView = `${this.viewId}`
           this.typeId = this.levels[0][0]
+          this.viewOption = this.relationViews.views[this.viewName].option ?? {}
           this.refreshTable()
         }
       })
     },
 
     async loadColumns() {
-      this.getAttributeList()
-      const res = await getSubscribeAttributes(this.currentTypeId[0])
-      this.preferenceAttrList = res.attributes
-      this.calcColumns()
+      if (this.currentTypeId[0]) {
+        this.getAttributeList()
+        const res = await getSubscribeAttributes(this.currentTypeId[0])
+        this.preferenceAttrList = res.attributes
+        this.calcColumns()
+      }
     },
 
     calcColumns() {
@@ -1183,7 +1243,6 @@ export default {
         const dragId = _splitDragKey[_splitDragKey.length - 1].split('%')[0]
         // const targetObj = JSON.parse(_splitTargetKey[_splitTargetKey.length - 1].split('%')[2])
         const targetId = _splitTargetKey[_splitTargetKey.length - 1].split('%')[0]
-        console.log(_splitDragKey)
         // TODO 拖拽这里不造咋弄 等等再说吧
         batchUpdateCIRelationChildren([dragId], [targetId]).then((res) => {
           this.reload()
@@ -1354,6 +1413,9 @@ export default {
               ...data,
             }
             this.initialInstanceList = _initialInstanceList
+            this.$nextTick(() => {
+              this.refreshTable()
+            })
           })
           .catch((err) => {
             console.log(err)
@@ -1579,7 +1641,6 @@ export default {
         .split('@^@')
         .filter((item) => !!item)
         .reverse()
-      console.log(needGrantNodes)
 
       const needGrantRids = [...department, ...user]
       const floor = Math.ceil(needGrantRids.length / 6)
@@ -1687,6 +1748,29 @@ export default {
       this.showBatchLevel = null
       this.batchTreeKey = []
     },
+    findNode(node, target) {
+      for (let i = 0; i < node.length; i++) {
+        if (node[i].id === target) {
+          return node[i]
+        }
+        if (node[i].children && node[i].children.length) {
+          for (let i = 0; i < node[i].children.length; i++) {
+            const found = this.findNode(node[i].children, target)
+            if (found) {
+              return found
+            }
+          }
+        }
+      }
+      return null
+    },
+    updateTreeData(ciId, value) {
+      const _find = this.findNode(this.treeData, ciId)
+      if (_find) {
+        this.$set(_find, 'title', value)
+      }
+      this.refreshTable()
+    },
   },
 }
 </script>
@@ -1701,15 +1785,24 @@ export default {
     width: 100%;
     float: left;
     position: relative;
-    // transition: all 0.3s;
-    background-color: #fff;
     overflow: hidden;
-    padding: 12px;
-    border-top-left-radius: 15px;
-    border-top-right-radius: 15px;
+    padding: 0;
     &:hover {
       overflow: auto;
     }
+    .relation-views-left-header {
+      border-left: 4px solid @primary-color;
+      height: 32px;
+      line-height: 32px;
+      padding-left: 12px;
+      margin-bottom: 12px;
+      color: @text-color_1;
+      font-weight: bold;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      cursor: default;
+    }
     .ant-tree li {
       padding: 2px 0;
     }
@@ -1732,15 +1825,8 @@ export default {
     width: 100%;
     overflow: auto;
     background-color: #fff;
-    .relation-views-right-bar {
-      display: flex;
-      flex-direction: row;
-      justify-content: flex-start;
-      align-items: center;
-      margin-bottom: 5px;
-      height: 32px;
-      padding: 0 12px;
-    }
+    padding: 20px;
+    border-radius: @border-radius-box;
   }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/relation_views/modules/ContextMenu.vue b/cmdb-ui/src/modules/cmdb/views/relation_views/modules/ContextMenu.vue
index c22ec7b..5d8f36e 100644
--- a/cmdb-ui/src/modules/cmdb/views/relation_views/modules/ContextMenu.vue
+++ b/cmdb-ui/src/modules/cmdb/views/relation_views/modules/ContextMenu.vue
@@ -6,7 +6,10 @@
     }"
     @click="clickNode"
   >
-    <span>
+    <span class="relation-views-node-switch">
+      <a-icon v-if="childLength && !isLeaf" :type="switchIcon"></a-icon>
+    </span>
+    <span class="relation-views-node-content">
       <a-checkbox @click.stop="clickCheckbox" class="relation-views-node-checkbox" v-if="showCheckbox" />
       <template v-if="icon">
         <img
@@ -24,61 +27,82 @@
         />
         <span class="relation-views-node-icon" v-else>{{ icon ? icon[0].toUpperCase() : 'i' }}</span>
       </template>
-      <span class="relation-views-node-title">{{ this.title }}</span>
-    </span>
-    <a-dropdown>
-      <a-menu slot="overlay" @click="({ key: menuKey }) => this.onContextMenuClick(this.treeKey, menuKey)">
-        <template v-if="showBatchLevel === null">
-          <a-menu-item
-            v-for="item in menuList"
-            :key="item.id"
-          ><a-icon type="plus-circle" />{{ $t('new') }} {{ item.alias }}</a-menu-item
-          >
-          <a-menu-item
-            v-if="showDelete"
-            key="delete"
-          ><ops-icon type="icon-xianxing-delete" />{{ $t('cmdb.serviceTree.deleteNode') }}</a-menu-item
-          >
-          <a-menu-divider />
-          <a-menu-item key="grant"><a-icon type="user-add" />{{ $t('grant') }}</a-menu-item>
-          <a-menu-item key="revoke"><a-icon type="user-delete" />{{ $t('revoke') }}</a-menu-item>
-          <a-menu-item key="view"><a-icon type="eye" />{{ $t('cmdb.serviceTree.view') }}</a-menu-item>
-          <a-menu-divider />
-          <a-menu-item
-            key="batch"
-          ><ops-icon type="icon-xianxing-copy" />{{ $t('cmdb.serviceTree.batch') }}</a-menu-item
-          >
-        </template>
-        <template v-else>
-          <a-menu-item
-            :disabled="!batchTreeKey || !batchTreeKey.length"
-            key="batchGrant"
-          ><a-icon type="user-add" />{{ $t('grant') }}</a-menu-item
-          >
-          <a-menu-item
-            :disabled="!batchTreeKey || !batchTreeKey.length"
-            key="batchRevoke"
-          ><a-icon type="user-delete" />{{ $t('revoke') }}</a-menu-item
-          >
-          <a-menu-divider />
-          <template v-if="showBatchLevel > 0">
+      <span class="relation-views-node-title" v-if="!isEditNodeName" :title="title">{{ title }}</span>
+      <a-input
+        ref="input"
+        @blur="changeNodeName"
+        @pressEnter="
+          () => {
+            $refs.input.blur()
+          }
+        "
+        size="small"
+        v-else
+        v-model="editNodeName"
+        :style="{ marginLeft: '5px' }"
+      />
+      <span class="relation-views-node-number">{{ number }}</span>
+      <a-dropdown overlayClassName="relation-views-node-dropdown" :overlayStyle="{ width: '200px' }">
+        <a-menu slot="overlay" @click="({ key: menuKey }) => onContextMenuClick(this.treeKey, menuKey)">
+          <template v-if="showBatchLevel === null">
+            <a-divider orientation="left">{{ $t('cmdb.relation') }}</a-divider>
+            <a-menu-item
+              v-for="item in menuList"
+              :key="item.id"
+            ><a-icon type="plus-circle" />{{ $t('add') }} {{ item.alias }}</a-menu-item
+            >
+            <a-menu-item
+              v-if="showDelete"
+              key="delete"
+            ><ops-icon type="icon-xianxing-delete" />{{
+              $t('cmdb.serviceTree.deleteNode', { name: title })
+            }}</a-menu-item
+            >
+            <a-divider orientation="left">{{ $t('cmdb.components.perm') }}</a-divider>
+            <a-menu-item key="grant"><a-icon type="user-add" />{{ $t('grant') }}</a-menu-item>
+            <a-menu-item key="revoke"><a-icon type="user-delete" />{{ $t('revoke') }}</a-menu-item>
+            <a-menu-item key="view"><a-icon type="eye" />{{ $t('cmdb.serviceTree.view') }}</a-menu-item>
+            <a-menu-divider />
+            <a-menu-item
+              key="editNodeName"
+            ><ops-icon type="icon-xianxing-edit" />{{ $t('cmdb.serviceTree.editNodeName') }}</a-menu-item
+            >
+            <a-menu-item
+              key="batch"
+            ><ops-icon type="veops-copy" />{{ $t('cmdb.serviceTree.batch') }}</a-menu-item
+            >
+          </template>
+          <template v-else>
             <a-menu-item
               :disabled="!batchTreeKey || !batchTreeKey.length"
-              key="batchDelete"
-            ><ops-icon type="icon-xianxing-delete" />{{ $t('delete') }}</a-menu-item
+              key="batchGrant"
+            ><a-icon type="user-add" />{{ $t('grant') }}</a-menu-item
+            >
+            <a-menu-item
+              :disabled="!batchTreeKey || !batchTreeKey.length"
+              key="batchRevoke"
+            ><a-icon type="user-delete" />{{ $t('revoke') }}</a-menu-item
             >
             <a-menu-divider />
+            <template v-if="showBatchLevel > 0">
+              <a-menu-item
+                :disabled="!batchTreeKey || !batchTreeKey.length"
+                key="batchDelete"
+              ><ops-icon type="icon-xianxing-delete" />{{ $t('delete') }}</a-menu-item
+              >
+              <a-menu-divider />
+            </template>
+            <a-menu-item key="batchCancel"><a-icon type="close-circle" />{{ $t('cancel') }}</a-menu-item>
           </template>
-          <a-menu-item key="batchCancel"><a-icon type="close-circle" />{{ $t('cancel') }}</a-menu-item>
-        </template>
-      </a-menu>
-      <a-icon class="relation-views-node-operation" type="ellipsis" />
-    </a-dropdown>
-    <a-icon :style="{ fontSize: '10px' }" v-if="childLength && !isLeaf" :type="switchIcon"></a-icon>
+        </a-menu>
+        <a-icon class="relation-views-node-operation" type="ellipsis" />
+      </a-dropdown>
+    </span>
   </div>
 </template>
 
 <script>
+import { updateCI } from '../../../api/ci.js'
 export default {
   name: 'ContextMenu',
   props: {
@@ -86,6 +110,10 @@ export default {
       type: String,
       default: '',
     },
+    number: {
+      type: Number,
+      default: 0,
+    },
     treeKey: {
       type: String,
       default: '',
@@ -121,13 +149,14 @@ export default {
   },
   data() {
     return {
-      switchIcon: 'down',
+      switchIcon: 'caret-right',
+      isEditNodeName: false,
+      editNodeName: '',
     }
   },
   computed: {
     childLength() {
-      const reg = /(?<=\()\S+(?=\))/g
-      return Number(this.title.match(reg)[0])
+      return this.number
     },
     splitTreeKey() {
       return this.treeKey.split('@^@')
@@ -175,26 +204,63 @@ export default {
   },
   methods: {
     onContextMenuClick(treeKey, menuKey) {
+      if (menuKey === 'editNodeName') {
+        this.isEditNodeName = true
+        this.editNodeName = this.title
+        this.$nextTick(() => {
+          this.$refs.input.focus()
+        })
+        return
+      }
       this.$emit('onContextMenuClick', treeKey, menuKey)
     },
     clickNode() {
       this.$emit('onNodeClick', this.treeKey)
-      this.switchIcon = this.switchIcon === 'down' ? 'up' : 'down'
+      this.switchIcon = this.switchIcon === 'caret-right' ? 'caret-down' : 'caret-right'
     },
     clickCheckbox() {
       this.$emit('clickCheckbox', this.treeKey)
     },
+    changeNodeName(e) {
+      const value = e.target.value
+      if (value !== this.title) {
+        const ci = this.treeKey
+          .split('@^@')
+          .slice(-1)[0]
+          .split('%')
+        const unique = Object.keys(JSON.parse(ci[2]))[0]
+        const ciId = Number(ci[0])
+
+        updateCI(ciId, { [unique]: value }).then((res) => {
+          this.$message.success(this.$t('updateSuccess'))
+          this.$emit('updateTreeData', ciId, value)
+        })
+      }
+      this.isEditNodeName = false
+      this.editNodeName = ''
+    },
   },
 }
 </script>
 
 <style lang="less" scoped>
+@import '~@/style/static.less';
+
 .relation-views-node {
   width: 100%;
   display: inline-flex;
   justify-content: space-between;
   align-items: center;
-  > span {
+  .relation-views-node-switch {
+    display: inline-block;
+    width: 15px;
+    color: @text-color_5;
+    i {
+      opacity: 0;
+      font-size: 10px;
+    }
+  }
+  .relation-views-node-content {
     display: flex;
     overflow: hidden;
     align-items: center;
@@ -215,16 +281,21 @@ export default {
       text-overflow: ellipsis;
       white-space: nowrap;
       overflow: hidden;
-      width: calc(100% - 16px);
+      flex: 1;
+      color: @text-color_1;
+    }
+    .relation-views-node-number {
+      color: @text-color_4;
+      font-size: 12px;
+      margin: 0 5px;
+    }
+    .relation-views-node-operation {
+      opacity: 0;
+      width: 15px;
     }
   }
-  .relation-views-node-operation {
-    display: none;
-    margin-right: 5px;
-  }
 }
-.relation-views-node-checkbox,
-.relation-views-node-moveright {
+.relation-views-node-checkbox {
   > span {
     .relation-views-node-checkbox {
       margin-right: 10px;
@@ -234,14 +305,16 @@ export default {
     }
   }
 }
+
+.relation-views-left .ant-tree:hover {
+  .relation-views-node .relation-views-node-switch i {
+    opacity: 1;
+  }
+}
 </style>
 
 <style lang="less">
-.relation-views-left .ant-tree-node-content-wrapper:hover {
-  .relation-views-node-operation {
-    display: inline-block;
-  }
-}
+@import '~@/style/static.less';
 .relation-views-left {
   ul:has(.relation-views-node-checkbox) > li > ul {
     margin-left: 26px;
@@ -249,5 +322,28 @@ export default {
   ul:has(.relation-views-node-checkbox) {
     margin-left: 0 !important;
   }
+  .ant-tree-node-content-wrapper:hover {
+    .relation-views-node-operation {
+      opacity: 1;
+    }
+  }
+  .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected,
+  .ant-tree li .ant-tree-node-content-wrapper:hover {
+    background-color: @primary-color_3;
+  }
+}
+
+.relation-views-node-dropdown {
+  .ant-divider {
+    margin: 0;
+    .ant-divider-inner-text {
+      font-size: 12px;
+      color: @text-color_3;
+    }
+  }
+  .ant-dropdown-menu-item {
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/resource_search/index.vue b/cmdb-ui/src/modules/cmdb/views/resource_search/index.vue
index 0468e84..b50e22d 100644
--- a/cmdb-ui/src/modules/cmdb/views/resource_search/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/resource_search/index.vue
@@ -1,196 +1,194 @@
 <template>
-  <div id="resource_search" :style="{ height: fromCronJob ? `${windowHeight - 48}px` : `${windowHeight - 90}px` }">
+  <div
+    class="resource-search"
+    id="resource_search"
+    :style="{ height: fromCronJob ? `${windowHeight - 48}px` : `${windowHeight - 64}px` }"
+  >
     <div class="cmdb-views-header">
       <span>
         <span class="cmdb-views-header-title">{{ $t('cmdb.menu.ciSearch') }}</span>
       </span>
-    </div>
-    <div :style="{ backgroundColor: '#fff', padding: '12px', borderRadius: '15px' }">
-      <SearchForm
-        ref="search"
-        type="resourceSearch"
-        @refresh="handleSearch"
-        :preferenceAttrList="allAttributesList"
-        @updateAllAttributesList="updateAllAttributesList"
-        @copyExpression="copyExpression"
-      />
-      <div
+      <a-button
         v-if="!fromCronJob"
-        :style="{
-          display: 'flex',
-          justifyContent: 'space-between',
-          height: '32px',
-          marginBottom: '5px',
-          alignItems: 'center',
-        }"
-      >
-        <a-button icon="download" type="primary" ghost size="small" @click="handleExport">{{
-          $t('download')
-        }}</a-button>
-        <PreferenceSearch
-          ref="preferenceSearch"
-          @getQAndSort="getQAndSort"
-          @setParamsFromPreferenceSearch="setParamsFromPreferenceSearch"
-        />
-      </div>
-      <vxe-table
-        :id="`cmdb-resource`"
-        border
-        keep-source
-        show-overflow
-        resizable
-        ref="xTable"
-        size="small"
-        row-id="_id"
-        :loading="loading"
-        :height="fromCronJob ? windowHeight - 180 : windowHeight - 250"
-        show-header-overflow
-        highlight-hover-row
-        :data="instanceList"
-        :sort-config="{ remote: true, trigger: 'cell' }"
-        @sort-change="handleSortCol"
-        :row-key="true"
-        :column-key="true"
-        :cell-style="getCellStyle"
-        :scroll-y="{ enabled: true, gt: 20 }"
-        :scroll-x="{ enabled: true, gt: 0 }"
-        :export-config="{
-          isColgroup: true,
-          type: 'xlsx',
-          types: ['xlsx', 'csv', 'html', 'xml', 'txt'],
-          mode: 'current',
-          modes: ['current'],
-          isFooter: false,
-          isHeader: true,
-          isColgroup: true,
-        }"
-        class="ops-unstripe-table"
-        :style="{ margin: '0 -12px' }"
-        :custom-config="{ storage: true }"
+        icon="download"
+        type="primary"
+        class="ops-button-ghost"
+        ghost
+        @click="handleExport"
+      >{{ $t('download') }}</a-button
       >
+    </div>
+    <SearchForm
+      ref="search"
+      type="resourceSearch"
+      @refresh="handleSearch"
+      :preferenceAttrList="allAttributesList"
+      @updateAllAttributesList="updateAllAttributesList"
+      @copyExpression="copyExpression"
+    >
+      <PreferenceSearch
+        v-if="!fromCronJob"
+        ref="preferenceSearch"
+        @getQAndSort="getQAndSort"
+        @setParamsFromPreferenceSearch="setParamsFromPreferenceSearch"
+      />
+    </SearchForm>
+    <vxe-table
+      :id="`cmdb-resource`"
+      border
+      keep-source
+      show-overflow
+      resizable
+      ref="xTable"
+      size="small"
+      row-id="_id"
+      :loading="loading"
+      :height="fromCronJob ? windowHeight - 180 : windowHeight - 240"
+      show-header-overflow
+      highlight-hover-row
+      :data="instanceList"
+      :sort-config="{ remote: true, trigger: 'cell' }"
+      @sort-change="handleSortCol"
+      :row-key="true"
+      :column-key="true"
+      :cell-style="getCellStyle"
+      :scroll-y="{ enabled: true, gt: 20 }"
+      :scroll-x="{ enabled: true, gt: 0 }"
+      :export-config="{
+        isColgroup: true,
+        type: 'xlsx',
+        types: ['xlsx', 'csv', 'html', 'xml', 'txt'],
+        mode: 'current',
+        modes: ['current'],
+        isFooter: false,
+        isHeader: true,
+        isColgroup: true,
+      }"
+      class="ops-unstripe-table"
+      :custom-config="{ storage: true }"
+    >
+      <vxe-column
+        v-if="instanceList.length"
+        :title="$t('cmdb.ciType.ciType')"
+        field="ci_type_alias"
+        :width="100"
+        fixed="left"
+      ></vxe-column>
+      <vxe-colgroup v-for="colGroup in columnsGroup" :key="colGroup.value" :title="colGroup.label">
+        <template #header>
+          <span :style="{ display: 'inline-flex', alignItems: 'center' }">
+            {{ colGroup.label }}
+            <EditAttrsPopover
+              :style="{ borderLeft: 'none', width: '30px', height: '38px', cursor: 'pointer' }"
+              v-if="colGroup.isCiType"
+              :typeId="Number(colGroup.id.split('-')[1])"
+              @refresh="loadInstance"
+            />
+          </span>
+        </template>
         <vxe-column
-          v-if="instanceList.length"
-          :title="$t('cmdb.ciType.ciType')"
-          field="ci_type_alias"
-          :width="100"
-          fixed="left"
-        ></vxe-column>
-        <vxe-colgroup v-for="colGroup in columnsGroup" :key="colGroup.value" :title="colGroup.label">
-          <template #header>
-            <span :style="{ display: 'inline-flex', alignItems: 'center' }">
-              {{ colGroup.label }}
-              <EditAttrsPopover
-                :style="{ borderLeft: 'none', width: '30px', height: '38px', cursor: 'pointer' }"
-                v-if="colGroup.isCiType"
-                :typeId="Number(colGroup.id.split('-')[1])"
-                @refresh="loadInstance"
-              />
-            </span>
-          </template>
-          <vxe-column
-            v-for="(col, index) in colGroup.children"
-            :key="`${col.field}_${index}`"
-            :title="col.title"
-            :field="col.field"
-            :width="col.width"
-            :minWidth="100"
-            :cell-type="col.value_type === '2' ? 'string' : 'auto'"
-          >
-            <template v-if="col.value_type === '6' || col.is_link || col.is_password || col.is_choice" #default="{row}">
-              <span v-if="col.value_type === '6' && row[col.field]">{{ JSON.stringify(row[col.field]) }}</span>
-              <a
-                v-else-if="col.is_link && row[col.field]"
-                :href="
-                  row[col.field].startsWith('http') || row[col.field].startsWith('https')
-                    ? `${row[col.field]}`
-                    : `http://${row[col.field]}`
-                "
-                target="_blank"
-              >{{ row[col.field] }}</a
-              >
-              <PasswordField
-                v-else-if="col.is_password && row[col.field]"
-                :ci_id="row._id"
-                :attr_id="col.attr_id"
-              ></PasswordField>
-              <template v-else-if="col.is_choice">
-                <template v-if="col.is_list">
-                  <span
-                    v-for="value in row[col.field]"
-                    :key="value"
-                    :style="{
-                      borderRadius: '4px',
-                      padding: '1px 5px',
-                      margin: '2px',
-                      ...getChoiceValueStyle(col, value),
-                    }"
-                  ><ops-icon
-                    :style="{ color: getChoiceValueIcon(col, value).color }"
-                    :type="getChoiceValueIcon(col, value).name"
-                  />{{ value }}</span
-                  >
-                </template>
+          v-for="(col, index) in colGroup.children"
+          :key="`${col.field}_${index}`"
+          :title="col.title"
+          :field="col.field"
+          :width="col.width"
+          :minWidth="100"
+          :cell-type="col.value_type === '2' ? 'string' : 'auto'"
+        >
+          <template v-if="col.value_type === '6' || col.is_link || col.is_password || col.is_choice" #default="{row}">
+            <span v-if="col.value_type === '6' && row[col.field]">{{ JSON.stringify(row[col.field]) }}</span>
+            <a
+              v-else-if="col.is_link && row[col.field]"
+              :href="
+                row[col.field].startsWith('http') || row[col.field].startsWith('https')
+                  ? `${row[col.field]}`
+                  : `http://${row[col.field]}`
+              "
+              target="_blank"
+            >{{ row[col.field] }}</a
+            >
+            <PasswordField
+              v-else-if="col.is_password && row[col.field]"
+              :ci_id="row._id"
+              :attr_id="col.attr_id"
+            ></PasswordField>
+            <template v-else-if="col.is_choice">
+              <template v-if="col.is_list">
                 <span
-                  v-else
+                  v-for="value in row[col.field]"
+                  :key="value"
                   :style="{
                     borderRadius: '4px',
                     padding: '1px 5px',
-                    margin: '2px 0',
-                    ...getChoiceValueStyle(col, row[col.field]),
+                    margin: '2px',
+                    ...getChoiceValueStyle(col, value),
                   }"
-                >
-                  <ops-icon
-                    :style="{ color: getChoiceValueIcon(col, row[col.field]).color }"
-                    :type="getChoiceValueIcon(col, row[col.field]).name"
-                  />
-                  {{ row[col.field] }}</span
+                ><ops-icon
+                  :style="{ color: getChoiceValueIcon(col, value).color }"
+                  :type="getChoiceValueIcon(col, value).name"
+                />{{ value }}</span
                 >
               </template>
+              <span
+                v-else
+                :style="{
+                  borderRadius: '4px',
+                  padding: '1px 5px',
+                  margin: '2px 0',
+                  ...getChoiceValueStyle(col, row[col.field]),
+                }"
+              >
+                <ops-icon
+                  :style="{ color: getChoiceValueIcon(col, row[col.field]).color }"
+                  :type="getChoiceValueIcon(col, row[col.field]).name"
+                />
+                {{ row[col.field] }}</span
+              >
             </template>
-          </vxe-column>
-        </vxe-colgroup>
-
-        <template #empty>
-          <div>
-            <img :style="{ width: '200px' }" :src="require('@/assets/data_empty.png')" />
-            <div>{{ $t('noData') }}</div>
-          </div>
-        </template>
-        <template #loading>
-          <div style="height: 200px; line-height: 200px">{{ $t('loading') }}</div>
-        </template>
-      </vxe-table>
-      <div :style="{ textAlign: 'right', marginTop: '4px' }">
-        <a-pagination
-          :showSizeChanger="true"
-          :current="currentPage"
-          size="small"
-          :total="totalNumber"
-          show-quick-jumper
-          :page-size="pageSize"
-          :page-size-options="pageSizeOptions"
-          @showSizeChange="onShowSizeChange"
-          :show-total="
-            (total, range) =>
-              $t('pagination.total', {
-                range0: range[0],
-                range1: range[1],
-                total,
-              })
-          "
-          @change="
-            (page) => {
-              currentPage = page
-              loadInstance(sortByTable)
-            }
-          "
-        >
-          <template slot="buildOptionText" slot-scope="props">
-            <span v-if="props.value !== '100000'">{{ props.value }}{{ $t('itemsPerPage') }}</span>
-            <span v-if="props.value === '100000'">{{ $t('all') }}</span>
           </template>
-        </a-pagination>
-      </div>
+        </vxe-column>
+      </vxe-colgroup>
+
+      <template #empty>
+        <div>
+          <img :style="{ width: '140px' }" :src="require('@/assets/data_empty.png')" />
+          <div>{{ $t('noData') }}</div>
+        </div>
+      </template>
+      <template #loading>
+        <div style="height: 200px; line-height: 200px">{{ $t('loading') }}</div>
+      </template>
+    </vxe-table>
+    <div :style="{ textAlign: 'right', marginTop: '4px' }">
+      <a-pagination
+        :showSizeChanger="true"
+        :current="currentPage"
+        size="small"
+        :total="totalNumber"
+        show-quick-jumper
+        :page-size="pageSize"
+        :page-size-options="pageSizeOptions"
+        @showSizeChange="onShowSizeChange"
+        :show-total="
+          (total, range) =>
+            $t('pagination.total', {
+              range0: range[0],
+              range1: range[1],
+              total,
+            })
+        "
+        @change="
+          (page) => {
+            currentPage = page
+            loadInstance(sortByTable)
+          }
+        "
+      >
+        <template slot="buildOptionText" slot-scope="props">
+          <span v-if="props.value !== '100000'">{{ props.value }}{{ $t('itemsPerPage') }}</span>
+          <span v-if="props.value === '100000'">{{ $t('all') }}</span>
+        </template>
+      </a-pagination>
     </div>
 
     <BatchDownload
@@ -227,6 +225,7 @@ export default {
   data() {
     return {
       ciTypes: [],
+      originAllAttributesList: [],
       allAttributesList: [], // 当前选择的模型的全部attributes  默认全部
       currentPage: 1,
       pageSizeOptions: ['50', '100', '200', '100000'],
@@ -260,18 +259,19 @@ export default {
         this.ciTypes = res.ci_types
       })
     },
-    getAllAttr() {
-      searchAttributes({ page_size: 9999 }).then((res) => {
+    async getAllAttr() {
+      await searchAttributes({ page_size: 9999 }).then((res) => {
         this.allAttributesList = res.attributes
+        this.originAllAttributesList = res.attributes
       })
     },
-    updateAllAttributesList(value) {
+    async updateAllAttributesList(value) {
       if (value && value.length) {
-        getCITypeAttributesByTypeIds({ type_ids: value.join(',') }).then((res) => {
+        await getCITypeAttributesByTypeIds({ type_ids: value.join(',') }).then((res) => {
           this.allAttributesList = res.attributes
         })
       } else {
-        this.getAllAttr()
+        this.allAttributesList = this.originAllAttributesList
       }
     },
     async loadInstance(sortByTable = undefined) {
@@ -373,7 +373,6 @@ export default {
               }
             }
           })
-
           const _commonColumnsGroup = Object.keys(commonObject).map((key) => {
             return {
               id: `parent-${key}`,
@@ -411,7 +410,7 @@ export default {
         return { ...item, id: item.field, label: item.title }
       })
     },
-    handleSearch() {
+    async handleSearch() {
       this.currentPage = 1
       this.loadInstance()
     },
@@ -534,3 +533,14 @@ export default {
   },
 }
 </script>
+
+<style lang="less" scoped>
+@import '~@/style/static.less';
+
+.resource-search {
+  margin-bottom: -24px;
+  background-color: #fff;
+  padding: 20px;
+  border-radius: @border-radius-box;
+}
+</style>
diff --git a/cmdb-ui/src/modules/cmdb/views/tree_views/index.vue b/cmdb-ui/src/modules/cmdb/views/tree_views/index.vue
index 9ffa723..4c27f2c 100644
--- a/cmdb-ui/src/modules/cmdb/views/tree_views/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/tree_views/index.vue
@@ -4,34 +4,15 @@
       <a-alert :message="$t('cmdb.tree.tips1')" banner></a-alert>
     </div>
     <div class="tree-views" v-else>
-      <div class="cmdb-views-header">
-        <span>
-          <span class="cmdb-views-header-title">{{ currentCiTypeName }}</span>
-          <span
-            @click="
-              () => {
-                $refs.metadataDrawer.open(typeId)
-              }
-            "
-            class="cmdb-views-header-metadata"
-          ><a-icon type="info-circle" />
-            {{ $t('cmdb.components.attributeDesc') }}
-          </span>
-        </span>
-        <a-button size="small" icon="plus" type="primary" @click="$refs.create.handleOpen(true, 'create')">{{
-          $t('create')
-        }}</a-button>
-      </div>
       <SplitPane
         :min="200"
         :max="500"
         :paneLengthPixel.sync="paneLengthPixel"
         appName="cmdb-tree-views"
-        triggerColor="#F0F5FF"
         :triggerLength="18"
       >
         <template #one>
-          <div class="tree-views-left" :style="{ height: `${windowHeight - 115}px` }">
+          <div class="tree-views-left" :style="{ height: `${windowHeight - 64}px` }">
             <draggable
               v-model="subscribeTreeViewCiTypes"
               :animation="300"
@@ -89,12 +70,12 @@
                   :expandedKeys="expandedKeys"
                   v-if="Number(ciType.type_id) === Number(typeId)"
                 >
-                  <a-icon slot="switcherIcon" type="down" />
-                  <template #title="{ key: treeKey, title, isLeaf }">
+                  <template #title="{ key: treeKey, title, isLeaf, childLength}">
                     <TreeViewsNode
                       :title="title"
                       :treeKey="treeKey"
                       :levels="levels"
+                      :childLength="childLength"
                       :isLeaf="isLeaf"
                       @onNodeClick="onNodeClick"
                     />
@@ -105,16 +86,49 @@
           </div>
         </template>
         <template #two>
-          <div class="tree-views-right" id="tree-views-right" :style="{ height: `${windowHeight - 115}px` }">
+          <div class="tree-views-right" id="tree-views-right" :style="{ height: `${windowHeight - 64}px` }">
+            <div class="cmdb-views-header">
+              <span>
+                <span class="cmdb-views-header-title">{{ currentCiTypeName }}</span>
+                <span
+                  @click="
+                    () => {
+                      $refs.metadataDrawer.open(typeId)
+                    }
+                  "
+                  class="cmdb-views-header-metadata"
+                ><a-icon type="info-circle" />
+                  {{ $t('cmdb.ci.attributeDesc') }}
+                </span>
+              </span>
+              <a-space>
+                <a-button
+                  type="primary"
+                  class="ops-button-ghost"
+                  ghost
+                  @click="$refs.create.handleOpen(true, 'create')"
+                ><ops-icon type="veops-increase" />
+                  {{ $t('create') }}
+                </a-button>
+                <EditAttrsPopover :typeId="Number(typeId)" class="operation-icon" @refresh="refreshAfterEditAttrs">
+                  <a-button
+                    type="primary"
+                    ghost
+                    class="ops-button-ghost"
+                  ><ops-icon type="veops-configuration_table" />{{ $t('cmdb.configTable') }}</a-button
+                  >
+                </EditAttrsPopover>
+              </a-space>
+            </div>
             <SearchForm
               ref="search"
               @refresh="reloadData"
               :preferenceAttrList="currentAttrList"
               :typeId="Number(typeId)"
               @copyExpression="copyExpression"
-            />
-            <div class="tree-views-right-bar">
+            >
               <PreferenceSearch
+                v-show="!selectedRowKeys.length"
                 ref="preferenceSearch"
                 @getQAndSort="getQAndSort"
                 @setParamsFromPreferenceSearch="setParamsFromPreferenceSearch"
@@ -129,7 +143,7 @@
                   <span>{{ $t('cmdb.ci.selectRows', { rows: selectedRowKeys.length }) }}</span>
                 </template>
               </div>
-            </div>
+            </SearchForm>
             <ops-table
               :id="`cmdb-tree-${typeId}`"
               border
@@ -150,7 +164,7 @@
               :cell-style="getCellStyle"
               :scroll-y="{ enabled: true, gt: 20 }"
               :scroll-x="{ enabled: true, gt: 0 }"
-              :height="`${windowHeight - 252}px`"
+              :height="`${windowHeight - 240}px`"
               @checkbox-change="onSelectChange"
               @checkbox-all="onSelectChange"
               @checkbox-range-end="onSelectRangeEnd"
@@ -159,7 +173,6 @@
               @edit-actived="handleEditActived"
               :edit-config="{ trigger: 'dblclick', mode: 'row', showIcon: false }"
               class="ops-unstripe-table"
-              :style="{ margin: '0 -12px' }"
               :custom-config="{ storage: true }"
             >
               <vxe-column align="center" type="checkbox" width="60" :fixed="isCheckboxFixed ? 'left' : ''"></vxe-column>
@@ -294,7 +307,6 @@
               <vxe-table-column align="left" field="operate" fixed="right" width="120">
                 <template #header>
                   <span>{{ $t('operation') }}</span>
-                  <EditAttrsPopover :typeId="Number(typeId)" class="operation-icon" @refresh="refreshAfterEditAttrs" />
                 </template>
                 <template #default="{ row }">
                   <a-space>
@@ -693,7 +705,8 @@ export default {
       console.log('facet', facet)
       const _treeData = Object.values(facet)[0].map((item) => {
         return {
-          title: `${item[0]} (${item[1]})`,
+          title: item[0],
+          childLength: item[1],
           key: this.treeKeys.join(this.keySplit) + this.keySplit + item[0],
           isLeaf: this.levels.length - 1 === this.treeKeys.length,
         }
@@ -1228,12 +1241,8 @@ export default {
   .tree-views-left {
     float: left;
     position: relative;
-    background-color: #fff;
     overflow: hidden;
     width: 100%;
-    padding: 12px;
-    border-top-left-radius: 15px;
-    border-top-right-radius: 15px;
     &:hover {
       overflow: auto;
     }
@@ -1249,7 +1258,7 @@ export default {
       border-radius: 2px;
       position: relative;
       &:hover {
-        background-color: #f0f5ff;
+        background-color: @primary-color_3;
         > .actions,
         > .move-icon {
           display: inherit;
@@ -1270,9 +1279,7 @@ export default {
         width: 20px;
         height: 20px;
         border-radius: 2px;
-        box-shadow: 0px 1px 2px rgba(47, 84, 235, 0.2);
         margin-right: 6px;
-        background-color: #fff;
       }
       .tree-views-left-header-name {
         flex: 1;
@@ -1281,6 +1288,7 @@ export default {
         overflow: hidden;
         text-overflow: ellipsis;
         white-space: nowrap;
+        color: @text-color_1;
       }
       .actions {
         display: none;
@@ -1298,7 +1306,7 @@ export default {
       }
     }
     .custom-header-selected {
-      background-color: #d3e3fd !important;
+      background-color: @primary-color_3 !important;
     }
     .ant-tree li {
       padding: 2px 0;
@@ -1317,23 +1325,18 @@ export default {
         padding: 0 6px;
       }
     }
+    .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected {
+      background-color: @primary-color_3;
+    }
   }
   .tree-views-right {
     background-color: #fff;
     display: flex;
     flex-direction: column;
-    padding: 12px;
+    padding: 20px;
     overflow: auto;
     width: 100%;
-    border-radius: 15px;
-    .tree-views-right-bar {
-      display: inline-flex;
-      flex-direction: row;
-      justify-content: flex-start;
-      align-items: center;
-      margin-bottom: 10px;
-      height: 36px;
-    }
+    border-radius: @border-radius-box;
   }
 }
 </style>
diff --git a/cmdb-ui/src/modules/cmdb/views/tree_views/modules/treeViewsNode.vue b/cmdb-ui/src/modules/cmdb/views/tree_views/modules/treeViewsNode.vue
index 4749b86..bba2f36 100644
--- a/cmdb-ui/src/modules/cmdb/views/tree_views/modules/treeViewsNode.vue
+++ b/cmdb-ui/src/modules/cmdb/views/tree_views/modules/treeViewsNode.vue
@@ -1,15 +1,11 @@
 <template>
-  <div
-    :style="{
-      width: '100%',
-      display: 'inline-flex',
-      justifyContent: 'space-between',
-      alignItems: 'center',
-    }"
-    @click="clickNode"
-  >
-    <span :style="{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }">{{ this.title }}</span>
-    <a-icon :style="{ fontSize: '10px', color: '#0C3CFF' }" v-if="childLength && !isLeaf" :type="switchIcon"></a-icon>
+  <div @click="clickNode" class="tree-views-node">
+    <a-icon v-if="childLength && !isLeaf" :type="switchIcon"></a-icon>
+    <div v-else></div>
+    <div class="tree-views-node-content">
+      <span>{{ this.title }}</span>
+      <span>{{ childLength }}</span>
+    </div>
   </div>
 </template>
 
@@ -18,7 +14,7 @@ export default {
   name: 'TreeViewsNode',
   props: {
     title: {
-      type: String,
+      type: [String, Number],
       default: '',
     },
     treeKey: {
@@ -33,25 +29,57 @@ export default {
       type: Boolean,
       default: () => false,
     },
+    childLength: {
+      type: Number,
+      default: 0,
+    },
   },
   data() {
     return {
-      switchIcon: 'down',
+      switchIcon: 'caret-right',
     }
   },
-  computed: {
-    childLength() {
-      const reg = /(?<=\()\S+(?=\))/g
-      return Number(this.title.match(reg)[0])
-    },
-  },
+  computed: {},
   methods: {
     clickNode() {
       this.$emit('onNodeClick', this.treeKey)
-      this.switchIcon = this.switchIcon === 'down' ? 'up' : 'down'
+      this.switchIcon = this.switchIcon === 'caret-right' ? 'caret-down' : 'caret-right'
     },
   },
 }
 </script>
 
-<style></style>
+<style lang="less" scoped>
+@import '~@/style/static.less';
+.tree-views-node {
+  width: 100%;
+  display: inline-flex;
+  justify-content: space-between;
+  align-items: center;
+  > div:first-child {
+    width: 10px;
+  }
+  i {
+    font-size: 10px;
+    color: @text-color_5;
+  }
+  .tree-views-node-content {
+    flex: 1;
+    display: inline-flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-left: 5px;
+    width: calc(100% - 10px);
+    > span:first-child {
+      width: calc(100% - 30px);
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      color: @text-color_1;
+    }
+    > span:last-child {
+      color: @text-color_4;
+    }
+  }
+}
+</style>
diff --git a/cmdb-ui/src/style/global.less b/cmdb-ui/src/style/global.less
index dcb0552..790f2e4 100644
--- a/cmdb-ui/src/style/global.less
+++ b/cmdb-ui/src/style/global.less
@@ -50,7 +50,7 @@ body {
 }
 
 .ant-layout {
-  background-color: #f7f8fa;
+  background-color: @layout-content-background;
 }
 
 .layout.ant-layout {
@@ -161,7 +161,7 @@ body {
       transition: width 0.2s;
 
       &.ant-header-side-opened {
-        width: calc(100% - 200px);
+        width: calc(100% - 220px);
       }
 
       &.ant-header-side-closed {
@@ -411,7 +411,6 @@ body {
 
 // 菜单样式
 .sider {
-  box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
   position: relative;
   z-index: 10;
   min-height: 100vh;
@@ -431,19 +430,9 @@ body {
   &.ant-fixed-sidemenu {
     position: fixed;
     height: 100%;
-    background: @layout-background-color;
     z-index: 99;
   }
 
-  .ant-menu-dark {
-    background: @layout-background-color;
-
-    .ant-menu-inline.ant-menu-sub {
-      background: @layout-background-color-light;
-      box-shadow: none;
-    }
-  }
-
   .logo {
     position: relative;
     height: @layout-header-height;
@@ -478,21 +467,11 @@ body {
 
   &.light {
     background-color: #fff;
-    box-shadow: 2px 0px 8px 0px rgba(29, 35, 41, 0.05);
 
     .logo {
       background: @layout-header-background;
-      box-shadow: 1px 1px 0px 0px #e8e8e8;
+      box-shadow: 0 1px 3px 0px #9eabbe25;
     }
-
-    // .ant-menu-light {
-    //   .ant-menu-item {
-    //     margin: 0;
-    //   }
-    //   .ant-menu-item-selected {
-    //     background: #0000000a;
-    //   }
-    // }
   }
 }
 
@@ -506,6 +485,9 @@ body {
 // 从此处开始
 .ops-side-bar.ant-menu {
   transition: none;
+  .ant-menu-item {
+    text-overflow: initial !important;
+  }
 }
 .ops-side-bar.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
   background: @layout-sidebar-selected-color;
@@ -525,7 +507,7 @@ body {
 }
 
 .ops-side-bar.ant-menu-light {
-  border-right-color: transparent;
+  border-right-color: #e8e8e8;
   background: @layout-sidebar-color;
   background-repeat: no-repeat !important;
   background-size: cover;
@@ -538,6 +520,9 @@ body {
       display: inline-flex;
       align-items: center;
       color: @layout-sidebar-font-color;
+      i {
+        color: @text-color_5;
+      }
     }
     &:hover {
       .scroll {
@@ -590,8 +575,11 @@ body {
   .ant-menu-item-selected {
     a,
     a:hover {
-      color: @layout-sidebar-font-color;
+      color: @layout-sidebar-selected-font-color;
       font-weight: 600;
+      i {
+        color: @layout-sidebar-selected-font-color;
+      }
     }
   }
   .ant-menu-item::after,
@@ -601,6 +589,9 @@ body {
 
   .ant-menu-submenu {
     color: @layout-sidebar-font-color;
+    i {
+      color: @text-color_5;
+    }
   }
   .ant-menu-submenu-title:hover {
     color: @layout-sidebar-font-color;
@@ -613,8 +604,11 @@ body {
   }
   .ant-menu-submenu-selected {
     > .ant-menu-submenu-title {
-      color: @layout-sidebar-font-color;
+      color: @layout-sidebar-selected-font-color;
       font-weight: 800;
+      i {
+        color: @layout-sidebar-selected-font-color;
+      }
     }
   }
   .ant-menu-submenu-content .ant-menu-submenu-active .ant-menu-submenu-title {
@@ -852,7 +846,7 @@ body {
   .ant-layout-sider {
     box-shadow: none;
     .ant-layout-sider-children {
-      background: @primary-color_5;
+      background: @primary-color_7;
       .ant-menu {
         display: none;
       }
@@ -883,7 +877,7 @@ body {
   }
 }
 
-.custom-vue-treeselect__control(@bgColor:@primary-color_5,@border:none) {
+.custom-vue-treeselect__control(@bgColor:@primary-color_7,@border:none) {
   background-color: @bgColor;
   border: @border;
 }
@@ -956,13 +950,13 @@ body {
 //非斑马纹
 .ops-unstripe-table {
   .vxe-table--border-line {
-    border: none !important;
+    // border: none !important;
   }
   .vxe-table--header-wrapper {
-    background-color: @primary-color_5 !important;
+    background-color: @primary-color_6 !important;
   }
   .vxe-header--row .vxe-header--column:hover {
-    background: #2f54eb1f !important;
+    background: @primary-color_3;
   }
 }
 .ops-unstripe-table.vxe-table--render-default.border--full {
@@ -983,7 +977,7 @@ body {
     border: none !important;
   }
   .vxe-table--header-wrapper {
-    background-color: @primary-color_5 !important;
+    background-color: @primary-color_6 !important;
   }
   // .vxe-table--header-wrapper.body--wrapper {
   //   border-radius: 8px !important;
@@ -1010,19 +1004,19 @@ body {
     }
   }
   .vxe-header--row .vxe-header--column:hover {
-    background: #2f54eb1f !important;
+    background: @primary-color_3;
   }
 }
 
 .ops-input {
   .ant-input,
   .ant-time-picker-input {
-    background-color: @primary-color_5;
+    background-color: @primary-color_7;
     border: none;
   }
 }
 .ops-input.ant-input {
-  background-color: @primary-color_5;
+  background-color: @primary-color_7;
   border: none;
 }
 .ops-input.ant-input[disabled] {
@@ -1030,14 +1024,6 @@ body {
   color: #333;
   cursor: default;
 }
-.ops-input-radius {
-  .ant-input {
-    border-radius: 20px;
-  }
-}
-.ops-input-radius.ant-input {
-  border-radius: 20px;
-}
 
 // vxe-table checkbox 选中 highlight
 .vxe-table--render-default .vxe-body--row.row--checked,
@@ -1110,12 +1096,12 @@ body {
 //批量操作
 .ops-list-batch-action {
   display: inline-block;
-  background-color: @primary-color_5;
+  background-color: @primary-color_6;
   font-size: 12px;
-  color: rgba(0, 0, 0, 0.55);
+  color: @text-color_3;
   > span {
     display: inline-block;
-    padding: 4px 8px;
+    padding: 7px 8px;
     cursor: pointer;
     &:hover {
       color: @primary-color;
@@ -1127,7 +1113,7 @@ body {
   }
 }
 
-//tab
+// card tab
 .ops-tab.ant-tabs.ant-tabs-card {
   .ant-tabs-card-bar {
     margin: 0;
@@ -1147,15 +1133,53 @@ body {
   }
 }
 
-//button
+// line tab
+.ops-tab.ant-tabs {
+  .ant-tabs-bar {
+    margin-bottom: 20px;
+    border-bottom: none;
+    .ant-tabs-nav.ant-tabs-nav-animated,
+    .ant-tabs-nav.ant-tabs-nav-animated > div:first-child {
+      border-bottom: 1px solid @border-color-base;
+    }
+    .ant-tabs-tab {
+      color: @text-color_4;
+    }
+    .ant-tabs-tab-active {
+      color: @primary-color;
+    }
+  }
+}
+
+// button
 .ops-button-primary {
   background-color: @primary-color_4;
   border-color: @primary-color_4;
   color: @primary-color;
   box-shadow: none;
 }
+// button
+.ops-button-ghost.ant-btn-background-ghost.ant-btn-primary {
+  background-color: @primary-color_5!important;
+  border-color: @primary-color_8;
+}
+.ops-button-ghost.ant-btn-background-ghost.ant-btn-primary[disabled] {
+  border-color: #d9d9d9;
+  background-color: @primary-color_7!important;
+}
 
-//select
+// button
+.ant-btn.ant-btn-icon-only {
+  &:hover > i {
+    color: @primary-color;
+    transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+  }
+  > i {
+    color: #d9d9d9;
+  }
+}
+
+// select
 .ops-select {
   &.white {
     .ant-select-selection {
@@ -1173,10 +1197,6 @@ body {
       }
     }
   }
-  .ant-select-selection {
-    background-color: @primary-color_5;
-    border-color: @primary-color_5;
-  }
 }
 
 //dropdown
@@ -1190,9 +1210,7 @@ body {
 
 //modal
 .ant-modal-content {
-  border-radius: 15px;
   .ant-modal-header {
-    border-radius: 15px;
     border-bottom: none;
     .ant-modal-title {
       padding-left: 10px;
@@ -1328,12 +1346,8 @@ body {
     border-bottom-color: @primary-color;
   }
 }
-// .ant-menu.ant-menu-light {
-//   &.ops-menu {
-//     background-color: white;
-//     background: none;
-//     .ant-menu-submenu {
-//       color: rgba(0, 0, 0, 0.65);
-//     }
-//   }
-// }
+
+.ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected,
+.ant-tree li .ant-tree-node-content-wrapper:hover {
+  background-color: @primary-color_3;
+}
diff --git a/cmdb-ui/src/style/static.less b/cmdb-ui/src/style/static.less
index 096a500..0e3b422 100644
--- a/cmdb-ui/src/style/static.less
+++ b/cmdb-ui/src/style/static.less
@@ -1,41 +1,48 @@
 @border-radius-base: 2px; // 组件/浮层圆角
 @border-radius-box: 4px; // big box radius
 
-@primary-color: #2f54eb; // 全局主色 六大品牌色
+// primary color
+@primary-color: #2f54eb;
 @primary-color_2: #7f97fa;
-@primary-color_3: #d3e3fd;
+@primary-color_3: #ebeff8;
 @primary-color_4: #e1efff;
 @primary-color_5: #f0f5ff;
 @primary-color_6: #f9fbff;
+@primary-color_7: #f7f8fa;
+@primary-color_8: #b1c9ff;
 
-@text-color_1: #1d2119;
+// Neutral color
+@text-color_1: #1d2129;
 @text-color_2: #4e5969;
 @text-color_3: #86909c;
 @text-color_4: #a5a9bc;
+@text-color_5: #cacdd9;
+@text-color_6: #e4e7ed;
+@text-color_7: #f0f1f5;
 
-@border-color: #e4e7ed;
+@func-color_1: #fd4c6a;
+@func-color_2: #ff7d00;
+@func-color_3: #00b42a;
+@func-color_4: #fad337;
+
+@border-color-base: @text-color_6; // 边框色
 
 @scrollbar-color: rgba(47, 122, 235, 0.2);
 
+@layout-content-background: @primary-color_7;
 @layout-header-background: #fff;
 @layout-header-height: 40px;
 @layout-header-icon-height: 34px;
 @layout-header-font-color: #020000;
-@layout-header-font-selected-color: #2857bc;
+@layout-header-font-selected-color: @primary-color;
 
-//dark
-@layout-background-color: #182132;
-@layout-background-color-light: #262f40;
-//light
-@layout-background-light-color: #fafafa;
-@layout-background-light-color-light: #f0f0f0;
-
-@layout-sidebar-color: #1d264c; //bg
-@layout-sidebar-sub-color: #000c37; //bg
-@layout-sidebar-selected-color: #3e4a71; //selected bg
-@layout-sidebar-arrow-color: rgba(255, 255, 255, 0.6);
-@layout-sidebar-font-color: #fff;
-@layout-sidebar-disabled-font-color: rgba(255, 255, 255, 0.6);
+@layout-sidebar-color: #ffffff; //bg
+@layout-sidebar-sub-color: @primary-color_7; //bg
+@layout-sidebar-selected-color: @primary-color_5; //selected bg
+@layout-sidebar-arrow-color: @text-color_4;
+@layout-sidebar-font-color: @text-color_2;
+@layout-sidebar-selected-font-color: @primary-color;
+@layout-sidebar-disabled-font-color: @text-color_4;
 
 #custom_colors() {
   color_1: #2f54eb; //primary color
@@ -47,7 +54,7 @@
   cursor: pointer;
   padding: 5px 8px;
   background-color: @backgroundColor;
-  border-radius: 5px;
+  border-radius: @border-radius-box;
   height: 30px;
   color: rgba(0, 0, 0, 0.6);
   white-space: nowrap;
@@ -57,10 +64,10 @@
   cursor: pointer;
   padding: 5px 10px;
   &:hover {
-    background-color: @primary-color_5;
+    background-color: @primary-color_3;
   }
 }
 .ops_popover_item_selected() {
-  background-color: @primary-color_5;
+  background-color: @primary-color_3;
   color: @primary-color;
 }
diff --git a/cmdb-ui/src/views/setting/auth/index.vue b/cmdb-ui/src/views/setting/auth/index.vue
index 1bfd111..65a2b59 100644
--- a/cmdb-ui/src/views/setting/auth/index.vue
+++ b/cmdb-ui/src/views/setting/auth/index.vue
@@ -17,8 +17,12 @@
             <a-space>
               <a-button :loading="loading" type="primary" @click="handleSave">{{ $t('save') }}</a-button>
               <template v-if="item.value === 'LDAP'">
-                <a-button :loading="loading" ghost type="primary" @click="handleTest('connect')">{{ $t('cs.auth.testConnect') }}</a-button>
-                <a-button :loading="loading" ghost type="primary" @click="handleTest('login')">{{ $t('cs.auth.testLogin') }}</a-button>
+                <a-button :loading="loading" ghost type="primary" @click="handleTest('connect')">{{
+                  $t('cs.auth.testConnect')
+                }}</a-button>
+                <a-button :loading="loading" ghost type="primary" @click="handleTest('login')">{{
+                  $t('cs.auth.testLogin')
+                }}</a-button>
               </template>
               <a-button :loading="loading" @click="handleReset">{{ $t('reset') }}</a-button>
             </a-space>
@@ -56,28 +60,28 @@ export default {
   computed: {
     authList() {
       return [
-      {
-        value: 'LDAP',
-        label: 'LDAP',
-      },
-      {
-        value: 'CAS',
-        label: 'CAS',
-      },
-      {
-        value: 'OAUTH2',
-        label: 'OAUTH2',
-      },
-      {
-        value: 'OIDC',
-        label: 'OIDC',
-      },
-      {
-        value: 'AuthCommonConfig',
-        label: this.$t('cs.auth.common'),
-      },
-    ]
-    }
+        {
+          value: 'LDAP',
+          label: 'LDAP',
+        },
+        {
+          value: 'CAS',
+          label: 'CAS',
+        },
+        {
+          value: 'OAUTH2',
+          label: 'OAUTH2',
+        },
+        {
+          value: 'OIDC',
+          label: 'OIDC',
+        },
+        {
+          value: 'AuthCommonConfig',
+          label: this.$t('cs.auth.common'),
+        },
+      ]
+    },
   },
   methods: {
     getAuthDataEnable() {
@@ -129,7 +133,7 @@ export default {
               ...values,
             }
           }
-          testLDAP(type, { data: _data })
+          testLDAP({ data: _data, test_type: type })
             .then((res) => {
               this.$message.success(this.$t('cs.auth.testSuccess'))
             })
diff --git a/cmdb-ui/src/views/user/Login.vue b/cmdb-ui/src/views/user/Login.vue
index a0d60aa..9353633 100644
--- a/cmdb-ui/src/views/user/Login.vue
+++ b/cmdb-ui/src/views/user/Login.vue
@@ -1,10 +1,12 @@
 <template>
   <div class="ops-login">
     <div class="ops-login-left">
-      <span>维易科技<br />让运维更简单</span>
+      <span>OneOps统一运维平台</span>
+      <img src="../../assets/login_img.png" />
     </div>
     <div class="ops-login-right">
-      <img src="../../assets/logo_VECMDB.png" />
+      <img src="../../assets/OneOps.png" />
+      <div class="ops-login-right-welcome"><span>欢迎登录</span></div>
       <a-form
         id="formLogin"
         ref="formLogin"
@@ -43,7 +45,7 @@
           <a-checkbox v-decorator="['rememberMe', { valuePropName: 'checked' }]">自动登录</a-checkbox>
         </a-form-item>
 
-        <a-form-item style="margin-top: 24px">
+        <a-form-item style="margin-top:24px">
           <a-button
             size="large"
             type="primary"
@@ -53,13 +55,18 @@
             :disabled="state.loginBtn"
           >登录</a-button
           >
+          <a-checkbox
+            v-if="enable_list && enable_list.length === 1 && enable_list[0].auth_type === 'LDAP'"
+            v-model="auth_with_ldap"
+          >LDAP</a-checkbox
+          >
         </a-form-item>
       </a-form>
       <template v-if="_enable_list && _enable_list.length >= 1">
         <a-divider style="font-size:14px">其他登录方式</a-divider>
         <div style="text-align:center">
           <span v-for="(item, index) in _enable_list" :key="item.auth_type">
-            <ops-icon :type="item.auth_type"/>
+            <ops-icon :type="item.auth_type" />
             <a @click="otherLogin(item.auth_type)">{{ item.auth_type }}</a>
             <a-divider v-if="index < _enable_list.length - 1" type="vertical" />
           </span>
@@ -93,6 +100,7 @@ export default {
         loginType: 0,
         smsSendBtn: false,
       },
+      auth_with_ldap: false,
     }
   },
   computed: {
@@ -104,6 +112,18 @@ export default {
       return this.enable_list.filter((en) => en.auth_type !== 'LDAP')
     },
   },
+  watch: {
+    enable_list: {
+      immediate: true,
+      handler(newVal) {
+        if (newVal && newVal.length === 1 && newVal[0].auth_type === 'LDAP') {
+          this.auth_with_ldap = true
+        } else {
+          this.auth_with_ldap = false
+        }
+      },
+    },
+  },
   created() {},
   async mounted() {
     await this.GetAuthDataEnable()
@@ -124,10 +144,12 @@ export default {
     handleSubmit(e) {
       e.preventDefault()
       const {
+        enable_list,
         form: { validateFields },
         state,
         customActiveKey,
         Login,
+        auth_with_ldap,
       } = this
 
       state.loginBtn = true
@@ -136,11 +158,15 @@ export default {
 
       validateFields(validateFieldsKey, { force: true }, (err, values) => {
         if (!err) {
-          console.log('login form', values)
           const loginParams = { ...values }
           delete loginParams.username
           loginParams.username = values.username
           loginParams.password = appConfig.useEncryption ? md5(values.password) : values.password
+          loginParams.auth_with_ldap =
+            enable_list && enable_list.length === 1 && enable_list[0].auth_type === 'LDAP'
+              ? Number(auth_with_ldap)
+              : undefined
+
           localStorage.setItem('ops_auth_type', '')
           Login({ userInfo: loginParams })
             .then((res) => this.loginSuccess(res))
@@ -184,6 +210,13 @@ export default {
     background: url('../../assets/login_bg.png') no-repeat;
     background-position: center;
     background-size: cover;
+    > img {
+      width: 80%;
+      position: absolute;
+      top: 60%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+    }
     > span {
       color: white;
       position: absolute;
@@ -191,7 +224,6 @@ export default {
       left: 50%;
       transform: translateX(-50%);
       font-size: 1.75vw;
-      text-align: center;
     }
   }
   .ops-login-right {
@@ -202,6 +234,14 @@ export default {
       width: 70%;
       margin-left: 15%;
     }
+    .ops-login-right-welcome {
+      text-align: center;
+      color: rgba(29, 57, 196, 1);
+      font-family: 'Inter';
+      font-style: normal;
+      font-weight: 600;
+      font-size: 1.25vw;
+    }
     .login-button {
       width: 100%;
     }