diff --git a/ruoyi-ui/src/assets/styles/ruoyi.scss b/ruoyi-ui/src/assets/styles/ruoyi.scss
index 55118fad..579e82db 100644
--- a/ruoyi-ui/src/assets/styles/ruoyi.scss
+++ b/ruoyi-ui/src/assets/styles/ruoyi.scss
@@ -176,6 +176,12 @@
   color: #FFFFFF;
 }
 
+/* submenu item */
+.el-menu--horizontal > .el-submenu .el-submenu__title {
+	height: 50px !important;
+	line-height: 50px !important;
+}
+
 /* text color */
 .text-navy {
 	color: #1ab394;
diff --git a/ruoyi-ui/src/assets/styles/sidebar.scss b/ruoyi-ui/src/assets/styles/sidebar.scss
index 9fad7998..3f45751e 100644
--- a/ruoyi-ui/src/assets/styles/sidebar.scss
+++ b/ruoyi-ui/src/assets/styles/sidebar.scss
@@ -135,9 +135,6 @@
           margin-left: 20px;
         }
 
-        .el-submenu__icon-arrow {
-          display: none;
-        }
       }
     }
 
diff --git a/ruoyi-ui/src/components/TopNav/index.vue b/ruoyi-ui/src/components/TopNav/index.vue
new file mode 100644
index 00000000..fb15c59e
--- /dev/null
+++ b/ruoyi-ui/src/components/TopNav/index.vue
@@ -0,0 +1,143 @@
+<template>
+  <el-menu
+    :default-active="activeMenu"
+    mode="horizontal"
+    @select="handleSelect"
+  >
+    <template v-for="(item, index) in topMenus">
+      <el-menu-item :index="item.path" :key="index" v-if="index < visibleNumber"
+        ><svg-icon :icon-class="item.meta.icon" />
+        {{ item.meta.title }}</el-menu-item
+      >
+    </template>
+
+    <!-- 顶部菜单超出数量折叠 -->
+    <el-submenu index="more" v-if="topMenus.length > visibleNumber">
+      <template slot="title">更多菜单</template>
+      <template v-for="(item, index) in topMenus">
+        <el-menu-item
+          :index="item.path"
+          :key="index"
+          v-if="index >= visibleNumber"
+          ><svg-icon :icon-class="item.meta.icon" />
+          {{ item.meta.title }}</el-menu-item
+        >
+      </template>
+    </el-submenu>
+  </el-menu>
+</template>
+
+<script>
+import { constantRoutes } from "@/router";
+
+export default {
+  data() {
+    return {
+      // 顶部栏初始数
+      visibleNumber: 5,
+      // 是否为首次加载
+      isFrist: false,
+    };
+  },
+  computed: {
+    // 顶部显示菜单
+    topMenus() {
+      return this.routers.map((menu) => ({
+        ...menu,
+        children: undefined,
+      }));
+    },
+    // 所有的路由信息
+    routers() {
+      return this.$store.state.permission.topbarRouters;
+    },
+    // 设置子路由
+    childrenMenus() {
+      var childrenMenus = [];
+      this.routers.map((router) => {
+        for (var item in router.children) {
+          if (router.children[item].parentPath === undefined) {
+            router.children[item].path = router.path + "/" + router.children[item].path;
+            router.children[item].parentPath = router.path;
+          }
+          childrenMenus.push(router.children[item]);
+        }
+      });
+      return constantRoutes.concat(childrenMenus);
+    },
+    // 默认激活的菜单
+    activeMenu() {
+      const path = this.$route.path;
+      let activePath = this.routers[0].path;
+      if (path.lastIndexOf("/") > 0) {
+        const tmpPath = path.substring(1, path.length);
+        activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"));
+      } else if ("/index" == path || "" == path) {
+        if (!this.isFrist) {
+          this.isFrist = true;
+        } else {
+          activePath = "index";
+        }
+      }
+      this.activeRoutes(activePath);
+      return activePath;
+    },
+  },
+  mounted() {
+    this.setVisibleNumber();
+  },
+  methods: {
+    // 根据宽度计算设置显示栏数
+    setVisibleNumber() {
+      const width = document.body.getBoundingClientRect().width - 200;
+      const elWidth = this.$el.getBoundingClientRect().width;
+      const menuItemNodes = this.$el.children;
+      const menuWidth = Array.from(menuItemNodes).map(
+        (i) => i.getBoundingClientRect().width
+      );
+      this.visibleNumber = (
+        parseInt(width - elWidth) / parseInt(menuWidth)
+      ).toFixed(0);
+    },
+    // 菜单选择事件
+    handleSelect(key, keyPath) {
+      if (key.indexOf("http://") !== -1 || key.indexOf("https://") !== -1) {
+        // http(s):// 路径新窗口打开
+        window.open(key, "_blank");
+      } else {
+        this.activeRoutes(key);
+      }
+    },
+    // 当前激活的路由
+    activeRoutes(key) {
+      var routes = [];
+      if (this.childrenMenus && this.childrenMenus.length > 0) {
+        this.childrenMenus.map((item) => {
+          if (key == item.parentPath || (key == "index" && "" == item.path)) {
+            routes.push(item);
+          }
+        });
+      }
+      this.$store.commit("SET_SIDEBAR_ROUTERS", routes);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.el-menu--horizontal > .el-menu-item {
+  float: left;
+  height: 50px;
+  line-height: 50px;
+  margin: 0;
+  border-bottom: 3px solid transparent;
+  color: #999093;
+  padding: 0 5px;
+  margin: 0 10px;
+}
+
+.el-menu--horizontal > .el-menu-item.is-active {
+  border-bottom: 3px solid #409eff;
+  color: #303133;
+}
+</style>
diff --git a/ruoyi-ui/src/layout/components/Navbar.vue b/ruoyi-ui/src/layout/components/Navbar.vue
index db46ec55..db69e1df 100644
--- a/ruoyi-ui/src/layout/components/Navbar.vue
+++ b/ruoyi-ui/src/layout/components/Navbar.vue
@@ -2,7 +2,8 @@
   <div class="navbar">
     <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
 
-    <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
+    <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
+    <top-nav id="topmenu-container" class="breadcrumb-container" v-if="topNav"/>
 
     <div class="right-menu">
       <template v-if="device!=='mobile'">
@@ -48,6 +49,7 @@
 <script>
 import { mapGetters } from 'vuex'
 import Breadcrumb from '@/components/Breadcrumb'
+import TopNav from '@/components/TopNav'
 import Hamburger from '@/components/Hamburger'
 import Screenfull from '@/components/Screenfull'
 import SizeSelect from '@/components/SizeSelect'
@@ -58,6 +60,7 @@ import RuoYiDoc from '@/components/RuoYi/Doc'
 export default {
   components: {
     Breadcrumb,
+    TopNav,
     Hamburger,
     Screenfull,
     SizeSelect,
@@ -81,6 +84,11 @@ export default {
           value: val
         })
       }
+    },
+    topNav: {
+      get() {
+        return this.$store.state.settings.topNav
+      }
     }
   },
   methods: {
diff --git a/ruoyi-ui/src/layout/components/Settings/index.vue b/ruoyi-ui/src/layout/components/Settings/index.vue
index 7e495b7b..7e36d48d 100644
--- a/ruoyi-ui/src/layout/components/Settings/index.vue
+++ b/ruoyi-ui/src/layout/components/Settings/index.vue
@@ -41,6 +41,11 @@
       <el-divider/>
 
       <h3 class="drawer-title">系统布局配置</h3>
+      
+      <div class="drawer-item">
+        <span>开启 TopNav</span>
+        <el-switch v-model="topNav" class="drawer-switch" />
+      </div>
 
       <div class="drawer-item">
         <span>开启 Tags-Views</span>
@@ -87,6 +92,20 @@ export default {
         })
       }
     },
+    topNav: {
+      get() {
+        return this.$store.state.settings.topNav
+      },
+      set(val) {
+        this.$store.dispatch('settings/changeSetting', {
+          key: 'topNav',
+          value: val
+        })
+        if (!val) {
+          this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes);
+        }
+      }
+    },
     tagsView: {
       get() {
         return this.$store.state.settings.tagsView
diff --git a/ruoyi-ui/src/settings.js b/ruoyi-ui/src/settings.js
index 8eb92945..0e74c710 100644
--- a/ruoyi-ui/src/settings.js
+++ b/ruoyi-ui/src/settings.js
@@ -11,6 +11,11 @@ module.exports = {
    */
   showSettings: false,
 
+  /**
+   * 是否显示顶部导航
+   */
+  topNav: false,
+
   /**
    * 是否显示 tagsView
    */
diff --git a/ruoyi-ui/src/store/getters.js b/ruoyi-ui/src/store/getters.js
index ea4f90e1..8d723813 100644
--- a/ruoyi-ui/src/store/getters.js
+++ b/ruoyi-ui/src/store/getters.js
@@ -11,6 +11,8 @@ const getters = {
   roles: state => state.user.roles,
   permissions: state => state.user.permissions,
   permission_routes: state => state.permission.routes,
+  topbarRouters:state => state.permission.topbarRouters,
+  defaultRoutes:state => state.permission.defaultRoutes,
   sidebarRouters:state => state.permission.sidebarRouters,
 }
 export default getters
diff --git a/ruoyi-ui/src/store/modules/permission.js b/ruoyi-ui/src/store/modules/permission.js
index 61f681cd..f3a1d11f 100644
--- a/ruoyi-ui/src/store/modules/permission.js
+++ b/ruoyi-ui/src/store/modules/permission.js
@@ -7,6 +7,8 @@ const permission = {
   state: {
     routes: [],
     addRoutes: [],
+    defaultRoutes: [],
+    topbarRouters: [],
     sidebarRouters: []
   },
   mutations: {
@@ -14,8 +16,19 @@ const permission = {
       state.addRoutes = routes
       state.routes = constantRoutes.concat(routes)
     },
-    SET_SIDEBAR_ROUTERS: (state, routers) => {
-      state.sidebarRouters = constantRoutes.concat(routers)
+    SET_DEFAULT_ROUTES: (state, routes) => {
+      state.defaultRoutes = constantRoutes.concat(routes)
+    },
+    SET_TOPBAR_ROUTES: (state, routes) => {
+      // 顶部导航菜单默认添加统计报表栏指向首页
+      const index = [{
+        path: 'index',
+        meta: { title: '统计报表', icon: 'dashboard'}
+      }]
+      state.topbarRouters = routes.concat(index);
+    },
+    SET_SIDEBAR_ROUTERS: (state, routes) => {
+      state.sidebarRouters = routes
     },
   },
   actions: {
@@ -30,7 +43,9 @@ const permission = {
           const rewriteRoutes = filterAsyncRouter(rdata, false, true)
           rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
           commit('SET_ROUTES', rewriteRoutes)
-          commit('SET_SIDEBAR_ROUTERS', sidebarRoutes)
+          commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
+          commit('SET_DEFAULT_ROUTES', sidebarRoutes)
+          commit('SET_TOPBAR_ROUTES', sidebarRoutes)
           resolve(rewriteRoutes)
         })
       })
diff --git a/ruoyi-ui/src/store/modules/settings.js b/ruoyi-ui/src/store/modules/settings.js
index a246a3c4..f113e9a8 100644
--- a/ruoyi-ui/src/store/modules/settings.js
+++ b/ruoyi-ui/src/store/modules/settings.js
@@ -1,12 +1,13 @@
 import variables from '@/assets/styles/element-variables.scss'
 import defaultSettings from '@/settings'
 
-const { sideTheme, showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings
+const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo } = defaultSettings
 
 const state = {
   theme: variables.theme,
   sideTheme: sideTheme,
   showSettings: showSettings,
+  topNav: topNav,
   tagsView: tagsView,
   fixedHeader: fixedHeader,
   sidebarLogo: sidebarLogo