浏览代码

Merge branch 'dev' into 'main'

Dev

See merge request hsayi/hsayi_docsecurity/hsayi_docsecurity_web_pc!1
张甫 3 年之前
父节点
当前提交
7fdcf63607
共有 40 个文件被更改,包括 3446 次插入3690 次删除
  1. 240 2936
      package-lock.json
  2. 0 1
      package.json
  3. 1 1
      public/index.html
  4. 4 3
      public/js/config.js
  5. 二进制
      public/title.ico
  6. 0 10
      src/App.vue
  7. 58 0
      src/api/api/index.js
  8. 138 14
      src/assets/styles/element.less
  9. 0 1
      src/components/FileUpload.vue
  10. 0 78
      src/components/elTable/index.vue
  11. 11 11
      src/layout/components/AppMain.vue
  12. 18 11
      src/layout/components/Navbar.vue
  13. 12 5
      src/layout/components/Sidebar/menuList.vue
  14. 15 3
      src/layout/components/index.less
  15. 31 2
      src/layout/index.vue
  16. 2 1
      src/main.js
  17. 188 21
      src/pages/classification/edit.vue
  18. 257 180
      src/pages/classification/index.vue
  19. 77 8
      src/pages/fileManagement/detail.vue
  20. 264 43
      src/pages/fileManagement/edit.vue
  21. 313 135
      src/pages/fileManagement/index.vue
  22. 8 9
      src/pages/login/index.less
  23. 24 37
      src/pages/login/index.vue
  24. 170 0
      src/pages/userManagement/components/edit.vue
  25. 88 18
      src/pages/userManagement/detail.vue
  26. 158 22
      src/pages/userManagement/edit.vue
  27. 251 97
      src/pages/userManagement/index.vue
  28. 2 9
      src/router/index.js
  29. 3 3
      src/router/routes.js
  30. 5 19
      src/store/permission.js
  31. 4 4
      src/utils/pubFun.js
  32. 539 0
      static/font_hsy/demo.css
  33. 418 0
      static/font_hsy/demo_index.html
  34. 55 0
      static/font_hsy/iconfont.css
  35. 1 0
      static/font_hsy/iconfont.js
  36. 79 0
      static/font_hsy/iconfont.json
  37. 二进制
      static/font_hsy/iconfont.ttf
  38. 二进制
      static/font_hsy/iconfont.woff
  39. 二进制
      static/font_hsy/iconfont.woff2
  40. 12 8
      vue.config.js

文件差异内容过多而无法显示
+ 240 - 2936
package-lock.json


+ 0 - 1
package.json

@@ -32,7 +32,6 @@
     "babel-eslint": "^10.1.0",
     "eslint": "^6.7.2",
     "eslint-plugin-vue": "^6.2.2",
-    "image-webpack-loader": "^7.0.1",
     "prettier": "^2.3.2",
     "svg-loader": "0.0.2",
     "svg-sprite-loader": "^6.0.9",

+ 1 - 1
public/index.html

@@ -14,7 +14,7 @@
     />
     <meta http-equiv="expires" content="0" />
  
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <link rel="icon" href="<%= BASE_URL %>title.ico">
     <!-- <title><%= htmlWebpackPlugin.options.title %></title> --> 
     <title>沪上阿姨</title>
   </head>

+ 4 - 3
public/js/config.js

@@ -7,12 +7,13 @@ window.global_config = {
   // BASE_URL: 'http://172.16.0.22:10143'
   // BASE_URL: 'http://221.224.53.27:10144',
   //  BASE_URL:'http://172.16.0.14:10143',
-  // BASE_URL: 'http://172.16.0.36:10143' //吴国建
+  // BASE_URL: 'http://172.16.0.135:8083' //沪上阿姨
+  BASE_URL: 'http://221.224.53.27:20018'
   //  BASE_URL:'http://172.16.0.107:10143',
   // BASE_URL: 'http://172.16.0.36:10143' //吴国建
   // BASE_URL:'http://172.16.0.114:10143' //胡志豪
   // BASE_URL: 'http://172.16.100.40:10143'
-  BASE_URL:'http://221.224.53.27:20008'
+  // BASE_URL:'http://221.224.53.27:20008'
   // BASE_URL: 'http://172.16.0.245:10143'
   // BASE_URL: 'http://101.200.220.128:8081'
-}
+}

二进制
public/title.ico


+ 0 - 10
src/App.vue

@@ -17,16 +17,6 @@ export default {
       include: []
     }
   },
-  computed: {
-    // 是否显示顶部栏、菜单栏
-    showComponents() {
-      if (this.$route.path != '/' && this.$route.name != 'full-link') {
-        return true
-      } else {
-        return false
-      }
-    }
-  },
   watch: {
     $route(to, from) {
       if (to.meta.keepAlive) {

+ 58 - 0
src/api/api/index.js

@@ -0,0 +1,58 @@
+import request from '@/utils/request'
+
+export function REQUEST(url, method, data, headers) {
+    return request({
+        url: url,
+        method: method,
+        data: data || {},
+        headers: headers || {}
+    })
+}
+
+
+
+/*
+推荐用法:cw.GET("company-service/company/list").then()
+*/
+export function GET(url, data, headers) {
+    return request.get(url, {
+        params: data,
+        headers: headers || {}
+    })
+}
+
+// 同上
+export function POST(url, data, headers) {
+    return REQUEST(url, 'POST', data, headers)
+}
+
+// 同上
+export function PUT(url, data, headers) {
+    return REQUEST(url, 'PUT', data, headers)
+}
+
+// 同上
+export function DELETE(url, data, headers) {
+    return REQUEST(url, 'DELETE', data, headers)
+}
+
+// 同上
+export function PATCH(url, data, headers) {
+    return REQUEST(url, 'PATCH', data, headers)
+}
+/*
+文件导入接口 cw.IMPORT(url, file)
+*/
+export function IMPORT(url, files) {
+    const formData = new FormData()
+    formData.append('file', files.file)
+  
+    return request({
+      url: url,
+      method: 'POST',
+      data: formData,
+      headers: {
+        'Content-Type': 'multipart/form-data'
+      }
+    })
+  }

+ 138 - 14
src/assets/styles/element.less

@@ -4,27 +4,29 @@
   font-weight: 400;
   color: #666666;
 }
-.el-button--primary{
-  background:#F23F3A;
-  border-color:#F23F3A;
-  color:#FFFFFF;
+
+.el-button--primary {
+  background: #F23F3A;
+  border-color: #F23F3A;
+  color: #FFFFFF;
 }
+
 .el-button--default {
-  background: rgba(242, 63, 58, 0.1);
   color: #F23F3A;
   border-color: #F23F3A;
-  
+
 }
 
 .el-pagination {
   text-align: right;
-  padding: 20px;
+  padding: 20px 20px 10px 20px;
 }
 
 .el-pagination.is-background .el-pager li:not(.disabled).active {
   background-color: #F23F3A;
   border: 1px solid #F23F3A;
-  border-radius: 4px;;
+  border-radius: 4px;
+  ;
   color: #fff;
 }
 
@@ -58,13 +60,16 @@
     position: relative;
   }
 }
-.el-dialog__footer{
+
+.el-dialog__footer {
   text-align: center;
   padding: 60px 20px;
-  .el-button{
+
+  .el-button {
     width: 120px;
   }
 }
+
 .el-dialog__headerbtn {
   width: 28px;
   height: 28px;
@@ -121,9 +126,11 @@
 .rowover.hover-row {
   background: #fd5f5140 !important;
 }
-.el-table thead{
+
+.el-table thead {
   color: #040000;
 }
+
 .el-table thead.is-group th {
   background: #ffffff;
 }
@@ -138,7 +145,7 @@
   border-right: 1px solid #ebeef5;
 }
 
-.el-tree-node.is-current > .el-tree-node__content {
+.el-tree-node.is-current>.el-tree-node__content {
   background-color: #f7e0e3 !important;
 }
 
@@ -165,6 +172,7 @@ input[maxlength='32']:not([disabled]) {
 //   padding-right: 40px;
 // }
 #app #main .serchArea {
+
   .el-date-editor--daterange.el-input,
   .el-date-editor--daterange.el-input__inner,
   .el-date-editor--timerange.el-input,
@@ -177,7 +185,7 @@ input[maxlength='32']:not([disabled]) {
   padding: 0 !important;
 }
 
-.el-cascader__tags .el-tag > span {
+.el-cascader__tags .el-tag>span {
   flex: auto;
 }
 
@@ -239,6 +247,7 @@ input[maxlength='32']:not([disabled]) {
 
 // 多选限制宽度
 .el-tag__close_icon {
+
   //根据自己的需要调整文字宽度
   .el-select__tags-text {
     display: inline-block;
@@ -247,10 +256,12 @@ input[maxlength='32']:not([disabled]) {
     text-overflow: ellipsis;
     white-space: nowrap;
   }
+
   .el-tag__close.el-icon-close {
     top: 0px;
   }
 }
+
 .el-table__row:last-child td:last-child {
   top: 0;
 }
@@ -265,14 +276,127 @@ input[maxlength='32']:not([disabled]) {
     max-width: 400px;
   }
 }
+
 .el-select-dropdown__wrap {
   max-height: 350px;
 }
+
 .screen {
   max-width: 340px !important;
   min-width: none;
 }
-.el_form_item_content{
+
+.el_form_item_content {
   width: 230px !important;
   min-width: none;
 }
+
+.header_top_form {
+  .el-form-item__label {
+    color: #333;
+    font-weight: bold;
+  }
+}
+
+.el-menu-item,
+.el-menu-item [class^=el-icon-] {
+  font-size: 20px;
+  color: #A5A5A5 !important;
+  font-weight: 400;
+}
+
+.el-menu-item {
+  padding-left: 42px !important;
+}
+
+.el-menu-item.is-active {
+  padding-left: 0 !important;
+}
+
+.el-menu-item.is-active,
+.el-menu-item.is-active [class^=el-icon-] {
+  color: #F4453E !important;
+}
+
+.el-menu-item.is-active .icon_left {
+  border-right: 4px solid #F4453E;
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 4px;
+  margin-right: 38px;
+}
+
+.el-radio__input.is-checked .el-radio__inner {
+  background: #F4453E;
+  border-color: #F4453E;
+}
+
+.el-radio__inner:hover,
+.el-select .el-input.is-focus .el-input__inner,
+.el-input__inner:focus {
+  border-color: #F4453E;
+}
+
+.el-radio__input.is-checked+.el-radio__label {
+  color: #F4453E;
+}
+
+.el-loading-spinner .path {
+  stroke: #F4453E;
+}
+
+.el-upload-list__item.is-success .el-upload-list__item-name:focus,
+.el-upload-list__item.is-success .el-upload-list__item-name:hover {
+  color: #F4453E;
+
+  i {
+    color: #F4453E;
+    cursor: pointer;
+    transition: all .5s cubic-bezier(.55, 0, .1, 1)
+  }
+}
+
+.el-dropdown-menu__item:focus,
+.el-dropdown-menu__item:not(.is-disabled):hover,
+.el-select-dropdown__item.selected,
+.el-dialog__headerbtn .el-dialog__close:hover {
+  color: #F4453E;
+}
+
+.el-upload-list__item {
+  .el-upload-list__item-name {
+    .el-icon-document {
+      font-family: "iconfont" !important;
+      font-size: 16px;
+      font-style: normal;
+      -webkit-font-smoothing: antialiased;
+      -moz-osx-font-smoothing: grayscale;
+    }
+
+    .el-icon-document:before {
+      content: '\e616'
+    }
+  }
+}
+
+.el-breadcrumb__inner {
+  color: #A5A5A5;
+}
+
+.el-select .el-input__inner:focus {
+  border-color: #F4453E;
+}
+
+.el-progress-bar__inner {
+  background-color: #F4453E;
+}
+
+.el-pagination.is-background .el-pager li:not(.active):hover {
+  color: #F4453E;
+}
+
+// maxlength 
+.maxlength-input {
+  .el-input__inner {
+    padding-right: 48px;
+  }
+}

+ 0 - 1
src/components/FileUpload.vue

@@ -75,7 +75,6 @@ export default {
     }
   },
   created() {
-    console.log(this.typeList)
   },
   methods: {
     handleAvatarSuccess(res) {

+ 0 - 78
src/components/elTable/index.vue

@@ -1,78 +0,0 @@
-<template>
-  <div>
-    <el-table :data="tableData" style="width: 100%">
-      <el-table-column
-        v-for="(item, index) in listData"
-        :key="index"
-        :width="item.width"
-        :min-width="item.minWidth"
-        :align="item.align"
-      >
-        <template slot="header">
-          <div>
-            {{ item.name }}
-          </div>
-        </template>
-        <template slot-scope="scope">
-          <div>
-            <div>{{ scope.row[item.value] }}</div>
-          </div>
-        </template>
-      </el-table-column>
-    </el-table>
-    <el-pagination
-      @size-change="handleSizeChange"
-      @current-change="handleCurrentChange"
-      :current-page="form.currentPage4"
-      :page-sizes="[100, 200, 300, 400]"
-      :page-size="10"
-      background
-      layout="total,prev, pager, next,jumper"
-      :total="100"
-    >
-    </el-pagination>
-  </div>
-</template>
-<script>
-export default {
-  data() {
-    return {
-      form: {
-        currentPage4: 1
-      },
-      tableData: [],
-      listData: []
-    }
-  },
-  props: {
-    formList: {
-      type: Object,
-      default: () => {}
-    },
-    listdata: {
-      type: Array,
-      default: () => []
-    },
-    tabledata: {
-      type: Array,
-      default: () => []
-    }
-  },
-  watch: {
-    listdata(val) {
-      console.log(val)
-      this.listData = val
-    },
-    tabledata(val) {
-      this.tableData = val
-    },
-    formList(val) {
-      this.form = val
-    }
-  },
-  methods: {
-    handleSizeChange() {},
-    handleCurrentChange() {}
-  }
-}
-</script>

+ 11 - 11
src/layout/components/AppMain.vue

@@ -1,11 +1,9 @@
 <template>
-  <section class="app-main">
-    <transition name="fade-transform" mode="out-in">
+  <div class="app-main" :id="isApp_main ? 'app-main-id' : ''">
       <keep-alive :include="include">
-        <router-view :id="isApp_main?'appMain-box':''" />
+        <router-view :id="isApp_main ? 'appMain-box' : ''" />
       </keep-alive>
-    </transition>
-  </section>
+  </div>
 </template>
 
 <script>
@@ -57,23 +55,25 @@ export default {
 </script>
 
 <style lang="less" type="text/scss" scoped>
-#appMain-box{
-  margin: 28px 16px 35px 23px;
-  padding: 20px;
+#appMain-box {
+  margin: 20px 16px 20px 23px;
+  padding: 10px 20px;
   background: #fff;
 }
+#app-main-id {
+  max-height: calc(100vh - 40px);
+}
 .app-main {
-  min-height: calc(100vh - 50px);
   width: 100%;
+  height: 100%;
   position: relative;
   overflow-y: auto;
   flex: 1;
-  background: #FFF9F9;
+  background: #fff9f9;
 }
 .fixed-header + .app-main {
   padding-top: 50px;
 }
-// fix css style bug in open el-dialog
 .el-popup-parent--hidden {
   .fixed-header {
     padding-right: 15px;

+ 18 - 11
src/layout/components/Navbar.vue

@@ -1,30 +1,35 @@
 <template>
   <div>
-    <el-header class="el-Navbar" style="height:80px">
-      <el-breadcrumb separator-class="el-icon-arrow-right">
-        <el-breadcrumb-item>首页</el-breadcrumb-item>
-        <el-breadcrumb-item>{{$route.meta.title}}</el-breadcrumb-item>
+    <el-header class="el-Navbar" style="height: 80px">
+      <el-breadcrumb separator-class="el-icon-arrow-right separator">
+        <el-breadcrumb-item>沪上阿姨</el-breadcrumb-item>
+        <el-breadcrumb-item>{{ $route.meta.title }}</el-breadcrumb-item>
       </el-breadcrumb>
       <el-dropdown>
         <span class="el-dropdown-link">
-          <img class="userImg" src="../../../static/images/default.png" alt />
+          <img class="userImg" src="@/assets/image/lolo2.png" alt />
           <span>{{ name }}</span>
           <i class="el-icon-arrow-down el-icon--right"></i>
         </span>
         <el-dropdown-menu slot="dropdown" trigger="click" style="width: 160px">
-          <el-dropdown-item @click.native="changePassword">
-            修改密码
-          </el-dropdown-item>
+          <el-dropdown-item @click.native="changePassword"
+            >修改密码</el-dropdown-item
+          >
           <el-dropdown-item @click.native="logout">退出</el-dropdown-item>
         </el-dropdown-menu>
       </el-dropdown>
     </el-header>
+    <edit ref="changePassword" />
   </div>
 </template>
 <script>
 import { mapState } from 'vuex'
 import { logout } from '@/api/login'
+import edit from '@/pages/userManagement/components/edit.vue'
 export default {
+  components: {
+    edit
+  },
   props: {
     activeMenu: {
       type: String,
@@ -47,12 +52,14 @@ export default {
   }),
   methods: {
     logout() {
-      logout().then(() => {
-        this.$router.push('/')
+      logout().then(res => {
+        if (res.code == 0) {
+          this.$router.push('/')
+        }
       })
     },
     changePassword() {
-      this.cgpwdVisible = true
+      this.$refs.changePassword.openClose()
     }
   }
 }

+ 12 - 5
src/layout/components/Sidebar/menuList.vue

@@ -1,7 +1,11 @@
 <template>
   <div>
-    <div style="text-align:center">
-      <img src="@/assets/image/lolo2.png" style="width:136px;margin:75px 0 60px 0" alt="">
+    <div style="text-align: center">
+      <img
+        src="@/assets/image/lolo2.png"
+        style="width: 136px; margin: 75px 0 60px 0"
+        alt=""
+      />
     </div>
     <template v-for="(item, i) in routesData">
       <el-submenu
@@ -11,8 +15,10 @@
         :key="i"
       >
         <template slot="title">
-          <i :class="item.meta.icon"></i>
-          <span slot="title">{{ item.meta.title }}</span>
+          <span>
+            <i :class="item.meta.icon" class="iconfont"></i>
+            <span slot="title">{{ item.meta.title }}</span>
+          </span>
         </template>
         <submenu :routes-data="item.children"></submenu>
       </el-submenu>
@@ -30,7 +36,8 @@
           @click="changeMenu(item)"
           :key="item.name"
         >
-          <i :class="item.meta.icon"></i>
+          <span class="icon_left"> </span>
+          <i :class="item.meta.icon" class="iconfont"></i>
           <span slot="title">
             {{ item.meta.title }}
           </span>

+ 15 - 3
src/layout/components/index.less

@@ -4,6 +4,16 @@
   justify-content: space-between;
   align-items: center;
 
+  .el-breadcrumb__separator[class*=icon] {
+    margin: 0;
+  }
+.el-icon-arrow-right:before{
+  content:'>'
+}
+  .el-breadcrumb__inner {
+    color: #A5A5A5 !important;
+  }
+
   .el-dropdown {
     cursor: pointer;
 
@@ -16,12 +26,14 @@
         font-size: 14px;
       }
 
-      .el-icon-arrow-down:before {
-        content: '\e790';
+      .el-icon-arrow-down {
+        box-shadow: 0px 3px 6px rgba(4, 0, 0, 0.08);
+        margin-left: 20px;
       }
 
       .el-icon--right {
-        font-size: 24px;
+        font-size: 20px;
+        line-height: 20px;
       }
 
       .userImg {

+ 31 - 2
src/layout/index.vue

@@ -1,10 +1,10 @@
 <template>
   <div>
-    <el-container style="overflow: hidden">
+    <el-container>
       <el-aside v-if="showComponents" width="200px">
         <Sidebar />
       </el-aside>
-      <el-container style="display: block">
+      <el-container style="display: block;width:100%">
         <Navbar v-if="showComponents" />
         <app-main />
       </el-container>
@@ -21,6 +21,11 @@ export default {
     AppMain,
     Sidebar
   },
+  data() {
+    return {
+      include: []
+    }
+  },
   computed: {
     // 是否显示顶部栏、菜单栏
     showComponents() {
@@ -30,6 +35,30 @@ export default {
         return false
       }
     }
+  },
+  watch: {
+    $route(to, from) {
+      if (to.meta.keepAlive) {
+        !this.include.includes(to.name) && this.include.push(to.name)
+      }
+      if (to.meta.parentNode && to.meta.parentNode.indexOf(from.name) > -1) {
+        !this.include.includes(from.name) && this.include.push(from.name)
+      } else if (
+        from.meta.parentNode &&
+        from.meta.parentNode.indexOf(to.name) > -1
+      ) {
+        console.log()
+      } else {
+        if (from.meta.parentNode) {
+          let index = this.include.indexOf(from.meta.parentNode)
+          index !== -1 && this.include.splice(index, 1)
+        }
+        if (!from.meta.parentNode) {
+          let index = this.include.indexOf(from.name)
+          index !== -1 && this.include.splice(index, 1)
+        }
+      }
+    }
   }
 }
 </script>

+ 2 - 1
src/main.js

@@ -4,7 +4,8 @@ import router from './router'
 import store from './store'
 import ElementUI from 'element-ui'
 import 'element-ui/lib/theme-chalk/index.css'
-import '../static/iconfont/iconfont.css'
+// import '../static/iconfont/iconfont.css'
+import '../static/font_hsy/iconfont.css'
 import pubFun from '@/utils/pubFun'
 import '@/assets/theme/index.css'
 import '@/assets/styles/element.less'

+ 188 - 21
src/pages/classification/edit.vue

@@ -1,61 +1,228 @@
 <template>
   <el-dialog
-    title="提示"
+    :title="classString.title"
     :visible.sync="dialogVisible"
     width="33%"
     :before-close="handleClose"
+    :close-on-press-escape="false"
+    :close-on-click-modal="false"
+    :append-to-body="true"
+    v-loading.fullscreen.lock="fullscreenLoading"
   >
-    <el-form>
-      <el-form-item label="分类名称:" required>
-        <el-input placeholder="请输入"></el-input>
+    <el-form label-width="100px" :model="form" ref="form" :rules="rules">
+      <el-form-item label="分类名称:" prop="name">
+        <el-input
+          placeholder="请输入名称"
+          v-model="form.name"
+          maxlength="64"
+          show-word-limit
+        ></el-input>
       </el-form-item>
-      <el-form-item  required>
-        <label solt="label" class="status"><span style="letter-spacing: 14px;">状态</span>:</label>
-        <el-radio-group v-model="radio">
-          <el-radio :label="3">启用</el-radio>
-          <el-radio :label="6">禁用</el-radio>
+      <el-form-item label prop="status">
+        <template slot="label"> <span>状&#8195;&emsp;态</span>: </template>
+        <el-radio-group v-model="form.status">
+          <el-radio :label="1">启用</el-radio>
+          <el-radio :label="0">禁用</el-radio>
         </el-radio-group>
       </el-form-item>
-      <el-form-item label="访问权限:" required>
-        <el-input placeholder="请输入"></el-input>
+      <el-form-item
+        style="margin-bottom: 20px"
+        label
+        v-for="(item, index) in form.role"
+        :key="index"
+        :prop="`role.${index}.value`"
+        :rules="rules.value"
+      >
+        <template v-if="index == 0" slot="label">
+          <span>访问权限:</span>
+        </template>
+        <div class="form_item_content">
+          <el-input
+            placeholder="请输入手机号"
+            v-onlyInt
+            maxlength="11"
+            show-word-limit
+            v-model="item.value"
+          ></el-input>
+          <i class="iconfont icon-a-zu903" @click="addjurisdiction"></i>
+          <i
+            class="iconfont icon-a-zu904"
+            v-if="form.role.length != 1"
+            @click="deletjurisdiction(index)"
+          ></i>
+        </div>
       </el-form-item>
     </el-form>
     <span slot="footer" class="dialog-footer">
-      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" @click="handleClose">取 消</el-button>
       <el-button
         size="small"
         style="margin-left: 60px"
         type="primary"
-        @click="dialogVisible = false"
+        @click="submit('form')"
         >确 定</el-button
       >
     </span>
   </el-dialog>
 </template>
 <script>
+import * as api from '@/api/api'
 export default {
   data() {
+    const validateUser = (rule, value, callback) => {
+      if (!/^1[3456789]\d{9}$/.test(value)) {
+        callback(new Error('请输入正确的手机号'))
+      } else {
+        callback()
+      }
+    }
     return {
-      dialogVisible: false
+      fullscreenLoading: false,
+      dialogVisible: false,
+      classString: {},
+      form: {
+        name: '',
+        status: 1,
+        role: [{ value: '' }]
+      },
+      rules: {
+        value: [{ required: true, trigger: 'blur', validator: validateUser }],
+        name: [{ required: true, trigger: 'blur', message: '请输入分类名称' }]
+      }
     }
   },
   methods: {
     handleClose() {
       this.dialogVisible = false
+      this.$parent.search()
+      this.form = {
+        name: '',
+        status: 1,
+        role: [{ value: '' }]
+      }
+      this.$refs['form'].resetFields()
     },
-    openClose() {
+    openClose(val) {
+      if (val) {
+        this.classString = val
+        if (!val.show) {
+          this.detailList()
+        }
+      }
+      this.title = val.title
       this.dialogVisible = true
+    },
+    /**
+     * @method 分类管理详情
+     * **/
+    detailList() {
+      let code = {
+        typeId: this.classString.typeId
+      }
+      api.POST('/doc/type/detail', code).then(data => {
+        if (data.code == 0) {
+          this.form = data.data
+          let role = []
+          if (this.form.role.length != 0) {
+            this.form.role.forEach(item => {
+              role.push({ value: item })
+            })
+            this.form.role = role
+          } else {
+            this.form.role = [{ value: '' }]
+          }
+        }
+      })
+    },
+    /**
+     * @method 增加访问权限
+     * **/
+    addjurisdiction() {
+      this.form.role.push({ value: '' })
+    },
+    /**
+     * @method 删除访问权限
+     * **/
+    deletjurisdiction(val) {
+      this.form.role.splice(val, 1)
+    },
+    /**
+     * @method 确定提交
+     **/
+    submit(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          this.fullscreenLoading = true
+          let role = []
+          this.form.role.forEach(item => {
+            role.push(item.value)
+          })
+          let code = {
+            linkUrl: '',
+            name: this.form.name,
+            role: role,
+            status: this.form.status
+          }
+          this.classString.show ? this.addclass(code) : this.editclass(code)
+        }
+      })
+    },
+    /**
+     * @method 新增
+     * **/
+    addclass(val) {
+      api
+        .POST('/doc/type/add', val)
+        .then(data => {
+          if (data.code == 0) {
+            this.handleClose()
+            this.$message.success(data.message)
+            this.fullscreenLoading = false
+          }
+        })
+        .catch(() => {
+          this.fullscreenLoading = false
+        })
+    },
+    /**
+     * @method 编辑
+     * **/
+    editclass(val) {
+      val.typeId = this.form.typeId
+      api
+        .POST('/doc/type/update', val)
+        .then(data => {
+          if (data.code == 0) {
+            this.handleClose()
+            this.$message.success(data.message)
+            this.fullscreenLoading = false
+          }
+        })
+        .catch(() => {
+          this.fullscreenLoading = false
+        })
     }
   }
 }
 </script>
 <style lang="less" scoped>
-.status{
-    padding: 0 12px 0 0;
+.form_item_content {
+  display: flex;
+  align-items: center;
+  margin-bottom: 10px;
+}
+.icon-a-zu903 {
+  color: #f23f3a;
+  margin-left: 10px;
+  margin-right: 20px;
+  cursor: pointer;
+  font-size: 22px;
+}
+.icon-a-zu904 {
+  cursor: pointer;
+  font-size: 22px;
 }
-.status::before {
-  content: '*';
-  color: #f56c6c;
-  margin-right: 4px;
+.el-icon-minus {
+  margin-right: 16px;
 }
 </style>

+ 257 - 180
src/pages/classification/index.vue

@@ -1,73 +1,125 @@
 <template>
-  <div class="classification_list">
+  <div
+    class="classification_list"
+    v-loading.fullscreen.lock="fullscreenLoading"
+  >
     <div class="classification_list_headerSelect">
-      <el-form
-        slot="form"
-        style="display: inline"
-        inline
-        :addList="true"
-      >
-        <el-form-item label="分类名称:">
-          <el-input size="small" placeholder="请输入"></el-input>
-        </el-form-item>
-        <el-form-item label="状态:">
-          <el-input size="small"></el-input>
-        </el-form-item>
-        <el-form-item>
-          <el-button size="small" style="width:88px" type="primary">查询</el-button>
-        </el-form-item>
-      </el-form>
-      <el-button size="small" style="width:104px;margin-right:23px">新增</el-button>
+      <div class="classification-list-btn">
+        <el-form ref="form" :model="form" inline label-width="90px">
+          <el-form-item class="header_top_form" label="分类名称:" prop="name">
+            <el-input
+              v-model.trim="form.name"
+              size="small"
+              placeholder="请输入"
+              clearable
+            ></el-input>
+          </el-form-item>
+          <el-form-item class="header_top_form" label="状态:" prop="status">
+            <el-select
+              v-model="form.status"
+              clearable
+              size="small"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+        <div style="margin-right: 23px">
+          <el-button
+            size="small"
+            style="width: 88px"
+            type="primary"
+            @click="search"
+            >查询</el-button
+          >
+          <el-button size="small" style="width: 88px" @click="resetForm('form')"
+            >重置</el-button
+          >
+        </div>
+      </div>
+      <div style="text-align: right">
+        <el-button
+          size="small"
+          style="width: 104px; margin-right: 23px"
+          @click="addList"
+          icon="iconfont icon-a-zu13"
+          >新增</el-button
+        >
+      </div>
     </div>
-    <el-table
-      :data="tableData"
-      style="width: 100%"
-      stripe
-      :header-cell-style="{ background: '#F7F7F7' }"
-      height="60vh"
-    >
-      <el-table-column
-        v-for="(item, index) in listData"
-        :key="index"
-        :label="item.name"
-        :prop="item.value"
-        :width="item.width"
-        :min-width="item.minWidth"
-        :align="item.align"
+    <div>
+      <el-table
+        ref="editTable"
+        :data="tableData"
+        stripe
+        :header-cell-style="{ background: '#F7F7F7' }"
+        :height="screenHeight"
       >
-        <template slot-scope="scope">
-          <div>
-            <div v-if="item.value == 'status'">
-              <el-switch
-                v-model="scope.row[scope.column.property]"
-                active-color="#17A8FF"
-                inactive-color="#AFAFAF"
-              >
-              </el-switch>
-            </div>
-            <div v-else>
-              {{ scope.row[scope.column.property] }}
+        <el-table-column
+          label="分类名称"
+          prop="name"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column
+          label="链接地址"
+          prop="linkUrl"
+          align="center"
+          min-width="180"
+        ></el-table-column>
+        <el-table-column
+          label="禁用/启用"
+          prop="status"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <div>
+                <el-switch
+                  v-model="scope.row.status"
+                  active-color="#17A8FF"
+                  inactive-color="#AFAFAF"
+                  @change="switchChange($event, scope.row)"
+                >
+                </el-switch>
+            </div> </template
+        ></el-table-column>
+        <el-table-column
+          label="创建人"
+          prop="createUserName"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column
+          label="创建时间"
+          prop="createTime"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column label="操作" width="140px" align="center">
+          <template slot-scope="scope">
+            <div>
+              <el-button type="text" @click="edit(scope.row)">编辑</el-button>
             </div>
-          </div>
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" align="center">
-        <template slot-scope="scope">
-          <div>
-            <el-button type="text" @click="edit(scope.row)">编辑</el-button>
-          </div>
-        </template>
-      </el-table-column>
-    </el-table>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
     <el-pagination
       @size-change="handleSizeChange"
       @current-change="handleCurrentChange"
       :current-page="form.pageNum"
       :page-sizes="[100, 200, 300, 400]"
-      :page-size="10"
+      :page-size="form.pageSize"
       background
       layout="total,prev, pager, next,jumper"
-      :total="100"
+      :total="form.total"
     >
     </el-pagination>
     <edit-dialog ref="editDialogRefs" />
@@ -75,6 +127,7 @@
 </template>
 <script>
 import editDialog from './edit'
+import * as api from '@/api/api'
 export default {
   name: 'classification',
   components: {
@@ -82,131 +135,147 @@ export default {
   },
   data() {
     return {
+      fullscreenLoading: false,
+      form: {
+        name: '',
+        status: '',
+        pageNum: 1,
+        pageSize: 10,
+        start: '',
+        total: 0
+      },
       tableData: [],
-      listData: [
-        {
-          name: '分类名称',
-          value: 'name',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '链接地址',
-          value: 'string',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '状态',
-          value: 'status',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '创建人',
-          value: 'userName',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '创建时间',
-          value: 'userTime',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        }
+      options: [
+        { label: '启用', value: 1 },
+        { label: '禁用', value: 0 }
       ],
-      form: {
-        pageNum: 4
-      }
+      screenHeight: document.body.clientHeight - 320,
+      tableDataheight: 0
     }
   },
   mounted() {
-    this.$nextTick(() => {
-      this.tableData = [
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        },
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        },
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        },
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        },
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        },
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        },
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        },
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        },
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        },
-        {
-          name: '1',
-          string: '1',
-          status: true,
-          userName: 'ss',
-          userTime: '2021'
-        }
-      ]
-    })
+    this.screenHeight = document.body.clientHeight - 320
+    window.onresize = () => {
+      return (() => {
+        this.screenHeight = document.body.clientHeight - 320
+      })()
+    }
+    this.tableDataList()
   },
   methods: {
-    handleSizeChange() {},
-    handleCurrentChange() {},
+    /**
+     * @method 重置
+     * **/
+    resetForm(formName) {
+      this.$refs[formName].resetFields()
+      this.search()
+    },
+    /**
+     * @method 搜索
+     * **/
+    search() {
+      if (sessionStorage.getItem('classifica')) {
+        this.form.pageNum = Number(sessionStorage.getItem('classifica'))
+        sessionStorage.removeItem('classifica')
+      } else {
+        this.form.pageNum = 1
+      }
+
+      this.tableDataList()
+    },
+    /**
+     * @method 列表数据
+     * **/
+    tableDataList() {
+      this.tableData = []
+      this.fullscreenLoading = true
+      let code = {
+        name: this.form.name,
+        page: this.form.pageNum,
+        pageSize: this.form.pageSize,
+        start: this.form.start,
+        status: this.form.status
+      }
+      api
+        .GET('/doc/type/list', code)
+        .then(res => {
+          if (res.code == 0) {
+            this.tableData = res.data.list
+            this.tableData.forEach(item => {
+              item.status == 1 ? (item.status = true) : (item.status = false)
+            })
+            this.form.pageNum = res.data.currPage
+            this.form.pageSize = res.data.pageSize
+            this.form.total = res.data.totalCount
+            this.fullscreenLoading = false
+            this.$nextTick(() => {
+              this.$refs.editTable.bodyWrapper.scrollTop = this.tableDataheight
+              this.tableDataheight = 0
+            })
+          }
+        })
+        .catch(() => {
+          this.fullscreenLoading = false
+        })
+    },
+    /**
+     * @method 分页条数
+     * **/
+    handleSizeChange(val) {
+      this.form.pageNum = 1
+      this.form.pageSize = val
+      this.tableDataList()
+    },
+    /**
+     * @method 分页
+     * **/
+    handleCurrentChange(val) {
+      this.form.pageNum = val
+      this.tableDataList()
+    },
     // 编辑
-    edit() {
-      this.$refs.editDialogRefs.openClose()
+    edit(val) {
+      this.tableDataheight = this.$refs.editTable.bodyWrapper.scrollTop
+      sessionStorage.setItem('classifica', this.form.pageNum)
+      let code = {
+        title: '分类编辑',
+        show: false,
+        typeId: val.typeId
+      }
+      this.$refs.editDialogRefs.openClose(code)
+    },
+    /**
+     * @method 新增
+     * **/
+    addList() {
+      let code = {
+        title: '分类新增',
+        show: true
+      }
+      this.$refs.editDialogRefs.openClose(code)
+    },
+    /**
+     * @method 切换状态
+     * **/
+    switchChange(val, item) {
+      this.tableDataheight = this.$refs.editTable.bodyWrapper.scrollTop
+      sessionStorage.setItem('classifica', this.form.pageNum)
+      val ? (val = 1) : (val = 0)
+      let code = {
+        id: item.typeId,
+        status: val
+      }
+      api
+        .PUT('/doc/type/updateSwitch', code)
+        .then(data => {
+          if (data.code == 0) {
+            this.search()
+            this.$message.success(data.message)
+          }
+        })
+        .catch(() => {
+          this.search()
+        })
     }
   }
 }
@@ -214,12 +283,16 @@ export default {
 <style lang="less">
 .classification_list {
   .classification_list_headerSelect {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 32px;
+    .classification-list-btn {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 10px;
+    }
+
+    margin-bottom: 20px;
     .el-form-item {
-      margin-bottom: 0;
+      margin-bottom: 10px;
       margin-right: 60px;
       .el-input__inner {
         background: #f5f5f5;
@@ -227,6 +300,10 @@ export default {
         border-radius: 17px;
       }
     }
+    .icon-a-zu13 {
+      font-size: 11px;
+      margin-right: 5px;
+    }
   }
 }
 </style>

+ 77 - 8
src/pages/fileManagement/detail.vue

@@ -4,6 +4,10 @@
     :visible.sync="dialogVisible"
     width="50%"
     :before-close="handleClose"
+    :close-on-press-escape="false"
+    :close-on-click-modal="false"
+    :append-to-body="true"
+    v-loading.fullscreen.lock="fullscreenLoading"
   >
     <template>
       <el-table
@@ -12,34 +16,99 @@
         stripe
         :header-cell-style="{ background: '#F7F7F7' }"
       >
-        <el-table-column prop="date" label="文件名称" width="180">
+        <el-table-column
+          prop="name"
+          align="center"
+          show-overflow-tooltip
+          label="文件名称"
+          width="180"
+        >
         </el-table-column>
-        <el-table-column prop="name" label="链接地址" width="180">
+        <el-table-column
+          prop="createUser"
+          align="center"
+          show-overflow-tooltip
+          label="操作人"
+        >
+        </el-table-column>
+        <el-table-column
+          prop="createTime"
+          align="center"
+          show-overflow-tooltip
+          label="操作时间"
+        >
+        </el-table-column>
+        <el-table-column label="操作" align="center">
+          <template slot-scope="scope">
+            <el-button type="text" @click="download(scope.row)">下载</el-button>
+          </template>
         </el-table-column>
-        <el-table-column prop="address" label="创建人"> </el-table-column>
-        <el-table-column prop="address" label="创建时间"> </el-table-column>
-        <el-table-column prop="address" label="操作"> </el-table-column>
       </el-table>
     </template>
     <span slot="footer" class="dialog-footer">
-      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" @click="handleClose">取 消</el-button>
     </span>
   </el-dialog>
 </template>
 <script>
+import * as api from '@/api/api'
+import axios from 'axios'
 export default {
   data() {
     return {
       dialogVisible: false,
-      tableData: []
+      tableData: [],
+      fullscreenLoading: false
     }
   },
   methods: {
     handleClose() {
       this.dialogVisible = false
     },
-    openClose() {
+    openClose(val) {
       this.dialogVisible = true
+      this.listDataInit(val)
+    },
+    /**
+     * @method 历史版本信息
+     * **/
+    listDataInit(val) {
+      let code = {
+        id: val.id
+      }
+      api.GET('/doc/getDocHistoryList', code).then(data => {
+        if (data.code == 0) {
+          this.tableData = data.data
+        }
+      })
+    },
+    /**
+     * @method 下载
+     * **/
+    download(val) {
+      this.fullscreenLoading = true
+      axios.get(val.docUrl, { responseType: 'blob' }).then(res => {
+        //  如果支持微软的文件下载方式(ie10+浏览器)
+        if (window.navigator.msSaveBlob) {
+          try {
+            const blobObject = new Blob([res.data])
+            window.navigator.msSaveBlob(blobObject, `${val.name}.pdf`)
+          } catch (e) {
+            console.log(e)
+          }
+        } else {
+          //  其他浏览器
+          const url = window.URL.createObjectURL(new Blob([res.data]))
+          const link = document.createElement('a')
+          link.href = url
+          link.setAttribute('download', `${val.name}.pdf`)
+          document.body.appendChild(link)
+          link.click()
+          document.body.removeChild(link) // 下载完成移除元素
+          window.URL.revokeObjectURL(url) // 释放掉blob对象
+        }
+        this.fullscreenLoading = false
+      })
     }
   }
 }

+ 264 - 43
src/pages/fileManagement/edit.vue

@@ -1,83 +1,304 @@
 <template>
   <el-dialog
-    title="提示"
+    :title="refList.title"
     :visible.sync="dialogVisible"
     width="33%"
     :before-close="handleClose"
+    :close-on-press-escape="false"
+    :close-on-click-modal="false"
+    :append-to-body="true"
+    v-loading.fullscreen.lock="fullscreenLoading"
   >
-    <el-form>
-      <el-form-item label="分类名称:" required="">
-        <el-input></el-input>
-      </el-form-item>
-      <el-form-item label="文件名称:" required="">
-        <el-input></el-input>
+    <el-form :model="form" ref="form" :rules="rules" label-width="100px">
+      <el-form-item label="分类名称:" prop="typeId">
+        <el-select
+          filterable
+          placeholder="请选择"
+          v-model="form.typeId"
+          @visible-change="visbleChange"
+          @change="classifyChange"
+        >
+          <el-option
+            v-for="(item, index) in classifyList"
+            :key="index"
+            :label="item.name"
+            :value="item.typeId"
+          >
+          </el-option>
+        </el-select>
       </el-form-item>
-      <el-form-item label="上传文件:" required="">
-        <div style="padding-left:94px">
+
+      <el-form-item label="上传文件:" prop="docUrl">
+        <div>
           <el-upload
-          class="upload-demo"
-          action="https://jsonplaceholder.typicode.com/posts/"
-          :on-preview="handlePreview"
-          :on-remove="handleRemove"
-          :before-remove="beforeRemove"
-          multiple
-          :limit="3"
-          :on-exceed="handleExceed"
-          :file-list="fileList"
-        >
-          <el-button size="small" type="primary">点击上传</el-button>
-          <div slot="tip" class="el-upload__tip">
-            仅支持pdf文件
-          </div>
-        </el-upload>
+            class="upload-demo"
+            :action="url"
+            :on-success="handleSuccess"
+            :on-remove="handleRemove"
+            multiple
+            :limit="1"
+            :on-exceed="handleExceed"
+            :file-list="fileList"
+            :before-upload="beforeAvatarUpload"
+            accept=".pdf, application/pdf"
+          >
+            <el-button
+              size="small"
+              style="background: #579ef8; border-color: #579ef8"
+              type="primary"
+              >点击上传</el-button
+            >
+            <div slot="tip" class="el-upload__tip">
+              仅支持pdf文件,文件名称保存时生效
+            </div>
+          </el-upload>
         </div>
       </el-form-item>
-      <el-form-item required>
-        <label solt="label" class="status"
-          ><span style="letter-spacing: 14px">状态</span>:</label
-        >
-        <el-radio-group v-model="radio">
-          <el-radio :label="3">启用</el-radio>
-          <el-radio :label="6">禁用</el-radio>
+      <el-form-item label="文件名称:" prop="name">
+        <el-input
+          class="maxlength-input"
+          placeholder="请输入"
+          maxlength="64"
+          show-word-limit
+          v-model.trim="form.name"
+        ></el-input>
+      </el-form-item>
+      <el-form-item prop="status">
+        <template slot="label"><span>状&#8195;&emsp;态</span>:</template>
+        <el-radio-group v-model="form.status">
+          <el-radio :label="1">启用</el-radio>
+          <el-radio :label="0">禁用</el-radio>
         </el-radio-group>
       </el-form-item>
     </el-form>
     <span slot="footer" class="dialog-footer">
-      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" @click="handleClose">取 消</el-button>
       <el-button
         size="small"
         style="margin-left: 60px"
         type="primary"
-        @click="dialogVisible = false"
+        @click="addList('form')"
         >确 定</el-button
       >
     </span>
   </el-dialog>
 </template>
 <script>
+import * as api from '@/api/api'
 export default {
   data() {
     return {
-      dialogVisible: false
+      fullscreenLoading: false,
+      dialogVisible: false,
+      form: {
+        docUrl: '',
+        id: '',
+        linkUrl: '',
+        name: '',
+        status: 1,
+        typeId: ''
+      },
+      refList: {},
+      fileList: [],
+      classifyList: [],
+      rules: {
+        typeId: [
+          { required: true, trigger: 'change', message: '请选择分类名称' }
+        ],
+        name: [{ required: true, trigger: 'blur', message: '请输入文件名称' }],
+        docUrl: [{ required: true, trigger: 'click', message: '请上传文件' }]
+      },
+      url: window.global_config.BASE_URL + '/api/file/local/upload'
     }
   },
   methods: {
+    /**
+     * @method 关闭弹框
+     * **/
     handleClose() {
       this.dialogVisible = false
+      this.$parent.search()
+      this.form = {
+        docUrl: '',
+        id: '',
+        linkUrl: '',
+        name: '',
+        status: 1,
+        typeId: '',
+        fileSize: ''
+      }
+      this.fileList = []
+      this.$refs['form'].resetFields()
     },
-    openClose() {
+    /**
+     * @method 打开文件弹框
+     * **/
+    openClose(val) {
+      if (val) {
+        this.refList = val
+        if (val.id) {
+          this.visbleChange(true)
+          this.details()
+        }
+      }
       this.dialogVisible = true
+    },
+    /**
+     * @method 详情
+     * **/
+    details() {
+      api.GET('/doc/getDetail', { id: this.refList.id }).then(data => {
+        if (data.code == 0) {
+          this.form = data.data
+          this.fileList = [{ name: this.form.name, url: this.form.docUrl }]
+        }
+      })
+    },
+    /**
+     * @method 分类下拉列表
+     * **/
+    visbleChange(val) {
+      if (val) {
+        api.POST('/doc/type/dropList').then(data => {
+          if (data.code == 0) {
+            this.classifyList = data.data
+          }
+        })
+      }
+    },
+    /**
+     * @method 分类选择
+     * **/
+    classifyChange(val) {
+      this.classifyList.find(item => {
+        if (item.typeId == val) {
+          this.form.linkUrl = item.linkUrl
+        }
+      })
+    },
+    /**
+     * @method 上传
+     * **/
+    // api_import(file) {
+    //   const files = {
+    //     file: file.file
+    //   }
+    //   api
+    //     .IMPORT('/api/file/local/upload', files)
+    //     .then(data => {
+    //       if (data.code == 0) {
+    //         this.form.name == ''
+    //           ? (this.form.name = file.file.name)
+    //           : this.form.name
+
+    //         // data.data.name = this.form.name
+    //         // this.fileList = [data.data]
+    //         this.form.docUrl = data.data.url
+    //         this.form.fileSize = data.data.size
+    //         this.$message.success('上传成功')
+    //       }
+    //     })
+    //     .catch(() => {
+    //       this.fileList = []
+    //     })
+    // },
+    /**
+     * @method 文件上传限制
+     * **/
+    handleExceed(files, fileList) {
+      if (fileList.length == 1) {
+        this.$message.warning('只能上传单个文件')
+      }
+    },
+    /**
+     * @method 上传成功
+     * **/
+    handleSuccess(file, fileList) {
+      this.form.name == ''
+        ? (this.form.name = fileList.name.split('.pdf')[0].substring(0, 64))
+        : this.form.name
+      file.data.name = this.form.name
+      this.fileList = [file.data]
+      this.form.docUrl = file.data.url
+      this.form.fileSize = file.data.size
+      this.$message.success('上传成功')
+    },
+    /**
+     * @method 文件删除
+     * **/
+    handleRemove(files, fileList) {
+      this.form.name = ''
+      this.fileList = fileList
+      this.form.docUrl = ''
+      this.form.fileSize = ''
+    },
+    /**
+     * @method 上传限制
+     * **/
+    beforeAvatarUpload(file) {
+      const ispaf = file.type === 'application/pdf'
+
+      if (!ispaf) {
+        this.$message.error('上传文件只能是 PDF 格式!')
+      }
+      return ispaf
+    },
+    /**
+     * @method 提交确定
+     * **/
+    addList(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          this.fullscreenLoading = true
+          let code = {
+            docUrl: this.form.docUrl,
+            linkUrl: this.form.linkUrl,
+            name: this.form.name,
+            status: this.form.status,
+            typeId: this.form.typeId,
+            fileSize: this.form.fileSize
+          }
+          this.refList.show ? this.addfile(code) : this.editfile(code)
+        }
+      })
+    },
+    /**
+     * @method 新增文件
+     * **/
+    addfile(val) {
+      api
+        .POST('/doc/addDoc', val)
+        .then(data => {
+          if (data.code == 0) {
+            this.$message.success(data.message)
+            this.handleClose()
+            this.fullscreenLoading = false
+          }
+        })
+        .catch(() => {
+          this.fullscreenLoading = false
+        })
+    },
+    /**
+     * @method 编辑文件
+     * **/
+    editfile(val) {
+      val.id = this.form.id
+      api
+        .PUT('/doc/updateDoc', val)
+        .then(data => {
+          if (data.code == 0) {
+            this.$message.success(data.message)
+            this.handleClose()
+            this.fullscreenLoading = false
+          }
+        })
+        .catch(() => {
+          this.fullscreenLoading = false
+        })
     }
   }
 }
 </script>
 <style lang="less" scoped>
-.status {
-  padding: 0 12px 0 0;
-}
-.status::before {
-  content: '*';
-  color: #f56c6c;
-  margin-right: 4px;
-}
 </style>

+ 313 - 135
src/pages/fileManagement/index.vue

@@ -1,83 +1,169 @@
 <template>
-  <div class="fileManagement_List">
+  <div
+    class="fileManagement_List"
+    v-loading.fullscreen.lock="fullscreenLoading"
+  >
     <div class="fileManagement_List_headerSelect">
-        <el-form
-        slot="form"
-        style="display: inline"
-        inline
-        :addList="true"
-      >
-        <el-form-item label="分类名称:">
-          <el-input size="small"></el-input>
-        </el-form-item>
-        <el-form-item label="状态:">
-          <el-input size="small"></el-input>
-        </el-form-item>
-        <el-form-item>
-          <el-button size="small" type="primary" style="width:88px" >查询</el-button>
-        </el-form-item>
-      </el-form>
-      <el-button size="small" style="width:104px;margin-right:23px">新增</el-button>
+      <div class="fileManagement-list-btn">
+        <el-form style="display: inline" :model="form" ref="form" inline>
+          <el-form-item
+            class="header_top_form"
+            label="分类名称:"
+            prop="typeId"
+          >
+            <el-select
+              clearable
+              filterable
+              size="small"
+              placeholder="请选择"
+              v-model="form.typeId"
+              @visible-change="visbleChange"
+            >
+              <el-option
+                v-for="(item, index) in classifyList"
+                :key="index"
+                :label="item.name"
+                :value="item.typeId"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item class="header_top_form" label="文件名称:" prop="name">
+            <el-input
+              clearable
+              v-model.trim="form.name"
+              placeholder="请输入"
+              size="small"
+            ></el-input>
+          </el-form-item>
+          <el-form-item class="header_top_form" label="状态:" prop="status">
+            <el-select
+              v-model="form.status"
+              clearable
+              size="small"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+        <div style="margin-right: 23px">
+          <el-button
+            size="small"
+            type="primary"
+            style="width: 88px"
+            @click="search"
+            >查询</el-button
+          >
+          <el-button size="small" style="width: 88px" @click="resetForm('form')"
+            >重置</el-button
+          >
+        </div>
+      </div>
+
+      <div style="text-align: right">
+        <el-button
+          size="small"
+          style="width: 104px; margin-right: 23px"
+          icon="iconfont icon-a-zu13"
+          @click="addList"
+          >新增</el-button
+        >
+      </div>
     </div>
-    <el-table
-      :data="tableData"
-      style="width: 100%"
-      stripe
-      :header-cell-style="{ background: '#F7F7F7' }"
-    >
-      <el-table-column
-        v-for="(item, index) in listData"
-        :key="index"
-        :label="item.name"
-        :prop="item.value"
-        :width="item.width"
-        :min-width="item.minWidth"
-        :align="item.align"
+    <div>
+      <el-table
+        :data="tableData"
+        stripe
+        ref="editTable"
+        :header-cell-style="{ background: '#F7F7F7' }"
+        :height="screenHeight"
       >
-        <template slot-scope="scope">
-          <div>
-            <div v-if="item.value == 'status'">
-              <el-switch
-                v-model="scope.row.status"
-                active-color="#17A8FF"
-                inactive-color="#AFAFAF"
+        <el-table-column
+          label="分类名称"
+          prop="typeName"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column
+          label="文件名称"
+          prop="name"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column
+          label="链接地址"
+          prop="linkUrl"
+          align="center"
+          min-width="180"
+        ></el-table-column>
+        <el-table-column
+          label="禁用/启用"
+          prop="status"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <div>
+              <div>
+                <el-switch
+                  v-model="scope.row.status"
+                  active-color="#17A8FF"
+                  inactive-color="#AFAFAF"
+                  @change="statusChange($event, scope.row)"
+                >
+                </el-switch>
+              </div>
+            </div> </template
+        ></el-table-column>
+        <el-table-column
+          label="创建人"
+          prop="createUser"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column
+          label="创建时间"
+          prop="createTime"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column label="操作" width="140px" align="center">
+          <template slot-scope="scope">
+            <div>
+              <el-button type="text" @click="history(scope.row)"
+                >历史版本</el-button
               >
-              </el-switch>
-            </div>
-            <div v-else>
-              {{ scope.row[scope.column.property] }}
+              <el-button type="text" @click="edit(scope.row)">编辑</el-button>
             </div>
-          </div>
-        </template>
-      </el-table-column>
-
-      <el-table-column label="操作" align="center">
-        <template slot-scope="scope">
-          <div>
-            <el-button type="text" @click="history(scope.row)">历史版本</el-button>
-            <el-button type="text" @click="edit">编辑</el-button>
-          </div>
-        </template>
-      </el-table-column>
-    </el-table>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
     <el-pagination
       @size-change="handleSizeChange"
       @current-change="handleCurrentChange"
       :current-page="form.pageNum"
       :page-sizes="[100, 200, 300, 400]"
-      :page-size="10"
+      :page-size="form.pageSize"
       background
       layout="total,prev, pager, next,jumper"
-      :total="100"
+      :total="form.total"
     >
     </el-pagination>
     <editDialog ref="editDialogRefs" />
-    <detailDialog ref="detailDialogRefs"/>
+    <detailDialog ref="detailDialogRefs" />
   </div>
 </template>
 <script>
 import editDialog from './edit'
 import detailDialog from './detail'
+import * as api from '@/api/api'
 export default {
   name: 'fileManagement',
   components: {
@@ -86,88 +172,170 @@ export default {
   },
   data() {
     return {
+      fullscreenLoading: false,
       tableData: [],
-      listData: [
-        {
-          name: '分类名称',
-          value: 'name',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '文件名称',
-          value: 'flieName',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '连接地址',
-          value: 'file',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '禁用/启用',
-          value: 'status',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '创建人',
-          value: 'userName',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '创建时间',
-          value: 'userTime',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        }
+      options: [
+        { label: '启用', value: 1 },
+        { label: '禁用', value: 0 }
       ],
       form: {
-        pageNum: 4
-      }
+        pageNum: 1,
+        pageSize: 10,
+        total: 0,
+        name: '',
+        start: '',
+        status: '',
+        typeId: ''
+      },
+      classifyList: [],
+      screenHeight: document.body.clientHeight - 320,
+      tableDataheight: 0
     }
   },
   mounted() {
-    this.$nextTick(() => {
-      this.tableData = [
-        {
-          name: '1',
-          flieName: '2',
-          file: '3',
-          status: true,
-          userName: '4',
-          userTime: '5'
-        },
-        {
-          name: '1',
-          flieName: '2',
-          file: '3',
-          status: false,
-          userName: '4',
-          userTime: '5'
-        },
-      ]
-    })
+    this.screenHeight = document.body.clientHeight - 320
+    window.onresize = () => {
+      return (() => {
+        this.screenHeight = document.body.clientHeight - 320
+      })()
+    }
+    this.listDataInit()
   },
   methods: {
-    handleSizeChange() {},
-    handleCurrentChange() {},
+    /**
+     * @method 重置
+     * **/
+    resetForm(formName) {
+      this.$refs[formName].resetFields()
+      this.search()
+    },
+    /**
+     * @method 分类下拉列表
+     * **/
+    visbleChange(val) {
+      if (val) {
+        api.GET('/doc/type/dropListAll').then(data => {
+          if (data.code == 0) {
+            this.classifyList = data.data
+          }
+        })
+      }
+    },
+    /**
+     * @method 搜索
+     * **/
+    search() {
+      if (sessionStorage.getItem('filemanage')) {
+        this.form.pageNum = Number(sessionStorage.getItem('filemanage'))
+        sessionStorage.removeItem('filemanage')
+      } else {
+        this.form.pageNum = 1
+      }
+      this.listDataInit()
+    },
+    /**
+     * @method 列表数据
+     * **/
+    listDataInit() {
+      this.tableData = []
+      this.fullscreenLoading = true
+      let code = {
+        name: this.form.name,
+        page: this.form.pageNum,
+        pageSize: this.form.pageSize,
+        start: this.form.start,
+        status: this.form.status,
+        typeId: this.form.typeId
+      }
+      api
+        .POST('/doc/getDocList', code)
+        .then(res => {
+          if (res.code == 0) {
+            this.tableData = res.data.list
+            this.tableData.forEach(item => {
+              item.status == 1 ? (item.status = true) : (item.status = false)
+            })
+            this.form.pageNum = res.data.currPage
+            this.form.pageSize = res.data.pageSize
+            this.form.total = res.data.totalCount
+            this.fullscreenLoading = false
+            this.$nextTick(() => {
+              this.$refs.editTable.bodyWrapper.scrollTop = this.tableDataheight
+              this.tableDataheight = 0
+            })
+          }
+        })
+        .catch(() => {
+          this.fullscreenLoading = false
+        })
+    },
+    /**
+     * @method 条数分页
+     * **/
+    handleSizeChange(val) {
+      this.form.pageNum = 1
+      this.form.pageSize = val
+      this.listDataInit()
+    },
+    /**
+     * @method 分页
+     * **/
+    handleCurrentChange(val) {
+      this.form.pageNum = val
+      this.listDataInit()
+    },
+    /**
+     * @method 新增
+     * **/
+    addList() {
+      let code = {
+        title: '文件新增',
+        show: true
+      }
+      this.$refs.editDialogRefs.openClose(code)
+    },
     // 编辑
-    edit() {
-      this.$refs.editDialogRefs.openClose()
+    edit(val) {
+      this.tableDataheight = this.$refs.editTable.bodyWrapper.scrollTop
+      sessionStorage.setItem('filemanage', this.form.pageNum)
+      let code = {
+        title: '文件编辑',
+        show: false,
+        id: val.id
+      }
+      this.$refs.editDialogRefs.openClose(code)
     },
     // 历史版本
-    history(){
-      this.$refs.detailDialogRefs.openClose()
+    history(val) {
+      this.tableDataheight = this.$refs.editTable.bodyWrapper.scrollTop
+      sessionStorage.setItem('filemanage', this.form.pageNum)
+      const code = {
+        id: val.id
+      }
+      this.$refs.detailDialogRefs.openClose(code)
+    },
+    /**
+     * @method 状态修改
+     * **/
+    statusChange(val, item) {
+      this.tableDataheight = this.$refs.editTable.bodyWrapper.scrollTop
+      sessionStorage.setItem('filemanage', this.form.pageNum)
+      val ? (val = 1) : (val = 0)
+      let code = {
+        id: item.id,
+        status: val
+      }
+      api
+        .PUT('/doc/updateSwitch', code)
+        .then(data => {
+          if (data.code == 0) {
+            this.search()
+            this.$message.success(data.message)
+          }
+        })
+        .catch(() => {
+          this.search()
+        })
     }
   }
 }
@@ -175,12 +343,18 @@ export default {
 <style lang="less">
 .fileManagement_List {
   .fileManagement_List_headerSelect {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 32px;
+    .fileManagement-list-btn {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 10px;
+      .el-input__suffix {
+        height: 32px;
+      }
+    }
+    margin-bottom: 20px;
     .el-form-item {
-      margin-bottom: 0;
+      margin-bottom: 10px;
       margin-right: 60px;
       .el-input__inner {
         background: #f5f5f5;
@@ -188,6 +362,10 @@ export default {
         border-radius: 17px;
       }
     }
+    .icon-a-zu13 {
+      font-size: 11px;
+      margin-right: 5px;
+    }
   }
 }
 </style>

+ 8 - 9
src/pages/login/index.less

@@ -7,6 +7,7 @@
   background-color: #f4e1e4 !important;
   width: 100vw;
   min-height: 100vh;
+  height: 100vh !important;
   display: flex;
   align-items: center;
   justify-content: center;
@@ -39,15 +40,9 @@
 
   .form-box {
     background: #fff;
-    // display: flex;
-    // flex-direction: column;
-    // justify-content: center;
     width: 25vw;
     height: 50vh;
     padding: 5vh;
-    // position: fixed;
-    // right: 5vw;
-    // top: 15vh;
     border-radius: 2vh;
     z-index: 2;
 
@@ -75,7 +70,7 @@
       }
 
       .el-form-item {
-        margin-bottom: 2vh;
+        // margin-bottom: 2vh;
       }
 
       .el-form-item__label {
@@ -105,7 +100,7 @@
         border-color: linear-gradient(90deg, #FA6253 0%, #F23D39 100%);
         opacity: 1;
         border-radius: 46px;
-        font-size: 28px;
+        font-size: 3vh;
         font-weight: 400
       }
     }
@@ -122,7 +117,11 @@
     border-bottom: 1px solid #AFAFAF;
     background-color: #fff;
   }
-
+  & /deep/ .el-input__inner:focus{
+    border-top-color: #fff;
+    border-left-color: #fff;
+    border-right-color:#fff;
+  }
   & /deep/ .el-form-item__content {
     line-height: 6vh;
     font-size: 2vh;

+ 24 - 37
src/pages/login/index.vue

@@ -10,20 +10,19 @@
             maxlength="11"
             v-model.trim="form.account"
             prefix-icon="el-icon-user"
-            placeholder="请输入"
-            onkeyup="this.value=this.value.replace(/[.]/g,'');"
+            placeholder="请输入账号"
           ></el-input>
         </el-form-item>
         <el-form-item prop="password">
           <el-input
             prefix-icon="el-icon-lock"
-            placeholder="请输入"
+            placeholder="请输入密码"
             v-model="form.password"
             show-password
-            @keyup.enter.native="loginFun"
+            @keyup.enter.native="loginFun('form')"
           ></el-input>
         </el-form-item>
-        <el-button type="primary" class="loginButton" @click="loginFun"
+        <el-button type="primary" class="loginButton" @click="loginFun('form')"
           >登录
         </el-button>
       </el-form>
@@ -37,23 +36,9 @@ import { mapMutations } from 'vuex'
 export default {
   name: 'Login',
   data() {
-    const validateUsername = (rule, value, callback) => {
-      if (!/^1[3456789]\d{9}$/.test(value)) {
-        callback(new Error('请输入正确的手机号'))
-      } else {
-        callback()
-      }
-    }
-    const validateUser = (rule, value, callback) => {
-      if (!/^1[3456789]\d{9}$/.test(value)) {
-        callback(new Error('请输入正确的手机号'))
-      } else {
-        callback()
-      }
-    }
     const validatePass = (rule, value, callback) => {
-      if (value.length < 5) {
-        callback(new Error('密码不能小于5位'))
+      if (value == '') {
+        callback(new Error('密码不能为空'))
       } else {
         callback()
       }
@@ -64,11 +49,9 @@ export default {
         password: ''
       },
       loginRules: {
-        // account: [{ required: true, trigger: 'blur', validator: validateUser }],
-        password: [
-          { required: true, trigger: 'blur', validator: validatePass }
-        ],
-      },
+        account: [{ required: true, trigger: 'blur', message: '账号不能为空' }],
+        password: [{ required: true, trigger: 'blur', validator: validatePass }]
+      }
     }
   },
   mounted() {
@@ -78,17 +61,21 @@ export default {
     ...mapMutations({
       clearRouter: 'permission/ClEAR_LIST'
     }),
-    loginFun() {
-      let params = {
-        account: this.form.account,
-        password: this.form.password ? this.$md5(this.form.password) : ''
-      }
-      login(params).then(res => {
-        localStorage.setItem('Token', res.data.token)
-        localStorage.setItem('userInfo', JSON.stringify(res.data))
-        this.$store.commit('getLoginReturnInformation', res.data)
-        this.$router.push('/index')
-        sessionStorage.setItem('currentPage', '/index')
+    loginFun(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          let params = {
+            account: this.form.account,
+            password: this.form.password
+          }
+          login(params).then(res => {
+            localStorage.setItem('Token', res.data.token)
+            localStorage.setItem('userInfo', JSON.stringify(res.data))
+            this.$store.commit('getLoginReturnInformation', res.data)
+            sessionStorage.setItem('currentPage', '/index')
+            this.$router.push('/index')
+          })
+        }
       })
     }
   }

+ 170 - 0
src/pages/userManagement/components/edit.vue

@@ -0,0 +1,170 @@
+<template>
+  <el-dialog
+    title="修改密码"
+    :visible.sync="dialogVisible"
+    width="33%"
+    :before-close="handleClose"
+    :close-on-press-escape="false"
+    :close-on-click-modal="false"
+    :append-to-body="true"
+    v-loading.fullscreen.lock="fullscreenLoading"
+  >
+    <el-form
+      v-if="dialogVisible"
+      :model="number"
+      ref="number"
+      :rules="rules"
+      label-width="100px"
+      label-position="right"
+    >
+      <el-form-item label prop="oldPassword">
+        <template slot="label" class="status"><span>原密码</span>:</template>
+        <el-input
+          placeholder="请输入原密码"
+          v-model.trim="number.oldPassword"
+          show-password
+          minlength="6"
+          maxlength="18"
+          show-word-limit
+        >
+        </el-input>
+      </el-form-item>
+      <el-form-item label prop="newPassword">
+        <template slot="label" class="status"><span>新密码</span>:</template>
+        <el-input
+          placeholder="请输入新密码"
+          v-model.trim="number.newPassword"
+          show-password
+          minlength="6"
+          maxlength="18"
+          show-word-limit
+        ></el-input>
+      </el-form-item>
+      <el-form-item label prop="password">
+        <template slot="label" class="status"><span>确认密码</span>:</template>
+        <el-input
+          placeholder="请输入确认密码"
+          v-model.trim="number.password"
+          show-password
+          minlength="6"
+          maxlength="18"
+          show-word-limit
+        >
+        </el-input>
+      </el-form-item>
+    </el-form>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="handleClose">取 消</el-button>
+      <el-button
+        size="small"
+        style="margin-left: 60px"
+        type="primary"
+        @click="submit('number')"
+        >确 定</el-button
+      >
+    </span>
+  </el-dialog>
+</template>
+<script>
+import * as api from '@/api/api'
+export default {
+  data() {
+    const validatePass = (rule, value, callback) => {
+      if (value == '') {
+        callback(new Error('原密码不能为空'))
+      } else if (value.length < 6 || value.length > 18) {
+        callback(new Error('密码不能小于6位,大于18位'))
+      } else {
+        callback()
+      }
+    }
+    const validatenewPassword = (rule, value, callback) => {
+      if (value == '') {
+        callback(new Error('新密码不能为空'))
+      } else if (value.length < 6 || value.length > 18) {
+        callback(new Error('密码不能小于6位,大于18位'))
+      } else {
+        callback()
+      }
+    }
+    const validatenewPass = (rule, value, callback) => {
+      if (value == '') {
+        callback(new Error('确认密码不能为空'))
+      } else if (value != this.number.newPassword) {
+        callback(new Error('确认密码与新密码不一致'))
+      } else {
+        callback()
+      }
+    }
+    return {
+      fullscreenLoading: false,
+      dialogVisible: false,
+      number: {
+        account: JSON.parse(localStorage.getItem('userInfo')).account,
+        newPassword: '',
+        oldPassword: '',
+        password: ''
+      },
+      id: '',
+      rules: {
+        oldPassword: [
+          { required: true, trigger: 'blur', validator: validatePass }
+        ],
+        newPassword: [
+          { required: true, trigger: 'blur', validator: validatenewPassword }
+        ],
+        password: [
+          { required: true, trigger: 'blur', validator: validatenewPass }
+        ]
+      }
+    }
+  },
+  methods: {
+    handleClose() {
+      this.dialogVisible = false
+      this.$refs['number'].resetFields()
+    },
+    openClose() {
+      this.dialogVisible = true
+    },
+    /**
+     * @method 确定提交
+     * **/
+    submit(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          this.fullscreenLoading = true
+          let code = {
+            account: this.number.account,
+            newPassword: this.number.newPassword,
+            oldPassword: this.number.oldPassword,
+            password: this.number.password
+          }
+          api
+            .POST('/update', code)
+            .then(res => {
+              if (res.code == 0) {
+                this.handleClose()
+                this.$message.success(res.message)
+                this.fullscreenLoading = false
+              }
+            })
+            .catch(() => {
+              this.fullscreenLoading = false
+            })
+        }
+      })
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+// .status {
+//   padding: 0 12px 0 0;
+// }
+// .status::before {
+//   content: '*';
+//   color: #f56c6c;
+//   margin-right: 4px;
+// }
+</style>

+ 88 - 18
src/pages/userManagement/detail.vue

@@ -4,51 +4,121 @@
     :visible.sync="dialogVisible"
     width="33%"
     :before-close="handleClose"
+    :close-on-press-escape="false"
+    :close-on-click-modal="false"
+    :append-to-body="true"
+    v-loading.fullscreen.lock="fullscreenLoading"
   >
-    <el-form>
-      <el-form-item >
-        <label solt="label" class="status"
-          ><span>密   码</span>:</label
+    <el-form :model="number" ref="number" :rules="rules" label-width="100px">
+      <el-form-item label prop="password">
+        <template slot="label" class="status"
+          ><span>密&#8195;&emsp;码</span>:</template
         >
-        <el-input placeholder="请输入"></el-input>
+        <el-input
+          :type="type"
+          placeholder="请输入"
+          v-model.trim="number.password"
+          autocomplete="off"
+          minlength="6"
+          maxlength="18"
+          show-word-limit
+          readonly
+          @focus="focus"
+          onfocus="this.removeAttribute('readonly')"
+        >
+          <template slot="suffix">
+            <span class="el-icon-view" @click="elIconView"> </span>
+          </template>
+        </el-input>
       </el-form-item>
     </el-form>
     <span slot="footer" class="dialog-footer">
-      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" @click="handleClose">取 消</el-button>
       <el-button
         size="small"
         style="margin-left: 60px"
         type="primary"
-        @click="dialogVisible = false"
+        @click="submit('number')"
         >确 定</el-button
       >
     </span>
   </el-dialog>
 </template>
 <script>
+import * as api from '@/api/api'
 export default {
   data() {
+    const validatePass = (rule, value, callback) => {
+      if (value == '') {
+        callback(new Error('密码不能为空'))
+      } else if (value.length < 6 || value.length > 18) {
+        callback(new Error('密码不能小于6位'))
+      } else {
+        callback()
+      }
+    }
     return {
-      dialogVisible: false
+      type: 'text',
+      readonlsy: true,
+      fullscreenLoading: false,
+      dialogVisible: false,
+      number: {
+        password: ''
+      },
+      id: '',
+      rules: {
+        password: [{ required: true, trigger: 'blur', validator: validatePass }]
+      }
     }
   },
   methods: {
+    elIconView() {
+      this.type == 'password' ? (this.type = 'text') : (this.type = 'password')
+    },
+    focus() {
+      this.number.password==''? this.type='password':''
+      if(this.number.password!==''&&this.type=='text'){
+        this.type = 'text'
+      }
+    },
     handleClose() {
+      this.type = 'text'
       this.dialogVisible = false
+      this.$parent.search()
+      this.$refs['number'].resetFields()
     },
-    openClose() {
+    openClose(val) {
       this.dialogVisible = true
+      this.id = val.id
+    },
+    /**
+     * @method 确定提交
+     * **/
+    submit(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          this.fullscreenLoading = true
+          let code = {
+            id: this.id,
+            password: this.number.password
+          }
+          api
+            .PUT('/user/resetPassword', code)
+            .then(res => {
+              if (res.code == 0) {
+                this.handleClose()
+                this.$message.success(res.message)
+                this.fullscreenLoading = false
+              }
+            })
+            .catch(() => {
+              this.fullscreenLoading = false
+            })
+        }
+      })
     }
   }
 }
 </script>
-<style lang="less" scoped>
-.status {
-  padding: 0 12px 0 0;
-}
-.status::before {
-  content: '*';
-  color: #f56c6c;
-  margin-right: 4px;
-}
+<style lang="less">
 </style>

+ 158 - 22
src/pages/userManagement/edit.vue

@@ -1,61 +1,197 @@
 <template>
   <el-dialog
-    title="提示"
+    :title="title"
     :visible.sync="dialogVisible"
     width="33%"
     :before-close="handleClose"
+    :close-on-press-escape="false"
+    :close-on-click-modal="false"
+    :append-to-body="true"
+    v-loading.fullscreen.lock="fullscreenLoading"
   >
-    <el-form>
-      <el-form-item >
-        <label solt="label" class="status"
-          ><span >账   号</span>:</label
+    <el-form ref="form" :model="form" label-width="100px" :rules="rules">
+      <el-form-item prop="account">
+        <template slot="label" class="status"
+          ><span>账&#8195;&emsp;号</span>:</template
         >
-        <el-input></el-input>
+        <el-input
+          placeholder="请输入"
+          v-model.trim="form.account"
+          maxlength="32"
+          show-word-limit
+        ></el-input>
       </el-form-item>
-      <el-form-item >
-        <label solt="label" class="status"
-          ><span >姓   名</span>:</label
+      <el-form-item prop="name">
+        <template slot="label" class="status"
+          ><span>姓&#8195;&emsp;名</span>:</template
         >
-        <el-input></el-input>
+        <el-input
+          type="text"
+          placeholder="请输入"
+          v-model.trim="form.name"
+          maxlength="32"
+          show-word-limit
+        ></el-input>
       </el-form-item>
-      <el-form-item >
-        <label solt="label" class="status"
-          ><span>密   码</span>:</label
+      <el-form-item prop="password" v-if="userString.show">
+        <template slot="label" class="status"
+          ><span>密&#8195;&emsp;码</span>:</template
         >
-        <el-input></el-input>
+        <el-input
+          autoComplete="new-password"
+          show-password
+          placeholder="请输入"
+          v-model.trim="form.password"
+          minlength="6"
+          maxlength="18"
+          show-word-limit
+        ></el-input>
       </el-form-item>
-      <el-form-item label="状   态:">
-        <el-radio-group v-model="radio">
-          <el-radio :label="3">启用</el-radio>
-          <el-radio :label="6">禁用</el-radio>
+      <el-form-item label prop="status">
+        <template slot="label" class="status"
+          ><span>状&#8195;&emsp;态</span>:</template
+        >
+        <el-radio-group v-model="form.status">
+          <el-radio :label="1">启用</el-radio>
+          <el-radio :label="0">禁用</el-radio>
         </el-radio-group>
       </el-form-item>
     </el-form>
     <span slot="footer" class="dialog-footer">
-      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" @click="handleClose">取 消</el-button>
       <el-button
         size="small"
         style="margin-left: 60px"
         type="primary"
-        @click="dialogVisible = false"
+        @click="addList('form')"
         >确 定</el-button
       >
     </span>
   </el-dialog>
 </template>
 <script>
+import * as api from '@/api/api'
 export default {
   data() {
+    const validatePass = (rule, value, callback) => {
+      if (value == '') {
+        callback(new Error('密码不能为空'))
+      } else if (value.length < 6 || value.length > 18) {
+        callback(new Error('密码不能小于6位'))
+      } else {
+        callback()
+      }
+    }
     return {
-      dialogVisible: false
+      fullscreenLoading: false,
+      dialogVisible: false,
+      radio: '',
+      title: '',
+      form: {
+        account: '',
+        name: '',
+        password: '',
+        status: 1,
+        userId: ''
+      },
+      userString: {},
+      rules: {
+        account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
+        name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
+        password: [{ required: true, trigger: 'blur', validator: validatePass }]
+      }
     }
   },
   methods: {
     handleClose() {
       this.dialogVisible = false
+      this.$parent.search()
+      this.form = {
+        account: '',
+        name: '',
+        password: '',
+        status: 1,
+        userId: ''
+      }
+      this.$refs['form'].resetFields()
     },
-    openClose() {
+    openClose(val) {
+      this.title = val.title
+      if (val) {
+        this.userString = val
+        if (val.id) {
+          this.detail()
+        }
+      }
+
       this.dialogVisible = true
+    },
+    /**
+     * @method 用户确定
+     * **/
+    addList(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          this.fullscreenLoading = true
+          let code = {
+            account: this.form.account,
+            name: this.form.name,
+            password: this.form.password,
+            status: this.form.status
+          }
+          this.userString.show
+            ? this.addListData(code)
+            : this.editListData(code)
+        }
+      })
+    },
+    /**
+     * @method 详情
+     * **/
+    detail() {
+      const code = {
+        id: this.userString.id
+      }
+      api.GET('/user/detail', code).then(data => {
+        if (data.code == 0) {
+          this.form = data.data
+        }
+      })
+    },
+    /**
+     * @method 新增
+     * **/
+    addListData(val) {
+      api
+        .POST('/user/add', val)
+        .then(data => {
+          if (data.code == 0) {
+            this.handleClose()
+            this.$message.success(data.message)
+            this.fullscreenLoading = false
+          }
+        })
+        .catch(() => {
+          this.fullscreenLoading = false
+        })
+    },
+    /**
+     * @method 编辑
+     * **/
+    editListData(val) {
+      val.userId = this.form.userId
+      api
+        .POST('/user/update', val)
+        .then(data => {
+          if (data.code == 0) {
+            this.handleClose()
+            this.$message.success(data.message)
+            this.fullscreenLoading = false
+          }
+        })
+        .catch(() => {
+          this.fullscreenLoading = false
+        })
     }
   }
 }

+ 251 - 97
src/pages/userManagement/index.vue

@@ -1,85 +1,128 @@
 <template>
-  <div v-loading.fullscreen.lock="fullscreenLoading" class="userManagement_list">
-      <div class="userManagement_list_headerSelect">
-        <el-form
-        slot="form"
-        style="display: inline"
-        inline
-        :addList="true"
-      >
-        <el-form-item label="分类名称:">
-          <el-input size="small"></el-input>
-        </el-form-item>
-        <el-form-item label="状态:">
-          <el-input size="small"></el-input>
-        </el-form-item>
-        <el-form-item>
-          <el-button size="small" type="primary" style="width:88px" >查询</el-button>
-        </el-form-item>
-      </el-form>
-      <el-button size="small" style="width:104px;margin-right:23px">新增</el-button>
+  <div
+    v-loading.fullscreen.lock="fullscreenLoading"
+    class="userManagement_list"
+  >
+    <div class="userManagement_list_headerSelect">
+      <div class="userManagement-list-btn">
+        <el-form :model="form" ref="form" style="display: inline" inline>
+          <el-form-item class="header_top_form" label="账号:" prop="account">
+            <el-input
+              placeholder="请输入"
+              size="small"
+              v-model.trim="form.account"
+              clearable
+            ></el-input>
+          </el-form-item>
+          <el-form-item class="header_top_form" label="姓名:" prop="name">
+            <el-input
+              placeholder="请输入"
+              size="small"
+              v-model.trim="form.name"
+              clearable
+            ></el-input>
+          </el-form-item>
+        </el-form>
+        <div style="margin-right: 23px">
+          <el-button
+            size="small"
+            type="primary"
+            style="width: 88px"
+            @click="search"
+            >查询</el-button
+          >
+          <el-button size="small" style="width: 88px" @click="resetForm('form')"
+            >重置</el-button
+          >
+        </div>
+      </div>
+      <div style="text-align: right">
+        <el-button
+          size="small"
+          style="width: 104px; margin-right: 23px"
+          icon="iconfont icon-a-zu13"
+          @click="addList"
+          >新增</el-button
+        >
+      </div>
     </div>
-    <el-table
-      :data="tableData"
-      style="width: 100%"
-      stripe
-      :header-cell-style="{ background: '#F7F7F7' }"
-    >
-      <el-table-column
-        v-for="(item, index) in listData"
-        :key="index"
-        :label="item.name"
-        :prop="item.value"
-        :width="item.width"
-        :min-width="item.minWidth"
-        :align="item.align"
+    <div>
+      <el-table
+        :data="tableData"
+        ref="editTable"
+        stripe
+        :header-cell-style="{ background: '#F7F7F7' }"
+        :height="screenHeight"
       >
-        <template slot-scope="scope">
-          <div>
-            <div v-if="item.value == 'status'">
-              <el-switch
-                v-model="scope.row[scope.column.property]"
-                active-color="#17A8FF"
-                inactive-color="#AFAFAF"
+        <el-table-column
+          label="账号"
+          prop="account"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column
+          label="姓名"
+          prop="name"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column label="禁用/启用" prop="status" align="center">
+          <template slot-scope="scope">
+            <div>
+              <div>
+                <el-switch
+                  v-model="scope.row.status"
+                  active-color="#17A8FF"
+                  inactive-color="#AFAFAF"
+                  @change="statusChange($event, scope.row)"
+                >
+                </el-switch>
+              </div>
+            </div> </template
+        ></el-table-column>
+        <el-table-column
+          label="创建时间"
+          prop="createTime"
+          align="center"
+          show-overflow-tooltip
+        ></el-table-column>
+        <el-table-column label="操作" width="140px" align="center">
+          <template slot-scope="scope">
+            <div>
+              <el-button type="text" @click="edit(scope.row)">编辑</el-button>
+              <el-button
+                type="text"
+                @click="resetPasswords(scope.row)"
+                style="color: #f4453e"
+                >重置密码</el-button
               >
-              </el-switch>
-            </div>
-            <div v-else>
-              {{ scope.row[scope.column.property] }}
             </div>
-          </div>
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" align="center">
-        <template slot-scope="scope">
-          <div>
-            <el-button type="text" @click="edit(scope.row)">编辑</el-button>
-            <el-button type="text" @click="resetPasswords(scope.row)">重置密码</el-button>
-          </div>
-        </template>
-      </el-table-column>
-    </el-table>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
     <el-pagination
       @size-change="handleSizeChange"
       @current-change="handleCurrentChange"
       :current-page="form.pageNum"
       :page-sizes="[100, 200, 300, 400]"
-      :page-size="10"
+      :page-size="form.pageSize"
       background
       layout="total,prev, pager, next,jumper"
-      :total="100"
+      :total="form.total"
     >
     </el-pagination>
-    <editDialog ref="editDialogRefs"/>
-    <detailDialog ref="detailDialogRefs"/>
+    <editDialog ref="editDialogRefs" />
+    <detailDialog ref="detailDialogRefs" />
   </div>
 </template>
 <script>
 import editDialog from './edit'
 import detailDialog from './detail'
+import * as api from '@/api/api'
 export default {
   name: 'userManagement',
-  components:{
+  components: {
     editDialog,
     detailDialog
   },
@@ -87,46 +130,150 @@ export default {
     return {
       fullscreenLoading: false,
       tableData: [],
-      listData: [
-        { name: '账号', value: '', width: '', minWidth: '', align: 'center' },
-        { name: '姓名', value: '', width: '', minWidth: '', align: 'center' },
-        {
-          name: '禁用/启用',
-          value: '',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        },
-        {
-          name: '创建时间',
-          value: '',
-          width: '',
-          minWidth: '',
-          align: 'center'
-        }
-      ],
       form: {
-        pageNum: 4
-      }
+        pageNum: 1,
+        pageSize: 10,
+        account: '',
+        name: '',
+        start: '',
+        total: 0
+      },
+      screenHeight: document.body.clientHeight - 320,
+      tableDataheight: 0
     }
   },
   mounted() {
-    this.$nextTick(()=>{
-      this.tableData = [
-        {}
-      ]
-    })
+    this.screenHeight = document.body.clientHeight - 320
+    window.onresize = () => {
+      return (() => {
+        this.screenHeight = document.body.clientHeight - 320
+      })()
+    }
+    this.listDataInit()
   },
   methods: {
-    handleSizeChange() {},
-    handleCurrentChange() {},
+    /**
+     * @method 重置
+     * **/
+    resetForm(formName) {
+      this.$refs[formName].resetFields()
+      this.search()
+    },
+    /**
+     * @method 搜索
+     * **/
+    search() {
+      if (sessionStorage.getItem('usermanage')) {
+        this.form.pageNum = Number(sessionStorage.getItem('usermanage'))
+        sessionStorage.removeItem('usermanage')
+      } else {
+        this.form.pageNum = 1
+      }
+
+      this.listDataInit()
+    },
+    /**
+     * @method 用户数据列表
+     * **/
+    listDataInit() {
+      this.tableData = []
+      this.fullscreenLoading = true
+      let code = {
+        account: this.form.account,
+        name: this.form.name,
+        page: this.form.pageNum,
+        pageSize: this.form.pageSize,
+        start: this.form.start
+      }
+      api
+        .GET('/user/list', code)
+        .then(res => {
+          if (res.code == 0) {
+            this.tableData = res.data.list
+            this.tableData.forEach(item => {
+              item.status == 1 ? (item.status = true) : (item.status = false)
+            })
+            this.form.pageNum = res.data.currPage
+            this.form.pageSize = res.data.pageSize
+            this.form.total = res.data.totalCount
+            this.fullscreenLoading = false
+            this.$nextTick(() => {
+              this.$refs.editTable.bodyWrapper.scrollTop = this.tableDataheight
+              this.tableDataheight = 0
+            })
+          }
+        })
+        .catch(() => {
+          this.fullscreenLoading = false
+        })
+    },
+    /**
+     * @method 条数分页
+     * **/
+    handleSizeChange(val) {
+      this.form.pageSize = val
+      this.form.pageNum = 1
+      this.listDataInit()
+    },
+    /**
+     * @method 分页
+     * **/
+    handleCurrentChange(val) {
+      this.form.pageNum = val
+      this.listDataInit()
+    },
+    /**
+     * @method 新增
+     * **/
+    addList() {
+      let code = {
+        title: '新增用户',
+        show: true
+      }
+      this.$refs.editDialogRefs.openClose(code)
+    },
     // 编辑
-    edit(){
-      this.$refs.editDialogRefs.openClose()
+    edit(val) {
+      this.tableDataheight = this.$refs.editTable.bodyWrapper.scrollTop
+      sessionStorage.setItem('usermanage', this.form.pageNum)
+      let code = {
+        title: '编辑用户',
+        show: false,
+        id: val.userId
+      }
+      this.$refs.editDialogRefs.openClose(code)
     },
     // 重置密码
-    resetPasswords(){
-      this.$refs.detailDialogRefs.openClose()
+    resetPasswords(val) {
+      this.tableDataheight = this.$refs.editTable.bodyWrapper.scrollTop
+      sessionStorage.setItem('usermanage', this.form.pageNum)
+      let code = {
+        id: val.userId
+      }
+      this.$refs.detailDialogRefs.openClose(code)
+    },
+    /**
+     * @method 状态修改
+     * **/
+    statusChange(val, item) {
+      this.tableDataheight = this.$refs.editTable.bodyWrapper.scrollTop
+      sessionStorage.setItem('usermanage', this.form.pageNum)
+      val ? (val = 1) : (val = 0)
+      let code = {
+        id: item.userId,
+        status: val
+      }
+      api
+        .PUT('/user/updateSwitch', code)
+        .then(data => {
+          if (data.code == 0) {
+            this.search()
+            this.$message.success(data.message)
+          }
+        })
+        .catch(() => {
+          this.search()
+        })
     }
   }
 }
@@ -134,12 +281,15 @@ export default {
 <style lang="less">
 .userManagement_list {
   .userManagement_list_headerSelect {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 32px;
+    .userManagement-list-btn {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 10px;
+    }
+    margin-bottom: 20px;
     .el-form-item {
-      margin-bottom: 0;
+      margin-bottom: 10px;
       margin-right: 60px;
       .el-input__inner {
         background: #f5f5f5;
@@ -147,6 +297,10 @@ export default {
         border-radius: 17px;
       }
     }
+    .icon-a-zu13 {
+      font-size: 11px;
+      margin-right: 5px;
+    }
   }
 }
 </style>

+ 2 - 9
src/router/index.js

@@ -31,14 +31,7 @@ router.beforeEach(async (to, from, next) => {
           let flag = ruleValidate(accessRoutes, to.path)
           if (flag) {
             next({ ...to, replace: true })
-          } else {
-            Message({
-              showClose: true,
-              message: '当前路由没有权限',
-              type: 'error'
-            })
-            next({ ...accessRoutes[0], replace: true })
-          }
+          } 
         } catch (err) {
           if (err.code != '0') {
             next({
@@ -47,7 +40,7 @@ router.beforeEach(async (to, from, next) => {
           }
         }
       } else {
-        store.dispatch('permission/FETCH_AUTHORID')
+        // store.dispatch('permission/FETCH_AUTHORID')
         next()
       }
     } else {

+ 3 - 3
src/router/routes.js

@@ -20,7 +20,7 @@ export const appRouter = [{
     path: '/index',
     meta: {
       title: '分类管理',
-      icon: 'el-icon-files'
+      icon: 'icon-a-lujing3'
     },
     component: () => import('@/pages/classification')
   },
@@ -31,7 +31,7 @@ export const appRouter = [{
     path: '/fileManagement',
     meta: {
       title: '文件管理',
-      icon: 'el-icon-folder-opened'
+      icon: 'icon-a-zu8'
     },
     component: () => import('@/pages/fileManagement')
   },
@@ -42,7 +42,7 @@ export const appRouter = [{
     path: '/userManagement',
     meta: {
       title: '用户管理',
-      icon: 'el-icon-s-custom'
+      icon: 'icon-a-zu10'
     },
     component: () => import('@/pages/userManagement')
   }

+ 5 - 19
src/store/permission.js

@@ -1,4 +1,4 @@
-import { getAuth } from '@/api/login'
+// import { getAuth } from '@/api/login'
 import { appRouter, loginRouter } from '../router/routes'
 const state = {
   permissionList: null,
@@ -28,29 +28,15 @@ const actions = {
   FETCH_PERMISSION({ commit }) {
     let allRoutes = clone(appRouter)
     return new Promise((resolve, reject) => {
-      getAuth()
-        .then(res => {
-          let routesData = []
-          let permissionList = res.data
-          commit('SET_AUTHORID', permissionList)
-          let authorityIds = [0, ...permissionList]
-          authorityIds.forEach(item => {
-            getNodeById(allRoutes, item, routesData)
-          })
-          getFilterNode(allRoutes)
           commit('SET_ROUTES', allRoutes)
           resolve(allRoutes)
-        })
-        .catch(err => {
-          reject(err)
-        })
     })
   },
   FETCH_AUTHORID({ commit }) {
-    getAuth().then(res => {
-      let authorIds = res.data
-      commit('SET_AUTHORID', authorIds)
-    })
+    // getAuth().then(res => {
+    //   let authorIds = res.data
+    //   commit('SET_AUTHORID', authorIds)
+    // })
   }
 }
 function clone(obj) {

+ 4 - 4
src/utils/pubFun.js

@@ -42,20 +42,20 @@ let pubFun = {
                 if (typeof window.navigator.msSaveBlob !== 'undefined') {
                   window.navigator.msSaveBlob(
                     new Blob([response], {
-                      type: 'application/vnd.ms-excel'
+                      type: 'application/pdf'
                     }),
-                    fileName + '.xlsx'
+                    fileName + '.pdf'
                   )
                 } else {
                   let url = window.URL.createObjectURL(
                     new Blob([response], {
-                      type: 'application/vnd.ms-excel'
+                      type: 'application/pdf'
                     })
                   )
                   let link = document.createElement('a')
                   link.style.display = 'none'
                   link.href = url
-                  link.setAttribute('download', fileName + '.xlsx')
+                  link.setAttribute('download', fileName + '.pdf')
                   document.body.appendChild(link)
                   link.click()
                   document.body.removeChild(link)

+ 539 - 0
static/font_hsy/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

+ 418 - 0
static/font_hsy/demo_index.html

@@ -0,0 +1,418 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <title>iconfont Demo</title>
+  <link rel="shortcut icon" href="//img.alicdn.com/imgextra/i2/O1CN01ZyAlrn1MwaMhqz36G_!!6000000001499-73-tps-64-64.ico" type="image/x-icon"/>
+  <link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01EYTRnJ297D6vehehJ_!!6000000008020-55-tps-64-64.svg"/>
+  <link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
+  <link rel="stylesheet" href="demo.css">
+  <link rel="stylesheet" href="iconfont.css">
+  <script src="iconfont.js"></script>
+  <!-- jQuery -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
+  <!-- 代码高亮 -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
+  <style>
+    .main .logo {
+      margin-top: 0;
+      height: auto;
+    }
+
+    .main .logo a {
+      display: flex;
+      align-items: center;
+    }
+
+    .main .logo .sub-title {
+      margin-left: 0.5em;
+      font-size: 22px;
+      color: #fff;
+      background: linear-gradient(-45deg, #3967FF, #B500FE);
+      -webkit-background-clip: text;
+      -webkit-text-fill-color: transparent;
+    }
+  </style>
+</head>
+<body>
+  <div class="main">
+    <h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
+      <img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
+      
+    </a></h1>
+    <div class="nav-tabs">
+      <ul id="tabs" class="dib-box">
+        <li class="dib active"><span>Unicode</span></li>
+        <li class="dib"><span>Font class</span></li>
+        <li class="dib"><span>Symbol</span></li>
+      </ul>
+      
+      <a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=2880374" target="_blank" class="nav-more">查看项目</a>
+      
+    </div>
+    <div class="tab-container">
+      <div class="content unicode" style="display: block;">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe619;</span>
+                <div class="name">组 904</div>
+                <div class="code-name">&amp;#xe619;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe618;</span>
+                <div class="name">组 903</div>
+                <div class="code-name">&amp;#xe618;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe616;</span>
+                <div class="name">组 829</div>
+                <div class="code-name">&amp;#xe616;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe617;</span>
+                <div class="name">组 850</div>
+                <div class="code-name">&amp;#xe617;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe614;</span>
+                <div class="name">组 3</div>
+                <div class="code-name">&amp;#xe614;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe615;</span>
+                <div class="name">组 10</div>
+                <div class="code-name">&amp;#xe615;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe610;</span>
+                <div class="name">组 13</div>
+                <div class="code-name">&amp;#xe610;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe611;</span>
+                <div class="name">路径 3</div>
+                <div class="code-name">&amp;#xe611;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe612;</span>
+                <div class="name">组 8</div>
+                <div class="code-name">&amp;#xe612;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe613;</span>
+                <div class="name">组 1</div>
+                <div class="code-name">&amp;#xe613;</div>
+              </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="unicode-">Unicode 引用</h2>
+          <hr>
+
+          <p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
+          <ul>
+            <li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
+            <li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
+          </ul>
+          <blockquote>
+            <p>注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
+          </blockquote>
+          <p>Unicode 使用步骤如下:</p>
+          <h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
+<pre><code class="language-css"
+>@font-face {
+  font-family: 'iconfont';
+  src: url('iconfont.woff2?t=1635484775543') format('woff2'),
+       url('iconfont.woff?t=1635484775543') format('woff'),
+       url('iconfont.ttf?t=1635484775543') format('truetype');
+}
+</code></pre>
+          <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
+<pre><code class="language-css"
+>.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
+<pre>
+<code class="language-html"
+>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
+</code></pre>
+          <blockquote>
+            <p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+          </blockquote>
+          </div>
+      </div>
+      <div class="content font-class">
+        <ul class="icon_lists dib-box">
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-zu904"></span>
+            <div class="name">
+              组 904
+            </div>
+            <div class="code-name">.icon-a-zu904
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-zu903"></span>
+            <div class="name">
+              组 903
+            </div>
+            <div class="code-name">.icon-a-zu903
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-zu829"></span>
+            <div class="name">
+              组 829
+            </div>
+            <div class="code-name">.icon-a-zu829
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-zu850"></span>
+            <div class="name">
+              组 850
+            </div>
+            <div class="code-name">.icon-a-zu850
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-zu3"></span>
+            <div class="name">
+              组 3
+            </div>
+            <div class="code-name">.icon-a-zu3
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-zu10"></span>
+            <div class="name">
+              组 10
+            </div>
+            <div class="code-name">.icon-a-zu10
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-zu13"></span>
+            <div class="name">
+              组 13
+            </div>
+            <div class="code-name">.icon-a-zu13
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-lujing3"></span>
+            <div class="name">
+              路径 3
+            </div>
+            <div class="code-name">.icon-a-lujing3
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-zu8"></span>
+            <div class="name">
+              组 8
+            </div>
+            <div class="code-name">.icon-a-zu8
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-zu1"></span>
+            <div class="name">
+              组 1
+            </div>
+            <div class="code-name">.icon-a-zu1
+            </div>
+          </li>
+          
+        </ul>
+        <div class="article markdown">
+        <h2 id="font-class-">font-class 引用</h2>
+        <hr>
+
+        <p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
+        <p>与 Unicode 使用方式相比,具有如下特点:</p>
+        <ul>
+          <li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
+          <li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
+        </ul>
+        <p>使用步骤如下:</p>
+        <h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
+<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
+</code></pre>
+        <h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
+</code></pre>
+        <blockquote>
+          <p>"
+            iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+        </blockquote>
+      </div>
+      </div>
+      <div class="content symbol">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-zu904"></use>
+                </svg>
+                <div class="name">组 904</div>
+                <div class="code-name">#icon-a-zu904</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-zu903"></use>
+                </svg>
+                <div class="name">组 903</div>
+                <div class="code-name">#icon-a-zu903</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-zu829"></use>
+                </svg>
+                <div class="name">组 829</div>
+                <div class="code-name">#icon-a-zu829</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-zu850"></use>
+                </svg>
+                <div class="name">组 850</div>
+                <div class="code-name">#icon-a-zu850</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-zu3"></use>
+                </svg>
+                <div class="name">组 3</div>
+                <div class="code-name">#icon-a-zu3</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-zu10"></use>
+                </svg>
+                <div class="name">组 10</div>
+                <div class="code-name">#icon-a-zu10</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-zu13"></use>
+                </svg>
+                <div class="name">组 13</div>
+                <div class="code-name">#icon-a-zu13</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-lujing3"></use>
+                </svg>
+                <div class="name">路径 3</div>
+                <div class="code-name">#icon-a-lujing3</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-zu8"></use>
+                </svg>
+                <div class="name">组 8</div>
+                <div class="code-name">#icon-a-zu8</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-zu1"></use>
+                </svg>
+                <div class="name">组 1</div>
+                <div class="code-name">#icon-a-zu1</div>
+            </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="symbol-">Symbol 引用</h2>
+          <hr>
+
+          <p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
+            这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
+          <ul>
+            <li>支持多色图标了,不再受单色限制。</li>
+            <li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
+            <li>兼容性较差,支持 IE9+,及现代浏览器。</li>
+            <li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
+          </ul>
+          <p>使用步骤如下:</p>
+          <h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
+<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
+</code></pre>
+          <h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
+<pre><code class="language-html">&lt;style&gt;
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+&lt;/style&gt;
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
+  &lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
+&lt;/svg&gt;
+</code></pre>
+          </div>
+      </div>
+
+    </div>
+  </div>
+  <script>
+  $(document).ready(function () {
+      $('.tab-container .content:first').show()
+
+      $('#tabs li').click(function (e) {
+        var tabContent = $('.tab-container .content')
+        var index = $(this).index()
+
+        if ($(this).hasClass('active')) {
+          return
+        } else {
+          $('#tabs li').removeClass('active')
+          $(this).addClass('active')
+
+          tabContent.hide().eq(index).fadeIn()
+        }
+      })
+    })
+  </script>
+</body>
+</html>

+ 55 - 0
static/font_hsy/iconfont.css

@@ -0,0 +1,55 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 2880374 */
+  src: url('iconfont.woff2?t=1635484775543') format('woff2'),
+       url('iconfont.woff?t=1635484775543') format('woff'),
+       url('iconfont.ttf?t=1635484775543') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-a-zu904:before {
+  content: "\e619";
+}
+
+.icon-a-zu903:before {
+  content: "\e618";
+}
+
+.icon-a-zu829:before {
+  content: "\e616";
+}
+
+.icon-a-zu850:before {
+  content: "\e617";
+}
+
+.icon-a-zu3:before {
+  content: "\e614";
+}
+
+.icon-a-zu10:before {
+  content: "\e615";
+}
+
+.icon-a-zu13:before {
+  content: "\e610";
+}
+
+.icon-a-lujing3:before {
+  content: "\e611";
+}
+
+.icon-a-zu8:before {
+  content: "\e612";
+}
+
+.icon-a-zu1:before {
+  content: "\e613";
+}
+

文件差异内容过多而无法显示
+ 1 - 0
static/font_hsy/iconfont.js


+ 79 - 0
static/font_hsy/iconfont.json

@@ -0,0 +1,79 @@
+{
+  "id": "2880374",
+  "name": "沪上阿姨",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "25285617",
+      "name": "组 904",
+      "font_class": "a-zu904",
+      "unicode": "e619",
+      "unicode_decimal": 58905
+    },
+    {
+      "icon_id": "25285616",
+      "name": "组 903",
+      "font_class": "a-zu903",
+      "unicode": "e618",
+      "unicode_decimal": 58904
+    },
+    {
+      "icon_id": "25095667",
+      "name": "组 829",
+      "font_class": "a-zu829",
+      "unicode": "e616",
+      "unicode_decimal": 58902
+    },
+    {
+      "icon_id": "25095668",
+      "name": "组 850",
+      "font_class": "a-zu850",
+      "unicode": "e617",
+      "unicode_decimal": 58903
+    },
+    {
+      "icon_id": "25068452",
+      "name": "组 3",
+      "font_class": "a-zu3",
+      "unicode": "e614",
+      "unicode_decimal": 58900
+    },
+    {
+      "icon_id": "25068453",
+      "name": "组 10",
+      "font_class": "a-zu10",
+      "unicode": "e615",
+      "unicode_decimal": 58901
+    },
+    {
+      "icon_id": "25068448",
+      "name": "组 13",
+      "font_class": "a-zu13",
+      "unicode": "e610",
+      "unicode_decimal": 58896
+    },
+    {
+      "icon_id": "25068449",
+      "name": "路径 3",
+      "font_class": "a-lujing3",
+      "unicode": "e611",
+      "unicode_decimal": 58897
+    },
+    {
+      "icon_id": "25068450",
+      "name": "组 8",
+      "font_class": "a-zu8",
+      "unicode": "e612",
+      "unicode_decimal": 58898
+    },
+    {
+      "icon_id": "25068451",
+      "name": "组 1",
+      "font_class": "a-zu1",
+      "unicode": "e613",
+      "unicode_decimal": 58899
+    }
+  ]
+}

二进制
static/font_hsy/iconfont.ttf


二进制
static/font_hsy/iconfont.woff


二进制
static/font_hsy/iconfont.woff2


+ 12 - 8
vue.config.js

@@ -13,6 +13,10 @@ module.exports = {
   css: {
     requireModuleExtension: true
   },
+  devServer: {
+    port: 8888, // 端口
+    open: true, // 启动后打开浏览器
+  },
   chainWebpack: config => {
     //最小化代码
     config.optimization.minimize(true)
@@ -21,14 +25,14 @@ module.exports = {
       chunks: 'all'
     })
     // //压缩图片
-    config.module
-      .rule('images')
-      .use('image-webpack-loader')
-      .loader('image-webpack-loader')
-      .options({
-        bypassOnDebug: true
-      })
-      .end()
+    // config.module
+    //   .rule('images')
+    //   .use('image-webpack-loader')
+    //   .loader('image-webpack-loader')
+    //   .options({
+    //     bypassOnDebug: true
+    //   })
+    //   .end()
     //set svg-sprite-loader
     config.module.rule('svg').exclude.add(resolve('src/icon')).end()
     config.module