mo 4 年之前
父節點
當前提交
99493a75c1

+ 17 - 21
src/App.vue

@@ -1,38 +1,34 @@
 <template>
-  <div id="app"
-       v-cloak>
+  <div id="app" v-cloak>
     <router-view v-if="isRouterAlive" />
   </div>
 </template>
 
 <script>
-import Vue from 'vue'
-
+import Vue from "vue";
 
 export default {
-  name: 'App',
-  provide () {
+  name: "App",
+  provide() {
     return {
-      reloads: this.reloads
-    }
+      reloads: this.reloads,
+    };
   },
-  data () {
+  data() {
     return {
       isRouterAlive: true,
-    }
-  },
-  created () {
-
+    };
   },
+  created() {},
   methods: {
-    reloads () {
-      this.isRouterAlive = false
+    reloads() {
+      this.isRouterAlive = false;
       this.$nextTick(function () {
-        this.isRouterAlive = true
-      })
-    }
-  }
-}
+        this.isRouterAlive = true;
+      });
+    },
+  },
+};
 </script>
 <style >
 * {
@@ -89,7 +85,7 @@ input::-webkit-inner-spin-button {
 input[type="number"] {
   -moz-appearance: textfield;
 }
-.el-dialog{
+.el-dialog {
   margin-bottom: 10vh;
 }
 .el-tabs__item.is-active {

二進制
src/assets/images/base/base-bell.png


文件差異過大導致無法顯示
+ 0 - 0
src/assets/images/base/base-bell.svg


+ 2 - 0
src/layout/components/AppMain.vue

@@ -42,6 +42,8 @@ export default {
   position: relative;
   /* overflow: auto; */
   box-sizing: border-box;
+  margin-left: 10px;
+  margin-top: 20px;
 }
 .fixed-header + .app-main {
   padding-top: 80px;

+ 3 - 3
src/layout/components/Navbar.vue

@@ -17,8 +17,7 @@
       <div class="msginfo"
            v-permission="'/journals'"
            @click="gotoRecode">
-        <img src="@/assets/images/base/base-bell.png"
-             alt="">
+       <img src='@/assets/images/base/base-bell.svg'/>
         <!-- <div class="active"></div> -->
       </div>
       <el-dropdown class="avatar-container"
@@ -29,6 +28,7 @@
                :src="$store.getters.avatar"
                class="user-avatar" />
           <img v-else
+          class="user-avatar"
                src="@/assets/images/base/placehorder-icon.png" />
           <!-- <i class="el-icon-caret-bottom" /> -->
           <span>{{ username }}</span>
@@ -178,7 +178,7 @@ export default {
       if (!this.isDisable) {
         this.isDisable = true;
         // 发请求成功后开启定时器
-        // 发送验证码 
+        // 发送验证码
         axios.post('/api-web/code/sendSms', qs.stringify({ mobile: this.$store.getters.phone })).then(res => {
           if (res.data.code == 200) {
             let timer = setInterval(res => {

+ 2 - 2
src/layout/components/Sidebar/Item.vue

@@ -15,9 +15,8 @@ export default {
   render(h, context) {
     const { icon, title } = context.props
     const vnodes = []
-
     if (icon) {
-      vnodes.push(<svg-icon icon-class={icon}/>)
+      vnodes.push(<svg-icon icon-class={icon} />)
     }
 
     if (title) {
@@ -27,3 +26,4 @@ export default {
   }
 }
 </script>
+

+ 3 - 3
src/layout/components/Sidebar/Logo.vue

@@ -38,9 +38,9 @@ export default {
   // top:10px;
   position: relative;
   width: 100%;
-  height: 60px;
-  line-height: 60px;
-  // background: #2b2f3a;
+  height: 80px;
+  line-height: 80px;
+  background: #363D55;
   text-align: center;
   overflow: hidden;
 

+ 82 - 63
src/layout/components/Sidebar/SidebarItem.vue

@@ -1,117 +1,136 @@
 <template>
-  <div v-if="!item.hidden"
-       class="menu-wrapper">
-    <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
-      <app-link v-if="onlyOneChild.meta"
-                :to="resolvePath(onlyOneChild.path)">
-        <el-menu-item :index="resolvePath(onlyOneChild.path)"
-                      :class="{'submenu-title-noDropdown':!isNest}">
-          <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)"
-                :title="onlyOneChild.meta.title" />
+  <div v-if="!item.hidden" class="menu-wrapper">
+    <template
+      v-if="
+        hasOneShowingChild(item.children, item) &&
+        (!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
+        !item.alwaysShow
+      "
+    >
+      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
+        <el-menu-item
+          :index="resolvePath(onlyOneChild.path)"
+          :class="{ 'submenu-title-noDropdown': !isNest }"
+        >
+          <item
+            :icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"
+            :title="onlyOneChild.meta.title"
+          />
         </el-menu-item>
       </app-link>
     </template>
 
-    <el-submenu v-else
-                ref="subMenu"
-                :index="resolvePath(item.path)"
-                popper-append-to-body>
+    <el-submenu
+      v-else
+      ref="subMenu"
+      :index="resolvePath(item.path)"
+      popper-append-to-body
+    >
       <template slot="title">
-        <item v-if="item.meta"
-              :icon="item.meta && item.meta.icon"
-              :title="item.meta.title" />
+        <item
+          v-if="item.meta"
+          :icon="item.meta && item.meta.icon"
+          :title="item.meta.title"
+        />
       </template>
-      <sidebar-item v-for="child in item.children"
-                    :key="child.id"
-                    :is-nest="true"
-                    :item="child"
-                    :base-path="resolvePath(child.path)"
-                    class="nest-menu" />
+      <sidebar-item
+        v-for="child in item.children"
+        :key="child.id"
+        :is-nest="true"
+        :item="child"
+        :base-path="resolvePath(child.path)"
+        class="nest-menu itemIcon"
+      />
     </el-submenu>
   </div>
 </template>
 
 <script>
-import path from 'path'
-import { isExternal } from '@/utils/validate'
-import Item from './Item'
-import AppLink from './Link'
-import FixiOSBug from './FixiOSBug'
+import path from "path";
+import { isExternal } from "@/utils/validate";
+import Item from "./Item";
+import AppLink from "./Link";
+import FixiOSBug from "./FixiOSBug";
 
 export default {
-  name: 'SidebarItem',
+  name: "SidebarItem",
   components: { Item, AppLink },
   mixins: [FixiOSBug],
   props: {
     // route object
     item: {
       type: Object,
-      required: true
+      required: true,
     },
     isNest: {
       type: Boolean,
-      default: false
+      default: false,
     },
     basePath: {
       type: String,
-      default: ''
-    }
+      default: "",
+    },
   },
-  data () {
+  data() {
     // To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
     // TODO: refactor with render function
 
-    return {}
+    return {};
+  },
+  mounted() {
+    this.onlyOneChild = null;
   },
-  mounted () {
-    this.onlyOneChild = null
-  }
-  ,
   methods: {
-    hasOneShowingChild (children = [], parent) {
-      const showingChildren = children.filter(item => {
+    hasOneShowingChild(children = [], parent) {
+      const showingChildren = children.filter((item) => {
         if (item.hidden) {
-          return false
+          return false;
         } else {
           // Temp set(will be used if only has one showing child)
-          this.onlyOneChild = item
-          return true
+          this.onlyOneChild = item;
+          return true;
         }
-      })
+      });
 
       // When there is only one child router, the child router is displayed by default
       if (showingChildren.length === 1) {
-        return true
+        return true;
       }
 
       // Show parent if there are no child router to display
       if (showingChildren.length === 0) {
-        this.onlyOneChild = { ...parent, path: '', noShowingChildren: true }
-        return true
+        this.onlyOneChild = { ...parent, path: "", noShowingChildren: true };
+        return true;
       }
 
-      return false
+      return false;
     },
-    resolvePath (routePath) {
+    resolvePath(routePath) {
       if (isExternal(routePath)) {
-        return routePath
+        return routePath;
       }
       if (isExternal(this.basePath)) {
-        return this.basePath
+        return this.basePath;
       }
       // debugger
-      return path.resolve(this.basePath, routePath)
-    }
-  }
-}
+      return path.resolve(this.basePath, routePath);
+    },
+  },
+};
 </script>
 <style lang="scss" scoped>
-  // 取消双击选中文字
-div{
-    -moz-user-select:none;/*火狐*/
-    -webkit-user-select:none;/*webkit浏览器*/
-    -ms-user-select:none;/*IE10*/
-    -khtml-user-select:none;/*早期浏览器*/
-      user-select:none;
+// 取消双击选中文字
+div {
+  -moz-user-select: none; /*火狐*/
+  -webkit-user-select: none; /*webkit浏览器*/
+  -ms-user-select: none; /*IE10*/
+  -khtml-user-select: none; /*早期浏览器*/
+  user-select: none;
+}
+.itemIcon {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
 }
-</style>
+
+</style>

+ 121 - 102
src/layout/components/TagsView.vue

@@ -1,23 +1,28 @@
 <template>
   <div class="tags-view-container">
-    <scroll-pane class='tags-view-wrapper'
-                 ref='scrollPane'>
-      <router-link ref='tag'
-                   class="tags-view-item"
-                   :class="isActive(tag)?'active':''"
-                   v-for="(tag,index) in Array.from(visitedViews)"
-                   :to="{path:tag.fullPath,query:tag.query,some:tag.path}"
-                   :key="index"
-                   @contextmenu.prevent.native="openMenu(tag,$event)">
-        {{generateTitle(tag.title)}}
+    <scroll-pane class="tags-view-wrapper" ref="scrollPane">
+      <router-link
+        ref="tag"
+        class="tags-view-item"
+        :class="isActive(tag) ? 'active' : ''"
+        v-for="(tag, index) in Array.from(visitedViews)"
+        :to="{ path: tag.fullPath, query: tag.query, some: tag.path }"
+        :key="index"
+        @contextmenu.prevent.native="openMenu(tag, $event)"
+      >
+        {{ generateTitle(tag.title) }}
         <!-- v-if="index == Array.from(visitedViews).length -1" -->
-        <span class='el-icon-close'
-              @click.prevent.stop='closeSelectedTag(tag)'></span>
+        <span
+          class="el-icon-close icon"
+          @click.prevent.stop="closeSelectedTag(tag)"
+        ></span>
       </router-link>
     </scroll-pane>
-    <ul class='contextmenu'
-        v-show="visible"
-        :style="{left:left+'px',top:top+'px'}">
+    <ul
+      class="contextmenu"
+      v-show="visible"
+      :style="{ left: left + 'px', top: top + 'px' }"
+    >
       <li @click="closeSelectedTag(selectedTag)">关闭</li>
       <li @click="closeOthersTags">关闭其他</li>
       <li @click="closeAllTags">关闭所有</li>
@@ -27,166 +32,180 @@
 </template>
 
 <script>
-import ScrollPane from '@/components/ScrollPane'
-import { generateTitle } from '@/utils/i18n'
-import { Searchs } from '@/helpers'
+import ScrollPane from "@/components/ScrollPane";
+import { generateTitle } from "@/utils/i18n";
+import { Searchs } from "@/helpers";
 
 export default {
-  name: 'TagsView',
+  name: "TagsView",
   components: { ScrollPane },
-  data () {
+  data() {
     return {
       visible: false,
       top: 0,
       left: 0,
-      selectedTag: {}
-    }
+      selectedTag: {},
+    };
   },
-  inject: ['reloads'],
+  inject: ["reloads"],
   computed: {
-    visitedViews () {
+    visitedViews() {
       // console.log(this.$store.state.tagsView.visitedViews)
-      return this.$store.state.tagsView.visitedViews
-    }
+      return this.$store.state.tagsView.visitedViews;
+    },
   },
   watch: {
-    $route () {
-      this.addViewTags()
-      this.moveToCurrentTag()
+    $route() {
+      this.addViewTags();
+      this.moveToCurrentTag();
     },
-    visible (value) {
+    visible(value) {
       if (value) {
-        document.body.addEventListener('click', this.closeMenu)
+        document.body.addEventListener("click", this.closeMenu);
       } else {
-        document.body.removeEventListener('click', this.closeMenu)
+        document.body.removeEventListener("click", this.closeMenu);
       }
-    }
+    },
   },
-  mounted () {
-    this.addViewTags()
-
+  mounted() {
+    this.addViewTags();
   },
   methods: {
     // generateTitle by vue-i18n
     generateTitle,
-    generateRoute () {
-      if (this.$route.path && this.$route.path != '/') {
-        return this.$route
+    generateRoute() {
+      if (this.$route.path && this.$route.path != "/") {
+        return this.$route;
       }
-      return false
+      return false;
     },
     // || route.name === this.$route.name
-    isActive (route) {
-      return route.path === this.$route.path
+    isActive(route) {
+      return route.path === this.$route.path;
     },
     syncTagViewAndSaveForm() {
-      const keys = this.$store.state.tagsView.visitedViews.map(item => item.path)
-      const searchs = new Searchs()
-      const allSearch = searchs.getSearchs()
-      const sks = Object.keys(allSearch)
+      const keys = this.$store.state.tagsView.visitedViews.map(
+        (item) => item.path
+      );
+      const searchs = new Searchs();
+      const allSearch = searchs.getSearchs();
+      const sks = Object.keys(allSearch);
       for (const item of sks) {
         if (!(keys.includes(item) || keys.includes(allSearch[item].bind))) {
-          searchs.removeByKey(item)
+          searchs.removeByKey(item);
         }
       }
     },
-    async addViewTags () {
-      const route = this.generateRoute()
+    async addViewTags() {
+      const route = this.generateRoute();
       if (!route) {
-        return false
+        return false;
       }
       // console.log(this.$route)
-      await this.$store.dispatch('addVisitedViews', route)
-      this.syncTagViewAndSaveForm()
+      await this.$store.dispatch("addVisitedViews", route);
+      this.syncTagViewAndSaveForm();
     },
-    moveToCurrentTag () {
-      const tags = this.$refs['tag']
+    moveToCurrentTag() {
+      const tags = this.$refs["tag"];
       this.$nextTick(() => {
         for (const tag of tags) {
           if (tag.path === this.$route.path) {
-            this.$refs.scrollPane.moveToTarget(tag.$el)
-            break
+            this.$refs.scrollPane.moveToTarget(tag.$el);
+            break;
           }
         }
-      })
+      });
     },
-    closeSelectedTag (view) {
-      const searchs = new Searchs()
-      searchs.remove(this.$route.path)
-      this.$store.dispatch('delVisitedViews', view).then((views) => {
+    closeSelectedTag(view) {
+      const searchs = new Searchs();
+      searchs.remove(this.$route.path);
+      this.$store.dispatch("delVisitedViews", view).then((views) => {
         if (this.isActive(view)) {
-          const latestView = views.slice(-1)[0]
+          const latestView = views.slice(-1)[0];
           if (latestView) {
-            this.$router.push(latestView.fullPath)
+            this.$router.push(latestView.fullPath);
           } else {
-            this.$router.push('/')
+            this.$router.push("/");
           }
         }
-      })
+      });
     },
-    closeOthersTags () {
-      this.$router.push(this.selectedTag.path)
-      this.$store.dispatch('delOthersViews', this.selectedTag).then(() => {
-        this.moveToCurrentTag()
-      })
+    closeOthersTags() {
+      this.$router.push(this.selectedTag.path);
+      this.$store.dispatch("delOthersViews", this.selectedTag).then(() => {
+        this.moveToCurrentTag();
+      });
     },
-    closeAllTags () {
-      this.$store.dispatch('delAllViews')
-      this.$router.push('/')
+    closeAllTags() {
+      this.$store.dispatch("delAllViews");
+      this.$router.push("/");
     },
-    openMenu (tag, e) {
-      this.visible = true
-      this.selectedTag = tag
-      this.left = e.clientX - 165
-      this.top = e.clientY + 15
+    openMenu(tag, e) {
+      this.visible = true;
+      this.selectedTag = tag;
+      this.left = e.clientX - 165;
+      this.top = e.clientY + 15;
     },
-    closeMenu () {
-      this.visible = false
+    closeMenu() {
+      this.visible = false;
     },
-    async refresh (view) {
-      await this.reloads()
-    }
-  }
-}
+    async refresh(view) {
+      await this.reloads();
+    },
+  },
+};
 </script>
 
 <style lang="less" scoped>
 .tags-view-container {
   .tags-view-wrapper {
-    background: #fff;
+    background: #edeef0;
     height: 34px;
     border-bottom: 1px solid #d8dce5;
     box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
     .tags-view-item {
+      width: 120px;
+      .icon {
+        font-size: 20px;
+        position: relative;
+        top: 3px;
+        float: right;
+        margin-right: 5px;
+      }
+      border-radius: 5px 5px 0 0;
       display: inline-block;
       position: relative;
-      height: 26px;
-      line-height: 26px;
-      border: 1px solid #d8dce5;
+      height: 30px;
+      line-height: 30px;
+      // border: 1px solid #d8dce5;
       color: #495060;
-      background: #fff;
+
       padding: 0 8px;
       font-size: 12px;
-      margin-left: 5px;
+      // margin-left: 5px;
       margin-top: 4px;
       &:first-of-type {
         margin-left: 15px;
       }
       &.active {
-        background-color: #13817a;
-        color: #fff;
-        border-color: #13817a;
+        color: #495060;
+        left: -1px;
+        background-color: #fff;
+        z-index: 2;
+
         &::before {
-          content: "";
-          background: #fff;
-          display: inline-block;
-          width: 8px;
-          height: 8px;
-          border-radius: 50%;
-          position: relative;
-          margin-right: 2px;
+           border-right: 0;
         }
       }
+      &::before {
+        content: "";
+        display: inline-block;
+        position: absolute;
+        right: 0;
+        height: 20px;
+        bottom: 6px;
+        border-right: 1px solid #b5b5b5;
+      }
     }
   }
   .contextmenu {

+ 39 - 28
src/styles/sidebar.scss

@@ -10,7 +10,7 @@
   .sidebar-container {
     transition: width 0.28s;
     width: $sideBarWidth !important;
-    // background-color: $menuBg;
+    background-color: $menuBg;
     height: 100%;
     position: fixed;
     font-size: 0px;
@@ -69,28 +69,35 @@
     }
 
     // menu hover
-    // .submenu-title-noDropdown,
-    // .el-submenu__title {
-    //   &:hover {
-    //     background-color: $menuHover !important;
-    //   }
-    // }
-
-    // .is-active>.el-submenu__title {
-    //   color: $subMenuActiveText !important;
-    // }
-
-    // & .nest-menu .el-submenu>.el-submenu__title,
-    // & .el-submenu .el-menu-item {
-    //   min-width: $sideBarWidth !important;
-    //   background-color: $subMenuBg !important;
-
-    //   &:hover {
-    //     background-color: $subMenuHover !important;
-    //   }
-    // }
-  }
+    .submenu-title-noDropdown,
+    .el-submenu__title {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+
+      &:hover {
+        background-color: $menuHover !important;
+      }
+    }
+
+    .is-active>.el-submenu__title {
+      i{color: #fff;}
+      color: $subMenuActiveText !important;
+    }
+
+    & .nest-menu .el-submenu>.el-submenu__title,
+    & .el-submenu .el-menu-item {
+      min-width: $sideBarWidth !important;
+      background-color: $subMenuBg;
 
+      &:hover {
+        background-color: $subMenuHover !important;
+      }
+    }
+  }
+  .el-menu-item.is-active {
+    background-color: $subMenuActiveBg!important;
+ }
   .hideSidebar {
     .sidebar-container {
       width: $sideBarWidth  !important;
@@ -124,6 +131,7 @@
         }
 
         .el-submenu__icon-arrow {
+          color: #fff;
           display: none;
         }
       }
@@ -186,12 +194,15 @@
   }
 
   // .nest-menu .el-submenu>.el-submenu__title,
-  // .el-menu-item {
-  //   &:hover {
-  //     // you can use $subMenuHover
-  //     background-color: $menuHover !important;
-  //   }
-  // }
+  .el-menu-item {
+    &:hover {
+      // you can use $subMenuHover
+      background-color: $menuHover !important;
+    }
+    .is-active {
+      background-color: #13817A !important;
+    }
+  }
 
   // the scroll bar appears when the subMenu is too long
   >.el-menu--popup {

+ 20 - 19
src/styles/variables.scss

@@ -1,26 +1,27 @@
 // sidebar
-// $menuText:#80BBB7;
-// $menuActiveText:#fff;
-// $subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
+$menuText:#CBCBCB;    // #000
+$menuActiveText:#fff;
+$subMenuActiveText:#fff; //https://github.com/ElemeFE/element/issues/12951
+// :#13817A;
+$menuBg:#363D55;
+$menuHover:#13817A;
 
-// $menuBg:#13817A;
-// $menuHover:#13817A;
-
-// $subMenuBg:#0E605B;
-// $subMenuHover:#0E605B;
+$subMenuBg:#2C3246;
+$subMenuHover:#2C3246;
+$subMenuActiveBg:#13817A;
 
 $sideBarWidth: 165px;
 /* 改变主题色变量 */
-// $--color-primary: rgb(19, 129, 122);
+$--color-primary: rgb(19, 129, 122);
 // the :export directive is the magic sauce for webpack
 // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
-// :export {
-//   menuText: $menuText;
-//   menuActiveText: $menuActiveText;
-//   subMenuActiveText: $subMenuActiveText;
-//   menuBg: $menuBg;
-//   menuHover: $menuHover;
-//   subMenuBg: $subMenuBg;
-//   subMenuHover: $subMenuHover;
-//   sideBarWidth: $sideBarWidth;
-// }
+:export {
+  menuText: $menuText;
+  menuActiveText: $menuActiveText;
+  subMenuActiveText: $subMenuActiveText;
+  menuBg: $menuBg;
+  menuHover: $menuHover;
+  subMenuBg: $subMenuBg;
+  subMenuHover: $subMenuHover;
+  sideBarWidth: $sideBarWidth;
+}

部分文件因文件數量過多而無法顯示