From 36b71142347dc524e18fa24c5ffdffff0d02287a Mon Sep 17 00:00:00 2001
From: long <515897141@qq.com>
Date: 星期二, 02 二月 2021 18:56:28 +0800
Subject: [PATCH] 优化列表、回到顶部组件、优化样式

---
 src/pages/login/index.vue                 |   31 +
 src/directive/el-drag-dialog/drag.js      |   77 +++++
 src/config/baseConfig.js                  |    6 
 src/directive/el-drag-dialog/index.js     |   13 
 src/pages/system/roleEdit.vue             |    4 
 src/components/BackToTop/index.vue        |  111 +++++++
 src/pages/demo/list.vue                   |  319 ++++++++++++++++++++++
 src/pages/system/basic.vue                |    2 
 src/pages/system/roleAdd.vue              |    4 
 src/pages/system/role.vue                 |    1 
 src/main.js                               |    4 
 src/pages/demo/index.vue                  |    9 
 src/pages/system/admin.vue                |   12 
 src/components_simple/jun_serveLabels.vue |    1 
 src/pages/demo/form.vue                   |   33 +
 src/assets/imgs/loginBg.jpg               |    0 
 src/router/demo_router.js                 |    6 
 src/components/HeaderSearch/index.vue     |  180 ++++++++++++
 src/pages/op/index.vue                    |    1 
 src/pages/system/banner.vue               |   10 
 20 files changed, 782 insertions(+), 42 deletions(-)

diff --git a/src/assets/imgs/loginBg.jpg b/src/assets/imgs/loginBg.jpg
new file mode 100644
index 0000000..9ee313e
--- /dev/null
+++ b/src/assets/imgs/loginBg.jpg
Binary files differ
diff --git a/src/components/BackToTop/index.vue b/src/components/BackToTop/index.vue
new file mode 100644
index 0000000..36522f4
--- /dev/null
+++ b/src/components/BackToTop/index.vue
@@ -0,0 +1,111 @@
+<template>
+  <transition :name="transitionName">
+    <div v-show="visible" :style="customStyle" class="back-to-ceiling" @click="backToTop">
+      <svg width="16" height="16" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg" class="Icon Icon--backToTopArrow" aria-hidden="true" style="height:16px;width:16px"><path d="M12.036 15.59a1 1 0 0 1-.997.995H5.032a.996.996 0 0 1-.997-.996V8.584H1.03c-1.1 0-1.36-.633-.578-1.416L7.33.29a1.003 1.003 0 0 1 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.004z" /></svg>
+    </div>
+  </transition>
+</template>
+
+<script>
+export default {
+  name: 'BackToTop',
+  props: {
+    visibilityHeight: {
+      type: Number,
+      default: 400
+    },
+    backPosition: {
+      type: Number,
+      default: 0
+    },
+    customStyle: {
+      type: Object,
+      default: function() {
+        return {
+          right: '50px',
+          bottom: '50px',
+          width: '40px',
+          height: '40px',
+          'border-radius': '4px',
+          'line-height': '45px',
+          background: '#e7eaf1'
+        }
+      }
+    },
+    transitionName: {
+      type: String,
+      default: 'fade'
+    }
+  },
+  data() {
+    return {
+      visible: false,
+      interval: null,
+      isMoving: false
+    }
+  },
+  mounted() {
+    window.addEventListener('scroll', this.handleScroll)
+  },
+  beforeDestroy() {
+    window.removeEventListener('scroll', this.handleScroll)
+    if (this.interval) {
+      clearInterval(this.interval)
+    }
+  },
+  methods: {
+    handleScroll() {
+      this.visible = window.pageYOffset > this.visibilityHeight
+    },
+    backToTop() {
+      if (this.isMoving) return
+      const start = window.pageYOffset
+      let i = 0
+      this.isMoving = true
+      this.interval = setInterval(() => {
+        const next = Math.floor(this.easeInOutQuad(10 * i, start, -start, 500))
+        if (next <= this.backPosition) {
+          window.scrollTo(0, this.backPosition)
+          clearInterval(this.interval)
+          this.isMoving = false
+        } else {
+          window.scrollTo(0, next)
+        }
+        i++
+      }, 16.7)
+    },
+    easeInOutQuad(t, b, c, d) {
+      if ((t /= d / 2) < 1) return c / 2 * t * t + b
+      return -c / 2 * (--t * (t - 2) - 1) + b
+    }
+  }
+}
+</script>
+
+<style scoped>
+.back-to-ceiling {
+  position: fixed;
+  display: inline-block;
+  text-align: center;
+  cursor: pointer;
+}
+
+.back-to-ceiling:hover {
+  background: #d5dbe7;
+}
+
+.fade-enter-active,
+.fade-leave-active {
+  transition: opacity .5s;
+}
+
+.fade-enter,
+.fade-leave-to {
+  opacity: 0
+}
+
+.back-to-ceiling .Icon {
+  fill: #9aaabf;
+  background: none;
+}
+</style>
diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue
new file mode 100644
index 0000000..6026ebb
--- /dev/null
+++ b/src/components/HeaderSearch/index.vue
@@ -0,0 +1,180 @@
+<template>
+  <div :class="{'show':show}" class="header-search">
+    <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
+    <el-select
+      ref="headerSearchSelect"
+      v-model="search"
+      :remote-method="querySearch"
+      filterable
+      default-first-option
+      remote
+      placeholder="Search"
+      class="header-search-select"
+      @change="change"
+    >
+      <el-option v-for="item in options" :key="item.path" :value="item" :label="item.title.join(' > ')" />
+    </el-select>
+  </div>
+</template>
+
+<script>
+// fuse is a lightweight fuzzy-search module
+// make search results more in line with expectations
+import Fuse from 'fuse.js'
+import path from 'path'
+
+export default {
+  name: 'HeaderSearch',
+  data() {
+    return {
+      search: '',
+      options: [],
+      searchPool: [],
+      show: false,
+      fuse: undefined
+    }
+  },
+  computed: {
+    routes() {
+      return this.$store.getters.permission_routes
+    }
+  },
+  watch: {
+    routes() {
+      this.searchPool = this.generateRoutes(this.routes)
+    },
+    searchPool(list) {
+      this.initFuse(list)
+    },
+    show(value) {
+      if (value) {
+        document.body.addEventListener('click', this.close)
+      } else {
+        document.body.removeEventListener('click', this.close)
+      }
+    }
+  },
+  mounted() {
+    this.searchPool = this.generateRoutes(this.routes)
+  },
+  methods: {
+    click() {
+      this.show = !this.show
+      if (this.show) {
+        this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus()
+      }
+    },
+    close() {
+      this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur()
+      this.options = []
+      this.show = false
+    },
+    change(val) {
+      this.$router.push(val.path)
+      this.search = ''
+      this.options = []
+      this.$nextTick(() => {
+        this.show = false
+      })
+    },
+    initFuse(list) {
+      this.fuse = new Fuse(list, {
+        shouldSort: true,
+        threshold: 0.4,
+        location: 0,
+        distance: 100,
+        maxPatternLength: 32,
+        minMatchCharLength: 1,
+        keys: [{
+          name: 'title',
+          weight: 0.7
+        }, {
+          name: 'path',
+          weight: 0.3
+        }]
+      })
+    },
+    // Filter out the routes that can be displayed in the sidebar
+    // And generate the internationalized title
+    generateRoutes(routes, basePath = '/', prefixTitle = []) {
+      let res = []
+
+      for (const router of routes) {
+        // skip hidden router
+        if (router.hidden) { continue }
+
+        const data = {
+          path: path.resolve(basePath, router.path),
+          title: [...prefixTitle]
+        }
+
+        if (router.meta && router.meta.title) {
+          data.title = [...data.title, router.meta.title]
+
+          if (router.redirect !== 'noRedirect') {
+            // only push the routes with title
+            // special case: need to exclude parent router without redirect
+            res.push(data)
+          }
+        }
+
+        // recursive child routes
+        if (router.children) {
+          const tempRoutes = this.generateRoutes(router.children, data.path, data.title)
+          if (tempRoutes.length >= 1) {
+            res = [...res, ...tempRoutes]
+          }
+        }
+      }
+      return res
+    },
+    querySearch(query) {
+      if (query !== '') {
+        this.options = this.fuse.search(query)
+      } else {
+        this.options = []
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.header-search {
+  font-size: 0 !important;
+
+  .search-icon {
+    cursor: pointer;
+    font-size: 18px;
+    vertical-align: middle;
+  }
+
+  .header-search-select {
+    font-size: 18px;
+    transition: width 0.2s;
+    width: 0;
+    overflow: hidden;
+    background: transparent;
+    border-radius: 0;
+    display: inline-block;
+    vertical-align: middle;
+
+    ::v-deep .el-input__inner {
+      border-radius: 0;
+      border: 0;
+      padding-left: 0;
+      padding-right: 0;
+      box-shadow: none !important;
+      border-bottom: 1px solid #d9d9d9;
+      vertical-align: middle;
+    }
+  }
+
+  &.show {
+    .header-search-select {
+      width: 210px;
+      margin-left: 10px;
+    }
+  }
+}
+</style>
diff --git a/src/components_simple/jun_serveLabels.vue b/src/components_simple/jun_serveLabels.vue
index 0b062da..ffacd87 100644
--- a/src/components_simple/jun_serveLabels.vue
+++ b/src/components_simple/jun_serveLabels.vue
@@ -16,6 +16,7 @@
       v-model="labelValue"
       class="input-new-tag"
       size="small"
+      maxlength="50"
       placeholder="杈撳叆鏍囩锛屽洖杞﹀垎闅�"
       @keyup.enter.native="handleInputConfirm"
       @blur="handleInputConfirm"
diff --git a/src/config/baseConfig.js b/src/config/baseConfig.js
index 1b387f0..4668a9b 100644
--- a/src/config/baseConfig.js
+++ b/src/config/baseConfig.js
@@ -8,9 +8,9 @@
 var isMock = 1 // 鏄惁浣跨敤mock
 
 // 鎵撳寘鍚庣殑鐜
-if (baseUrl.env.NODE_ENV !== 'development') {
-  baseUrl = '/';
-  isCrossDomain = 0;
+if (baseUrl.env && baseUrl.env.NODE_ENV !== 'development') {
+  baseUrl = '/'
+  isCrossDomain = 0
   isTest = 0
   isMock = 0
 }
diff --git a/src/directive/el-drag-dialog/drag.js b/src/directive/el-drag-dialog/drag.js
new file mode 100644
index 0000000..299e985
--- /dev/null
+++ b/src/directive/el-drag-dialog/drag.js
@@ -0,0 +1,77 @@
+export default {
+  bind(el, binding, vnode) {
+    const dialogHeaderEl = el.querySelector('.el-dialog__header')
+    const dragDom = el.querySelector('.el-dialog')
+    dialogHeaderEl.style.cssText += ';cursor:move;'
+    dragDom.style.cssText += ';top:0px;'
+
+    // 鑾峰彇鍘熸湁灞炴�� ie dom鍏冪礌.currentStyle 鐏嫄璋锋瓕 window.getComputedStyle(dom鍏冪礌, null);
+    const getStyle = (function() {
+      if (window.document.currentStyle) {
+        return (dom, attr) => dom.currentStyle[attr]
+      } else {
+        return (dom, attr) => getComputedStyle(dom, false)[attr]
+      }
+    })()
+
+    dialogHeaderEl.onmousedown = (e) => {
+      // 榧犳爣鎸変笅锛岃绠楀綋鍓嶅厓绱犺窛绂诲彲瑙嗗尯鐨勮窛绂�
+      const disX = e.clientX - dialogHeaderEl.offsetLeft
+      const disY = e.clientY - dialogHeaderEl.offsetTop
+
+      const dragDomWidth = dragDom.offsetWidth
+      const dragDomHeight = dragDom.offsetHeight
+
+      const screenWidth = document.body.clientWidth
+      const screenHeight = document.body.clientHeight
+
+      const minDragDomLeft = dragDom.offsetLeft
+      const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth
+
+      const minDragDomTop = dragDom.offsetTop
+      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight
+
+      // 鑾峰彇鍒扮殑鍊煎甫px 姝e垯鍖归厤鏇挎崲
+      let styL = getStyle(dragDom, 'left')
+      let styT = getStyle(dragDom, 'top')
+
+      if (styL.includes('%')) {
+        styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100)
+        styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100)
+      } else {
+        styL = +styL.replace(/\px/g, '')
+        styT = +styT.replace(/\px/g, '')
+      }
+
+      document.onmousemove = function(e) {
+        // 閫氳繃浜嬩欢濮旀墭锛岃绠楃Щ鍔ㄧ殑璺濈
+        let left = e.clientX - disX
+        let top = e.clientY - disY
+
+        // 杈圭晫澶勭悊
+        if (-(left) > minDragDomLeft) {
+          left = -minDragDomLeft
+        } else if (left > maxDragDomLeft) {
+          left = maxDragDomLeft
+        }
+
+        if (-(top) > minDragDomTop) {
+          top = -minDragDomTop
+        } else if (top > maxDragDomTop) {
+          top = maxDragDomTop
+        }
+
+        // 绉诲姩褰撳墠鍏冪礌
+        dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`
+
+        // emit onDrag event
+        vnode.child.$emit('dragDialog')
+      }
+
+      document.onmouseup = function(e) {
+        document.onmousemove = null
+        document.onmouseup = null
+      }
+    }
+  }
+}
diff --git a/src/directive/el-drag-dialog/index.js b/src/directive/el-drag-dialog/index.js
new file mode 100644
index 0000000..29facbf
--- /dev/null
+++ b/src/directive/el-drag-dialog/index.js
@@ -0,0 +1,13 @@
+import drag from './drag'
+
+const install = function(Vue) {
+  Vue.directive('el-drag-dialog', drag)
+}
+
+if (window.Vue) {
+  window['el-drag-dialog'] = drag
+  Vue.use(install); // eslint-disable-line
+}
+
+drag.install = install
+export default drag
diff --git a/src/main.js b/src/main.js
index 1cfd752..1499820 100644
--- a/src/main.js
+++ b/src/main.js
@@ -20,6 +20,8 @@
 import Pagination from '@/components/Pagination'
 // 鑷畾涔夎〃鏍煎伐鍏锋墿灞�
 import RightToolbar from '@/components/RightToolbar'
+// 鎷栨嫿寮圭獥
+import drag from './directive/el-drag-dialog/drag'
 
 // 杩囨护鍣ㄧ粺涓�澶勭悊鍔犺浇
 Object.keys(filter).forEach(key => {
@@ -44,6 +46,8 @@
   this.$message({ message: msg, dangerouslyUseHTMLString: true, type: 'error' })
 }
 
+Vue.directive('el-drag-dialog', drag)
+
 Vue.config.productionTip = false
 
 new Vue({
diff --git a/src/pages/demo/form.vue b/src/pages/demo/form.vue
index 3475cab..a3cf94b 100644
--- a/src/pages/demo/form.vue
+++ b/src/pages/demo/form.vue
@@ -1,12 +1,15 @@
 <template>
   <div class="app-container">
     <el-page-header class="mb20" @back="jumpBack" />
-    <el-form ref="couponForm" label-position="left" :model="mData" label-width="150px" :rules="rules">
+    <el-form ref="couponForm" :model="mData" label-width="150px" :rules="rules" size="small">
       <el-form-item label="鏍囬锛�" prop="title">
-        <el-input v-model="mData.title" placeholder="璇疯緭鍏ユ爣棰�" class="com-edit-input" />
+        <el-input v-model="mData.title" placeholder="璇疯緭鍏ユ爣棰�" class="com-edit-input" maxlength="50" />
       </el-form-item>
       <el-form-item label="闈㈠�硷細" prop="valueMoney">
-        <el-input v-model.number="mData.valueMoney" placeholder="璇疯緭鍏ラ潰鍊�" class="com-edit-input" />
+        <el-input v-model.number="mData.valueMoney" placeholder="璇疯緭鍏ラ潰鍊�" class="com-edit-input" maxlength="50" />
+      </el-form-item>
+      <el-form-item label="闈㈠�硷細" prop="valueMoney">
+        <el-input v-model.number="mData.valueMoney" placeholder="璇疯緭鍏ラ潰鍊�" class="com-edit-input" maxlength="50" />
       </el-form-item>
       <el-form-item label="鐪佸競鍖�" prop="provinces">
         <el-cascader
@@ -30,7 +33,7 @@
       </el-form-item>
       <el-form-item prop="uploadImgs">
         <span slot="label">
-          鍥剧墖锛�<br><span>(668*164鍍忕礌)</span>
+          鍥剧墖锛�<br><span>(xxx*xxx鍍忕礌)</span>
         </span>
         <!-- 涓婁紶鍥剧墖缁勪欢(鍗曞浘) -->
         <UploadSingleImg
@@ -58,6 +61,8 @@
       <img style="max-width:100%" :src="uploadPreviewUrl" alt="">
     </el-dialog>
 
+    <back-to-top :custom-style="myBackToTopStyle" :visibility-height="300" :back-position="50" transition-name="fade" />
+
   </div>
 </template>
 
@@ -66,9 +71,10 @@
 import mixin_upload from '@/mixins/upload.js' // 閫氱敤涓婁紶鍥剧墖棰勮
 import UploadSingleImg from '@/components_simple/UploadSingleImg'
 import Area from '@/utils/area' // 鍦板尯閫夋嫨
+import BackToTop from '@/components/BackToTop'
 export default {
   name: 'DemoForm',
-  components: { WangEnduit, UploadSingleImg },
+  components: { WangEnduit, UploadSingleImg, BackToTop },
   mixins: [
     mixin_upload
   ],
@@ -90,6 +96,17 @@
 
       // 鍒濆鍖栧湴鍖�
       areaOpts: Area.getAreaOpts(Area.data), // 鐪佸競鍖烘暟鎹�
+
+      // 鍥炲埌椤堕儴
+      myBackToTopStyle: {
+        right: '50px',
+        bottom: '50px',
+        width: '40px',
+        height: '40px',
+        'border-radius': '4px',
+        'line-height': '45px', // 璇蜂繚鎸佷笌楂樺害涓�鑷翠互鍨傜洿灞呬腑
+        background: '#e7eaf1'// 鎸夐挳鐨勮儗鏅鑹�
+      },
 
       // 琛ㄥ崟鏍¢獙
       rules: {
@@ -114,12 +131,6 @@
           required: true, message: '璇烽�夋嫨鍥剧墖'
         }]
       }
-    }
-  },
-  computed: {
-    // 绂佺敤涓婁紶鍥剧墖鍔熻兘
-    uploadDisabled() {
-      return this.mData.uploadImgs.length > 0
     }
   },
   mounted() {
diff --git a/src/pages/demo/index.vue b/src/pages/demo/index.vue
index b10bcf5..91decb3 100644
--- a/src/pages/demo/index.vue
+++ b/src/pages/demo/index.vue
@@ -9,6 +9,7 @@
           clearable
           size="small"
           style="width: 240px"
+          maxlength="50"
           @keyup.enter.native="reGetList"
         />
       </el-form-item>
@@ -33,7 +34,7 @@
     </el-row>
     <!-- 鎿嶄綔鍖� 鈫戔啈鈫戔啈鈫戔啈鈫戔啈鈫戔啈 -->
 
-    <el-table :data="list">
+    <el-table :data="list" max-height="500px" stripe>
       <el-table-column type="index" label="搴忓彿" align="center" width="60" />
       <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
       <el-table-column label="鏄惁涓婃灦" prop="isUp" align="center" min-width="100">
@@ -47,7 +48,7 @@
         </template>
       </el-table-column>
       <el-table-column label="鍒涘缓鏃堕棿" prop="createTime" align="center" min-width="160" />
-      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width" min-width="100">
+      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width" width="120">
         <template slot-scope="scope">
           <el-button
             size="mini"
@@ -66,10 +67,10 @@
     </el-table>
 
     <!-- 鏂板&缂栬緫 -->
-    <el-dialog :title="dialogData.type=='add'?'鏂板鍖婚櫌绉戝':'缂栬緫鍖婚櫌绉戝'" width="500px" :visible.sync="dialogVisible" append-to-body :before-close="hideDialog">
+    <el-dialog v-el-drag-dialog :title="dialogData.type=='add'?'鏂板鍖婚櫌绉戝':'缂栬緫鍖婚櫌绉戝'" width="500px" :visible.sync="dialogVisible" append-to-body :before-close="hideDialog">
       <el-form ref="refDialog" :model="dialogData" label-width="110px" :rules="rules" size="small">
         <el-form-item label="鍚嶇О" prop="name">
-          <el-input v-model="dialogData.name" placeholder="璇疯緭鍏ュ悕绉�" />
+          <el-input v-model="dialogData.name" placeholder="璇疯緭鍏ュ悕绉�" maxlength="50" />
         </el-form-item>
         <el-form-item label="鏄惁涓婃灦" prop="isUp">
           <el-switch
diff --git a/src/pages/demo/list.vue b/src/pages/demo/list.vue
new file mode 100644
index 0000000..e110d7e
--- /dev/null
+++ b/src/pages/demo/list.vue
@@ -0,0 +1,319 @@
+<template>
+  <div class="app-container">
+    <!-- 鎼滅储鍖� 鈫撯啌鈫撯啌鈫撯啌鈫撯啌鈫撯啌 -->
+    <el-form v-show="showSearch" ref="searchForm" :inline="true">
+      <el-form-item label="瑙掕壊鍚嶇О">
+        <el-input
+          v-model="keyWord"
+          placeholder="璇疯緭鍏ヨ鑹插悕绉�"
+          clearable
+          size="small"
+          style="width: 240px"
+          maxlength="50"
+          @keyup.enter.native="reGetList"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="reGetList">鎼滅储</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetHandle">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 鎼滅储鍖� 鈫戔啈鈫戔啈鈫戔啈鈫戔啈鈫戔啈 -->
+
+    <!-- 鎿嶄綔鍖� 鈫撯啌鈫撯啌鈫撯啌鈫撯啌鈫撯啌 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="showAddDialog"
+        >鏂板</el-button>
+      </el-col>
+      <right-toolbar :show-search.sync="showSearch" @queryTable="getList" />
+    </el-row>
+    <!-- 鎿嶄綔鍖� 鈫戔啈鈫戔啈鈫戔啈鈫戔啈鈫戔啈 -->
+
+    <el-table :data="list" max-height="500px" stripe>
+      <el-table-column type="index" label="搴忓彿" align="center" width="60" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="瑙掕壊鍚嶇О" prop="name" align="center" min-width="120" />
+      <el-table-column label="鏄惁涓婃灦" prop="isUp" align="center" min-width="100">
+        <template slot-scope="scope">
+          <el-switch
+            v-model="scope.row.isUp"
+            :active-value="1"
+            :inactive-value="0"
+            @change="handleUpChange(scope.row)"
+          />
+        </template>
+      </el-table-column>
+      <el-table-column label="鍒涘缓鏃堕棿" prop="createTime" align="center" min-width="160" />
+      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width" width="120" fixed="right">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="showEditDialog(scope.row)"
+          >缂栬緫</el-button>
+          <el-button
+            size="mini"
+            type="text warn"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+          >鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 鏂板&缂栬緫 -->
+    <el-dialog v-el-drag-dialog :title="dialogData.type=='add'?'鏂板鍖婚櫌绉戝':'缂栬緫鍖婚櫌绉戝'" width="500px" :visible.sync="dialogVisible" append-to-body :before-close="hideDialog">
+      <el-form ref="refDialog" :model="dialogData" label-width="110px" :rules="rules" size="small">
+        <el-form-item label="鍚嶇О" prop="name">
+          <el-input v-model="dialogData.name" placeholder="璇疯緭鍏ュ悕绉�" maxlength="50" />
+        </el-form-item>
+        <el-form-item label="鏄惁涓婃灦" prop="isUp">
+          <el-switch
+            v-model="dialogData.isUp"
+            :active-value="1"
+            :inactive-value="0"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="hideDialog">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitHandle">纭畾</el-button>
+      </div>
+    </el-dialog>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="pageNum"
+      :limit.sync="pageSize"
+      @pagination="getList"
+    />
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: 'Demo',
+  data() {
+    return {
+      showSearch: true, // 鏄惁鏄剧ず鎼滅储鍖�
+      keyWord: '',
+
+      list: [],
+
+      // 寮圭獥鏁版嵁
+      dialogVisible: false,
+      dialogData: {},
+
+      // 鍒嗛〉 鈫撯啌鈫撯啌鈫撯啌鈫撯啌鈫撯啌
+      total: 0,
+      pageNum: 1,
+      pageSize: 20,
+      // 鍒嗛〉 鈫戔啈鈫戔啈鈫戔啈鈫戔啈鈫戔啈
+
+      // 琛ㄥ崟鏍¢獙
+      rules: {
+        name: [
+          { required: true, message: '鍚嶇О涓嶈兘涓虹┖', trigger: 'change' }
+        ],
+        isUp: [
+          { required: true, message: '鏄惁涓婃灦涓嶈兘涓虹┖', trigger: 'change' }
+        ]
+      }
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    // 鍒濆鍖�
+    init() {
+      this.getList()
+    },
+
+    // 鑾峰彇鍒楄〃
+    getList() {
+      var { pageNum, pageSize, keyWord } = this
+      this.postFN({
+        url: 'xxx',
+        params: {
+          pageNum: pageNum,
+          pageSize: pageSize,
+          keyWord: keyWord
+        },
+        mockData: {
+          code: 100,
+          msg: '',
+          data: {
+            list: [{
+              id: 'xxx',
+              index: 1,
+              name: '瓒呯骇绠$悊鍛�',
+              createTime: '2020-08-09 10:10:10'
+            }],
+            total: 100
+          }
+        }
+      }, (inf) => {
+        for (var i = 0; i < 19; i++) {
+          inf.list.push({
+            id: 'xxx',
+            index: 1,
+            name: '瓒呯骇绠$悊鍛�',
+            createTime: '2020-08-09 10:10:10'
+          })
+        }
+        this.list = inf.list || []
+        this.total = inf.total
+      })
+    },
+    // 閲嶆柊鑾峰彇鍒楄〃
+    reGetList() {
+      this.pageNum = 1
+      this.getList()
+    },
+    // 閲嶇疆
+    resetHandle() {
+      this.keyWord = ''
+      this.reGetList()
+    },
+    // 鍒犻櫎
+    handleDelete(item) {
+      // 鎵撳紑浜屾纭寮圭獥
+      this.$confirm('鏄惁纭鍒犻櫎璇ヨ鑹�?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        // 纭畾鍥炶皟
+        this.postFN({
+          url: 'xxx',
+          params: {
+            id: item.id
+          },
+          mockData: {
+            code: 100,
+            msg: '',
+            data: {}
+          }
+        }, () => {
+          this.getList()
+          this.$messageSuc('鍒犻櫎鎴愬姛')
+        })
+      }).catch(() => {})
+    },
+    // 淇敼鏄惁涓婃灦 todo
+    handleUpChange(item) {
+      const text = item.isUp === 1 ? '涓婃灦' : '涓嬫灦'
+      this.$confirm('纭瑕�' + text + '璇ヨ鑹插悧?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.postFN({
+          url: 'xxx',
+          params: {
+            id: item.id
+          },
+          mockData: {
+            code: 100,
+            msg: '',
+            data: {}
+          }
+        }, () => {
+          this.$messageSuc(text + '鎴愬姛')
+        })
+      }).catch(() => {
+        item.isUp = item.isUp === 1 ? 0 : 1
+      })
+    },
+
+    // 鎵撳紑鏂板寮圭獥
+    showAddDialog() {
+      var dialogData = {
+        type: 'add',
+        isUp: 1
+      }
+      this.dialogVisible = true
+      this.$nextTick(() => {
+        this.dialogData = dialogData
+        this.$refs['refDialog'].resetFields()
+      })
+    },
+    // 鎵撳紑缂栬緫寮规
+    showEditDialog(item) {
+      var dialogData = {
+        type: 'edit',
+        ...item
+      }
+      console.log('dialogData', dialogData)
+      this.dialogVisible = true
+      this.$nextTick(() => {
+        this.dialogData = dialogData
+        this.$refs['refDialog'].resetFields()
+      })
+    },
+    // 鍏抽棴缂栬緫寮圭獥
+    hideDialog() {
+      this.dialogData = {}
+      this.dialogVisible = false
+    },
+    // 鎻愪氦鏂板&缂栬緫
+    submitHandle() {
+      this.$refs['refDialog'].validate(valid => {
+        if (valid) {
+          this.submitReq()
+        }
+      })
+    },
+    // 鎻愪氦鎺ュ彛
+    submitReq() {
+      var { dialogData } = this
+      var params = {
+        name: dialogData.name,
+        isUp: dialogData.isUp
+      }
+
+      if (dialogData.password) params.password = dialogData.password
+
+      var isAdd = dialogData.type === 'add'
+      var url = isAdd ? 'admin/hospital/department/add' : 'admin/hospital/department/edit'
+
+      !isAdd && (params.id = dialogData.id)
+
+      this.postFN({
+        url: url,
+        params: params,
+        mockData: {
+          code: 100,
+          msg: '',
+          data: {}
+        }
+      }, () => {
+        this.$messageSuc('淇濆瓨鎴愬姛')
+        this.hideDialog()
+        this.reGetList()
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>
diff --git a/src/pages/login/index.vue b/src/pages/login/index.vue
index a48c623..61d0696 100644
--- a/src/pages/login/index.vue
+++ b/src/pages/login/index.vue
@@ -3,7 +3,7 @@
     <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
 
       <div class="title-container">
-        <h3 class="title">琚佹洣钘忛厭</h3>
+        <h3 class="title">鈥濋」鐩悕绉扳��</h3>
       </div>
 
       <el-form-item prop="username">
@@ -18,6 +18,7 @@
           type="text"
           tabindex="1"
           autocomplete="on"
+          maxlength="20"
           @keyup.enter.native="handleLogin"
         />
       </el-form-item>
@@ -36,6 +37,7 @@
             name="password"
             tabindex="2"
             autocomplete="on"
+            maxlength="20"
             @keyup.native="checkCapslock"
             @blur="capsTooltip = false"
             @keyup.enter.native="handleLogin"
@@ -58,6 +60,7 @@
           name="safecode"
           type="text"
           tabindex="3"
+          maxlength="10"
           autocomplete="off"
           @keyup.enter.native="handleLogin"
         />
@@ -114,9 +117,9 @@
         checkedId: ''
       },
       loginRules: {
-        username: [{ required: true, trigger: 'change', validator: validateUsername }],
-        password: [{ required: true, trigger: 'change', validator: validatePassword }],
-        safecode: [{ required: true, trigger: 'change', validator: validateSafecode }]
+        username: [{ required: true, trigger: 'blur', validator: validateUsername }],
+        password: [{ required: true, trigger: 'blur', validator: validatePassword }],
+        safecode: [{ required: true, trigger: 'blur', validator: validateSafecode }]
       },
       passwordType: 'password',
       capsTooltip: false,
@@ -144,7 +147,7 @@
   },
   methods: {
     init() {
-      var loginData = localStorage.getItem('loginData')
+      var loginData = localStorage.getItem('loginData_XXXX')
       // 鑾峰彇淇濆瓨鐨勮处鍙峰瘑鐮�
       if (loginData) this.loginForm = JSON.parse(loginData)
 
@@ -233,7 +236,7 @@
               username: this.loginForm.username.trim(),
               password: this.loginForm.password.trim()
             })
-            localStorage.setItem('loginData', loginData)
+            localStorage.setItem('loginData_XXXX', loginData)
 
             // 淇濆瓨鐢ㄦ埛鏁版嵁
             setUserData(inf)
@@ -283,6 +286,11 @@
 
 /* reset element-ui css */
 .login-container {
+  // 鑳屾櫙 鈫撯啌鈫撯啌鈫撯啌鈫撯啌鈫撯啌
+  // background: url(../../assets/imgs/loginBg.jpg) no-repeat;
+  // background-size: cover;
+  // 鑳屾櫙 鈫戔啈鈫戔啈鈫戔啈鈫戔啈鈫戔啈
+  background-color: $bg;
   .el-input {
     display: inline-block;
     height: 47px;
@@ -323,16 +331,23 @@
 .login-container {
   min-height: 100%;
   width: 100%;
-  background-color: $bg;
+  // background-color: $bg;
   overflow: hidden;
 
   .login-form {
     position: relative;
     width: 520px;
     max-width: 100%;
-    padding: 160px 35px 0;
+    padding: 35px 35px 0;
     margin: 0 auto;
+    margin-top: 160px;
     overflow: hidden;
+    // 鑳屾櫙 鈫撯啌鈫撯啌鈫撯啌鈫撯啌鈫撯啌
+    // background-color: $bg;
+    // opacity: .96;
+    // border-radius: 10px;
+    // box-shadow: 0px 20px 60px rgba(0,0,0,0.4), 0px 0px 150px rgba(0,0,0,0.4);
+    // 鑳屾櫙 鈫戔啈鈫戔啈鈫戔啈鈫戔啈鈫戔啈
   }
 
   .tips {
diff --git a/src/pages/op/index.vue b/src/pages/op/index.vue
index 077373e..b195669 100644
--- a/src/pages/op/index.vue
+++ b/src/pages/op/index.vue
@@ -9,6 +9,7 @@
           clearable
           size="small"
           style="width: 240px"
+          maxlength="10"
           @keyup.enter.native="reGetList"
         />
       </el-form-item>
diff --git a/src/pages/system/admin.vue b/src/pages/system/admin.vue
index 9217881..478604d 100644
--- a/src/pages/system/admin.vue
+++ b/src/pages/system/admin.vue
@@ -9,6 +9,7 @@
           clearable
           size="small"
           style="width: 240px"
+          maxlength="50"
           @keyup.enter.native="reGetList"
         />
       </el-form-item>
@@ -85,19 +86,19 @@
     />
 
     <!-- 鏂板&缂栬緫 -->
-    <el-dialog :title="adminDialogData.type==='add'?'鏂板绠$悊鍛�':'缂栬緫绠$悊鍛�'" width="500px" :visible.sync="adminDialogVisible" append-to-body>
+    <el-dialog v-el-drag-dialog :title="adminDialogData.type==='add'?'鏂板绠$悊鍛�':'缂栬緫绠$悊鍛�'" width="500px" :visible.sync="adminDialogVisible" append-to-body>
       <el-form ref="adminDialog" :model="adminDialogData" label-width="80px" :rules="rules" size="small">
         <el-form-item label="鍚嶇О" prop="name">
-          <el-input v-model="adminDialogData.name" placeholder="璇疯緭鍏ュ悕绉�" />
+          <el-input v-model="adminDialogData.name" placeholder="璇疯緭鍏ュ悕绉�" maxlength="50" />
         </el-form-item>
         <el-form-item label="璐﹀彿" prop="account">
-          <el-input v-model="adminDialogData.account" placeholder="璇疯緭鍏ュ笎鍙�" :disabled="adminDialogData.type!='add'" />
+          <el-input v-model="adminDialogData.account" placeholder="璇疯緭鍏ュ笎鍙�" maxlength="20" :disabled="adminDialogData.type!='add'" />
         </el-form-item>
         <el-form-item label="瀵嗙爜" :prop="adminDialogData.type==='add'?'password':'none'">
-          <el-input v-model="adminDialogData.password" type="password" placeholder="璇疯緭鍏ュ瘑鐮�" />
+          <el-input v-model="adminDialogData.password" type="password" placeholder="璇疯緭鍏ュ瘑鐮�" maxlength="20" />
         </el-form-item>
         <el-form-item label="纭瀵嗙爜" :prop="adminDialogData.type==='add'?'passwordSure':'none'">
-          <el-input v-model="adminDialogData.passwordSure" type="password" placeholder="璇疯緭鍏ョ‘璁ゅ瘑鐮�" />
+          <el-input v-model="adminDialogData.passwordSure" type="password" placeholder="璇疯緭鍏ョ‘璁ゅ瘑鐮�" maxlength="20" />
         </el-form-item>
         <!-- 璐﹀彿绫诲瀷 -->
         <el-form-item label="璐﹀彿绫诲瀷" prop="accountType">
@@ -140,7 +141,6 @@
 </template>
 
 <script>
-
 export default {
   name: 'Admin',
   data() {
diff --git a/src/pages/system/banner.vue b/src/pages/system/banner.vue
index ff35688..1fb64b5 100644
--- a/src/pages/system/banner.vue
+++ b/src/pages/system/banner.vue
@@ -58,10 +58,10 @@
     />
 
     <!-- 鏂板&缂栬緫 -->
-    <el-dialog :title="dialogData.type=='add'?'鏂板杞挱鍥�':'缂栬緫杞挱鍥�'" width="500px" :visible.sync="isShowDialog" append-to-body :before-close="hideDialog">
+    <el-dialog v-el-drag-dialog :title="dialogData.type=='add'?'鏂板杞挱鍥�':'缂栬緫杞挱鍥�'" width="500px" :visible.sync="isShowDialog" append-to-body :before-close="hideDialog">
       <el-form :ref="formName" :model="dialogData" label-width="120px" :rules="rules" size="small">
         <el-form-item label="鎺掑簭鍙凤細" prop="orderNum">
-          <el-input v-model="dialogData.orderNum" placeholder="璇疯緭鍏ユ帓搴忓彿" />
+          <el-input v-model="dialogData.orderNum" placeholder="璇疯緭鍏ユ帓搴忓彿" maxlength="10" />
         </el-form-item>
         <el-form-item ref="uploadFormItem" label="杞挱鍥撅細" prop="uploadImgs">
           <!-- 涓婁紶鍥剧墖缁勪欢(澶氬浘) -->
@@ -82,10 +82,10 @@
           </el-select>
         </el-form-item>
         <el-form-item v-if="dialogData.jumpType" label="璺宠浆閾炬帴锛�" prop="jumpUrl">
-          <el-input v-model="dialogData.jumpUrl" placeholder="璇疯緭鍏ヨ烦杞摼鎺�" class="com-edit-input" />
+          <el-input v-model="dialogData.jumpUrl" placeholder="璇疯緭鍏ヨ烦杞摼鎺�" class="com-edit-input" maxlength="100" />
         </el-form-item>
         <el-form-item v-if="dialogData.jumpType===3" label="appId锛�" prop="jumpMpId">
-          <el-input v-model="dialogData.jumpMpId" placeholder="璇疯緭鍏ュ皬绋嬪簭appId" class="com-edit-input" />
+          <el-input v-model="dialogData.jumpMpId" placeholder="璇疯緭鍏ュ皬绋嬪簭appId" class="com-edit-input" maxlength="50" />
         </el-form-item>
         <el-form-item v-if="dialogData.jumpType===3" label="灏忕▼搴忕増鏈細" prop="envVersion">
           <el-select
@@ -98,7 +98,7 @@
           </el-select>
         </el-form-item>
         <el-form-item v-if="dialogData.jumpType===3" label="棰濆鏁版嵁锛�" prop="extraData">
-          <el-input v-model="dialogData.extraData" placeholder="璇疯緭鍏ュ皬绋嬪簭棰濆鏁版嵁" class="com-edit-input" />
+          <el-input v-model="dialogData.extraData" placeholder="璇疯緭鍏ュ皬绋嬪簭棰濆鏁版嵁" class="com-edit-input" maxlength="50" />
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
diff --git a/src/pages/system/basic.vue b/src/pages/system/basic.vue
index d7e9c46..ebcdc98 100644
--- a/src/pages/system/basic.vue
+++ b/src/pages/system/basic.vue
@@ -5,7 +5,7 @@
     <el-form ref="basicForm" label-position="left" :model="basicData" label-width="150px" :rules="rules">
 
       <el-form-item label="鍒嗕韩鏍囬锛�" prop="shareTitle">
-        <el-input v-model="basicData.shareTitle" placeholder="璇疯緭鍏ュ垎浜爣棰�" class="com-edit-input" />
+        <el-input v-model="basicData.shareTitle" placeholder="璇疯緭鍏ュ垎浜爣棰�" maxlength="100" class="com-edit-input" />
       </el-form-item>
 
       <el-form-item prop="uploadShareImgs">
diff --git a/src/pages/system/role.vue b/src/pages/system/role.vue
index b3fdecc..4e6e92e 100644
--- a/src/pages/system/role.vue
+++ b/src/pages/system/role.vue
@@ -9,6 +9,7 @@
           clearable
           size="small"
           style="width: 240px"
+          maxlength="50"
           @keyup.enter.native="reGetList"
         />
       </el-form-item>
diff --git a/src/pages/system/roleAdd.vue b/src/pages/system/roleAdd.vue
index 53e3816..a741300 100644
--- a/src/pages/system/roleAdd.vue
+++ b/src/pages/system/roleAdd.vue
@@ -1,9 +1,9 @@
 <template>
   <div class="app-container">
     <el-page-header class="mb20" @back="jumpBack" />
-    <el-form ref="roleAddForm" label-position="left" :model="mData" label-width="150px" :rules="rules">
+    <el-form ref="roleAddForm" label-position="left" :model="mData" label-width="150px" :rules="rules" size="small">
       <el-form-item label="瑙掕壊鍚嶇О锛�" prop="name">
-        <el-input v-model="mData.name" placeholder="璇疯緭鍏ュ悕绉�" class="com-edit-input" />
+        <el-input v-model="mData.name" placeholder="璇疯緭鍏ュ悕绉�" maxlength="50" class="com-edit-input" />
       </el-form-item>
       <el-form-item label="鏄惁鍚敤锛�">
         <el-switch v-model="mData.isUse" :active-value="1" :inactive-value="0" />
diff --git a/src/pages/system/roleEdit.vue b/src/pages/system/roleEdit.vue
index c25b9ab..0037ce2 100644
--- a/src/pages/system/roleEdit.vue
+++ b/src/pages/system/roleEdit.vue
@@ -1,9 +1,9 @@
 <template>
   <div class="app-container">
     <el-page-header class="mb20" @back="jumpBack" />
-    <el-form ref="roleAddForm" label-position="left" :model="mData" label-width="150px" :rules="rules">
+    <el-form ref="roleAddForm" label-position="left" :model="mData" label-width="150px" :rules="rules" size="small">
       <el-form-item label="瑙掕壊鍚嶇О锛�" prop="name">
-        <el-input v-model="mData.name" placeholder="璇疯緭鍏ュ悕绉�" class="com-edit-input" />
+        <el-input v-model="mData.name" placeholder="璇疯緭鍏ュ悕绉�" maxlength="50" class="com-edit-input" />
       </el-form-item>
       <el-form-item label="鏄惁鍚敤锛�">
         <el-switch v-model="mData.isUse" :active-value="1" :inactive-value="0" />
diff --git a/src/router/demo_router.js b/src/router/demo_router.js
index 8526de2..c8817ec 100644
--- a/src/router/demo_router.js
+++ b/src/router/demo_router.js
@@ -18,6 +18,12 @@
       meta: { title: '妯℃澘鍒楄〃' }
     },
     {
+      path: 'list',
+      component: () => import('@/pages/demo/list'), // Parent router-view
+      name: 'demoList',
+      meta: { title: '妯℃澘瓒呭鍒楄〃' }
+    },
+    {
       path: 'form',
       component: () => import('@/pages/demo/form'), // Parent router-view
       name: 'demoForm',

--
Gitblit v1.8.0