浏览代码

前端导航栏,菜单样式引入vue-element-admin,第一次改动

zwq 2 年之前
父节点
当前提交
9e39588d91
共有 59 个文件被更改,包括 3520 次插入172 次删除
  1. 9 2
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/package.json
  2. 78 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/components/Breadcrumb/index.vue
  3. 44 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/components/Hamburger/index.vue
  4. 62 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/components/SvgIcon/index.vue
  5. 9 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/index.js
  6. 0 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/dashboard.svg
  7. 1 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/example.svg
  8. 1 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/eye-open.svg
  9. 1 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/eye.svg
  10. 0 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/form.svg
  11. 1 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/link.svg
  12. 1 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/nested.svg
  13. 1 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/password.svg
  14. 1 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/table.svg
  15. 1 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/tree.svg
  16. 1 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/user.svg
  17. 22 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svgo.yml
  18. 57 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/AppMain.vue
  19. 311 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Navbar.vue
  20. 26 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/FixiOSBug.js
  21. 41 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/Item.vue
  22. 43 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/Link.vue
  23. 82 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/Logo.vue
  24. 95 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/SidebarItem.vue
  25. 57 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/index.vue
  26. 94 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/TagsView/ScrollPane.vue
  27. 292 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/TagsView/index.vue
  28. 4 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/index.js
  29. 96 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/index.vue
  30. 45 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/mixin/ResizeHandler.js
  31. 5 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/main.js
  32. 41 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/permission.js
  33. 146 93
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/router/index.js
  34. 11 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/getters.js
  35. 27 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/index.js
  36. 48 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/app.js
  37. 69 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/permission.js
  38. 30 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/settings.js
  39. 160 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/tagsView.js
  40. 98 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/user.js
  41. 49 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/element-ui.scss
  42. 65 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/index.scss
  43. 28 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/mixin.scss
  44. 226 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/sidebar.scss
  45. 48 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/transition.scss
  46. 25 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/variables.scss
  47. 8 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/utils/get-page-title.js
  48. 20 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/utils/validate.js
  49. 11 6
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/LoginPage.vue
  50. 885 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/decisionMatters/DecisionMatters.vue
  51. 4 9
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/history/History.vue
  52. 2 8
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/history/HistoryDetail.vue
  53. 4 9
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/history/InformationEntry.vue
  54. 15 19
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/impressionNanan/Administration.vue
  55. 2 8
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/impressionNanan/ImpressionNanan.vue
  56. 2 6
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/mapEdit/MapDetails.vue
  57. 3 7
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/mapEdit/MapEdit.vue
  58. 0 5
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/new/HuaLongData.vue
  59. 12 0
      nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/redirect/index.vue

+ 9 - 2
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/package.json

@@ -11,10 +11,13 @@
   "dependencies": {
     "axios": "^0.27.2",
     "core-js": "^3.6.5",
+    "js-cookie": "2.2.0",
     "element-ui": "^2.15.7",
     "vue": "^2.6.11",
     "vue-baidu-map": "^0.21.22",
-    "vue-router": "^3.2.0"
+    "vue-router": "^3.2.0",
+	  "vuex": "3.1.0",
+    "nprogress": "0.2.0"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "~4.5.15",
@@ -29,6 +32,10 @@
     "less": "^3.0.4",
     "less-loader": "^5.0.0",
     "prettier": "^2.2.1",
-    "vue-template-compiler": "^2.6.11"
+    "vue-template-compiler": "^2.6.11",
+	  "sass": "1.26.8",
+	  "sass-loader": "8.0.2",
+    "svg-sprite-loader": "4.1.3",
+    "svgo": "1.2.2"
   }
 }

+ 78 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/components/Breadcrumb/index.vue

@@ -0,0 +1,78 @@
+<template>
+  <el-breadcrumb class="app-breadcrumb" separator="/">
+    <transition-group name="breadcrumb">
+      <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
+        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
+        <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
+      </el-breadcrumb-item>
+    </transition-group>
+  </el-breadcrumb>
+</template>
+
+<script>
+import pathToRegexp from 'path-to-regexp'
+
+export default {
+  data() {
+    return {
+      levelList: null
+    }
+  },
+  watch: {
+    $route() {
+      this.getBreadcrumb()
+    }
+  },
+  created() {
+    this.getBreadcrumb()
+  },
+  methods: {
+    getBreadcrumb() {
+      // only show routes with meta.title
+      let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
+      const first = matched[0]
+
+      if (!this.isDashboard(first)) {
+        matched = [{ path: '/dashboard', meta: { title: '主页' }}].concat(matched)
+      }
+
+      this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
+    },
+    isDashboard(route) {
+      const name = route && route.name
+      if (!name) {
+        return false
+      }
+      return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
+    },
+    pathCompile(path) {
+      // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
+      const { params } = this.$route
+      var toPath = pathToRegexp.compile(path)
+      return toPath(params)
+    },
+    handleLink(item) {
+      const { redirect, path } = item
+      if (redirect) {
+        this.$router.push(redirect)
+        return
+      }
+      this.$router.push(this.pathCompile(path))
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.app-breadcrumb.el-breadcrumb {
+  display: inline-block;
+  font-size: 14px;
+  line-height: 50px;
+  margin-left: 8px;
+
+  .no-redirect {
+    color: #97a8be;
+    cursor: text;
+  }
+}
+</style>

+ 44 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/components/Hamburger/index.vue

@@ -0,0 +1,44 @@
+<template>
+  <div style="padding: 0 15px;" @click="toggleClick">
+    <svg
+      :class="{'is-active':isActive}"
+      class="hamburger"
+      viewBox="0 0 1024 1024"
+      xmlns="http://www.w3.org/2000/svg"
+      width="64"
+      height="64"
+    >
+      <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
+    </svg>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'Hamburger',
+  props: {
+    isActive: {
+      type: Boolean,
+      default: false
+    }
+  },
+  methods: {
+    toggleClick() {
+      this.$emit('toggleClick')
+    }
+  }
+}
+</script>
+
+<style scoped>
+.hamburger {
+  display: inline-block;
+  vertical-align: middle;
+  width: 20px;
+  height: 20px;
+}
+
+.hamburger.is-active {
+  transform: rotate(180deg);
+}
+</style>

+ 62 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/components/SvgIcon/index.vue

@@ -0,0 +1,62 @@
+<template>
+  <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
+  <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
+    <use :xlink:href="iconName" />
+  </svg>
+</template>
+
+<script>
+// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
+import { isExternal } from '@/utils/validate'
+
+export default {
+  name: 'SvgIcon',
+  props: {
+    iconClass: {
+      type: String,
+      required: true
+    },
+    className: {
+      type: String,
+      default: ''
+    }
+  },
+  computed: {
+    isExternal() {
+      return isExternal(this.iconClass)
+    },
+    iconName() {
+      return `#icon-${this.iconClass}`
+    },
+    svgClass() {
+      if (this.className) {
+        return 'svg-icon ' + this.className
+      } else {
+        return 'svg-icon'
+      }
+    },
+    styleExternalIcon() {
+      return {
+        mask: `url(${this.iconClass}) no-repeat 50% 50%`,
+        '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.svg-icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+
+.svg-external-icon {
+  background-color: currentColor;
+  mask-size: cover!important;
+  display: inline-block;
+}
+</style>

+ 9 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/index.js

@@ -0,0 +1,9 @@
+import Vue from 'vue'
+import SvgIcon from '@/components/SvgIcon'// svg component
+
+// register globally
+Vue.component('svg-icon', SvgIcon)
+
+const req = require.context('./svg', false, /\.svg$/)
+const requireAll = requireContext => requireContext.keys().map(requireContext)
+requireAll(req)

文件差异内容过多而无法显示
+ 0 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/dashboard.svg


+ 1 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/example.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>

+ 1 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/eye-open.svg

@@ -0,0 +1 @@
+<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>

+ 1 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/eye.svg

@@ -0,0 +1 @@
+<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>

文件差异内容过多而无法显示
+ 0 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/form.svg


+ 1 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/link.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>

+ 1 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/nested.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>

+ 1 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/password.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>

+ 1 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/table.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg>

+ 1 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/tree.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>

+ 1 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svg/user.svg

@@ -0,0 +1 @@
+<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>

+ 22 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/icons/svgo.yml

@@ -0,0 +1,22 @@
+# replace default config
+
+# multipass: true
+# full: true
+
+plugins:
+
+  # - name
+  #
+  # or:
+  # - name: false
+  # - name: true
+  #
+  # or:
+  # - name:
+  #     param1: 1
+  #     param2: 2
+
+- removeAttrs:
+    attrs:
+      - 'fill'
+      - 'fill-rule'

+ 57 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/AppMain.vue

@@ -0,0 +1,57 @@
+<template>
+  <section class="app-main">
+    <transition name="fade-transform" mode="out-in">
+      <keep-alive :include="cachedViews">
+        <router-view :key="key" />
+      </keep-alive>
+    </transition>
+  </section>
+</template>
+
+<script>
+export default {
+  name: 'AppMain',
+  computed: {
+    cachedViews() {
+      return this.$store.state.tagsView.cachedViews
+    },
+    key() {
+      return this.$route.path
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.app-main {
+  /* 50= navbar  50  */
+  min-height: calc(100vh - 50px);
+  width: 100%;
+  position: relative;
+  overflow: hidden;
+}
+
+.fixed-header+.app-main {
+  padding-top: 50px;
+}
+
+.hasTagsView {
+  .app-main {
+    /* 84 = navbar + tags-view = 50 + 34 */
+    min-height: calc(100vh - 84px);
+  }
+
+  .fixed-header+.app-main {
+    padding-top: 84px;
+  }
+}
+</style>
+
+<style lang="scss">
+// fix css style bug in open el-dialog
+.el-popup-parent--hidden {
+  .fixed-header {
+    padding-right: 15px;
+  }
+}
+</style>

+ 311 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Navbar.vue

@@ -0,0 +1,311 @@
+<template>
+  <div class="navbar">
+    <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+
+    <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
+
+    <div class="right-menu">
+      <template v-if="device!=='mobile'">
+
+      </template>
+
+      <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
+        <div class="avatar-wrapper">
+          <i class="el-icon-user"></i>
+          <i class="el-icon-caret-bottom" />
+        </div>
+        <el-dropdown-menu slot="dropdown">
+          <el-dropdown-item divided @click.native="seting('modifypwd')">
+            <span style="display:block;">修改密码</span>
+          </el-dropdown-item>
+          <router-link to="/">
+            <el-dropdown-item>首页</el-dropdown-item>
+          </router-link>
+          <el-dropdown-item divided @click.native="logout">
+            <span style="display:block;">注销</span>
+          </el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+    </div>
+    <!-- 修改密码 -->
+        <el-dialog width="80%" :visible.sync="modifyPwdDialog">
+            <div slot="title">
+                <div class="addTitle">修改密码</div>
+            </div>
+            <div>
+                <el-form label-width="110px" ref="modifypwd" :model="modifyPwdForm" :rules="modifypwdRules">
+                    <el-form-item label="原密码" prop="pwd">
+                        <el-input v-model.trim="modifyPwdForm.pwd" show-password type="password"
+                                  placeholder="请输入原密码"></el-input>
+                    </el-form-item>
+                    <el-form-item label="新密码" prop="newPwd">
+                        <el-input v-model.trim="modifyPwdForm.newPwd" show-password type="password"
+                                  placeholder="请输入新密码"></el-input>
+                    </el-form-item>
+                    <el-form-item label="确认新密码" prop="sureNewPwd">
+                        <el-input v-model.trim="modifyPwdForm.sureNewPwd" show-password type="password"
+                                  placeholder="请确认新密码"></el-input>
+                    </el-form-item>
+                </el-form>
+            </div>
+            <div slot="footer">
+                <el-button type="primary" @click="confirmBtn">确认</el-button>
+                <el-button @click="modifyPwdDialog=false">取消</el-button>
+            </div>
+        </el-dialog>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import Breadcrumb from '@/components/Breadcrumb'
+import Hamburger from '@/components/Hamburger'
+import api from '../../api/index'
+
+    const requiredValidator = (rule, value, callback) => {
+        if (typeof value === 'string' && value.trim() !== '') {
+            callback()
+        } else {
+            // 验证失败
+            if (rule.field === 'pwd') callback(new Error('请输入原密码'))
+            if (rule.field === 'newPwd') callback(new Error('请输入新密码'))
+            if (rule.field === 'sureNewPwd') callback(new Error('请确认新密码'))
+
+        }
+    }
+
+export default {
+  components: {
+    Breadcrumb,
+    Hamburger,
+  },
+  computed: {
+    ...mapGetters([
+      'sidebar',
+      'avatar',
+      'device'
+    ])
+  },
+  data() {
+    return { 
+      gitUrl: '#',
+      username: '',
+      modifyPwdDialog: false,
+                modifyPwdForm: {
+                    pwd: '',
+                    newPwd: '',
+                    sureNewPwd: '',
+                },
+      modifypwdRules: {
+                    pwd: [
+                        {
+                            message: '请输入原密码',
+                            trigger: 'blur'
+                        },
+                        {
+                            validator: requiredValidator
+                        }
+                    ],
+                    newPwd: [
+                        {
+                            message: '请输入新密码',
+                            trigger: 'blur'
+                        },
+                        {
+                            validator: requiredValidator
+                        }
+                    ],
+                    sureNewPwd: [
+                        {
+                            message: '请确认新密码',
+                            trigger: 'blur'
+                        },
+                        {
+                            validator: requiredValidator
+                        }
+                    ],
+                }
+      
+     }
+     
+  },
+  created() {
+    this.username = JSON.parse(sessionStorage['username'])
+  },
+  methods: {
+    toggleSideBar() {
+      this.$store.dispatch('app/toggleSideBar')
+    },
+    logout() {
+      // await this.$store.dispatch('admin/logout')
+      this.$confirm('您确定要退出吗', {
+        cancelButtonClass: "btn-custom-cancel",
+        confirmButtonText: '确定',
+        closeOnClickModal: false,
+        cancelButtonText: '取消',
+        type: 'warning' 
+	  }).then(() => {
+        this.$router.push(`/login?redirect=${this.$route.fullPath}`)
+        sessionStorage.removeItem('utoken')
+        this.$message({
+          type: 'success',
+          message: '安全退出'
+        });
+	  }).catch(() => { 
+	    this.$message({
+        type: 'info',
+        message: '取消退出'
+        });
+      })
+    },
+    //    修改密码
+            seting(modifypwd) {
+                this.modifyPwdDialog = true
+                this.modifyPwdForm = {}
+                if (this.$refs[modifypwd]==undefined){
+                    return
+                }else{
+                    this.$refs[modifypwd].resetFields()
+                }
+                /*this.$prompt('请输入新密码', '修改密码', {
+                    cancelButtonClass: "btn-custom-cancel",
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                }).then(({value}) => {
+                    let data = {
+                        pid: 5,
+                        password: value
+                    }
+                    api.updateUser(data).then(() => {
+                        this.$message({
+                            type: 'success',
+                            message: '你的新密码是: ' + value
+                        });
+                    }).catch(() => {
+                        this.$message.error('修改密码失败')
+                    })
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '取消修改'
+                    });
+                });*/
+            },
+            confirmBtn() {
+                this.$refs.modifypwd.validate(valid => {
+                    if (valid) {
+                        if (this.modifyPwdForm.newPwd !== this.modifyPwdForm.sureNewPwd) {
+                            this.$message.error('请再次确认密码')
+                            return
+                        }
+                        // let data = `pid=${JSON.parse(localStorage.getItem('user')).pid}&originalPassword=${this.modifyPwdForm.pwd}&newPassword=${this.modifyPwdForm.newPwd}`
+                        let fd = new FormData()
+                        fd.append('pid', JSON.parse(localStorage.getItem('user')).pid);//传文件
+                        fd.append('originalPassword', this.modifyPwdForm.pwd);//传其他参数
+                        fd.append('newPassword', this.modifyPwdForm.newPwd);//传其他参数
+                        // let params = {
+                        //     pid:JSON.parse(localStorage.getItem('user')).pid,
+                        //     originalPassword: this.modifyPwdForm.pwd,
+                        //     newPassword: this.modifyPwdForm.newPwd,
+                        // }
+                        api.updatePwd(fd).then((r) => {
+                            if (r.data.result&&this.modifyPwdForm.newPwd!=this.modifyPwdForm.pwd) {
+                                this.$message.success('密码修改成功')
+                            } else {
+                                this.$message.error('密码修改失败')
+                            }
+
+                            this.modifyPwdDialog = false
+                        }).catch(() => {
+                            this.$message.error('密码修改失败')
+                        })
+                    }
+                })
+            },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.navbar {
+  height: 50px;
+  overflow: hidden;
+  position: relative;
+  background: #fff;
+  box-shadow: 0 1px 4px rgba(0,21,41,.08);
+
+  .hamburger-container {
+    line-height: 46px;
+    height: 100%;
+    float: left;
+    cursor: pointer;
+    transition: background .3s;
+    -webkit-tap-highlight-color:transparent;
+
+    &:hover {
+      background: rgba(0, 0, 0, .025)
+    }
+  }
+
+  .breadcrumb-container {
+    float: left;
+  }
+
+  .errLog-container {
+    display: inline-block;
+    vertical-align: top;
+  }
+
+  .right-menu {
+    float: right;
+    height: 100%;
+    line-height: 50px;
+
+    &:focus {
+      outline: none;
+    }
+
+    .right-menu-item {
+      display: inline-block;
+      padding: 0 8px;
+      height: 100%;
+      font-size: 18px;
+      color: #5a5e66;
+      vertical-align: text-bottom;
+
+      &.hover-effect {
+        cursor: pointer;
+        transition: background .3s;
+
+        &:hover {
+          background: rgba(0, 0, 0, .025)
+        }
+      }
+    }
+
+    .avatar-container {
+      margin-right: 30px;
+
+      .avatar-wrapper {
+        margin-top: 5px;
+        position: relative;
+
+        .user-avatar {
+          cursor: pointer;
+          width: 40px;
+          height: 40px;
+          border-radius: 10px;
+        }
+
+        .el-icon-caret-bottom {
+          cursor: pointer;
+          position: absolute;
+          right: -20px;
+          top: 25px;
+          font-size: 12px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 26 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/FixiOSBug.js

@@ -0,0 +1,26 @@
+export default {
+  computed: {
+    device() {
+      return this.$store.state.app.device
+    }
+  },
+  mounted() {
+    // In order to fix the click on menu on the ios device will trigger the mouseleave bug
+    // https://github.com/PanJiaChen/vue-element-admin/issues/1135
+    this.fixBugIniOS()
+  },
+  methods: {
+    fixBugIniOS() {
+      const $subMenu = this.$refs.subMenu
+      if ($subMenu) {
+        const handleMouseleave = $subMenu.handleMouseleave
+        $subMenu.handleMouseleave = (e) => {
+          if (this.device === 'mobile') {
+            return
+          }
+          handleMouseleave(e)
+        }
+      }
+    }
+  }
+}

+ 41 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/Item.vue

@@ -0,0 +1,41 @@
+<script>
+export default {
+  name: 'MenuItem',
+  functional: true,
+  props: {
+    icon: {
+      type: String,
+      default: ''
+    },
+    title: {
+      type: String,
+      default: ''
+    }
+  },
+  render(h, context) {
+    const { icon, title } = context.props
+    const vnodes = []
+
+    if (icon) {
+      if (icon.includes('el-icon')) {
+        vnodes.push(<i class={[icon, 'sub-el-icon']} />)
+      } else {
+        vnodes.push(<svg-icon icon-class={icon}/>)
+      }
+    }
+
+    if (title) {
+      vnodes.push(<span slot='title'>{(title)}</span>)
+    }
+    return vnodes
+  }
+}
+</script>
+
+<style scoped>
+.sub-el-icon {
+  color: currentColor;
+  width: 1em;
+  height: 1em;
+}
+</style>

+ 43 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/Link.vue

@@ -0,0 +1,43 @@
+<template>
+  <component :is="type" v-bind="linkProps(to)">
+    <slot />
+  </component>
+</template>
+
+<script>
+import { isExternal } from '@/utils/validate'
+
+export default {
+  props: {
+    to: {
+      type: String,
+      required: true
+    }
+  },
+  computed: {
+    isExternal() {
+      return isExternal(this.to)
+    },
+    type() {
+      if (this.isExternal) {
+        return 'a'
+      }
+      return 'router-link'
+    }
+  },
+  methods: {
+    linkProps(to) {
+      if (this.isExternal) {
+        return {
+          href: to,
+          target: '_blank',
+          rel: 'noopener'
+        }
+      }
+      return {
+        to: to
+      }
+    }
+  }
+}
+</script>

+ 82 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/Logo.vue

@@ -0,0 +1,82 @@
+<template>
+  <div class="sidebar-logo-container" :class="{'collapse':collapse}">
+    <transition name="sidebarLogoFade">
+      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
+        <img v-if="logo" :src="logo" class="sidebar-logo">
+        <h1 v-else class="sidebar-title">{{ title }} </h1>
+      </router-link>
+      <router-link v-else key="expand" class="sidebar-logo-link" to="/">
+        <img v-if="logo" :src="logo" class="sidebar-logo">
+        <h1 class="sidebar-title">{{ title }} </h1>
+      </router-link>
+    </transition>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'SidebarLogo',
+  props: {
+    collapse: {
+      type: Boolean,
+      required: true
+    }
+  },
+  data() {
+    return {
+      title: '南岸区网站数据统计',
+      logo: false
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.sidebarLogoFade-enter-active {
+  transition: opacity 1.5s;
+}
+
+.sidebarLogoFade-enter,
+.sidebarLogoFade-leave-to {
+  opacity: 0;
+}
+
+.sidebar-logo-container {
+  position: relative;
+  width: 100%;
+  height: 50px;
+  line-height: 50px;
+  background: #2b2f3a;
+  text-align: center;
+  overflow: hidden;
+
+  & .sidebar-logo-link {
+    height: 100%;
+    width: 100%;
+
+    & .sidebar-logo {
+      width: 32px;
+      height: 32px;
+      vertical-align: middle;
+      margin-right: 12px;
+    }
+
+    & .sidebar-title {
+      display: inline-block;
+      margin: 0;
+      color: #fff;
+      font-weight: 600;
+      line-height: 50px;
+      font-size: 14px;
+      font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
+      vertical-align: middle;
+    }
+  }
+
+  &.collapse {
+    .sidebar-logo {
+      margin-right: 0px;
+    }
+  }
+}
+</style>

+ 95 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/SidebarItem.vue

@@ -0,0 +1,95 @@
+<template>
+  <div v-if="!item.hidden">
+    <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>
+      <template slot="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.path"
+        :is-nest="true"
+        :item="child"
+        :base-path="resolvePath(child.path)"
+        class="nest-menu"
+      />
+    </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'
+
+export default {
+  name: 'SidebarItem',
+  components: { Item, AppLink },
+  mixins: [FixiOSBug],
+  props: {
+    // route object
+    item: {
+      type: Object,
+      required: true
+    },
+    isNest: {
+      type: Boolean,
+      default: false
+    },
+    basePath: {
+      type: String,
+      default: ''
+    }
+  },
+  data() {
+    // To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
+    // TODO: refactor with render function
+    this.onlyOneChild = null
+    return {}
+  },
+  methods: {
+    hasOneShowingChild(children = [], parent) {
+      const showingChildren = children.filter(item => {
+        if (item.hidden) {
+          return false
+        } else {
+          // Temp set(will be used if only has one showing child)
+          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
+      }
+
+      // Show parent if there are no child router to display
+      if (showingChildren.length === 0) {
+        this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
+        return true
+      }
+
+      return false
+    },
+    resolvePath(routePath) {
+      if (isExternal(routePath)) {
+        return routePath
+      }
+      if (isExternal(this.basePath)) {
+        return this.basePath
+      }
+      return path.resolve(this.basePath, routePath)
+    }
+  }
+}
+</script>

+ 57 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/Sidebar/index.vue

@@ -0,0 +1,57 @@
+<template>
+  <div :class="{'has-logo':showLogo}">
+    <logo v-if="showLogo" :collapse="isCollapse" />
+    <el-scrollbar wrap-class="scrollbar-wrapper">
+      <el-menu
+        :default-active="activeMenu"
+        :collapse="isCollapse"
+        :background-color="variables.menuBg"
+        :text-color="variables.menuText"
+        :unique-opened="false"
+        :active-text-color="variables.menuActiveText"
+        :collapse-transition="false"
+        mode="vertical"
+      >
+        <sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />
+      </el-menu>
+    </el-scrollbar>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import Logo from './Logo'
+import SidebarItem from './SidebarItem'
+import variables from '@/styles/variables.scss'
+
+export default {
+  components: { SidebarItem, Logo },
+  computed: {
+    ...mapGetters([
+      'permission_routes',
+      'sidebar'
+    ]),
+    activeMenu() {
+      const route = this.$route
+      const { meta, path } = route
+      // if set path, the sidebar will highlight the path you set
+      if (meta.activeMenu) {
+        return meta.activeMenu
+      }
+      return path
+    },
+    showLogo() {
+      return this.$store.state.settings.sidebarLogo
+    },
+    variables() {
+      return variables
+    },
+    isCollapse() {
+      return !this.sidebar.opened
+    }
+  },
+  created() {
+    console.log('routes', this.permission_routes)
+  }
+}
+</script>

+ 94 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/TagsView/ScrollPane.vue

@@ -0,0 +1,94 @@
+<template>
+  <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
+    <slot />
+  </el-scrollbar>
+</template>
+
+<script>
+const tagAndTagSpacing = 4 // tagAndTagSpacing
+
+export default {
+  name: 'ScrollPane',
+  data() {
+    return {
+      left: 0
+    }
+  },
+  computed: {
+    scrollWrapper() {
+      return this.$refs.scrollContainer.$refs.wrap
+    }
+  },
+  mounted() {
+    this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)
+  },
+  beforeDestroy() {
+    this.scrollWrapper.removeEventListener('scroll', this.emitScroll)
+  },
+  methods: {
+    handleScroll(e) {
+      const eventDelta = e.wheelDelta || -e.deltaY * 40
+      const $scrollWrapper = this.scrollWrapper
+      $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
+    },
+    emitScroll() {
+      this.$emit('scroll')
+    },
+    moveToTarget(currentTag) {
+      const $container = this.$refs.scrollContainer.$el
+      const $containerWidth = $container.offsetWidth
+      const $scrollWrapper = this.scrollWrapper
+      const tagList = this.$parent.$refs.tag
+
+      let firstTag = null
+      let lastTag = null
+
+      // find first tag and last tag
+      if (tagList.length > 0) {
+        firstTag = tagList[0]
+        lastTag = tagList[tagList.length - 1]
+      }
+
+      if (firstTag === currentTag) {
+        $scrollWrapper.scrollLeft = 0
+      } else if (lastTag === currentTag) {
+        $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
+      } else {
+        // find preTag and nextTag
+        const currentIndex = tagList.findIndex(item => item === currentTag)
+        const prevTag = tagList[currentIndex - 1]
+        const nextTag = tagList[currentIndex + 1]
+
+        // the tag's offsetLeft after of nextTag
+        const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
+
+        // the tag's offsetLeft before of prevTag
+        const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
+
+        if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
+          $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
+        } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
+          $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.scroll-container {
+  white-space: nowrap;
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+  ::v-deep {
+    .el-scrollbar__bar {
+      bottom: 0px;
+    }
+    .el-scrollbar__wrap {
+      height: 49px;
+    }
+  }
+}
+</style>

+ 292 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/TagsView/index.vue

@@ -0,0 +1,292 @@
+<template>
+  <div id="tags-view-container" class="tags-view-container">
+    <scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
+      <router-link
+        v-for="tag in visitedViews"
+        ref="tag"
+        :key="tag.path"
+        :class="isActive(tag)?'active':''"
+        :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
+        tag="span"
+        class="tags-view-item"
+        @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
+        @contextmenu.prevent.native="openMenu(tag,$event)"
+      >
+        {{ tag.title }}
+        <span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
+      </router-link>
+    </scroll-pane>
+    <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
+      <li @click="refreshSelectedTag(selectedTag)">刷新</li>
+      <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭</li>
+      <li @click="closeOthersTags">关闭其他</li>
+      <li @click="closeAllTags(selectedTag)">关闭所有</li>
+    </ul>
+  </div>
+</template>
+
+<script>
+import ScrollPane from './ScrollPane'
+import path from 'path'
+
+export default {
+  components: { ScrollPane },
+  data() {
+    return {
+      visible: false,
+      top: 0,
+      left: 0,
+      selectedTag: {},
+      affixTags: []
+    }
+  },
+  computed: {
+    visitedViews() {
+      return this.$store.state.tagsView.visitedViews
+    },
+    routes() {
+      return this.$store.state.permission.routes
+    }
+  },
+  watch: {
+    $route() {
+      this.addTags()
+      this.moveToCurrentTag()
+    },
+    visible(value) {
+      if (value) {
+        document.body.addEventListener('click', this.closeMenu)
+      } else {
+        document.body.removeEventListener('click', this.closeMenu)
+      }
+    }
+  },
+  mounted() {
+    this.initTags()
+    this.addTags()
+  },
+  methods: {
+    isActive(route) {
+      return route.path === this.$route.path
+    },
+    isAffix(tag) {
+      return tag.meta && tag.meta.affix
+    },
+    filterAffixTags(routes, basePath = '/') {
+      let tags = []
+      routes.forEach(route => {
+        if (route.meta && route.meta.affix) {
+          const tagPath = path.resolve(basePath, route.path)
+          tags.push({
+            fullPath: tagPath,
+            path: tagPath,
+            name: route.name,
+            meta: { ...route.meta }
+          })
+        }
+        if (route.children) {
+          const tempTags = this.filterAffixTags(route.children, route.path)
+          if (tempTags.length >= 1) {
+            tags = [...tags, ...tempTags]
+          }
+        }
+      })
+      return tags
+    },
+    initTags() {
+      const affixTags = this.affixTags = this.filterAffixTags(this.routes)
+      for (const tag of affixTags) {
+        // Must have tag name
+        if (tag.name) {
+          this.$store.dispatch('tagsView/addVisitedView', tag)
+        }
+      }
+    },
+    addTags() {
+      const { name } = this.$route
+      if (name) {
+        this.$store.dispatch('tagsView/addView', this.$route)
+      }
+      return false
+    },
+    moveToCurrentTag() {
+      const tags = this.$refs.tag
+      this.$nextTick(() => {
+        for (const tag of tags) {
+          if (tag.to.path === this.$route.path) {
+            this.$refs.scrollPane.moveToTarget(tag)
+            // when query is different then update
+            if (tag.to.fullPath !== this.$route.fullPath) {
+              this.$store.dispatch('tagsView/updateVisitedView', this.$route)
+            }
+            break
+          }
+        }
+      })
+    },
+    refreshSelectedTag(view) {
+      this.$store.dispatch('tagsView/delCachedView', view).then(() => {
+        const { fullPath } = view
+        this.$nextTick(() => {
+          this.$router.replace({
+            path: '/redirect' + fullPath
+          })
+        })
+      })
+    },
+    closeSelectedTag(view) {
+      this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
+        if (this.isActive(view)) {
+          this.toLastView(visitedViews, view)
+        }
+      })
+    },
+    closeOthersTags() {
+      this.$router.push(this.selectedTag)
+      this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
+        this.moveToCurrentTag()
+      })
+    },
+    closeAllTags(view) {
+      this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
+        if (this.affixTags.some(tag => tag.path === view.path)) {
+          return
+        }
+        this.toLastView(visitedViews, view)
+      })
+    },
+    toLastView(visitedViews, view) {
+      const latestView = visitedViews.slice(-1)[0]
+      if (latestView) {
+        this.$router.push(latestView.fullPath)
+      } else {
+        // now the default is to redirect to the home page if there is no tags-view,
+        // you can adjust it according to your needs.
+        if (view.name === 'Dashboard') {
+          // to reload home page
+          this.$router.replace({ path: '/redirect' + view.fullPath })
+        } else {
+          this.$router.push('/')
+        }
+      }
+    },
+    openMenu(tag, e) {
+      const menuMinWidth = 105
+      const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
+      const offsetWidth = this.$el.offsetWidth // container width
+      const maxLeft = offsetWidth - menuMinWidth // left boundary
+      const left = e.clientX - offsetLeft + 15 // 15: margin right
+
+      if (left > maxLeft) {
+        this.left = maxLeft
+      } else {
+        this.left = left
+      }
+
+      this.top = e.clientY
+      this.visible = true
+      this.selectedTag = tag
+    },
+    closeMenu() {
+      this.visible = false
+    },
+    handleScroll() {
+      this.closeMenu()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.tags-view-container {
+  height: 34px;
+  width: 100%;
+  background: #fff;
+  border-bottom: 1px solid #d8dce5;
+  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
+  .tags-view-wrapper {
+    .tags-view-item {
+      display: inline-block;
+      position: relative;
+      cursor: pointer;
+      height: 26px;
+      line-height: 26px;
+      border: 1px solid #d8dce5;
+      color: #495060;
+      background: #fff;
+      padding: 0 8px;
+      font-size: 12px;
+      margin-left: 5px;
+      margin-top: 4px;
+      &:first-of-type {
+        margin-left: 15px;
+      }
+      &:last-of-type {
+        margin-right: 15px;
+      }
+      &.active {
+        background-color: #42b983;
+        color: #fff;
+        border-color: #42b983;
+        &::before {
+          content: '';
+          background: #fff;
+          display: inline-block;
+          width: 8px;
+          height: 8px;
+          border-radius: 50%;
+          position: relative;
+          margin-right: 2px;
+        }
+      }
+    }
+  }
+  .contextmenu {
+    margin: 0;
+    background: #fff;
+    z-index: 3000;
+    position: absolute;
+    list-style-type: none;
+    padding: 5px 0;
+    border-radius: 4px;
+    font-size: 12px;
+    font-weight: 400;
+    color: #333;
+    box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
+    li {
+      margin: 0;
+      padding: 7px 16px;
+      cursor: pointer;
+      &:hover {
+        background: #eee;
+      }
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+//reset element css of el-icon-close
+.tags-view-wrapper {
+  .tags-view-item {
+    .el-icon-close {
+      width: 16px;
+      height: 16px;
+      vertical-align: 2px;
+      border-radius: 50%;
+      text-align: center;
+      transition: all .3s cubic-bezier(.645, .045, .355, 1);
+      transform-origin: 100% 50%;
+      &:before {
+        transform: scale(.6);
+        display: inline-block;
+        vertical-align: -3px;
+      }
+      &:hover {
+        background-color: #b4bccc;
+        color: #fff;
+      }
+    }
+  }
+}
+</style>

+ 4 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/components/index.js

@@ -0,0 +1,4 @@
+export { default as AppMain } from './AppMain'
+export { default as Navbar } from './Navbar'
+export { default as Sidebar } from './Sidebar/index.vue'
+export { default as TagsView } from './TagsView/index.vue'

+ 96 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/index.vue

@@ -0,0 +1,96 @@
+<template>
+  <div :class="classObj" class="app-wrapper">
+    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
+    <sidebar class="sidebar-container" />
+    <div :class="{hasTagsView:needTagsView}" class="main-container">
+      <div :class="{'fixed-header':fixedHeader}">
+        <navbar />
+        <tags-view v-if="needTagsView" />
+      </div>
+      <app-main />
+    </div>
+  </div>
+</template>
+
+<script>
+import { AppMain, Navbar, Sidebar, TagsView } from './components'
+import ResizeMixin from './mixin/ResizeHandler'
+import { mapState } from 'vuex'
+
+export default {
+  name: 'Layout',
+  components: {
+    AppMain,
+    Navbar,
+    Sidebar,
+    TagsView
+  },
+  mixins: [ResizeMixin],
+  computed: {
+    ...mapState({
+      sidebar: state => state.app.sidebar,
+      device: state => state.app.device,
+      showSettings: state => state.settings.showSettings,
+      needTagsView: state => state.settings.tagsView,
+      fixedHeader: state => state.settings.fixedHeader
+    }),
+    classObj() {
+      return {
+        hideSidebar: !this.sidebar.opened,
+        openSidebar: this.sidebar.opened,
+        withoutAnimation: this.sidebar.withoutAnimation,
+        mobile: this.device === 'mobile'
+      }
+    }
+  },
+  methods: {
+    handleClickOutside() {
+      this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  @import "~@/styles/mixin.scss";
+  @import "~@/styles/variables.scss";
+
+  .app-wrapper {
+    @include clearfix;
+    position: relative;
+    height: 100%;
+    width: 100%;
+
+    &.mobile.openSidebar {
+      position: fixed;
+      top: 0;
+    }
+  }
+
+  .drawer-bg {
+    background: #000;
+    opacity: 0.3;
+    width: 100%;
+    top: 0;
+    height: 100%;
+    position: absolute;
+    z-index: 999;
+  }
+
+  .fixed-header {
+    position: fixed;
+    top: 0;
+    right: 0;
+    z-index: 9;
+    width: calc(100% - #{$sideBarWidth});
+    transition: width 0.28s;
+  }
+
+  .hideSidebar .fixed-header {
+    width: calc(100% - 54px)
+  }
+
+  .mobile .fixed-header {
+    width: 100%;
+  }
+</style>

+ 45 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/layout/mixin/ResizeHandler.js

@@ -0,0 +1,45 @@
+import store from '@/store'
+
+const { body } = document
+const WIDTH = 992 // refer to Bootstrap's responsive design
+
+export default {
+  watch: {
+    $route(route) {
+      if (this.device === 'mobile' && this.sidebar.opened) {
+        store.dispatch('app/closeSideBar', { withoutAnimation: false })
+      }
+    }
+  },
+  beforeMount() {
+    window.addEventListener('resize', this.$_resizeHandler)
+  },
+  beforeDestroy() {
+    window.removeEventListener('resize', this.$_resizeHandler)
+  },
+  mounted() {
+    const isMobile = this.$_isMobile()
+    if (isMobile) {
+      store.dispatch('app/toggleDevice', 'mobile')
+      store.dispatch('app/closeSideBar', { withoutAnimation: true })
+    }
+  },
+  methods: {
+    // use $_ for mixins properties
+    // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
+    $_isMobile() {
+      const rect = body.getBoundingClientRect()
+      return rect.width - 1 < WIDTH
+    },
+    $_resizeHandler() {
+      if (!document.hidden) {
+        const isMobile = this.$_isMobile()
+        store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
+
+        if (isMobile) {
+          store.dispatch('app/closeSideBar', { withoutAnimation: true })
+        }
+      }
+    }
+  }
+}

+ 5 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/main.js

@@ -1,9 +1,13 @@
 import Vue from "vue";
 import App from "./App.vue";
 import router from "./router";
+import store from './store'
 import ElementUI from 'element-ui';
 import 'element-ui/lib/theme-chalk/index.css';
 import BaiduMap from 'vue-baidu-map'
+import '@/styles/index.scss'
+import '@/icons'
+import './permission'
 
 Vue.config.productionTip = false;
 
@@ -15,5 +19,6 @@ Vue.use(BaiduMap, {
 
 new Vue({
   router,
+  store,
   render: (h) => h(App),
 }).$mount("#app");

+ 41 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/permission.js

@@ -0,0 +1,41 @@
+import router from './router'
+import store from './store'
+import NProgress from 'nprogress'
+import 'nprogress/nprogress.css'
+import getPageTitle from '@/utils/get-page-title'
+
+NProgress.configure({ showSpinner: true })
+
+const whiteList = ['/LoginPage', '/login']
+// 路由拦截
+router.beforeEach(async(to, from, next) => {
+  // 虚假进度条
+  NProgress.start()
+  // 标签名
+  document.title = getPageTitle(to.meta.title)
+  
+  if (sessionStorage.getItem('utoken')) {
+    // 如果已登录,加载routes,直接跳转
+    // routes是根据角色动态的菜单列表,这里没有角色,默认admin
+    const role = ['admin']
+    // 这里要生成一次用户访问路由的权限,不然vuex拿不到
+    const accessRoutes = await store.dispatch('permission/generateRoutes', role)
+    // 没有动态路由,不添加
+    // router.addRoutes(accessRoutes)
+    next()
+  } else {
+    // 没有登录
+    if (whiteList.indexOf(to.path) !== -1) {
+      // 白名单直接跳转
+      next()
+    } else {
+      // 跳转登录界面
+      next(`/login?redirect=${to.path}`)
+      NProgress.done()
+    }
+  }
+})
+
+router.afterEach(() => {
+  NProgress.done()
+})

+ 146 - 93
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/router/index.js

@@ -1,107 +1,160 @@
 import Vue from 'vue'
-import VueRouter from 'vue-router'
+import Router from 'vue-router'
 
-Vue.use(VueRouter)
+Vue.use(Router)
 
+/* Layout */
+import Layout from '@/layout'
 
+/* Router Modules */
 import HomePage from '../views/HomePage'
-import History from '../views/History'//历史信息
-import ImpressionNanan from '../views/ImpressionNanan'//印象南岸
-import InformationEntry from '../views/InformationEntry'//信息录入
-import HistoryDetail from '../views/HistoryDetail'//历史详情
+import History from '../views/history/History'//历史信息
+import ImpressionNanan from '../views/impressionNanan/ImpressionNanan'//印象南岸
+import InformationEntry from '../views/history/InformationEntry'//信息录入
+import HistoryDetail from '../views/history/HistoryDetail'//历史详情
 import LoginPage from '../views/LoginPage.vue'//登录
 import HuaLongData from '../views/new/HuaLongData'//华龙网数据
-import Administration from '../views/administration'//印象南岸专辑管理
-import MapEdit from '../views/MapEdit' // 地图纠错
-import MapDetails from '../views/MapDetails' // 地图详情
-import DecisionMatters from '../views/DecisionMatters' // 决策事项管理
-const originalPush = VueRouter.prototype.push
-VueRouter.prototype.push = function push(location) {
-    return originalPush.call(this, location).catch(err => err)
-}
+import Administration from '../views/impressionNanan/Administration'//印象南岸专辑管理
+import MapEdit from '../views/mapEdit/MapEdit' // 地图纠错
+import MapDetails from '../views/mapEdit/MapDetails' // 地图详情
+import DecisionMatters from '../views/decisionMatters/DecisionMatters' // 决策事项管理
+
 
-const routes = [
-    {
-        path: '/',
-        name: 'HomePage',
-        component: HomePage,
-        redirect: '/impressionNanan',
-        children: [
-            {
-                path: '/informationEntry',
-                name: 'informationEntry',
-                component: InformationEntry
-            },
-            {
-                path: '/history',
-                name: 'history',
-                component: History
-            },
-            {
-                path: '/impressionNanan',
-                name: 'impressionNanan',
-                component: ImpressionNanan
-            },
-            {
-                path: '/historyDetail',
-                name: 'historyDetail',
-                component: HistoryDetail
-            },
-            {
-                path: '/administration',
-                name: 'administration',
-                component: Administration
-            },
-            //华龙网数据
-            {
-                path: '/HuaLongData',
-                name: 'HuaLongData',
-                component: HuaLongData
-            },
-            // 地图纠错
-			{
-				path: '/MapEditList',
-				name: 'EditList',
-				component: MapEdit
-			},
-			// 地图详情
-			{
-				path: '/MapDetails',
-				name: 'Details',
-				component: MapDetails,
-				meta: { activeMenu: '/MapEditList' }
-			},
-             // 决策事项
-			{
-				path: '/DecisionMatters',
-				name: 'DecisionMatters',
-				component: DecisionMatters
-			}
-        ],
-    },
-    {
-        path: '/LoginPage',
-        name: 'LoginPage',
-        component: LoginPage
-    }
+export const constantRoutes = [
+  {
+    path: '/redirect',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: '/redirect/:path(.*)',
+        component: () => import('@/views/redirect/index')
+      }
+    ]
+  },
+  {
+    path: '/login',
+    component: 'LoginPage',
+    name: LoginPage,
+    hidden: true
+  },
+  {
+    path: '/404',
+    component: LoginPage,
+    hidden: true
+  },
+  {
+    path: '/',
+    component: Layout,
+    redirect: '/ImpressionNanan/index',
+    meta: { title: '印象南岸', icon: 'dashboard', affix: true },
+    children: [
+      {
+        path: '/ImpressionNanan/index',
+        component: ImpressionNanan,
+        name: 'ImpressionNanan',
+        meta: { title: '印象南岸' }
+      },
+      {
+        path: '/ImpressionNanan/administration',
+        component: Administration,
+        name: 'Administration',
+        meta: { title: '印象南岸专辑管理' }
+      }
+    ]
+  },
+  {
+    path: '/history',
+    component: Layout,
+    redirect: '/history/index',
+    name: 'history',
+    children: [
+      {
+        path: 'index',
+        component: History,
+        name: 'History',
+        meta: { title: '历史记录', icon: 'dashboard' }
+      },
+      {
+        path: 'informationEntry',
+        component: InformationEntry,
+        name: 'InformationEntry',
+        hidden: true,
+        meta: { title: '信息录入', icon: 'dashboard', activeMenu: '/history/index' }
+      },
+      {
+        path: 'historyDetail',
+        component: HistoryDetail,
+        name: 'HistoryDetail',
+        hidden: true,
+        meta: { title: '历史记录详情', icon: 'dashboard', activeMenu: '/history/index' }
+      }
+    ]
+  },
+  {
+    path: '/huaLongData',
+    component: Layout,
+    redirect: '/huaLongData/index',
+    name: 'HuaLongData',
+    children: [
+      {
+        path: 'index',
+        component: HuaLongData,
+        name: 'HuaLongData',
+        meta: { title: '华龙网数据', icon: 'dashboard' }
+      }
+    ]
+  },
+  {
+    path: '/decisionMatters',
+    component: Layout,
+    redirect: '/decisionMatters/index',
+    name: 'DecisionMatters',
+    children: [
+      {
+        path: 'index',
+        component: DecisionMatters,
+        name: 'DecisionMatters',
+        meta: { title: '决策事项管理', icon: 'dashboard' }
+      }
+    ]
+  },
+  {
+    path: '/mapEdit',
+    component: Layout,
+    redirect: '/mapEdit/index',
+    name: 'MapEdit',
+    meta: { title: '地图纠错', icon: 'dashboard' },
+    children: [
+      {
+        path: 'index',
+        component: MapEdit,
+        name: 'MapEdit',
+        meta: { title: '地图纠错', icon: 'dashboard' }
+      },
+      {
+        path: 'mapDetails',
+        component: MapDetails,
+        name: 'MapDetails',
+        meta: { title: '地图详情', icon: 'dashboard', activeMenu: '/mapEdit/index' },
+        hidden: true
+      }
+    ]
+  }
 ]
 
-const router = new VueRouter({ routes })
+export const asyncRoutes = []
 
-const whiteList = [
-    '/LoginPage'
-]
-// 通过路由守卫判断用户是否登录
-router.beforeEach((to, from, next) => {
-    if (whiteList.includes(to.path)) {
-        next()
-    } else {
-        if (sessionStorage['utoken']) {
-            next()
-        } else {
-            next('/LoginPage')
-        }
-    }
+const createRouter = () => new Router({
+  scrollBehavior: () => ({ y: 0 }),
+  routes: constantRoutes
 })
 
+const router = createRouter()
+
+export function resetRouter() {
+  const newRouter = createRouter()
+  router.matcher = newRouter.matcher // reset router
+}
+
 export default router

+ 11 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/getters.js

@@ -0,0 +1,11 @@
+const getters = {
+  sidebar: state => state.app.sidebar,
+  device: state => state.app.device,
+  token: state => state.user.token,
+  avatar: state => state.user.avatar,
+  name: state => state.user.name,
+  visitedViews: state => state.tagsView.visitedViews,
+  cachedViews: state => state.tagsView.cachedViews,
+  permission_routes: state => state.permission.routes
+}
+export default getters

+ 27 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/index.js

@@ -0,0 +1,27 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import getters from './getters'
+// import createPersistedState from 'vuex-persistedstate'
+
+Vue.use(Vuex)
+
+// https://webpack.js.org/guides/dependency-management/#requirecontext
+const modulesFiles = require.context('./modules', true, /\.js$/)
+
+// you do not need `import app from './modules/app'`
+// it will auto require all vuex module from modules file
+const modules = modulesFiles.keys().reduce((modules, modulePath) => {
+  // set './app.js' => 'app'
+  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
+  const value = modulesFiles(modulePath)
+  modules[moduleName] = value.default
+  return modules
+}, {})
+
+const store = new Vuex.Store({
+  modules,
+  getters,
+  // plugins: [createPersistedState()]
+})
+
+export default store

+ 48 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/app.js

@@ -0,0 +1,48 @@
+import Cookies from 'js-cookie'
+
+const state = {
+  sidebar: {
+    opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
+    withoutAnimation: false
+  },
+  device: 'desktop'
+}
+
+const mutations = {
+  TOGGLE_SIDEBAR: state => {
+    state.sidebar.opened = !state.sidebar.opened
+    state.sidebar.withoutAnimation = false
+    if (state.sidebar.opened) {
+      Cookies.set('sidebarStatus', 1)
+    } else {
+      Cookies.set('sidebarStatus', 0)
+    }
+  },
+  CLOSE_SIDEBAR: (state, withoutAnimation) => {
+    Cookies.set('sidebarStatus', 0)
+    state.sidebar.opened = false
+    state.sidebar.withoutAnimation = withoutAnimation
+  },
+  TOGGLE_DEVICE: (state, device) => {
+    state.device = device
+  }
+}
+
+const actions = {
+  toggleSideBar({ commit }) {
+    commit('TOGGLE_SIDEBAR')
+  },
+  closeSideBar({ commit }, { withoutAnimation }) {
+    commit('CLOSE_SIDEBAR', withoutAnimation)
+  },
+  toggleDevice({ commit }, device) {
+    commit('TOGGLE_DEVICE', device)
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}

+ 69 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/permission.js

@@ -0,0 +1,69 @@
+import { asyncRoutes, constantRoutes } from '@/router'
+
+/**
+ * 使用meta.role来确定当前用户是否拥有权限
+ * @param roles
+ * @param route
+ */
+function hasPermission(roles, route) {
+  if (route.meta && route.meta.roles) {
+    return roles.some(role => route.meta.roles.includes(role))
+  } else {
+    return true
+  }
+}
+
+/**
+ * Filter asynchronous routing tables by recursion
+ * @param routes asyncRoutes
+ * @param roles
+ */
+export function filterAsyncRoutes(routes, roles) {
+  const res = []
+
+  routes.forEach(route => {
+    const tmp = { ...route }
+    if (hasPermission(roles, tmp)) {
+      if (tmp.children) {
+        tmp.children = filterAsyncRoutes(tmp.children, roles)
+      }
+      res.push(tmp)
+    }
+  })
+
+  return res
+}
+
+const state = {
+  routes: [],
+  addRoutes: []
+}
+
+const mutations = {
+  SET_ROUTES: (state, routes) => {
+    state.addRoutes = routes
+    state.routes = constantRoutes.concat(routes)
+  }
+}
+
+const actions = {
+  generateRoutes({ commit }, roles) {
+    return new Promise(resolve => {
+      let accessedRoutes
+      if (roles.includes('ALL')) {
+        accessedRoutes = asyncRoutes || []
+      } else {
+        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
+      }
+      commit('SET_ROUTES', accessedRoutes)
+      resolve(accessedRoutes)
+    })
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}

+ 30 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/settings.js

@@ -0,0 +1,30 @@
+
+const state = {
+  showSettings: false,
+  tagsView: true,
+  fixedHeader: false,
+  sidebarLogo: true
+}
+
+const mutations = {
+  CHANGE_SETTING: (state, { key, value }) => {
+    // eslint-disable-next-line no-prototype-builtins
+    if (state.hasOwnProperty(key)) {
+      state[key] = value
+    }
+  }
+}
+
+const actions = {
+  changeSetting({ commit }, data) {
+    commit('CHANGE_SETTING', data)
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}
+

+ 160 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/tagsView.js

@@ -0,0 +1,160 @@
+const state = {
+  visitedViews: [],
+  cachedViews: []
+}
+
+const mutations = {
+  ADD_VISITED_VIEW: (state, view) => {
+    if (state.visitedViews.some(v => v.path === view.path)) return
+    state.visitedViews.push(
+      Object.assign({}, view, {
+        title: view.meta.title || 'no-name'
+      })
+    )
+  },
+  ADD_CACHED_VIEW: (state, view) => {
+    if (state.cachedViews.includes(view.name)) return
+    if (!view.meta.noCache) {
+      state.cachedViews.push(view.name)
+    }
+  },
+
+  DEL_VISITED_VIEW: (state, view) => {
+    for (const [i, v] of state.visitedViews.entries()) {
+      if (v.path === view.path) {
+        state.visitedViews.splice(i, 1)
+        break
+      }
+    }
+  },
+  DEL_CACHED_VIEW: (state, view) => {
+    const index = state.cachedViews.indexOf(view.name)
+    index > -1 && state.cachedViews.splice(index, 1)
+  },
+
+  DEL_OTHERS_VISITED_VIEWS: (state, view) => {
+    state.visitedViews = state.visitedViews.filter(v => {
+      return v.meta.affix || v.path === view.path
+    })
+  },
+  DEL_OTHERS_CACHED_VIEWS: (state, view) => {
+    const index = state.cachedViews.indexOf(view.name)
+    if (index > -1) {
+      state.cachedViews = state.cachedViews.slice(index, index + 1)
+    } else {
+      // if index = -1, there is no cached tags
+      state.cachedViews = []
+    }
+  },
+
+  DEL_ALL_VISITED_VIEWS: state => {
+    // keep affix tags
+    const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
+    state.visitedViews = affixTags
+  },
+  DEL_ALL_CACHED_VIEWS: state => {
+    state.cachedViews = []
+  },
+
+  UPDATE_VISITED_VIEW: (state, view) => {
+    for (let v of state.visitedViews) {
+      if (v.path === view.path) {
+        v = Object.assign(v, view)
+        break
+      }
+    }
+  }
+}
+
+const actions = {
+  addView({ dispatch }, view) {
+    dispatch('addVisitedView', view)
+    dispatch('addCachedView', view)
+  },
+  addVisitedView({ commit }, view) {
+    commit('ADD_VISITED_VIEW', view)
+  },
+  addCachedView({ commit }, view) {
+    commit('ADD_CACHED_VIEW', view)
+  },
+
+  delView({ dispatch, state }, view) {
+    return new Promise(resolve => {
+      dispatch('delVisitedView', view)
+      dispatch('delCachedView', view)
+      resolve({
+        visitedViews: [...state.visitedViews],
+        cachedViews: [...state.cachedViews]
+      })
+    })
+  },
+  delVisitedView({ commit, state }, view) {
+    return new Promise(resolve => {
+      commit('DEL_VISITED_VIEW', view)
+      resolve([...state.visitedViews])
+    })
+  },
+  delCachedView({ commit, state }, view) {
+    return new Promise(resolve => {
+      commit('DEL_CACHED_VIEW', view)
+      resolve([...state.cachedViews])
+    })
+  },
+
+  delOthersViews({ dispatch, state }, view) {
+    return new Promise(resolve => {
+      dispatch('delOthersVisitedViews', view)
+      dispatch('delOthersCachedViews', view)
+      resolve({
+        visitedViews: [...state.visitedViews],
+        cachedViews: [...state.cachedViews]
+      })
+    })
+  },
+  delOthersVisitedViews({ commit, state }, view) {
+    return new Promise(resolve => {
+      commit('DEL_OTHERS_VISITED_VIEWS', view)
+      resolve([...state.visitedViews])
+    })
+  },
+  delOthersCachedViews({ commit, state }, view) {
+    return new Promise(resolve => {
+      commit('DEL_OTHERS_CACHED_VIEWS', view)
+      resolve([...state.cachedViews])
+    })
+  },
+
+  delAllViews({ dispatch, state }, view) {
+    return new Promise(resolve => {
+      dispatch('delAllVisitedViews', view)
+      dispatch('delAllCachedViews', view)
+      resolve({
+        visitedViews: [...state.visitedViews],
+        cachedViews: [...state.cachedViews]
+      })
+    })
+  },
+  delAllVisitedViews({ commit, state }) {
+    return new Promise(resolve => {
+      commit('DEL_ALL_VISITED_VIEWS')
+      resolve([...state.visitedViews])
+    })
+  },
+  delAllCachedViews({ commit, state }) {
+    return new Promise(resolve => {
+      commit('DEL_ALL_CACHED_VIEWS')
+      resolve([...state.cachedViews])
+    })
+  },
+
+  updateVisitedView({ commit }, view) {
+    commit('UPDATE_VISITED_VIEW', view)
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}

+ 98 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/store/modules/user.js

@@ -0,0 +1,98 @@
+// import { login, logout, getInfo } from '@/api/user'
+// import { getToken, setToken, removeToken } from '@/utils/auth'
+import { resetRouter } from '@/router'
+
+const getDefaultState = () => {
+  return {
+    // token: getToken(),
+    token: '',
+    name: '',
+    avatar: ''
+  }
+}
+
+const state = getDefaultState()
+
+const mutations = {
+  RESET_STATE: (state) => {
+    Object.assign(state, getDefaultState())
+  },
+  SET_TOKEN: (state, token) => {
+    state.token = token
+  },
+  SET_NAME: (state, name) => {
+    state.name = name
+  },
+  SET_AVATAR: (state, avatar) => {
+    state.avatar = avatar
+  }
+}
+
+const actions = {
+  // // user login
+  // login({ commit }, userInfo) {
+  //   const { username, password } = userInfo
+  //   return new Promise((resolve, reject) => {
+  //     login({ username: username.trim(), password: password }).then(response => {
+  //       const { data } = response
+  //       commit('SET_TOKEN', data.token)
+  //       setToken(data.token)
+  //       resolve()
+  //     }).catch(error => {
+  //       reject(error)
+  //     })
+  //   })
+  // },
+
+  // // get user info
+  // getInfo({ commit, state }) {
+  //   return new Promise((resolve, reject) => {
+  //     getInfo(state.token).then(response => {
+  //       const { data } = response
+
+  //       if (!data) {
+  //         return reject('Verification failed, please Login again.')
+  //       }
+
+  //       const { name, avatar } = data
+
+  //       commit('SET_NAME', name)
+  //       commit('SET_AVATAR', avatar)
+  //       resolve(data)
+  //     }).catch(error => {
+  //       reject(error)
+  //     })
+  //   })
+  // },
+
+  // // user logout
+  // logout({ commit, state }) {
+  //   return new Promise((resolve, reject) => {
+  //     logout(state.token).then(() => {
+  //       removeToken() // must remove  token  first
+  //       resetRouter()
+  //       commit('RESET_STATE')
+  //       resolve()
+  //     }).catch(error => {
+  //       reject(error)
+  //     })
+  //   })
+  // },
+
+  // // remove token
+  // resetToken({ commit }) {
+  //   return new Promise(resolve => {
+  //     removeToken() // must remove  token  first
+  //     commit('RESET_STATE')
+  //     resolve()
+  //   })
+  // }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}
+

+ 49 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/element-ui.scss

@@ -0,0 +1,49 @@
+// cover some element-ui styles
+
+.el-breadcrumb__inner,
+.el-breadcrumb__inner a {
+  font-weight: 400 !important;
+}
+
+.el-upload {
+  input[type="file"] {
+    display: none !important;
+  }
+}
+
+.el-upload__input {
+  display: none;
+}
+
+
+// to fixed https://github.com/ElemeFE/element/issues/2461
+.el-dialog {
+  transform: none;
+  left: 0;
+  position: relative;
+  margin: 0 auto;
+}
+
+// refine element ui upload
+.upload-container {
+  .el-upload {
+    width: 100%;
+
+    .el-upload-dragger {
+      width: 100%;
+      height: 200px;
+    }
+  }
+}
+
+// dropdown
+.el-dropdown-menu {
+  a {
+    display: block
+  }
+}
+
+// to fix el-date-picker css style
+.el-range-separator {
+  box-sizing: content-box;
+}

+ 65 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/index.scss

@@ -0,0 +1,65 @@
+@import './variables.scss';
+@import './mixin.scss';
+@import './transition.scss';
+@import './element-ui.scss';
+@import './sidebar.scss';
+
+body {
+  height: 100%;
+  -moz-osx-font-smoothing: grayscale;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+}
+
+label {
+  font-weight: 700;
+}
+
+html {
+  height: 100%;
+  box-sizing: border-box;
+}
+
+#app {
+  height: 100%;
+}
+
+*,
+*:before,
+*:after {
+  box-sizing: inherit;
+}
+
+a:focus,
+a:active {
+  outline: none;
+}
+
+a,
+a:focus,
+a:hover {
+  cursor: pointer;
+  color: inherit;
+  text-decoration: none;
+}
+
+div:focus {
+  outline: none;
+}
+
+.clearfix {
+  &:after {
+    visibility: hidden;
+    display: block;
+    font-size: 0;
+    content: " ";
+    clear: both;
+    height: 0;
+  }
+}
+
+// main-container global css
+.app-container {
+  padding: 20px;
+}

+ 28 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/mixin.scss

@@ -0,0 +1,28 @@
+@mixin clearfix {
+  &:after {
+    content: "";
+    display: table;
+    clear: both;
+  }
+}
+
+@mixin scrollBar {
+  &::-webkit-scrollbar-track-piece {
+    background: #d3dce6;
+  }
+
+  &::-webkit-scrollbar {
+    width: 6px;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    background: #99a9bf;
+    border-radius: 20px;
+  }
+}
+
+@mixin relative {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}

+ 226 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/sidebar.scss

@@ -0,0 +1,226 @@
+#app {
+
+  .main-container {
+    min-height: 100%;
+    transition: margin-left .28s;
+    margin-left: $sideBarWidth;
+    position: relative;
+  }
+
+  .sidebar-container {
+    transition: width 0.28s;
+    width: $sideBarWidth !important;
+    background-color: $menuBg;
+    height: 100%;
+    position: fixed;
+    font-size: 0px;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 1001;
+    overflow: hidden;
+
+    // reset element-ui css
+    .horizontal-collapse-transition {
+      transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
+    }
+
+    .scrollbar-wrapper {
+      overflow-x: hidden !important;
+    }
+
+    .el-scrollbar__bar.is-vertical {
+      right: 0px;
+    }
+
+    .el-scrollbar {
+      height: 100%;
+    }
+
+    &.has-logo {
+      .el-scrollbar {
+        height: calc(100% - 50px);
+      }
+    }
+
+    .is-horizontal {
+      display: none;
+    }
+
+    a {
+      display: inline-block;
+      width: 100%;
+      overflow: hidden;
+    }
+
+    .svg-icon {
+      margin-right: 16px;
+    }
+
+    .sub-el-icon {
+      margin-right: 12px;
+      margin-left: -2px;
+    }
+
+    .el-menu {
+      border: none;
+      height: 100%;
+      width: 100% !important;
+    }
+
+    // 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;
+      }
+    }
+  }
+
+  .hideSidebar {
+    .sidebar-container {
+      width: 54px !important;
+    }
+
+    .main-container {
+      margin-left: 54px;
+    }
+
+    .submenu-title-noDropdown {
+      padding: 0 !important;
+      position: relative;
+
+      .el-tooltip {
+        padding: 0 !important;
+
+        .svg-icon {
+          margin-left: 20px;
+        }
+
+        .sub-el-icon {
+          margin-left: 19px;
+        }
+      }
+    }
+
+    .el-submenu {
+      overflow: hidden;
+
+      &>.el-submenu__title {
+        padding: 0 !important;
+
+        .svg-icon {
+          margin-left: 20px;
+        }
+
+        .sub-el-icon {
+          margin-left: 19px;
+        }
+
+        .el-submenu__icon-arrow {
+          display: none;
+        }
+      }
+    }
+
+    .el-menu--collapse {
+      .el-submenu {
+        &>.el-submenu__title {
+          &>span {
+            height: 0;
+            width: 0;
+            overflow: hidden;
+            visibility: hidden;
+            display: inline-block;
+          }
+        }
+      }
+    }
+  }
+
+  .el-menu--collapse .el-menu .el-submenu {
+    min-width: $sideBarWidth !important;
+  }
+
+  // mobile responsive
+  .mobile {
+    .main-container {
+      margin-left: 0px;
+    }
+
+    .sidebar-container {
+      transition: transform .28s;
+      width: $sideBarWidth !important;
+    }
+
+    &.hideSidebar {
+      .sidebar-container {
+        pointer-events: none;
+        transition-duration: 0.3s;
+        transform: translate3d(-$sideBarWidth, 0, 0);
+      }
+    }
+  }
+
+  .withoutAnimation {
+
+    .main-container,
+    .sidebar-container {
+      transition: none;
+    }
+  }
+}
+
+// when menu collapsed
+.el-menu--vertical {
+  &>.el-menu {
+    .svg-icon {
+      margin-right: 16px;
+    }
+    .sub-el-icon {
+      margin-right: 12px;
+      margin-left: -2px;
+    }
+  }
+
+  .nest-menu .el-submenu>.el-submenu__title,
+  .el-menu-item {
+    &:hover {
+      // you can use $subMenuHover
+      background-color: $menuHover !important;
+    }
+  }
+
+  // the scroll bar appears when the subMenu is too long
+  >.el-menu--popup {
+    max-height: 100vh;
+    overflow-y: auto;
+
+    &::-webkit-scrollbar-track-piece {
+      background: #d3dce6;
+    }
+
+    &::-webkit-scrollbar {
+      width: 6px;
+    }
+
+    &::-webkit-scrollbar-thumb {
+      background: #99a9bf;
+      border-radius: 20px;
+    }
+  }
+}

+ 48 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/transition.scss

@@ -0,0 +1,48 @@
+// global transition css
+
+/* fade */
+.fade-enter-active,
+.fade-leave-active {
+  transition: opacity 0.28s;
+}
+
+.fade-enter,
+.fade-leave-active {
+  opacity: 0;
+}
+
+/* fade-transform */
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+  transition: all .5s;
+}
+
+.fade-transform-enter {
+  opacity: 0;
+  transform: translateX(-30px);
+}
+
+.fade-transform-leave-to {
+  opacity: 0;
+  transform: translateX(30px);
+}
+
+/* breadcrumb transition */
+.breadcrumb-enter-active,
+.breadcrumb-leave-active {
+  transition: all .5s;
+}
+
+.breadcrumb-enter,
+.breadcrumb-leave-active {
+  opacity: 0;
+  transform: translateX(20px);
+}
+
+.breadcrumb-move {
+  transition: all .5s;
+}
+
+.breadcrumb-leave-active {
+  position: absolute;
+}

+ 25 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/styles/variables.scss

@@ -0,0 +1,25 @@
+// sidebar
+$menuText:#bfcbd9;
+$menuActiveText:#409EFF;
+$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
+
+$menuBg:#304156;
+$menuHover:#263445;
+
+$subMenuBg:#1f2d3d;
+$subMenuHover:#001528;
+
+$sideBarWidth: 210px;
+
+// 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;
+}

+ 8 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/utils/get-page-title.js

@@ -0,0 +1,8 @@
+const title = 'Vue Element Admin'
+
+export default function getPageTitle(pageTitle) {
+  if (pageTitle) {
+    return `${pageTitle} - ${title}`
+  }
+  return `${title}`
+}

+ 20 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/utils/validate.js

@@ -0,0 +1,20 @@
+/**
+ * Created by PanJiaChen on 16/11/18.
+ */
+
+/**
+ * @param {string} path
+ * @returns {Boolean}
+ */
+export function isExternal(path) {
+  return /^(https?:|mailto:|tel:)/.test(path)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUsername(str) {
+  const valid_map = ['admin', 'editor']
+  return valid_map.indexOf(str.trim()) >= 0
+}

+ 11 - 6
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/LoginPage.vue

@@ -97,12 +97,17 @@
                     if (valid) {
                         let data = `userName=${this.loginForm.userName}&password=${this.loginForm.password}`
                         api.login(data).then(r => {
-                            // console.log(r.data.data)
-                            localStorage.setItem('user',JSON.stringify(r.data.data))
-                            sessionStorage['utoken'] = JSON.stringify(r.data.data.utoken)
-                            sessionStorage['pid'] = JSON.stringify(r.data.data.pid)
-                            sessionStorage['username'] = JSON.stringify(r.data.data.username)
-                            this.$router.push('/')
+                            if (r.data.result) {
+                                // 成功登陆
+                                localStorage.setItem('user',JSON.stringify(r.data.data))
+                                sessionStorage['utoken'] = JSON.stringify(r.data.data.utoken)
+                                sessionStorage['pid'] = JSON.stringify(r.data.data.pid)
+                                sessionStorage['username'] = JSON.stringify(r.data.data.username)
+                                console.log('登录成功')
+                                this.$router.push('/')
+                            } else {
+                                this.$message.error('登录失败,请确认密码')
+                            }
                         }).catch(() => {
                             this.$message.error('登录失败')
                         })

+ 885 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/decisionMatters/DecisionMatters.vue

@@ -0,0 +1,885 @@
+<template>
+    <div class="yxnaContent">
+        <!--        操作栏-->
+        <div style="display: flex;justify-content: space-between;margin-bottom: 10px">
+            <el-button type="primary" class="add" @click="openAddWork">新增</el-button>
+            <!-- <div style="display: flex">
+                <el-select ref="querySelect" style="width: 200px" clearable v-model="form.region" placeholder="请选择搜索方式"
+                    @change="selectRegion">
+                    <el-option label="作品电话" value="uploaderPhone"></el-option>
+                    <el-option label="作品名称" value="pictureTitle"></el-option>
+                    <el-option label="作品作者" value="pictureAuthor"></el-option>
+                </el-select>
+                <el-input v-model.trim="form.name" clearable @clear="clearreset" style="margin: 0 10px;width: 200px">
+                </el-input>
+                <el-button type="primary" class="search" @click="serachWork">搜索</el-button>
+                <el-button type="primary" class="search" @click="reset" style="margin-left: 5px">重置</el-button>
+            </div> -->
+        </div>
+        <!--表格-->
+        <el-table :data="tableData" border ref='multipleTable' :height="tableH" stripe
+            :header-cell-style="{ background: '#e5e8ed', color: '#666', textAlign: 'center' }" :cell-style="tableStyle"
+            style="cursor: default">
+            <el-table-column width="50" label="序号">
+                <template slot-scope="scope">
+                    {{ (sorts.page - 1) * sorts.limit + scope.$index + 1 }}
+                </template>
+            </el-table-column>
+            <el-table-column prop="postTitle" label="发文标题" :show-overflow-tooltip="true" />
+            <el-table-column prop="state" label="发布状态" :show-overflow-tooltip="true">
+                <template slot-scope="scope">
+                    <el-tag v-if="scope.row.state == 0">未发布</el-tag>
+                    <el-tag type="success" v-else-if="scope.row.state == 1">已发布</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column prop="addTime" label="创建时间" :show-overflow-tooltip="true" />
+            <el-table-column prop="releaseTime" label="发布时间" :show-overflow-tooltip="true" />
+            <!-- <el-table-column prop="vestingDate" label="决策公示开始时间" width="140" :show-overflow-tooltip="true">
+            </el-table-column>
+            <el-table-column prop="vestingDate" label="决策公示结束时间" width="140" :show-overflow-tooltip="true">
+            </el-table-column>
+            <el-table-column prop="vestingDate" label="意见征集开始时间" width="140" :show-overflow-tooltip="true">
+            </el-table-column>
+            <el-table-column prop="vestingDate" label="意见征集结束时间" width="140" :show-overflow-tooltip="true">
+            </el-table-column>
+            <el-table-column prop="opinionFeedbackEnd" label="意见反馈开始时间" width="140" :show-overflow-tooltip="true">
+            </el-table-column>
+            <el-table-column prop="uploadTime" sortable label="意见反馈结束时间" width="140"></el-table-column> -->
+            <el-table-column label="操作" prop="examineState,id" width="220" slot="default" fixed="right">
+                <template slot-scope="scope">
+                    <el-button class="but" type="primary" @click="openDialog(scope.row.id)">查看</el-button>
+                    <el-button class="but" type="primary" @click="releaseDecision(scope.row.id)">发布</el-button>
+                    <el-button class="but" type="primary" @click="openModifyWorkDialog(scope.row.id)">修改</el-button>
+                    <el-button class="but" type="danger" @click="handleDelete(scope.row.id, scope.$index)">删除
+                    </el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="block">
+            <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
+                :current-page="sorts.page" :page-sizes="[10, 20, 30, 40, 50]" :page-size="sorts.limit"
+                layout="prev, pager,next,jumper,total,sizes" :total="total">
+            </el-pagination>
+        </div>
+        <!-- 新增/编辑决策事项 -->
+        <el-dialog :visible.sync="workDialog" width="80%" class="detailDialog" :close-on-click-modal="false" top="40px">
+            <div slot="title">
+                <div class="addTitle">{{workTitle}}</div>
+            </div>
+            <div style="height:65vh;overflow: auto;padding-right: 20px">
+                <el-form :model="postManagement" label-width="140px">
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="发文标题" prop="postTitle">
+                                <el-input v-model="postManagement.postTitle" placeholder="请输入发文标题" clearable>
+                                </el-input>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="类型" prop="type">
+                                <el-select v-model="postManagement.type" placeholder="请选择类型" style="width: 100%">
+                                    <el-option v-for="(el, index) in typeSelectData" :key="index" :label="el.label"
+                                        :value="el.value"></el-option>
+                                </el-select>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="意见反馈结束时间" prop="opinionFeedbackEnd">
+                                <el-date-picker v-model="postManagement.opinionFeedbackEnd" type="datetime"
+                                    placeholder="请选择意见反馈结束时间" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%">
+                                </el-date-picker>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <div v-for="(item, index) in fileUploadList" style="display: flex;">
+                        <el-form-item :label="item.value"></el-form-item>
+                        <el-upload action="#" ref="upload" :auto-upload="false" accept="application/pdf"
+                            :file-list="item.fileList"
+                            :on-change="function(file, fileList) {return onChange(file,fileList, index)}"
+                            :on-remove="function(file, fileList) {return handleRemove(file,fileList, index)}">
+                            <el-button type="primary" slot="trigger" style="margin-left: 10px">上传文件</el-button>
+                        </el-upload>
+                    </div>
+                </el-form>
+            </div>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" size="mini" @click="saveWork">提交</el-button>
+                <el-button @click="goBackyynn" size="mini">返回</el-button>
+            </div>
+        </el-dialog>
+
+        <!--查看详细-->
+        <el-dialog :visible.sync="dialogTableVisible" :append-to-body="true" class="detailDialog" width="80%"
+            top="40px">
+            <div slot="title">
+                <div class="addTitle">查看决策事项详情</div>
+            </div>
+            <div style="height: 65vh;overflow: auto;padding-right: 20px">
+                <el-form :model="tableDetail" class="demo-form-inline" label-width="130px">
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="发文标题">
+                                <el-input disabled v-model="tableDetail.postTitle" />
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="部门名称">
+                                <el-input disabled v-model="tableDetail.deptName" />
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="类型">
+                                <el-select disabled v-model="tableDetail.type" style="width: 100%">
+                                    <el-option v-for="(el, index) in typeSelectData" :key="index" :label="el.label"
+                                        :value="el.value"></el-option>
+                                </el-select>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="发布时间">
+                                <el-date-picker v-model="tableDetail.releaseTime" type="datetime"
+                                    value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" disabled>
+                                </el-date-picker>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="意见反馈结束时间">
+                                <el-date-picker v-model="tableDetail.opinionFeedbackEnd" type="datetime"
+                                    value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" disabled>
+                                </el-date-picker>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="决策草案">
+                                <el-input disabled v-model="tableDetail.draftInterpretation" />
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="草案解读">
+                                <el-input disabled v-model="tableDetail.draftDecision" />
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="政策解读">
+                                <el-input disabled v-model="tableDetail.policyInterpretation" />
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="决策文件">
+                                <el-input disabled v-model="tableDetail.makePolicy" />
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="征集情况反馈">
+                                <el-input disabled v-model="tableDetail.pdfContent" />
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                </el-form>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+    import api from '../../api/index'
+
+    export default {
+        created() {
+            this.getData()
+        },
+        mounted() {},
+        data() {
+            return {
+                fileUploadList: [{
+                        value: '决策草案',
+                        fileList: []
+                    }, {
+                        value: '草案解读',
+                        fileList: []
+                    },
+                    {
+                        value: '政策解读',
+                        fileList: []
+                    },
+                    {
+                        value: '决策文件',
+                        fileList: []
+                    },
+                    {
+                        value: '征集情况反馈',
+                        fileList: []
+                    }
+                ],
+                tableStyle: {
+                    textAlign: 'center',
+                },
+                tableH: 'calc(100vh - 230px)',
+                label: "决策事项管理",
+                // 搜索参数
+                form: {
+                    name: '',
+                    region: '',
+                    type: []
+                },
+                // 列表数据
+                tableData: [],
+                // 总数
+                total: 0,
+                // 查看详细界面
+                dialogTableVisible: false,
+                //新增/编辑决策事项界面
+                workDialog: false,
+                //新增/编辑决策事项标题
+                workTitle: '新增决策事项',
+                // 新增/编辑表单
+                postManagement: {
+                    postTitle: '', //发文标题
+                    opinionFeedbackEnd: '', //意见反馈结束时间
+                    type: '', //类型
+                    file1: null,
+                    file2: null,
+                    file3: null,
+                    file4: null,
+                    file5: null
+                },
+                //类型选择框
+                typeSelectData: [{
+                        label: '决策公示',
+                        value: 0
+                    },
+                    {
+                        label: '意见征集',
+                        value: 1
+                    },
+                    {
+                        label: '意见反馈',
+                        value: 2
+                    },
+                    {
+                        label: '待公示',
+                        value: 3
+                    },
+                    {
+                        label: '决策完成',
+                        value: 4
+                    }
+                ],
+                // 详细内容
+                tableDetail: {},
+                // 分页
+                sorts: {
+                    page: 1,
+                    limit: 10,
+                },
+            }
+        },
+        methods: {
+            //上传文件
+            onChange(file, fileList, index) {
+                if (file.raw.type === 'application/pdf') {
+                    this.assignFile(index, file);
+                    // 覆盖上次上传的文件
+                    if (fileList.length > 0) {
+                        this.fileUploadList[index].fileList = [fileList[fileList.length - 1]];
+                    }
+                } else {
+                    if (this.fileUploadList[index].fileList.length == 0) {
+                        this.fileUploadList[index].fileList = [];
+                    } else {
+                        this.fileUploadList[index].fileList = [fileList[0]];
+                    }
+                    this.$message.error('只能上传PDF!');
+                }
+            },
+            //删除文件
+            handleRemove(file, fileList, index) {
+                switch (index) {
+                    case 0:
+                        this.postManagement.draftInterpretation = '';
+                        break;
+                    case 1:
+                        this.postManagement.draftDecision = '';
+                        break;
+                    case 2:
+                        this.postManagement.policyInterpretation = '';
+                        break;
+                    case 3:
+                        this.postManagement.makePolicy = '';
+                        break;
+                    case 4:
+                        this.postManagement.pdfContent = '';
+                        break;
+                }
+                this.assignFile(index, null);
+            },
+            //文件流赋值
+            assignFile(index, file) {
+                switch (index) {
+                    case 0:
+                        this.postManagement.file1 = file;
+                        break;
+                    case 1:
+                        this.postManagement.file2 = file;
+                        break;
+                    case 2:
+                        this.postManagement.file3 = file;
+                        break;
+                    case 3:
+                        this.postManagement.file4 = file;
+                        break;
+                    case 4:
+                        this.postManagement.file5 = file;
+                        break;
+                }
+            },
+            //返回
+            goBackyynn() {
+                this.workDialog = false;
+            },
+            //打开新增决策事项
+            openAddWork() {
+                this.postManagement = {
+                    postTitle: '',
+                    opinionFeedbackEnd: '',
+                    type: '',
+                    file1: null,
+                    file2: null,
+                    file3: null,
+                    file4: null,
+                    file5: null
+                };
+                this.fileUploadList.forEach(element => {
+                    element.fileList = [];
+                });
+                this.workTitle = '新增决策事项'
+                this.workDialog = true;
+            },
+            //打开修改决策事项
+            openModifyWorkDialog(id) {
+                this.workTitle = '编辑决策事项';
+                api.getPostById(id).then(r => {
+                    let data = r.data.data;
+                    this.postManagement = data;
+                    this.postManagement.file1 = null;
+                    this.postManagement.file2 = null;
+                    this.postManagement.file3 = null;
+                    this.postManagement.file4 = null;
+                    this.postManagement.file5 = null;
+                    this.fileUploadList[0].fileList = data.draftInterpretation ? [{
+                        name: data.draftInterpretation
+                    }] : [];
+                    this.fileUploadList[1].fileList = data.draftDecision ? [{
+                        name: data.draftDecision
+                    }] : [];
+                    this.fileUploadList[2].fileList = data.policyInterpretation ? [{
+                        name: data.policyInterpretation
+                    }] : [];
+                    this.fileUploadList[3].fileList = data.makePolicy ? [{
+                        name: data.makePolicy
+                    }] : [];
+                    this.fileUploadList[4].fileList = data.pdfContent ? [{
+                        name: data.pdfContent
+                    }] : [];
+                    this.workDialog = true;
+                })
+            },
+            //保存
+            saveWork() {
+                if (!this.postManagement.postTitle) {
+                    this.$message.error('请输入发文标题!');
+                    return;
+                }
+                if (!this.postManagement.type) {
+                    this.$message.error('请选择类型!');
+                    return;
+                }
+                if (!this.postManagement.opinionFeedbackEnd) {
+                    this.$message.error('请选择意见反馈结束时间!');
+                    return;
+                }
+                let fd = new FormData();
+                fd.append('file1', this.postManagement.file1 ? this.postManagement.file1.raw : null);
+                fd.append('file2', this.postManagement.file2 ? this.postManagement.file2.raw : null);
+                fd.append('file3', this.postManagement.file3 ? this.postManagement.file3.raw : null);
+                fd.append('file4', this.postManagement.file4 ? this.postManagement.file4.raw : null);
+                fd.append('file5', this.postManagement.file5 ? this.postManagement.file5.raw : null);
+                fd.append('postTitle', this.postManagement.postTitle);
+                fd.append('opinionFeedbackEnd', this.postManagement.opinionFeedbackEnd);
+                fd.append('type', this.postManagement.type);
+                if (this.workTitle == '编辑决策事项') {
+                    console.log(this.postManagement);
+                    fd.append('id', this.postManagement.id);
+                    fd.append('draftInterpretation', this.postManagement.file1 ? null : this.postManagement
+                        .draftInterpretation);
+                    fd.append('draftDecision', this.postManagement.file2 ? null : this.postManagement.draftDecision);
+                    fd.append('policyInterpretation', this.postManagement.file3 ? null : this.postManagement
+                        .policyInterpretation);
+                    fd.append('makePolicy', this.postManagement.file4 ? null : this.postManagement.makePolicy);
+                    fd.append('pdfContent', this.postManagement.file5 ? null : this.postManagement.pdfContent);
+                    api.updatePostById(fd).then(r => {
+                        if (r.data.result) {
+                            this.$message.success('修改成功');
+                            this.getData();
+                            this.workDialog = false;
+                        } else {
+                            this.$message.error("修改失败");
+                        }
+                    }).catch(() => {
+                        this.$message.error("修改失败");
+                    })
+                } else {
+                    api.savePost(fd).then(r => {
+                        if (r.data.result) {
+                            this.$message.success('新增成功');
+                            this.getData();
+                            this.workDialog = false;
+                        } else {
+                            this.$message.error("新增失败");
+                        }
+                    }).catch(() => {
+                        this.$message.error("新增失败");
+                    })
+                }
+            },
+            //选取条件
+            selectRegion() {
+                // console.log(this.form.region)
+            },
+            //根据条件查询
+            serachWork() {
+                // if (this.form.region !== '') {
+                //     if (this.form.region === 'uploaderPhone') {
+                //         // let params = {
+                //         //     page: 1,
+                //         //     limit: 10,
+                //         //     uploaderPhone: this.form.name
+                //         // }
+                //         this.sorts.uploaderPhone = this.form.name;
+                //         this.sorts.pictureTitle = '';
+                //         this.sorts.pictureAuthor = '';
+                //         this.sorts.page = 1;
+                //         let params = this.sorts;
+                //         api.queryWork({
+                //             params
+                //         }).then(res => {
+                //             this.total = res.data.count
+                //             this.tableData = res.data.data
+                //         })
+                //     }
+                //     if (this.form.region === 'pictureTitle') {
+                //         // let params = {
+                //         //     page: 1,
+                //         //     limit: 10,
+                //         //     pictureTitle: this.form.name
+                //         // }
+                //         this.sorts.pictureTitle = this.form.name;
+                //         this.sorts.uploaderPhone = '';
+                //         this.sorts.pictureAuthor = '';
+                //         this.sorts.page = 1;
+                //         let params = this.sorts;
+                //         api.queryWork({
+                //             params
+                //         }).then(res => {
+                //             this.total = res.data.count
+                //             this.tableData = res.data.data
+                //             // console.log(this.tableData);
+                //         })
+                //     }
+                //     if (this.form.region === 'pictureAuthor') {
+                //         // let params = {
+                //         //     page: 1,
+                //         //     limit: 10,
+                //         //     pictureAuthor: this.form.name
+                //         // }
+                //         this.sorts.pictureTitle = '';
+                //         this.sorts.uploaderPhone = '';
+                //         this.sorts.pictureAuthor = this.form.name;
+                //         this.sorts.page = 1;
+                //         let params = this.sorts;
+                //         api.queryWork({
+                //             params
+                //         }).then(res => {
+                //             this.total = res.data.count
+                //             this.tableData = res.data.data
+                //             // console.log(this.tableData);
+                //         })
+                //     }
+                // } else {
+                //     this.$refs.multipleTable.clearSort();
+                //     this.column = undefined
+                //     this.sorts.page = 1
+                //     this.sorts = {
+                //         page: 1,
+                //         limit: 10,
+                //         isAlbum: '',
+                //         examineState: '',
+                //         pictureType: '',
+                //         uploadTime: '',
+                //         updateTime: '',
+                //         uploaderPhone: '',
+                //         pictureTitle: '',
+                //         pictureAuthor: '',
+                //     }
+                //     let params = this.sorts
+                //     // this.getData()
+                //     api.queryWork({
+                //         params
+                //     }).then(res => {
+                //         this.total = res.data.count
+                //         this.tableData = res.data.data
+                //         // console.log(this.tableData);
+                //     })
+                // }
+
+            },
+            //发布事项
+            releaseDecision(id) {
+                let params = {
+                    id: id
+                }
+                this.$confirm('是否发布该事项?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    api.updateState({
+                        params
+                    }).then(res => {
+                        if (res.data.result) {
+                            this.getData();
+                            this.$message({
+                                type: 'success',
+                                message: '发布成功!'
+                            });
+                        } else {
+                            this.$message({
+                                type: 'info',
+                                message: '发布失败!'
+                            });
+                        }
+                    })
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消发布'
+                    });
+                });
+            },
+            //切换列表条数
+            handleSizeChange(pageSize) {
+                this.sorts.limit = pageSize
+                this.sorts.page = 1;
+                this.getData();
+            },
+            //切换页码
+            handleCurrentChange(currentPage) {
+                this.$refs.multipleTable.bodyWrapper.scrollTop = 0;
+                this.sorts.page = currentPage;
+                this.getData();
+            },
+            //删除
+            handleDelete(id, index) {
+                this.$confirm("您确定要删除该数据吗?", "提示", {
+                    cancelButtonClass: "btn-custom-cancel",
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning"
+                }).then(() => {
+                    api.deletePostById(id).then(res => {
+                        if (res.data.result) {
+                            this.$message({
+                                type: 'success',
+                                message: '删除成功!'
+                            });
+                            this.tableData.splice(index, 1);
+                            this.getData();
+                        } else {
+                            this.$message({
+                                type: 'info',
+                                message: '删除失败!'
+                            });
+                        }
+                    })
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                })
+            },
+            //查看
+            openDialog(id) {
+                this.dialogTableVisible = true;
+                api.getPostById(id).then(r => {
+                    this.tableDetail = r.data.data;
+                })
+            },
+            // 获取列表数据
+            getData() {
+                if (this.form.region !== '') {
+                    if (this.form.region === 'uploaderPhone') {
+                        let params = {
+                            page: this.sorts.page,
+                            limit: this.sorts.limit,
+                            uploaderPhone: this.form.name
+                        }
+                        api.selectPostList({
+                            params
+                        }).then(r => {
+                            this.total = r.data.count
+                            this.tableData = r.data.data
+                        })
+                    }
+                    if (this.form.region === 'pictureTitle') {
+                        let params = {
+                            page: this.sorts.page,
+                            limit: this.sorts.limit,
+                            pictureTitle: this.form.name
+                        }
+                        api.selectPostList({
+                            params
+                        }).then(r => {
+                            this.total = r.data.count
+                            this.tableData = r.data.data
+                        })
+                    }
+                    if (this.form.region === 'pictureAuthor') {
+                        let params = {
+                            page: this.sorts.page,
+                            limit: this.sorts.limit,
+                            pictureAuthor: this.form.name
+                        }
+                        api.selectPostList({
+                            params
+                        }).then(r => {
+                            this.total = r.data.count
+                            this.tableData = r.data.data
+                        })
+                    }
+                } else {
+                    let params = {
+                        page: this.sorts.page,
+                        limit: this.sorts.limit,
+                    }
+                    api.selectPostList({
+                        params
+                    }).then(r => {
+                        this.total = r.data.count
+                        this.tableData = r.data.data
+                    })
+                }
+            },
+            // 清空输入框
+            clearreset() {
+                this.form.name = ''
+            },
+            // 清空输入框
+            reset() {
+                this.form.region = ''
+                this.form.name = ''
+                this.getData()
+            }
+        },
+    }
+</script>
+
+<style scoped lang="less">
+    /* 禁用后的勾选*/
+    /deep/ .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after {
+        border-color: #def5cb;
+    }
+
+    /deep/ .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
+        background-color: #157de9;
+        border-color: #DCDFE6;
+    }
+
+    /deep/ [data-v-2cde7735] .el-upload-list--picture .el-upload-list__item-name {
+        display: block;
+        margin-top: 0px;
+        margin-left: -78px;
+    }
+
+    /deep/ .el-upload-list--picture .el-upload-list__item {
+        display: flex;
+        flex-direction: column-reverse;
+        width: 100%;
+        height: 100%;
+    }
+
+    /deep/ .el-upload-list--picture .el-upload-list__item-name i {
+        display: none;
+    }
+
+    /deep/ .el-upload-list--picture .el-upload-list__item-name {
+        display: block;
+        margin-top: 0px;
+    }
+
+    /deep/ .el-upload-list--picture .el-upload-list__item-thumbnail {
+        width: 100%;
+        height: 100%;
+    }
+
+    /deep/ .el-dialog__body {
+        padding: 0 0 30px 20px;
+        color: #606266;
+        font-size: 14px;
+        word-break: break-all;
+    }
+
+    /deep/ .el-form-item__label {
+        padding: 0;
+    }
+
+    .yxnaContent {
+        padding: 10px;
+    }
+
+    .addTitle {
+        font-size: 18px;
+        font-weight: bold;
+        margin-bottom: 10px;
+    }
+
+    /deep/ .btn-custom-cancel {
+        float: right !important;
+        margin-left: 10px !important;
+    }
+
+    .add {
+        width: 66px;
+        height: 38px;
+        margin-left: 0;
+    }
+
+    /deep/ .el-message-box__btns .el-button:nth-child(2) {
+        margin-right: 10px;
+        float: right;
+    }
+
+    /deep/ .el-col-12 {
+        width: 50%;
+        text-align: left;
+    }
+
+    .search {
+        width: 66px;
+        height: 38px;
+        margin-left: 0;
+    }
+
+    /deep/ .el-form-item__label {
+        height: 40px;
+        width: 110px;
+        background-color: #FAFAFA;
+        text-align: center;
+        border: 1px solid #DCDFE6;
+        border-radius: 2px 0 0 2px;
+    }
+
+    /deep/ .el-button.is-disabled {
+        color: #C0C4CC !important;
+    }
+
+    /deep/.el-button--primary.is-disabled {
+        color: #FFF !important;
+    }
+
+    /deep/ .el-input__inner {
+        border-radius: 2px 0 0 2px;
+    }
+
+    .el-select>.el-input {
+        width: 200px;
+    }
+
+    /deep/ .el-textarea__inner {
+        height: 100px;
+    }
+
+
+    /deep/ .el-dialog__title {
+        font-size: 14px;
+    }
+
+    /deep/ .el-pagination__total {
+        margin-left: 10px !important;
+    }
+
+    .el-pagination {
+        margin: 0;
+        margin-top: 10px;
+        /* position: fixed;
+        left: 13rem; */
+    }
+
+    /deep/ .el-table--scrollable-x .el-table__body-wrapper {
+        z-index: 2;
+    }
+
+    .imgBox {
+        width: 100%;
+        /*height: 55vh;*/
+        height: 100%;
+    }
+
+    .but {
+        width: 36px;
+        height: 22px;
+        padding: 0;
+        font-size: 12px;
+    }
+
+    .el-checkbox {
+        margin: 0;
+        margin-right: 10px;
+    }
+
+    /deep/ .bewrite>.el-form-item__label {
+        width: 100%;
+        text-align: left;
+        padding-left: 21px;
+    }
+
+    /deep/ .el-form--inline .el-form-item {
+        margin-right: 0px;
+    }
+
+    /deep/ [data-v-2cde7735] .el-form-item__label {
+        border: 1px solid #DCDFE6;
+        /*border-right: transparent;*/
+    }
+
+    /*    空白框*/
+    /deep/ .formTempBox {
+        height: 38px;
+        border: 1px solid #DCDFE6;
+        width: 100%;
+        border-left: transparent;
+        background-color: #FAFAFA;
+    }
+</style>

+ 4 - 9
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/History.vue → nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/history/History.vue

@@ -1,6 +1,5 @@
 <template>
     <div class="historyContent">
-        <TopTitle :label="label"/>
         <div style="margin-bottom: 10px">
             <el-button type="primary" class="add" @click="addData()">导入</el-button>
         </div>
@@ -34,9 +33,8 @@
 </template>
 
 <script>
-    import TopTitle from '../components/TopTitle'
-    // import request from '../utils/request'
-    import api from '../api/index'
+    // import request from '../../utils/request'
+    import api from '../../api/index'
     // import {
     // 	getHistory
     // } from '../api/ImpressionNanan'
@@ -64,9 +62,6 @@
                 total: 0
             }
         },
-        components: {
-            TopTitle
-        },
         created() {
             this.getData()
         },
@@ -74,7 +69,7 @@
             toDetail(row) {
                 localStorage.removeItem("value")
                 localStorage.setItem("value", JSON.stringify(row))
-                this.$router.push('/historyDetail')
+                this.$router.push('/history/historyDetail')
             },
             //显示每条数据
             handleSizeChange(pageSize) {
@@ -99,7 +94,7 @@
                 })
             },
             addData() {
-                this.$router.push('/informationEntry')
+                this.$router.push('/history/informationEntry')
             },
         }
     }

+ 2 - 8
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/HistoryDetail.vue → nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/history/HistoryDetail.vue

@@ -1,6 +1,5 @@
 <template>
     <div>
-        <TopTitle :label="label"/>
         <el-button type="primary" style="margin-left: -93.8%;margin-top: 23px; width: 66px; height: 38px;" @click="importFile">导入
         </el-button>
         <div class="detailData">
@@ -36,8 +35,6 @@
 </template>
 
 <script>
-    import TopTitle from '../components/TopTitle'
-
     export default {
         data() {
             return {
@@ -45,19 +42,16 @@
                 detail: []
             }
         },
-        components: {
-            TopTitle
-        },
         created() {
             this.detail = JSON.parse(localStorage.getItem("value"))
             console.log(this.detail)
         },
         methods: {
             goBack() {
-                this.$router.push('/history')
+                this.$router.push('/history/index')
             },
             importFile(){
-                this.$router.push('/informationEntry')
+                this.$router.push('/history/informationEntry')
             },
         }
     }

+ 4 - 9
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/InformationEntry.vue → nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/history/InformationEntry.vue

@@ -1,6 +1,5 @@
 <template>
     <div class="infoentry">
-        <TopTitle :label="label"/>
         <div style="height: calc(100vh - 170px);overflow: auto">
             <el-form ref="ruleForm" status-icon :rules="rules" :model="ruleForm" label-width="80px" >
                 <el-form-item label="所属部门" prop="deptId">
@@ -63,11 +62,10 @@
 </template>
 
 <script>
-    import TopTitle from '../components/TopTitle'
     import {
         getDeptList
-    } from '../api/index'
-    import api from '../api/index'
+    } from '../../api/index'
+    import api from '../../api/index'
 
     export default {
         data() {
@@ -108,9 +106,6 @@
                 },
             }
         },
-        components: {
-            TopTitle
-        },
         created() {
             getDeptList().then(res => {
                 this.deptList = res.data.data;
@@ -141,7 +136,7 @@
                 fd.append('deptId', this.ruleForm.deptId);//传其他参数
                 api.addInfo(fd).then(() => {
                     this.$message.success('录入成功')
-                    this.$router.push('/History')
+                    this.$router.push('/history/index')
                     this.fileList=[]
                 }).catch(() => {
                     this.$message.error('录入失败')
@@ -167,7 +162,7 @@
                 console.log(file);
             },
             goBack() {
-                this.$router.push('/history')
+                this.$router.push('/history/index')
             },
             submitForm(ruleForm) {
                 this.$refs[ruleForm].validate((valid) => {

+ 15 - 19
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/administration.vue → nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/impressionNanan/Administration.vue

@@ -1,7 +1,5 @@
 <template>
     <div class="yxnaAlbum">
-        <!--        标题-->
-        <TopTitle :label="label" />
         <div v-show="actives">
             <el-button type="primary" class="add" style="margin-bottom:10px ;" @click="albumNewlyIncreased()">新增
             </el-button>
@@ -236,7 +234,7 @@
                         <div class="formTempBox"></div>
                     </div>
                     <div class="imgBox" style="margin-top: 20px">
-                        <img :src="`/` + tableDetail.urlAddress" alt="" style="max-width: 100%;">
+                        <img :src="`/` + tableDetail.urlAddress" alt="" style="width: 100%;">
                     </div>
                 </el-form>
             </div>
@@ -417,14 +415,10 @@
 </template>
 
 <script>
-import TopTitle from '../components/TopTitle'
-import request from '../utils/request'
-import api from '../api/index'
+import request from '../../utils/request'
+import api from '../../api/index'
 export default {
     name: "administration",
-    components: {
-        TopTitle
-    },
     created() {
         // this.getData();
         this.getalbum();
@@ -1283,8 +1277,9 @@ export default {
             this.impressionNanan = obj
             this.modifyWorkDialog = true
         },
+        //新增专辑
 
-        //修改背景图
+        //背景图
         albumbackground(value) {
             this.albumid = value.id
             this.upBackground = true;
@@ -1292,6 +1287,7 @@ export default {
             this.fileList=[];
         },
         beforeUpload(file) {
+          
             let fd = new FormData();
             fd.append('file', file);
             fd.append('id', this.albumid);//传文件
@@ -1299,15 +1295,15 @@ export default {
             api.albumRedact(fd).then((r) => {
                 if (r.data.result) {
                     let params = {
-                        page: this.currentPage,
-                        limit: this.pageSize,
+                        page: 1,
+                        limit: 10
                     }
                     api.queryAlbum({ params }).then(res => {
                         this.total = res.data.count;
                         this.albumTableData = res.data.data;
                     })
-                    this.$message.success('修改成功');
-                    this.upBackground = false;  
+                    this.$message.success('修改成功')
+                    // this.addWorkDialog = false;
                 } else {
                     this.$message.error("修改失败")
                 }
@@ -1345,7 +1341,9 @@ export default {
             }
             if (this.fileList.length > 0  ) {
                 this.$refs.upload.submit();
-                // this.upBackground = false;
+                setTimeout(()=>{
+                    this.upBackground = false;
+                },800)
             }
             //  else {
             //     let fd = new FormData();
@@ -1385,6 +1383,7 @@ export default {
         },
 
         addBeforeUpload(file) {
+
             let fd = new FormData();
             fd.append('file', file);
             fd.append('name', this.addWorkDialogs.ablumNames);
@@ -1413,14 +1412,11 @@ export default {
                 this.$message.error('专辑名称不能为空');
                 return;
             }
+            // console.log(this.fileList)
             if (this.fileList.length == 0) {
                 this.$message.error("文件不能为空");
                 return;
             }
-            if(this.fileList[0].size>5242880){
-                this.$message.error('文件过大');
-                return;
-            }
             this.$refs.upload.submit();
         },
         //删除

+ 2 - 8
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/ImpressionNanan.vue → nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/impressionNanan/ImpressionNanan.vue

@@ -1,7 +1,5 @@
 <template>
     <div class="yxnaContent">
-        <!--        标题-->
-        <TopTitle :label="label" />
         <!--        操作栏-->
         <div style="display: flex;justify-content: space-between;margin-bottom: 10px">
             <el-button type="primary" class="add" @click="openAddWork('addWorkForm')">新增</el-button>
@@ -575,9 +573,8 @@
 </template>
 
 <script>
-import TopTitle from '../components/TopTitle'
-import request from '../utils/request'
-import api from '../api/index'
+import request from '../../utils/request'
+import api from '../../api/index'
 
 const requiredValidator = (rule, value, callback) => {
     if (typeof value === 'string' && value.trim() !== '') {
@@ -592,9 +589,6 @@ const requiredValidator = (rule, value, callback) => {
 }
 
 export default {
-    components: {
-        TopTitle
-    },
     created() {
         this.getData()
     },

+ 2 - 6
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/MapDetails.vue → nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/mapEdit/MapDetails.vue

@@ -1,9 +1,8 @@
 <template>
 	<div class="yxnaContent">
-		<!-- 标题 -->
-		<TopTitle :label="title" style="padding-left: 10px;padding-top: 10px;" />
+		<div style="padding-top: 10px;" />
 		<div style="background-color: #ffffff;">
-			<div style="padding-bottom: 10px;position: relative;height: 40px;">
+			<div style="position: relative;height: 50px;">
 				<el-button style="position: absolute;right: 1%" @click="back" type="primary">返回</el-button>
 			</div>
 			<div style="padding: 0px 1% 0px 1%; display: flex;position: relative;">
@@ -92,10 +91,7 @@
 </template>
 
 <script>
-import TopTitle from '../components/TopTitle'
-
 export default {
-	components: { TopTitle },
 	created() {
 	// 传来的参数
 	var json = localStorage.getItem('mapTempData')

+ 3 - 7
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/MapEdit.vue → nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/mapEdit/MapEdit.vue

@@ -1,7 +1,5 @@
 <template>
     <div class="yxnaContent">
-        <!-- 标题 -->
-        <TopTitle :label="label" />
         <!-- 操作栏 -->
         <!-- <div style="display: flex;justify-content: space-between;margin-bottom: 10px">
             <div style="display: flex">
@@ -50,12 +48,10 @@
 </template>
 
 <script>
-import TopTitle from '../components/TopTitle'
-import api from '../api/index'
-import { mapState } from '../constants/mapState'
+import api from '../../api/index'
+import { mapState } from '../../constants/mapState'
 
 export default {
-    components: { TopTitle },
     created() {
         this.getData()
     },
@@ -125,7 +121,7 @@ export default {
 		// 查看详情
 		openDialog(row) {
 			localStorage.setItem('mapTempData', JSON.stringify(row))
-			this.$router.push({ name: 'Details' })
+            this.$router.push('/mapEdit/mapDetails')
 		},
 		// 获取地图状态名称
 		getState(code) {

+ 0 - 5
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/new/HuaLongData.vue

@@ -1,6 +1,5 @@
 <template>
     <div class="hualong-content">
-        <TopTitle :label="label"/>
         <!--        搜索栏-->
         <div class="query-tabbar">
             <div class="query-input">
@@ -62,14 +61,10 @@
 </template>
 
 <script>
-    import TopTitle from '../../components/TopTitle'
     import api from '../../api/index'
 
     export default {
         name: "HuaLongData",
-        components: {
-            TopTitle
-        },
         data() {
             return {
                 label: "华龙网数据",

+ 12 - 0
nngkxxdp/src/main/resources/static/naqwzsjtj/naqwzsjtj/src/views/redirect/index.vue

@@ -0,0 +1,12 @@
+<script>
+export default {
+  created() {
+    const { params, query } = this.$route
+    const { path } = params
+    this.$router.replace({ path: '/' + path, query })
+  },
+  render: function(h) {
+    return h() // avoid warning message
+  }
+}
+</script>

部分文件因为文件数量过多而无法显示