From 7e460156de73171f9660ce48f80703e79f8b478d Mon Sep 17 00:00:00 2001
From: Crunchy <3114200645@qq.com>
Date: 星期六, 14 六月 2025 11:48:26 +0800
Subject: [PATCH] 初始化提交

---
 vue.config.js                             |    2 
 src/views/login/index.vue                 |  264 ++-
 src/layout/components/Navbar.vue          |  198 ++
 src/layout/index.vue                      |    6 
 src/utils/auth.js                         |   14 
 src/styles/sidebar.scss                   |   27 
 src/views/out_operation/index.vue         |  816 ++++++++--
 src/components/SettingTitle/index.vue     |    9 
 src/views/add_operation/barcode/index.vue |  158 ++
 src/layout/components/Sidebar/Logo.vue    |   11 
 src/styles/variables.scss                 |   11 
 src/store/getters.js                      |    8 
 src/views/outbound/index.vue              |  241 +++
 src/permission.js                         |   20 
 src/store/modules/user.js                 |   82 
 public/index.html                         |   14 
 src/api/user.js                           |   93 
 src/store/index.js                        |    6 
 src/views/out_operation/manual/index.vue  |  327 ++++
 src/assets/images/logo.png                |    0 
 src/settings.js                           |    2 
 src/components/SvgIcon/index.vue          |   14 
 src/assets/images/loginbg.png             |    0 
 src/components/TableSearch/index.vue      |  123 +
 src/router/index.js                       |   82 
 src/styles/element-ui.scss                |    8 
 src/utils/validate.js                     |    6 
 src/utils/request.js                      |   75 
 .env.development                          |    3 
 /dev/null                                 |   15 
 src/views/system/user/index.vue           |  854 +++++++++++
 src/views/home/index.vue                  |  343 ++-
 src/api/table.js                          |    2 
 src/components/Hamburger/index.vue        |    1 
 src/main.js                               |   14 
 package.json                              |    5 
 .env.production                           |    3 
 src/layout/components/AppMain.vue         |    3 
 src/views/add_operation/index.vue         |  639 ++++++-
 src/views/system/dict/index.vue           |   24 
 40 files changed, 3,775 insertions(+), 748 deletions(-)

diff --git a/.env.development b/.env.development
index de583d0..3885991 100644
--- a/.env.development
+++ b/.env.development
@@ -2,4 +2,5 @@
 ENV = 'development'
 
 # base api
-VUE_APP_BASE_API = '/dev-api'
+VUE_APP_BASE_API = 'http://localhost:8011'
+# VUE_APP_BASE_API = '/dev-api'
diff --git a/.env.production b/.env.production
index 03e2f3e..917445e 100644
--- a/.env.production
+++ b/.env.production
@@ -2,5 +2,6 @@
 ENV = 'production'
 
 # base api
-VUE_APP_BASE_API = 'http://localhost:8080'
+VUE_APP_BASE_API = 'http://58.56.84.138:9155'
+# VUE_APP_BASE_API = 'http://localhost:8080'
 
diff --git a/package.json b/package.json
index 11e8d0e..5179747 100644
--- a/package.json
+++ b/package.json
@@ -17,12 +17,15 @@
     "axios": "0.18.1",
     "core-js": "3.6.5",
     "echarts": "^5.4.2",
-    "element-ui": "2.13.2",
+    "element-ui": "^2.15.3",
     "js-cookie": "2.2.0",
+    "jsbarcode": "^3.11.5",
     "normalize.css": "7.0.0",
     "nprogress": "0.2.0",
     "path-to-regexp": "2.4.0",
     "vue": "2.6.10",
+    "vue-barcode": "^1.3.0",
+    "vue-print-nb": "^1.7.5",
     "vue-router": "3.0.6",
     "vuex": "3.1.0"
   },
diff --git a/public/index.html b/public/index.html
index fa2be91..b392709 100644
--- a/public/index.html
+++ b/public/index.html
@@ -6,6 +6,20 @@
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= webpackConfig.name %></title>
+    <style media="print">
+      @page{
+        size: auto;
+        margin: 3mm;
+      }
+      html{
+        background-color: #fff;
+        margin: 0px;
+      }
+      body{
+        border: 1px solid #fff;
+        margin: 10mm 15mm 10mm 15mm;
+      }
+    </style>
   </head>
   <body>
     <noscript>
diff --git a/src/api/table.js b/src/api/table.js
index 2752f52..e29c294 100644
--- a/src/api/table.js
+++ b/src/api/table.js
@@ -2,7 +2,7 @@
 
 export function getList(params) {
   return request({
-    url: '/vue-admin-template/table/list',
+    url: '/table/list',
     method: 'get',
     params
   })
diff --git a/src/api/user.js b/src/api/user.js
index 0d4d221..e7c3bd9 100644
--- a/src/api/user.js
+++ b/src/api/user.js
@@ -1,24 +1,45 @@
 import request from '@/utils/request'
 
-export function login(data) {
+/* export function login(data) {
   return request({
     url: '/vue-admin-template/user/login',
     method: 'post',
     data
   })
+} */
+// refresh
+export function refresh(data) {
+  return request({
+    url: '/user/login/refresh',
+    method: 'post',
+    headers: {
+      'Content-Type': 'application/x-www-form-urlencoded'
+    },
+    data
+  })
 }
 
+export function login(data) {
+  return request({
+    url: '/user/login/account',
+    method: 'post',
+    headers: {
+      'Content-Type': 'application/x-www-form-urlencoded'
+    },
+    data
+  })
+}
 export function getInfo(token) {
   return request({
-    url: '/vue-admin-template/user/info',
-    method: 'get',
-    params: { token }
+    url: '/user/info',
+    method: 'get'
+    // params: { token }
   })
 }
 
 export function logout() {
   return request({
-    url: '/vue-admin-template/user/logout',
+    url: '/user/logout',
     method: 'post'
   })
 }
@@ -40,12 +61,30 @@
   })
 }
 
-// 鏂板鐢ㄦ埛
-export function addUser(data) {
+// 娣诲姞搴撳瓨鍚嶇О
+export function addProductName(params) {
   return request({
-    url: '/system/user',
+    url: '/product_name/add',
     method: 'post',
-    data: data
+    params
+  })
+}
+
+// 娣诲姞搴撳瓨鍚嶇О
+export function addProductModel(params) {
+  return request({
+    url: '/product_name/add',
+    method: 'post',
+    params
+  })
+}
+
+// 鏂板鐢ㄦ埛
+export function addUser(params) {
+  return request({
+    url: '/user/add',
+    method: 'post',
+    params
   })
 }
 
@@ -59,10 +98,11 @@
 }
 
 // 鍒犻櫎鐢ㄦ埛
-export function delUser(userId) {
+export function delUser(params) {
   return request({
-    url: '/system/user/' + userId,
-    method: 'delete'
+    url: '/user/delete',
+    method: 'delete',
+    params
   })
 }
 
@@ -101,24 +141,20 @@
 }
 
 // 淇敼鐢ㄦ埛涓汉淇℃伅
-export function updateUserProfile(data) {
+export function updateUserProfile(params) {
   return request({
-    url: '/system/user/profile',
+    url: '/user/update/user',
     method: 'put',
-    data: data
+    params
   })
 }
 
 // 鐢ㄦ埛瀵嗙爜閲嶇疆
-export function updateUserPwd(oldPassword, newPassword) {
-  const data = {
-    oldPassword,
-    newPassword
-  }
+export function updateUserPwd(params) {
   return request({
-    url: '/system/user/profile/updatePwd',
+    url: '/user/update/password',
     method: 'put',
-    params: data
+    params
   })
 }
 
@@ -149,10 +185,19 @@
 }
 
 // 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋�
-export function deptTreeSelect() {
+export function getUserList() {
   return request({
-    url: '/system/user/deptTree',
+    url: '/user/list',
     method: 'get'
   })
 }
 
+export function tideLogin(data) {
+  return request({
+    url: '/tide/tideLogin',
+    method: 'post',
+    data: {
+      code: data
+    }
+  })
+}
diff --git a/src/assets/images/loginbg.png b/src/assets/images/loginbg.png
index a6927fd..d0debd1 100644
--- a/src/assets/images/loginbg.png
+++ b/src/assets/images/loginbg.png
Binary files differ
diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png
index d192b19..5e61efc 100644
--- a/src/assets/images/logo.png
+++ b/src/assets/images/logo.png
Binary files differ
diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue
index 368b002..f495109 100644
--- a/src/components/Hamburger/index.vue
+++ b/src/components/Hamburger/index.vue
@@ -36,6 +36,7 @@
   vertical-align: middle;
   width: 20px;
   height: 20px;
+  fill: #fff;
 }
 
 .hamburger.is-active {
diff --git a/src/components/SettingTitle/index.vue b/src/components/SettingTitle/index.vue
index 32cbf62..632a54c 100644
--- a/src/components/SettingTitle/index.vue
+++ b/src/components/SettingTitle/index.vue
@@ -1,14 +1,19 @@
 <template>
   <div class="setting-title">
     <div class="title-left">{{left}}</div>
-    <div class="title-right">{{right}}</div>
+    <div class="title-right" @click="clickEvent"><span :class="icon"></span> {{right}}</div>
   </div>
 </template>
 
 <script>
 export default {
   name: 'SettingTitle',
-  props: ['left', 'right']
+  props: ['left', 'right', 'icon', 'clickFun'],
+  methods: {
+    clickEvent() {
+      this.clickFun()
+    }
+  }
 }
 </script>
 
diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue
index b07ded2..0cef74e 100644
--- a/src/components/SvgIcon/index.vue
+++ b/src/components/SvgIcon/index.vue
@@ -1,8 +1,11 @@
 <template>
   <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
-  <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
+  <!-- <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
     <use :xlink:href="iconName" />
-  </svg>
+  </svg> -->
+  <span v-else class="iconfont" :class="svgClass" aria-hidden="true" v-on="$listeners">
+    <!-- <i class="iconfont" :class="iconName"></i> -->
+  </span>
 </template>
 
 <script>
@@ -26,13 +29,14 @@
       return isExternal(this.iconClass)
     },
     iconName() {
-      return `#icon-${this.iconClass}`
+      // return `#icon-${this.iconClass}`
+      return `iconfont ${this.iconClass}`
     },
     svgClass() {
       if (this.className) {
-        return 'svg-icon ' + this.className
+        return 'svg-icon ' + this.iconClass + this.className
       } else {
-        return 'svg-icon'
+        return 'svg-icon ' + this.iconClass
       }
     },
     styleExternalIcon() {
diff --git a/src/components/TableSearch/index.vue b/src/components/TableSearch/index.vue
index 99eb459..221aaea 100644
--- a/src/components/TableSearch/index.vue
+++ b/src/components/TableSearch/index.vue
@@ -1,40 +1,139 @@
 <template>
   <div class="table-search">
     <el-form
-      v-model="queryParams"
       ref="queryForm"
+      v-model="queryParams"
       size="small"
       :inline="true"
       label-width="68px"
     >
       <el-form-item label="鏃ユ湡锛�">
         <el-date-picker
+          v-model="queryParams.date"
+          value-format="yyyy-MM-dd HH:mm"
+          format="yyyy-MM-dd HH:mm"
           type="datetimerange"
           :picker-options="pickerOptions"
           range-separator="鑷�"
           start-placeholder="寮�濮嬫棩鏈�"
           end-placeholder="缁撴潫鏃ユ湡"
           align="right"
-        >
-        </el-date-picker>
+        />
       </el-form-item>
-      <el-form-item label="瑙勬牸锛�">
-        <el-select placeholder="瑙勬牸鍨嬪彿" clearable style="width: 240px">
+      <el-form-item v-show="show" :label="searchParams.hasOwnProperty('productModel')? '瑙勬牸鍨嬪彿':'瀹㈡埛鍚嶇О'">
+        <el-select v-model="queryParams.type" :placeholder="searchParams.hasOwnProperty('productModel')? '璇烽�夋嫨瑙勬牸鍨嬪彿':'璇烽�夋嫨瀹㈡埛鍚嶇О'" clearable style="width: 240px">
+          <el-option
+            v-for="item in options"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          />
         </el-select>
       </el-form-item>
       <el-form-item>
-        <el-button type="primary" icon="el-icon-search" size="mini"
-          >鎼滅储</el-button
-        >
-        <el-button icon="el-icon-refresh" size="mini">瀵煎嚭</el-button>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="search"
+        >鎼滅储</el-button>
+        <el-button :style="{color:'#409EFF',border:' 1px solid #409EFF'}" icon="iconfont icon-wenjiandaochu" size="mini" @click="exportExcel">瀵煎嚭</el-button>
       </el-form-item>
     </el-form>
   </div>
 </template>
 
 <script>
-export default {
 
+export default {
+  props: [
+    'searchData',
+    'searchParams',
+    'options',
+    'getList',
+    'file',
+    'show',
+    'excelName'
+  ],
+  data() {
+    return {
+      queryParams: {
+        date: [],
+        type: ''
+      },
+      pickerOptions: {
+        shortcuts: [{
+          text: '鏈�杩戜竴鍛�',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '鏈�杩戜竴涓湀',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '鏈�杩戜笁涓湀',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+            picker.$emit('pick', [start, end])
+          }
+        }]
+      }
+    }
+  },
+  methods: {
+    search() {
+      // "鏌ヨ鏉′欢锛�"鏃堕棿闇�瑕佹牸寮忓寲鎴恲yyy-mm-dd hh-mm-ss
+      // console.log(this.queryParams)
+      let { date, type } = this.queryParams
+      date = date == null ? [] : date
+      let params = { ...this.searchParams, startTime: date[0], endTime: date[1] }
+      params = this.searchParams.hasOwnProperty('productModel') ? { ...params, productModel: type } : { ...params, customerName: type }
+      const obj = {}
+      const arr = Object.keys(params).filter(key => params[key])
+      arr.forEach(item => obj[item] = params[item])
+      console.log(obj)// 鏌ョ湅鎵�鏈夎姹傚弬鏁�
+      this.getList(obj).then(res => {
+        this.searchData({ ...res.data, startTime: date[0], endTime: date[1] })
+      })
+    },
+    exportExcel() {
+      let { date, type } = this.queryParams
+      date = date == null ? [] : date
+      let params = { startTime: date[0], endTime: date[1] }
+      params = this.searchParams.hasOwnProperty('productModel') ? { ...params, productModel: type } : { ...params, customerName: type }
+      const obj = {}
+      const arr = Object.keys(params).filter(key => params[key])
+      arr.forEach(item => obj[item] = params[item])
+      console.log(obj)// 鏌ョ湅鎵�鏈夎姹傚弬鏁�
+      this.file(obj).then(response => {
+        const blob = new Blob([response.data], { type: 'application/vnd.ms-excel;charset=utf-8' })
+        const downloadElement = document.createElement('a')
+        const href = window.URL.createObjectURL(blob) // 鍒涘缓涓嬭浇鐨勯摼鎺�
+        downloadElement.href = href
+        downloadElement.download = `${this.excelName}.xlsx` // 涓嬭浇鍚庢枃浠跺悕
+        document.body.appendChild(downloadElement)
+        downloadElement.click() // 鐐瑰嚮涓嬭浇
+        this.loadingBtn = false
+        document.body.removeChild(downloadElement) // 涓嬭浇瀹屾垚绉婚櫎鍏冪礌
+        window.URL.revokeObjectURL(href) // 閲婃斁鎺塨lob瀵硅薄
+      }).catch(message => {
+        this.$message.error({
+          message: '鎶辨瓑涓嬭浇閿欒锛侀敊璇師鍥狅細' + message,
+          type: 'error'
+        })
+      })
+    }
+  }
 }
 </script>
 
@@ -43,6 +142,6 @@
    .el-form-item{
       margin-bottom: 0;
       margin: 12px;
-    } 
+    }
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue
index f6a3286..3f65132 100644
--- a/src/layout/components/AppMain.vue
+++ b/src/layout/components/AppMain.vue
@@ -24,9 +24,10 @@
   width: 100%;
   position: relative;
   overflow: hidden;
+  
 }
 .fixed-header+.app-main {
-  padding-top: 50px;
+  padding-top: 97px;
 }
 </style>
 
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index 3db50d2..afcd2c4 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -1,74 +1,211 @@
 <template>
-  <div class="navbar">
-    <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+  <div class="header">
+    <div class="navbar">
+      <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+      <el-input v-model="keyword" size="small" placeholder="璇疯緭鍏ュ鎴峰悕绉版煡璇㈠彴璐�" class="input-with-select">
+        <el-button slot="append" type="primary" icon="el-icon-search" @click="goTo" />
+      </el-input>
+      <!-- <breadcrumb class="breadcrumb-container" /> -->
+      <div class="center-title">
+        WMS绯荤粺
+      </div>
 
-    <breadcrumb class="breadcrumb-container" />
-    <div class="center-title">
-      涓ぉ绉戞妧WMS绯荤粺
-    </div>
-
-    <div class="right-menu">
-      <el-dropdown class="avatar-container" trigger="click">
-        <div class="avatar-wrapper">
-          <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
-          <i class="el-icon-caret-bottom" />
-        </div>
-        <el-dropdown-menu slot="dropdown" class="user-dropdown">
-          <router-link to="/">
+      <div class="right-menu">
+        <el-dropdown class="avatar-container" trigger="click">
+          <div class="avatar-wrapper">
+            <!-- <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar"> -->
+            <img :src="baseUrl+'/img'+avatar" class="user-avatar">
+            <span class="avater-name">{{ name }}</span>
+          <!-- <i class="el-icon-caret-bottom" /> -->
+          </div>
+          <el-dropdown-menu slot="dropdown" class="user-dropdown">
+            <!-- <router-link to="/">
             <el-dropdown-item>
               Home
             </el-dropdown-item>
-          </router-link>
-          <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/">
+          </router-link> -->
+            <!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/">
             <el-dropdown-item>Github</el-dropdown-item>
           </a>
           <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
             <el-dropdown-item>Docs</el-dropdown-item>
-          </a>
-          <el-dropdown-item divided @click.native="logout">
-            <span style="display:block;">Log Out</span>
-          </el-dropdown-item>
-        </el-dropdown-menu>
-      </el-dropdown>
+          </a> -->
+            <!-- <el-button>閫�鍑�</el-button> -->
+            <el-dropdown-item divided @click.native="logout">
+              <span style="display:block;">閫� 鍑�</span>
+            </el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </div>
+    </div>
+    <div class="header-tabs">
+      <div class="el-icon-arrow-left" @click="prev" />
+      <div class="routers">
+        <a v-for="tag in openTab.openTab">
+          <el-tag
+
+            :key="tag.name"
+            closable
+            :class="tag.name==openTab.activeIndex?'active':''"
+            @close="handleClose(tag)"
+            @click="changeRouter(tag)"
+          >
+            {{ tag.name }}
+          </el-tag>
+        </a>
+
+      </div>
     </div>
   </div>
+
 </template>
 
 <script>
 import { mapGetters } from 'vuex'
 import Breadcrumb from '@/components/Breadcrumb'
 import Hamburger from '@/components/Hamburger'
+import openTab from '@/store/modules/openTab'
+// import openTab from '@/store/modules/openTab'
 
 export default {
   components: {
     Breadcrumb,
     Hamburger
   },
+  data() {
+    return {
+      keyword: '',
+      routers: [
+      ],
+      baseUrl: process.env.VUE_APP_BASE_API
+
+    }
+  },
   computed: {
     ...mapGetters([
       'sidebar',
-      'avatar'
+      'avatar',
+      'name',
+      'openTab'
     ])
   },
+  mounted() {
+    // console.log(this.openTab)
+  },
   methods: {
+    goTo() {
+      // console.log('鐐瑰嚮鏌ヨ', this.$route)
+      this.$router.push({ path: '/outbound/outboundLedger', query: { keyword: this.keyword }})
+      this.keyword = ''
+      // if (this.$route.name === '鍑哄簱鍙拌处') {
+      //   console.log('杈撳嚭褰撳墠')
+      //   // this.$router.go(0)
+      //   return
+      // }
+    },
+    prev() {
+      this.$router.go(-1)
+    },
+    handleClose(tag) {
+      console.log(this.openTab.activeIndex)
+      if (this.openTab.openTab.length == 1) {
+        if (tag.name == '涓婚〉') {
+          return
+        }
+        this.$store.commit('DEL_TAB', tag.route)
+        this.$router.push('/home')
+        this.$store.commit('SET_ACTIVE_INDEX', '/home')
+      }
+      if (this.openTab.activeIndex == tag.route) {
+        this.$store.commit('DEL_TAB', tag.route)
+        this.$router.push(this.openTab.openTab[0].route)
+        this.$store.commit('SET_ACTIVE_INDEX', this.openTab.openTab[0].route)
+      }
+      this.$store.commit('DEL_TAB', tag.route)
+    },
     toggleSideBar() {
       this.$store.dispatch('app/toggleSideBar')
     },
     async logout() {
       await this.$store.dispatch('user/logout')
       this.$router.push(`/login?redirect=${this.$route.fullPath}`)
+    },
+    goBack() {
+
+    },
+    changeRouter(tag) {
+      this.$router.push(tag.route)
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
+.header{
+  background: #efefef;
+  .header-tabs{
+    margin-top: 10px;
+    background: #304156;
+    color: #fff;
+    height: 35px;
+    display: flex;
+    align-items: center;
+    >div:nth-child(1){
+      width: 40px;
+      text-align: center;
+    }
+
+    .el-tabs{
+      flex: 1;
+    }
+    ::v-deep .el-breadcrumb .el-breadcrumb__inner a{
+      color: #fff !important;
+    }
+    .el-tag{
+      height: 100%;
+      background: #304156;
+      color: #fff;
+      border-radius: 0;
+      margin: 0;
+      border-right: 0px;
+      border-top: 0px;
+      border-bottom: 0px;
+      line-height: 35px;
+      .el-tag__close{
+        color: #fff;
+      }
+    }
+    .routers{
+      height: 100%;
+       a:last-of-type{
+      .el-tag{
+      border-right: 1px solid #fff;
+     }
+    }
+    }
+
+    // .el-tag,.active{
+    //   color: #409EFF !important;
+    // }
+  }
+}
 .navbar {
   height: 50px;
   overflow: hidden;
   position: relative;
-  background: #fff;
+  background: #304156;
+  color: #fff;
+  line-height: 50px;
   box-shadow: 0 1px 4px rgba(0,21,41,.08);
+  ::v-deep .el-input-group__append{
+    background: #448ACA;
+    border: 0px;
+    color: #fff;
+  }
+  .input-with-select{
+  width: 300px;
+  // height: 30px;
+}
   .center-title{
     position: absolute;
     left: 50%;
@@ -125,12 +262,19 @@
       .avatar-wrapper {
         margin-top: 5px;
         position: relative;
-
+        color: #fff;
+        display: flex;
+        .avater-name{
+          // position: absolute;
+          // top: 50%;
+          margin-left: 10px;
+        }
         .user-avatar {
           cursor: pointer;
+          border-radius: 50%;
           width: 40px;
           height: 40px;
-          border-radius: 10px;
+          // border-radius: 10px;
         }
 
         .el-icon-caret-bottom {
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
index 3b0346b..fc405dc 100644
--- a/src/layout/components/Sidebar/Logo.vue
+++ b/src/layout/components/Sidebar/Logo.vue
@@ -28,6 +28,9 @@
       title: 'Vue Admin Template',
       logo
     }
+  },
+  mounted() {
+    console.log(this.collapse)
   }
 }
 </script>
@@ -47,19 +50,21 @@
   width: 100%;
   height: 50px;
   line-height: 50px;
-  background: #6095FB;
+  background: #304156;
   text-align: center;
   overflow: hidden;
 
   & .sidebar-logo-link {
     height: 100%;
     width: 100%;
-
+    text-align:left;
     & .sidebar-logo {
-      padding: 7.5px 20px;
+      // padding: 7.5px 20px;
       width: 135px;
       height: 45px;
       vertical-align: middle;
+      // position: absolute;
+      // left: 20px;
     }
 
     & .sidebar-title {
diff --git a/src/layout/index.vue b/src/layout/index.vue
index db22a7b..4317904 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -63,6 +63,12 @@
       position: fixed;
       top: 0;
     }
+    
+  }
+  .hideSidebar .sidebar-container{
+     ::v-deep img{
+        //  content: url("@/a");
+      }
   }
   .drawer-bg {
     background: #000;
diff --git a/src/main.js b/src/main.js
index c5d6f13..1a25e48 100644
--- a/src/main.js
+++ b/src/main.js
@@ -7,10 +7,11 @@
 import locale from 'element-ui/lib/locale/lang/zh-CN' // lang i18n
 
 import '@/styles/index.scss' // global css
-
+import '@/assets/iconfont/iconfont.css'
 import App from './App'
 import store from './store'
 import router from './router'
+import Print from 'vue-print-nb'
 
 import '@/icons' // icon
 import '@/permission' // permission control
@@ -32,9 +33,16 @@
 Vue.use(ElementUI, { locale })
 // 濡傛灉鎯宠涓枃鐗� element-ui锛屾寜濡備笅鏂瑰紡澹版槑
 // Vue.use(ElementUI)
-
+Vue.use(Print)
 Vue.config.productionTip = false
-
+Vue.prototype.$flush = () => {
+  if (this.$route.path !== '/' && this.$route.path !== '/home') {
+    console.log('1');
+    this.$store.commit('ADD_TAB', {route: '/home' , name: 'home'});
+    this.$store.commit('ADD_TAB', {route: this.$route.path , name: this.$route.name });
+    this.$store.commit('SET_ACTIVE_INDEX', this.$route.path);
+  } 
+}
 new Vue({
   el: '#app',
   router,
diff --git a/src/permission.js b/src/permission.js
index fa1ea19..043b58f 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -13,27 +13,36 @@
 router.beforeEach(async(to, from, next) => {
   // start progress bar
   NProgress.start()
-
+  console.log(to)
+  if (to.query.code) {
+    console.log(to.query.code)
+    store.dispatch('user/tideLogin', to.query.code).then(res => {
+      next({ path: '/' })
+    })
+  }
   // set page title
   document.title = getPageTitle(to.meta.title)
-
   // determine whether the user has logged in
   const hasToken = getToken()
-
+  // console.log('璺敱瀹堝崼', hasToken)
   if (hasToken) {
+    // console.log('鏈嶅姟鍣ㄦ湁token')
     if (to.path === '/login') {
       // if is logged in, redirect to the home page
       next({ path: '/' })
       NProgress.done()
     } else {
+      // console.log('鏈嶅姟鍣ㄦ湁token锛岃闂笉鏄痩ogin椤甸潰')
       const hasGetUserInfo = store.getters.name
       if (hasGetUserInfo) {
         next()
       } else {
+        // console.log('娌℃湁鐢ㄦ埛淇℃伅')
         try {
           // get user info
-          await store.dispatch('user/getInfo')
-
+          // console.log('鑾峰彇鐢ㄦ埛淇℃伅')
+          const userInfo = await store.dispatch('user/getInfo')
+          // console.log('鑾峰彇鐢ㄦ埛鏁版嵁鎴愬姛', userInfo)
           next()
         } catch (error) {
           // remove token and go to login page to re-login
@@ -52,6 +61,7 @@
       next()
     } else {
       // other pages that do not have permission to access are redirected to the login page.
+      // next()
       next(`/login?redirect=${to.path}`)
       NProgress.done()
     }
diff --git a/src/router/index.js b/src/router/index.js
index 7219335..9bbbb95 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,6 +1,6 @@
 import Vue from 'vue'
 import Router from 'vue-router'
-
+import store from '@/store/index'
 Vue.use(Router)
 
 /* Layout */
@@ -33,6 +33,7 @@
 export const constantRoutes = [
   {
     path: '/login',
+    name: 'login',
     component: () => import('@/views/login/index'),
     hidden: true
   },
@@ -49,27 +50,27 @@
     redirect: '/home',
     children: [{
       path: 'home',
-      name: 'Home',
+      name: '涓婚〉',
       component: () => import('@/views/home/index'),
-      meta: { title: '棣栭〉', icon: 'el-icon-house' }
+      meta: { title: '棣栭〉', icon: 'icon-shouye' }
     }]
   },
-
   {
     path: '/add_operation',
     component: Layout,
     redirect: '/add_operation/table',
-    meta: { title: '鍏ュ簱鎿嶄綔', icon: 'el-icon-edit-outline' },
+    meta: { title: '鍏ュ簱鎿嶄綔', icon: 'icon-warehouse' },
     children: [
       {
         path: 'table',
+        name: '鍏ュ簱鎿嶄綔',
         component: () => import('@/views/add_operation/index'),
-        meta: { title: '鍏ュ簱鎿嶄綔', icon: 'el-icon-edit-outline' }
+        meta: { title: '鍏ュ簱鎿嶄綔', icon: 'icon-warehouse' }
       }
     // ,{
     //   path: 'barcode',
     //   component: () => import('@/views/add_operation/barcode'),
-    //   meta: { title: '鏉$爜鎵撳嵃', icon: 'el-icon-edit-outline' }
+    //   meta: { title: '鏉$爜鎵撳嵃', icon: 'icon-warehouse' }
     // }
     ]
   },
@@ -77,39 +78,39 @@
     path: '/out_operation',
     component: Layout,
     redirect: '/out_operation/table',
-    meta: { title: '鍑哄簱鎿嶄綔', icon: 'el-icon-box' },
+    meta: { title: '鍑哄簱鎿嶄綔', icon: 'icon-warehouseOut' },
     children: [
       {
         path: 'table',
-        name: 'OutOperation',
+        name: '鍑哄簱鎿嶄綔',
         component: () => import('@/views/out_operation/index'),
-        meta: { title: '鍑哄簱鎿嶄綔', icon: 'el-icon-box' }
+        meta: { title: '鍑哄簱鎿嶄綔', icon: 'icon-warehouseOut' }
       }
       // ,{
       //   path: 'manual',
       //   name: 'manual',
       //   component: () => import('@/views/out_operation/manual'),
       //   meta: { title: '鎵嬪姩鍑哄簱', icon: 'el-icon-box' }
-      // },
-      // {
-      //   path: 'outboundLedger',
-      //   name: 'outboundLedger',
-      //   component: () => import('@/views/out_operation/outboundLedger'),
-      //   meta: { title: '鍑哄簱鍙拌处', icon: 'el-icon-box' }
       // }
     ]
   },
-
   {
     path: '/outbound',
     component: Layout,
     redirect: '/outbound/book',
-    meta: { title: '搴撳瓨绠$悊', icon: 'el-icon-box' },
+    meta: { title: '搴撳瓨绠$悊', icon: 'icon-biaogeziduan' },
     children: [
       {
         path: 'book',
+        name: '鏀跺彂瀛樼鐞�',
         component: () => import('@/views/outbound/index.vue'),
-        meta: { title: '搴撳瓨绠$悊', icon: 'el-icon-box' }
+        meta: { title: '鏀跺彂瀛樼鐞�', icon: 'icon-kucunguanli' }
+      },
+      {
+        path: 'outboundLedger',
+        name: '鍑哄簱鍙拌处',
+        component: () => import('@/views/outbound/outboundLedger'),
+        meta: { title: '鍑哄簱鍙拌处', icon: 'icon-taizhangzhangbuxinxichaxun' }
       }
       // ,{
       //   path: 'depositoryManagement',
@@ -122,7 +123,7 @@
     path: '/system',
     component: Layout,
     redirect: '/system/user',
-    meta: { title: '绯荤粺璁剧疆', icon: 'el-icon-box' },
+    meta: { title: '绯荤粺璁剧疆', icon: 'icon-yonghuguanli' },
     children: [
       // {
       //   path: 'index',
@@ -131,8 +132,9 @@
       // },
       {
         path: 'user',
+        name: '绯荤粺璁剧疆',
         component: () => import('@/views/system/user'),
-        meta: { title: '鐢ㄦ埛绠$悊', icon: 'el-icon-box' }
+        meta: { title: '鐢ㄦ埛绠$悊', icon: 'icon-yonghuguanli' }
       }
       // ,{
       //   path: 'dict',
@@ -146,7 +148,7 @@
 ]
 
 const createRouter = () => new Router({
-  // mode: 'history', // require service support
+  mode: 'history', // require service support
   scrollBehavior: () => ({ y: 0 }),
   routes: constantRoutes
 })
@@ -159,4 +161,40 @@
   router.matcher = newRouter.matcher // reset router
 }
 
+const getState = ()=> import("@/store/index")
+
+router.beforeEach(async (to, from, next) => {
+  // console.log(to,from)
+ let state = (await getState()).default.state
+  // console.log(state)
+  // console.log(to)
+  if (to.name === 'login') {
+    next()
+    return
+  }
+  // console.log("璺宠浆璺敱鍓嶇殑鍒ゆ柇")
+  let flag = false;
+  let {openTab} = state.openTab
+  // console.log(openTab)
+  for (let item of openTab) {
+    // console.log(item)
+    // console.log("item.name" , item.name)
+    // console.log("t0.name",to.name)
+
+    if(item.name === to.name) {
+      // console.log('to.path',to.path);
+      store.commit('SET_ACTIVE_INDEX',to.path)
+      flag = true;
+      break;
+    }
+  }
+  if(!flag) {
+    // console.log("鎵ц涓�閬�")
+    // console.log('to.path',to.path);
+    store.commit('ADD_TAB', {route: to.path, name: to.name});
+    store.commit('SET_ACTIVE_INDEX', to.path);
+  }
+  next()
+
+})
 export default router
diff --git a/src/settings.js b/src/settings.js
index dec7204..677572e 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -6,7 +6,7 @@
    * @type {boolean} true | false
    * @description Whether fix the header
    */
-  fixedHeader: false,
+  fixedHeader: true,
 
   /**
    * @type {boolean} true | false
diff --git a/src/store/getters.js b/src/store/getters.js
index 5ab7b4c..f89e136 100644
--- a/src/store/getters.js
+++ b/src/store/getters.js
@@ -2,7 +2,13 @@
   sidebar: state => state.app.sidebar,
   device: state => state.app.device,
   token: state => state.user.token,
+  refresh: state => state.user.refresh,
   avatar: state => state.user.avatar,
-  name: state => state.user.name
+  name: state => state.user.name,
+  authority: state => state.user.authority,
+  user: state => state.user,
+  openTab: state => state.openTab,
+  allTab: state => state.tableKey.allTab,
+  addTab: state => state.tableKey.allTab[0]
 }
 export default getters
diff --git a/src/store/index.js b/src/store/index.js
index 6be466a..bb857cf 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -4,6 +4,8 @@
 import app from './modules/app'
 import settings from './modules/settings'
 import user from './modules/user'
+import openTab from './modules/openTab'
+import tableKey from './modules/tableKey'
 
 Vue.use(Vuex)
 
@@ -11,7 +13,9 @@
   modules: {
     app,
     settings,
-    user
+    user,
+    openTab,
+    tableKey
   },
   getters
 })
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 2f6423f..4e41471 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -1,12 +1,15 @@
-import { login, logout, getInfo } from '@/api/user'
-import { getToken, setToken, removeToken } from '@/utils/auth'
+import { login, logout, getInfo, tideLogin } from '@/api/user'
+import { getToken, setToken, removeToken, getrefreshToken, setrefreshToken, removerefreshToken } from '@/utils/auth'
 import { resetRouter } from '@/router'
+var qs = require('qs')
 
 const getDefaultState = () => {
   return {
     token: getToken(),
+    refresh: getrefreshToken(),
     name: '',
-    avatar: ''
+    avatar: '',
+    authority: ''
   }
 }
 
@@ -19,23 +22,35 @@
   SET_TOKEN: (state, token) => {
     state.token = token
   },
+  SET_REFRESH: (state, refresh) => {
+    state.refresh = refresh
+  },
   SET_NAME: (state, name) => {
     state.name = name
   },
   SET_AVATAR: (state, avatar) => {
     state.avatar = avatar
+  },
+  SET_AUTHORITY: (state, authority) => {
+    state.authority = authority
   }
 }
 
 const actions = {
   // user login
   login({ commit }, userInfo) {
+    console.log(userInfo)
     const { username, password } = userInfo
+    console.log(typeof username)
     return new Promise((resolve, reject) => {
-      login({ username: username.trim(), password: password }).then(response => {
+      // login()
+      login(qs.stringify({ username: typeof username === 'number' ? username.toString().trim() : username.trim(), password: password })).then(response => {
         const { data } = response
+        console.log(data)
         commit('SET_TOKEN', data.token)
+        commit('SET_REFRESH', data.refresh)
         setToken(data.token)
+        setrefreshToken(data.refresh)
         resolve()
       }).catch(error => {
         reject(error)
@@ -47,16 +62,20 @@
   getInfo({ commit, state }) {
     return new Promise((resolve, reject) => {
       getInfo(state.token).then(response => {
-        const { data } = response
-
+        const { data, message } = response
+        console.log(response)
+        if (response.code === 10010) {
+          resolve(message)
+        }
         if (!data) {
           return reject('Verification failed, please Login again.')
         }
 
-        const { name, avatar } = data
+        const { name, avatar, authority } = data
 
         commit('SET_NAME', name)
         commit('SET_AVATAR', avatar)
+        commit('SET_AUTHORITY', authority)
         resolve(data)
       }).catch(error => {
         reject(error)
@@ -66,15 +85,25 @@
 
   // user logout
   logout({ commit, state }) {
+    console.log('閫�鍑虹櫥褰�')
     return new Promise((resolve, reject) => {
-      logout(state.token).then(() => {
-        removeToken() // must remove  token  first
-        resetRouter()
-        commit('RESET_STATE')
-        resolve()
-      }).catch(error => {
-        reject(error)
-      })
+      for (const key in state) {
+        state[key] = ''
+      }
+      removeToken() // must remove  token  first
+      removerefreshToken()
+      resetRouter()
+      commit('RESET_STATE')
+      resolve()
+      // logout(state.token).then(() => {
+      //   removeToken() // must remove  token  first
+      //   removerefreshToken()
+      //   resetRouter()
+      //   commit('RESET_STATE')
+      //   resolve()
+      // }).catch(error => {
+      //   reject(error)
+      // })
     })
   },
 
@@ -85,6 +114,29 @@
       commit('RESET_STATE')
       resolve()
     })
+  },
+
+  // flushed Token
+  flushedToken({ commit }, newTokens) {
+    console.log('鍒锋柊token')
+    commit('SET_TOKEN', newTokens.token)
+    commit('SET_REFRESH', newTokens.refresh)
+  },
+
+  tideLogin({ commit }, code) {
+    return new Promise((resolve, reject) => {
+      tideLogin(code).then(response => {
+        const { data } = response
+        console.log(data)
+        commit('SET_TOKEN', data.token)
+        commit('SET_REFRESH', data.refresh)
+        setToken(data.token)
+        setrefreshToken(data.refresh)
+        resolve()
+      }).catch(error => {
+        reject(error)
+      })
+    })
   }
 }
 
diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss
index 0062411..7ded498 100644
--- a/src/styles/element-ui.scss
+++ b/src/styles/element-ui.scss
@@ -1,5 +1,10 @@
 // cover some element-ui styles
-
+// .el-input{
+//   input{
+//     background: #fff !important;
+//     box-shadow: none !important;
+//   }
+// }
 .el-breadcrumb__inner,
 .el-breadcrumb__inner a {
   font-weight: 400 !important;
@@ -47,3 +52,4 @@
 .el-range-separator {
   box-sizing: content-box;
 }
+
diff --git a/src/styles/sidebar.scss b/src/styles/sidebar.scss
index d0f6384..440ecd9 100644
--- a/src/styles/sidebar.scss
+++ b/src/styles/sidebar.scss
@@ -90,17 +90,17 @@
       }
     }
     .el-menu-item{
-      height: auto;
-      line-height: normal;
-      font-size: 12px;
-      .sub-el-icon{
-        font-size: 36px;
-        margin: 12px 0;
-      }
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      margin-right: 0;
+      // height: auto;
+      // line-height: normal;
+      // font-size: 12px;
+      // .sub-el-icon{
+      //   font-size: 36px;
+      //   margin: 12px 0;
+      // }
+      // display: flex;
+      // flex-direction: column;
+      // align-items: center;
+      // margin-right: 0;
       
     }
   }
@@ -108,6 +108,9 @@
   .hideSidebar {
     .sidebar-container {
       width: 54px !important;
+      img{
+        display: none !important; 
+      }
     }
 
     .main-container {
@@ -154,7 +157,7 @@
     .el-menu--collapse {
       .el-submenu {
         &>.el-submenu__title {
-          &>span {
+          &>span:nth-child(2) {
             height: 0;
             width: 0;
             overflow: hidden;
diff --git a/src/styles/variables.scss b/src/styles/variables.scss
index d9dba33..91b67a3 100644
--- a/src/styles/variables.scss
+++ b/src/styles/variables.scss
@@ -1,10 +1,13 @@
 // sidebar
-$menuText:#ddecfd;
+$menuText:#bfcbd9;
+// $menuActiveText:#409EFF;
 $menuActiveText:#fff;
-$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
+// $subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
+$subMenuActiveText:#fff; //https://github.com/ElemeFE/element/issues/12951
 
-$menuBg:#6095FB;
-$menuHover:#4283fe;
+$menuBg:#304156;
+$menuHover:#263445;
+$menuHover:#263445;
 
 $subMenuBg:#1f2d3d;
 $subMenuHover:#001528;
diff --git a/src/utils/auth.js b/src/utils/auth.js
index 059af18..97eb961 100644
--- a/src/utils/auth.js
+++ b/src/utils/auth.js
@@ -1,7 +1,7 @@
 import Cookies from 'js-cookie'
 
 const TokenKey = 'vue_admin_template_token'
-
+const refreshToken = 'refreshToken'
 export function getToken() {
   return Cookies.get(TokenKey)
 }
@@ -13,3 +13,15 @@
 export function removeToken() {
   return Cookies.remove(TokenKey)
 }
+
+export function getrefreshToken() {
+  return Cookies.get(refreshToken)
+}
+
+export function setrefreshToken(token) {
+  return Cookies.set(refreshToken, token)
+}
+
+export function removerefreshToken() {
+  return Cookies.remove(refreshToken)
+}
diff --git a/src/utils/request.js b/src/utils/request.js
index 2fb95ac..943d164 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -2,19 +2,23 @@
 import { MessageBox, Message } from 'element-ui'
 import store from '@/store'
 import { getToken } from '@/utils/auth'
+import { refresh } from '@/api/user'
+import getters from '@/store/getters'
+import { setToken, setrefreshToken } from '@/utils/auth'
 
+var qs = require('qs')
 // create an axios instance
 const service = axios.create({
   baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
   // withCredentials: true, // send cookies when cross-domain requests
-  timeout: 5000 // request timeout
+  timeout: 10000 // request timeout
 })
-
 // request interceptor
 service.interceptors.request.use(
   config => {
+    // console.log('璇锋眰鎷︽埅鍣�===>', config)
     // do something before request is sent
-
+    // console.log(config)
     if (store.getters.token) {
       // let each request carry token
       // ['X-Token'] is a custom headers key
@@ -42,39 +46,48 @@
    * Here is just an example
    * You can also judge the status by HTTP Status Code
    */
-  response => {
-    const res = response.data
-
-    // if the custom code is not 20000, it is judged as an error.
-    if (res.code !== 20000) {
-      Message({
-        message: res.message || 'Error',
-        type: 'error',
-        duration: 5 * 1000
-      })
-
-      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
-      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
-        // to re-login
-        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
-          confirmButtonText: 'Re-Login',
-          cancelButtonText: 'Cancel',
-          type: 'warning'
-        }).then(() => {
-          store.dispatch('user/resetToken').then(() => {
-            location.reload()
-          })
-        })
-      }
-      return Promise.reject(new Error(res.message || 'Error'))
-    } else {
-      return res
+  async(response) => {
+    // console.log(response)
+    if (response.headers.requesttype === 'excel') {
+      return response
     }
+    const res = response.data
+    // console.log(store)
+    // console.log(store.state.user.refresh)
+    if (res.code === 10010) {
+      const { data: { token, refresh: refreshToken }} = await refresh(qs.stringify({ refresh: store.state.user.refresh }))
+      store.commit('SET_TOKEN', token)
+      store.commit('SET_REFRESH', refreshToken)
+      //  console.log('閲嶆柊鍒锋柊token鎴愬姛', token, refreshToken)
+      setToken(token)
+      setrefreshToken(refreshToken)
+      axios.request(response.config)
+      // console.log('token鍒锋柊', getters.refresh())
+      // refresh({ refresh : getters.refresh() })
+      // refresh({ refresh : getters.refresh() }).then((res)=>{
+      //   console.log(res)
+      // })
+      return Promise.resolve(res)
+    }
+    // if (res.code === 10010) {
+    //   console.log('token鍒锋柊')
+    //   refresh({ refresh : getters.refresh() }).then(async (res) => {
+    //     console.log(res)
+    //     await store.dispatch('flushedToken', res.data)
+    //   })
+    //   return axios.request(response.config)
+    // }
+    // console.log(res)
+    // if the custom code is not 20000, it is judged as an error.
+    return res
   },
   error => {
+    console.log(error)
+
     console.log('err' + error) // for debug
     Message({
-      message: error.message,
+      message: '閿欒锛岃閲嶆柊灏濊瘯',
+      // message: error.message,
       type: 'error',
       duration: 5 * 1000
     })
diff --git a/src/utils/validate.js b/src/utils/validate.js
index 8d962ad..fb1214a 100644
--- a/src/utils/validate.js
+++ b/src/utils/validate.js
@@ -15,6 +15,8 @@
  * @returns {Boolean}
  */
 export function validUsername(str) {
-  const valid_map = ['admin', 'editor']
-  return valid_map.indexOf(str.trim()) >= 0
+  // const valid_map = ['admin', 'editor']
+  // return valid_map.indexOf(str.trim()) >= 0
+  console.log(str)
+  return Number.isInteger(str)
 }
diff --git a/src/views/add_operation/barcode/index.vue b/src/views/add_operation/barcode/index.vue
index b78441d..68fa86b 100644
--- a/src/views/add_operation/barcode/index.vue
+++ b/src/views/add_operation/barcode/index.vue
@@ -1,15 +1,167 @@
 <template>
   <div class="barcode">
-    鏉$爜鎵撳嵃
+<!--缁戝畾id鏂规硶-->
+<!-- <div id='box'>
+   <p>鎵撳嵃鍐呭</p>
+</div>
+<div v-print='#box'>鎵撳嵃</div> -->
+<!--缁戝畾瀵硅薄鏂规硶-->
+<div id='printMe'>
+  <vue-barcode
+  :value="value"
+  >涓嶆敮鎸乿ue-barcode</vue-barcode>
+   <div>
+    <div>浜у搧鍚嶇О</div>
+    <div>鏁伴噺</div>
+    <div>鍗曚綅</div>
+   </div>
+   <div>
+    <div>鏃堕棿</div>
+    <div>瑙勬牸</div>
+   </div>
+</div>
+
+<div v-for="(item,index) in table" :key="index">
+  {{item}}
+</div>
+
+<el-button @click="showCode">鐢熸垚鏉″舰鐮�</el-button>
+<el-button v-print='printObj'>鎵撳嵃</el-button>
+<el-input v-show="false" class="input" v-model="value" ref="input"></el-input> 
+
   </div>
 </template>
 
 <script>
-export default {
+   import VueBarcode from 'vue-barcode'
 
+export default{
+   data(){
+      return {
+         printObj:{
+            id: "printMe", // 鎵撳嵃鐨勫尯鍩�
+            // preview: false, // 棰勮宸ュ叿鏄惁鍚敤
+            previewTitle: '鎵撳嵃鏉$爜', // 棰勮椤甸潰鐨勬爣棰�
+            popTitle: '', // 鎵撳嵃椤甸潰鐨勯〉鐪�
+            previewBeforeOpenCallback(vue) {
+              console.log('姝e湪鍔犺浇棰勮绐楀彛')
+            },
+            previewOpenCallback(vue) {
+              console.log('宸茬粡鍔犺浇瀹岄瑙堢獥鍙�')
+            },
+            clickMounted: (vue) => {
+              console.log("瑙﹀彂鐐瑰嚮鎵撳嵃鍥炶皟");
+              vue.isShowPrint = true  //寮规鏄剧ず鏉$爜
+            },
+            beforeOpenCallback(vue) {
+              console.log('鎵撳紑涔嬪墠',vue.barcodeNum)
+            },
+            openCallback (vue) {
+              vue.isShowPrint = false  // 鍏抽棴鏉$爜鏄剧ず寮规
+              console.log('鎵ц浜嗘墦鍗�',vue.barcodeNum)
+            },
+         },
+         value: '',
+         table:[]
+      }
+   },
+   components: { VueBarcode },
+   mounted() {
+    
+    this.makeCode('1234567891234567')
+    this.addScanMonitor()
+   },
+   methods: {
+    // 鐩戝惉鎵弿
+    showCode() {
+      this.makeCode('1234567891234567')
+// window.document.onkeypress=undefined
+    },
+    addScanMonitor() {
+      window.document.onkeypress = e => {
+        console.log(e)
+        if (window.event) { // IE
+          this.nextCode = e.keyCode
+        } else if (e.which) { // Netscape/Firefox/Opera
+          this.nextCode = e.which
+        }
+
+        if (e.which === 13) { // 閿洏鍥炶溅浜嬩欢
+          if (this.code.length < 3) return // 鎵爜鏋殑閫熷害寰堝揩锛屾墜鍔ㄨ緭鍏ョ殑鏃堕棿涓嶄細璁ヽode鐨勯暱搴﹀ぇ浜�2锛屾墍浠ヨ繖閲屼笉浼氬鎵爜鏋湁鏁�
+          console.log('鎵爜缁撴潫,鏉″舰鐮侊細', this.code)
+          this.table.push(this.code)
+          this.scanningForm.scanCode = this.code
+          this.lastCode = ''
+          this.lastTime = ''
+          this.handleSubmitScanning()
+          return
+        }
+
+        this.nextTime = new Date().getTime()
+        if (!this.lastTime && !this.lastCode) {
+          this.code = '' // 娓呯┖涓婃鐨勬潯褰㈢爜
+          // 缁х画鎵弿涓�涓嬫潯鍓嶅叧闂脊绐�
+          // this.handleCloseTipsVisible()
+          this.code += e.key
+          console.log('鎵爜寮�濮�---', this.code)
+        }
+        if (this.lastCode && this.lastTime && this.nextTime - this.lastTime > 500) { // 褰撴壂鐮佸墠鏈塳eypress浜嬩欢鏃�,闃叉棣栧瓧缂哄け
+          this.code = e.key
+          console.log('闃叉棣栧瓧缂哄け銆傘�傘��', this.code)
+        } else if (this.lastCode && this.lastTime) {
+          this.code += e.key
+          console.log('鎵爜涓�傘�傘��', this.code)
+        }
+        this.lastCode = this.nextCode
+        this.lastTime = this.nextTime
+      }
+    },
+    makeCode(msg) {
+      // let obj = {jack: '1212'}
+     this.value = msg
+
+    }
+   }
 }
 </script>
 
-<style>
+<style lang="scss">
 
+  #printMe{
+  // height: 4cm;
+  width: 8cm;
+  display: flex;
+  flex-direction: column;
+  text-align: center;
+  img{
+    display: inline-block;
+    text-align: center;
+    width: 6cm;
+    height: 2cm;
+  }
+  >div{
+    width: 100%;
+    display: flex;
+    >div{
+      flex: 1;
+      // height: 30px;
+      border: 1px solid #ddd;
+    }
+  }
+}
+@media print {
+  @page {
+    size: 8cm 4cm !important;
+    // margin: 0cm;
+    // padding: 0cm;
+    // size: portrait;
+    // border: 1px solid #ddd;
+    
+  }
+  #printMe{
+    display: block;
+    width: 100%;
+      overflow: hidden;
+    }
+  }
 </style>
\ No newline at end of file
diff --git a/src/views/add_operation/index.vue b/src/views/add_operation/index.vue
index 5e02ce2..c7bc5f8 100644
--- a/src/views/add_operation/index.vue
+++ b/src/views/add_operation/index.vue
@@ -1,90 +1,164 @@
 <template>
   <div class="addOperation">
     <div class="addOperation-main">
-      <!-- <el-form v-model="statusType" ref="queryForm" size="small" :inline="true" label-width="68px">
-            <el-form-item label="鍏ュ簱鐘舵��">
-           <el-radio-group v-model="inStatus">
-            <el-radio-button label="鍏ㄩ儴"></el-radio-button>
-            <el-radio-button label="宸插叆搴�"></el-radio-button>
-            <el-radio-button label="宸插嚭搴�"></el-radio-button>
-          </el-radio-group>
-            </el-form-item>
-            <el-form-item label="鍏ュ簱绫诲瀷" prop="phonenumber">
-             <el-radio-group v-model="inType">
-            <el-radio-button label="鏉$爜鎵撳嵃"></el-radio-button>
-          </el-radio-group>
-          </el-form-item>
-          <el-form-item label="鏉$爜鎵撳嵃">
-            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鏂板鏉$爜鎵撳嵃</el-button>
-          </el-form-item>
-      </el-form> -->
-     <el-row type="flex" align="middle" class="main-top">
-      <el-col :span="2"><el-button type="primary">鏂板鍏ュ簱</el-button></el-col>
-      <el-col :span="20">
-        <TableSearch></TableSearch>
-      </el-col>
-      <el-col :span="2"><el-button>鏉$爜鎵撳嵃</el-button></el-col>
-     </el-row>
-    <el-table
-      :stripe="true"
-      :data="tableData"
-      :cell-style="{ textAlign: 'center' }"
-      :header-cell-style="{ textAlign: 'center' }"
-      :border="true"
-      header-row-class-name="table-header"
-    >
-      <el-table-column
-        prop="date"
-        label="搴忓彿">
-      </el-table-column>
-      <el-table-column
-        prop="name"
-        label="浜у搧缂栫爜">
-      </el-table-column>
-      <el-table-column
-        prop="address"
-        label="浜у搧鍚嶇О">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="瑙勬牸鍨嬪彿">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="鍗曚綅">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="鍏ュ簱鏁伴噺">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="鍏ュ簱浜�">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="鍏ュ簱鏃ユ湡">
-      </el-table-column>
-    </el-table>
-    </div>
-    <div class="addOperation-foot">
-      <el-pagination
-      :current-page="searchModel.pageNo"
-      :page-sizes="[10, 15, 20, 25]"
-      :page-size="searchModel.pageSize"
-      layout="->, total, sizes, prev, pager, next, jumper"
-      :total="total"
-      @size-change="handleSizeChange"
-      @current-change="handleCurrentChange"
+      <el-row type="flex" align="middle" class="main-top">
+        <el-col :span="2"><el-button icon="el-icon-plus" type="primary" @click="addOperation">鏂板鍏ュ簱</el-button></el-col>
+        <el-col :span="20">
+          <TableSearch :show="true" :excel-name="'鍏ュ簱琛�'" :file="file" :get-list="getList" :search-data="searchData" :search-params="searchModel" :options="options" />
+        </el-col>
+        <el-col :span="2"><el-button icon="iconfont icon-24px " @click="printFormVisible = true">鏉$爜鎵撳嵃</el-button></el-col>
+      </el-row>
+      <el-table
+        :row-class-name="onTableRowClassName"
+        :row-style="{height:0+'px'}"
+        :cell-style="{padding:8+'px',textAlign: 'center'}"
+        :header-cell-style="{borderRight:'0px',textAlign: 'center',background:'#52626F',color:'#fff', height:'10px', padding:'0px'}"
+        :stripe="true"
+        :data="tableData"
+        :border="true"
+        header-row-class-name="table-header"
       >
-    </el-pagination>
+        <el-table-column
+          label="搴忓彿"
+        >
+          <template v-slot="scope">
+            {{ (addPageParams.pageNo-1) * addPageParams.pageSize + scope.$index + 1 }}
+          </template>
+        </el-table-column>
+        <el-table-column
+          v-for="(item, index) in getKeys()"
+          v-if="item.show"
+          :key="index"
+          :prop="item.prop"
+          :label="item.name"
+        />
+      </el-table>
+      <div class="addOperation-foot">
+        <el-pagination
+          :current-page="searchModel.pageNo"
+          :page-sizes="[10, 15, 20, 25]"
+          :page-size="searchModel.pageSize"
+          layout="->, total, sizes, prev, pager, next, jumper"
+          :total="total"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
     </div>
+
+    <el-dialog title="鏂板鍏ュ簱" :visible.sync="addFormVisible" @close="addFormClose">
+      <el-form :model="addParams" label-position="left">
+        <el-table
+          :height="250"
+          :max-height="250"
+          :row-class-name="onTableRowClassName"
+          :row-style="{height:0+'px'}"
+          :cell-style="{padding:8+'px',textAlign: 'center'}"
+          :header-cell-style="{borderRight:'0px',textAlign: 'center',background:'#52626F',color:'#fff', height:'10px', padding:'0px'}"
+          :stripe="true"
+          :border="true"
+          header-row-class-name="table-header"
+          :data="this.addTable.slice(0, addPageParams.pageSize)"
+        >
+          <!-- <el-table-column property="addPerson" label="搴忓彿" >
+          </el-table-column> -->
+          <el-table-column property="productCode" label="浜у搧缂栫爜" />
+          <el-table-column property="productName" label="浜у搧鍚嶇О" />
+          <el-table-column property="productModel" label="瑙勬牸鍨嬪彿" />
+          <el-table-column property="unit" label="鍗曚綅" />
+          <el-table-column property="incomingQuantity" label="鍏ュ簱鏁伴噺" />
+          <el-table-column property="addPerson" label="鍏ュ簱浜�" />
+          <!-- <el-table-column property="address" label="鍏ュ簱鏃ユ湡"></el-table-column> -->
+        </el-table>
+        <div :style="{display: 'flex',justifyContent:'center',marginTop: '10px'}">
+          <el-pagination
+            :current-page="addPageParams.pageNo"
+            :page-sizes="[3, 4, 5, 6]"
+            :page-size="addPageParams.pageSize"
+            layout="->, total, sizes, prev, pager, next, jumper"
+            :total="addTable.length"
+            @size-change="inHandleSizeChange"
+            @current-change="inHandleCurrentChange"
+          />
+        </div>
+
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="storage">纭� 瀹�</el-button>
+        <el-button @click="addFormVisible = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog title="鏉$爜鎵撳嵃" :visible.sync="printFormVisible">
+      <el-form :model="printParams" label-position="left">
+        <el-row :gutter="20">
+          <el-col>
+            <el-form-item label="浜у搧鍚嶇О/瑙勬牸:" :label-width="formLabelWidth">
+              <el-cascader
+                v-model="chooseTypeName"
+                :options="scanTypeNameOptions"
+                @change="handleChange"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col>
+            <el-form-item label="浜у搧缂栫爜:" :label-width="formLabelWidth">
+              <el-input :value="printParams.productCode" :disabled="true" autocomplete="off" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍗曚綅:" :label-width="formLabelWidth">
+              <el-input v-model="printParams.unit" autocomplete="off" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏ュ簱鏁伴噺:" :label-width="formLabelWidth">
+              <el-input v-model="printParams.incomingQuantity" type="number" autocomplete="off" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="print">纭� 瀹�</el-button>
+        <el-button @click="printFormVisible = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog :visible.sync="printVisible" @close="printFormClose">
+      <div class="printMian">
+        <div id="printMe">
+          <vue-barcode :height="50" :width="2" :value="code" />
+          <div>
+            <div>{{ printParams.productName }}</div>
+            <div>{{ printParams.incomingQuantity }}</div>
+            <div>{{ printParams.unit }}</div>
+          </div>
+          <div>
+            <div :style="{flex:'2', paddingRight:'1px'}">2022-01-01 10:00</div>
+            <div>{{ printParams.productModel }}</div>
+          </div>
+        </div>
+      </div>
+      <div class="btn" :style="{display: 'flex',justifyContent: 'center'}">
+        <el-button v-print="printObj" :style="{width:'8cm',margin:'10px'}" type="primary">鎵撳嵃</el-button>
+
+      </div>
+
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import { getList } from '@/api/table'
+import { getList, file, addCache, selectCache, add } from '@/api/addOperation'
+import { selectAllName } from '@/api/productName'
+import { selectAllModel } from '@/api/productModel'
+import { mapGetters } from 'vuex'
 import TableSearch from '@/components/TableSearch'
+import VueBarcode from 'vue-barcode'
+
 export default {
   filters: {
     statusFilter(status) {
@@ -98,86 +172,278 @@
   },
   data() {
     return {
-      pickerOptions: {
-          shortcuts: [{
-            text: '鏈�杩戜竴鍛�',
-            onClick(picker) {
-              const end = new Date();
-              const start = new Date();
-              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
-              picker.$emit('pick', [start, end]);
-            }
-          }, {
-            text: '鏈�杩戜竴涓湀',
-            onClick(picker) {
-              const end = new Date();
-              const start = new Date();
-              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
-              picker.$emit('pick', [start, end]);
-            }
-          }, {
-            text: '鏈�杩戜笁涓湀',
-            onClick(picker) {
-              const end = new Date();
-              const start = new Date();
-              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
-              picker.$emit('pick', [start, end]);
-            }
-          }]
+      printObj: {
+        id: 'printMe', // 鎵撳嵃鐨勫尯鍩�
+        // preview: false, // 棰勮宸ュ叿鏄惁鍚敤
+        previewTitle: '鎵撳嵃鏉$爜', // 棰勮椤甸潰鐨勬爣棰�
+        popTitle: '', // 鎵撳嵃椤甸潰鐨勯〉鐪�
+        previewBeforeOpenCallback(vue) {
+          console.log('姝e湪鍔犺浇棰勮绐楀彛')
         },
-      inType: '',
-      inStatus: '',
-      deptName: '',
-      statusType: {},
-      queryParams: {
-        encode: '',
-        type: '',
-        depositor: ''
+        previewOpenCallback(vue) {
+          console.log('宸茬粡鍔犺浇瀹岄瑙堢獥鍙�')
+        },
+        clickMounted: (vue) => {
+          console.log('瑙﹀彂鐐瑰嚮鎵撳嵃鍥炶皟')
+          // vue.isShowPrint = true // 寮规鏄剧ず鏉$爜
+        },
+        beforeOpenCallback(vue) {
+          console.log('鎵撳紑涔嬪墠', vue.barcodeNum)
+        },
+        openCallback(vue) {
+          // vue.isShowPrint = false // 鍏抽棴鏉$爜鏄剧ず寮规
+          // 娓呯┖鏉$爜鎵撳嵃鏁版嵁
+          vue.printFormVisible = false
+          vue.printVisible = false
+          vue.chooseTypeName = ''
+          for (const key in vue.printParams) {
+            vue.printParams[key] = ''
+          }
+          console.log('鎵ц浜嗘墦鍗�', vue.barcodeNum)
+        }
       },
+      printVisible: false,
+      file,
+      getList,
+      options: [],
+      chooseTypeName: {},
+      scanData: {},
+      scanTypeNameOptions: [],
       total: 0,
       searchModel: {
         pageNo: 1,
-        pageSize: 10
+        pageSize: 10,
+        endTime: '',
+        productModel: '',
+        startTime: ''
       },
-      tableData: [{
-        date: '2016-05-02',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1518 寮�'
-      }, {
-        date: '2016-05-04',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1517 寮�'
-      }, {
-        date: '2016-05-01',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1519 寮�'
-      }, {
-        date: '2016-05-03',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1516 寮�'
-      }, {
-        date: '2016-05-03',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1516 寮�'
-      }, {
-        date: '2016-05-03',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1516 寮�'
-      }]
+      tableData: [],
+      addFormVisible: false,
+      printFormVisible: false,
+      printParams: {
+        addPerson: '',
+        incomingQuantity: '',
+        productModelId: '',
+        productNameId: '',
+        unit: '',
+        productCode: ''
+      },
+      showAddTable: [],
+      addTable: [],
+      addCodeTable: [],
+      addParams: {
+        name: '', // 浜у搧鍚嶇О
+        specs: '', // 浜у搧瑙勬牸
+        unit: '', // 鍗曚綅
+        number: '', // 鏁伴噺
+        depositor: '', // 鍏ュ簱浜猴紝鍙互涓哄叆搴撲汉id
+        date: '' // 鏃堕棿
+      },
+      formLabelWidth: '120px',
+      addPageParams: {
+        pageNo: 1,
+        pageSize: 3
+      },
+      code: ''
     }
+  },
+  computed: {
+    ...mapGetters([
+      'sidebar',
+      'avatar',
+      'name',
+      'addTab'
+    ])
+  },
+  watch: {
+    addFormVisible(to) {
+      if (!to) {
+        this.addTable = []
+        this.addCodeTable = []
+        window.document.onkeypress = undefined
+      }
+    }
+
   },
   created() {
     this.fetchData()
+    this.setOptions()
+    // console.log(this.$route,this.$router)
   },
   components: {
-    TableSearch
+    TableSearch,
+    VueBarcode
+  },
+  mounted() {
+    console.log(this.addTab[0])
+  },
+  beforeDestroy() {
+    window.document.onkeypress = null
   },
   methods: {
+    getKeys() {
+      return this.$store.state.tableKey.allTab[0].keys
+    },
+    addScanMonitor() {
+      window.document.onkeypress = e => {
+        console.log(e)
+        if (window.event) { // IE
+          this.nextCode = e.keyCode
+        } else if (e.which) { // Netscape/Firefox/Opera
+          this.nextCode = e.which
+        }
+
+        if (e.which === 13) { // 閿洏鍥炶溅浜嬩欢
+          console.log(new Date().getTime())
+          if (new Date().getTime() - this.lastTime > 40) {
+            return this.$message.error('鎵爜鏃朵笉鍙�氳繃閿洏杈撳叆')
+          }
+          // if (this.code.length < 3) return // 鎵爜鏋殑閫熷害寰堝揩锛屾墜鍔ㄨ緭鍏ョ殑鏃堕棿涓嶄細璁ヽode鐨勯暱搴﹀ぇ浜�2锛屾墍浠ヨ繖閲屼笉浼氬鎵爜鏋湁鏁�
+          console.log('鎵爜缁撴潫,鏉″舰鐮侊細', this.code)
+          // 鍙戦�佽姹�
+          if (this.addCodeTable.includes(this.code)) {
+            this.$message.error('璇峰嬁閲嶅鎵弿')
+            this.handleSubmitScanning()
+            return
+          }
+          selectCache({ code: this.code }).then(res => {
+            // 閫氳繃鎵弿鏉$爜鏌ヨ浜у搧淇℃伅鍔犲叆鍏ュ簱鏁扮粍涓�
+            this.$message.success(`${this.code}鎵弿鎴愬姛`)
+            res.data.addPerson = this.name
+            console.log(res, this.addCodeTable)
+            this.addTable.push(res.data)
+            this.addCodeTable.push(this.code)
+          })
+
+          this.scanningForm.scanCode = this.code
+          this.lastCode = ''
+          this.lastTime = ''
+          this.handleSubmitScanning()
+          return
+        }
+
+        this.nextTime = new Date().getTime()
+        if (!this.lastTime && !this.lastCode) {
+          this.code = '' // 娓呯┖涓婃鐨勬潯褰㈢爜
+          // 缁х画鎵弿涓�涓嬫潯鍓嶅叧闂脊绐�
+          // this.handleCloseTipsVisible()
+          this.code = this.code + '' + e.key
+          console.log('鎵爜寮�濮�---', this.code)
+        }
+        if (this.lastCode && this.lastTime && this.nextTime - this.lastTime > 500) { // 褰撴壂鐮佸墠鏈塳eypress浜嬩欢鏃�,闃叉棣栧瓧缂哄け
+          this.code = e.key
+          console.log('闃叉棣栧瓧缂哄け銆傘�傘��', this.code)
+        } else if (this.lastCode && this.lastTime) {
+          this.code = this.code + '' + e.key
+          console.log('鎵爜涓�傘�傘��', this.code)
+        }
+        this.lastCode = this.nextCode
+        this.lastTime = this.nextTime
+      }
+    },
+    // 鍏抽棴鎵弿鍏ュ簱寮圭獥
+    addFormClose() {
+      console.log('娓呯┖鏁版嵁')
+      // 娓呯┖鏁版嵁
+      this.addTable = []
+      this.addCodeTable = []
+    },
+    // 鐐瑰嚮鏂板鍏ュ簱
+    addOperation() {
+      this.addFormVisible = true
+      this.addScanMonitor()
+    },
+    printFormClose() {
+      for (const key in this.printParams) {
+        this.printParams[key] = ''
+      }
+      this.chooseTypeName = ''
+    },
+    async setOptions() {
+      const { data: nameRes } = await selectAllName()
+      // console.log(nameRes)
+      const nameArr = nameRes.productNames.map(item => {
+        return { value: item.id, label: item.productName }
+      })
+      for (const nameItem of nameArr) {
+        const { data } = await selectAllModel({ productNameId: nameItem.value })
+        // console.log(data)
+        this.options = [...this.options, ...data.models]
+        nameItem.children = data.models.map(item => {
+          return { value: item.id, label: item.productModel, productCode: item.productCode }
+        })
+      }
+
+      this.options = this.options.map(item => {
+        return { label: item.productModel, value: item.productModel, productCode: item.productCode }
+      })
+      this.scanTypeNameOptions = nameArr
+      // console.log(this.options)
+      // console.log(nameArr)
+    },
+    searchData(res) {
+      console.log(res)
+      const { row, total, productModel, startTime, endTime } = res
+      this.tableData = row
+      this.total = total
+      this.searchModel.productModel = productModel
+      this.searchModel.startTime = startTime
+      this.searchModel.endTime = endTime
+    },
+    handleChange(value) {
+      console.log(value)
+      this.printParams.productNameId = value[0]
+      this.printParams.productModelId = value[1]
+      console.log(this.scanTypeNameOptions)
+      const nameObj = this.scanTypeNameOptions.filter(item => item.value === value[0])
+      console.log(nameObj[0].label)
+      this.printParams.productName = nameObj[0].label
+      const children = nameObj[0].children
+      this.printParams.productCode = children.filter(item => item.value === value[1])[0].productCode
+      console.log(children.filter(item => item.value === value[1])[0].label)
+      this.printParams.productModel = children.filter(item => item.value === value[1])[0].label
+    },
+    onTableRowClassName({ row, rowIndex }) {
+      if (rowIndex % 2 != 0) {
+        return 'onAcitve'
+      } else {
+        return ''
+      }
+    },
+    storage() {
+      // 杈撳嚭鍏ュ簱鍙傛暟
+      if (this.addCodeTable.length === 0) return this.$message.error('璇峰厛鎵弿鏁版嵁鍏ュ簱')
+      add({ code: this.addCodeTable, addPerson: this.name }).then(() => {
+        this.addTable = []
+        this.addCodeTable = []
+        this.fetchData()
+        this.addFormVisible = false
+        this.$message.success('鍏ュ簱鎴愬姛')
+      })
+    },
+    async print() {
+      console.log('鐢熸垚鏉$爜')
+      this.printParams.addPerson = this.name
+      console.log(this.printParams)
+      const res = await addCache(this.printParams)
+      this.code = res.message
+      this.printFormVisible = false
+      // for( key in this.printParams){
+      //   this.printParams[key] = ''
+      // }
+      this.printVisible = true
+    },
     fetchData() {
       this.listLoading = true
-      getList().then(response => {
-        this.list = response.data.items
+      const obj = {}
+      const arr = Object.keys(this.searchModel).filter(key => this.searchModel[key])
+      arr.forEach(item => obj[item] = this.searchModel[item])
+      console.log(obj)
+      getList(obj).then(response => {
+        this.tableData = response.data.row
+        this.total = response.data.total
         this.listLoading = false
+        // console.log(this.tableData)
       })
     },
     handleSizeChange(val) {
@@ -185,31 +451,110 @@
     },
     handleCurrentChange(val) {
       console.log(`褰撳墠椤�: ${val}`)
+      this.searchModel.pageNo = val
+      this.fetchData()
+    },
+    inHandleSizeChange(val) {
+      console.log(`姣忛〉 ${val} 鏉)
+    },
+    inHandleCurrentChange(val) {
+      console.log(`褰撳墠椤�: ${val}`)
+      this.addPageParams.pageNo = val
+      // console.log(this.addTable.slice((this.addPageParams.pageSize * (val - 1)), (this.addPageParams.pageSize * (val - 1)) + this.addPageParams.pageSize))
     }
   }
+
 }
 </script>
 
 <style lang="scss" scoped>
+.printMian{
+  display: flex;
+  justify-content: center;
+  .btn{
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    .el-button{
+      width: 100%;
+    }
+  }
+}
 @import '../../styles/variables.scss';
+  #printMe{
+  // height: 4cm;
+  // visibility:hidden;
+  width: 8cm;
+  display: flex;
+  flex-direction: column;
+  text-align: center;
+  img{
+    align-items: center;
+    display: inline-block;
+    text-align: center;
+    width: 8cm;
+    height: 1.5cm;
+  }
+  >div{
+    width: 100%;
+    display: flex;
+    >div{
+      flex: 1;
+      // height: 30px;
+      border: 1px solid #ddd;
+      padding: 2px;
+    }
+  }
+}
+@media print {
+  @page {
+    size: 8cm 4cm !important;
+    // margin: 0cm;
+    // padding: 0cm;
+    // size: portrait;
+    // border: 1px solid #ddd;
+
+  }
+
+  }
 .addOperation {
- min-height: calc(100vh - 50px);
+ min-height: calc(100vh - 100px);
+ max-height: calc(100vh - 100px);
  padding: 25px;
+// margin: 25px;
  background: $mainBg;
+ display: flex;
+ flex-direction: column;
+
+ .dialog-footer{
+  text-align: center;
+
+ }
  .addOperation-main{
   background: #fff;
   padding: 20px;
+  flex: 80%;
+  display: flex;
+  flex-direction: column;
   .main-top{}
   .table-header{
     background: #6095FB;
   }
- }
- .addOperation-foot{
-  margin-top: 25px;
-  .el-pagination{
-    display: flex;
-    justify-content: center;
+  ::v-deep .el-table{
+    flex: 1;
+   ::v-deep .onAcitve td{
+    background-color: #F2F2F2 !important;
+  }
+  }
+    .addOperation-foot{
+    // flex: 20%;
+    margin-top: 25px;
+    .el-pagination{
+      display: flex;
+      justify-content: right;
+    }
   }
  }
+
 }
 </style>
diff --git a/src/views/home/index.vue b/src/views/home/index.vue
index bef0609..1374550 100644
--- a/src/views/home/index.vue
+++ b/src/views/home/index.vue
@@ -1,87 +1,194 @@
+<!-- eslint-disable vue/attributes-order -->
 <template>
   <div class="dashboard-container">
-      <div class="home-annular-list">
-        <div class="annular-item" v-for="item in 4" :key="item">
-        </div>
+    <el-empty
+      description="鏆傛棤鏁版嵁"
+      v-if="chartData.PieData&&chartData.DailyTotal&&
+        chartData.WeekNumData&&chartData.ExceedThirtyDay.length!=0
+      "
+    />
+    <template v-else>
+      <div class="home-annular-list" v-show="chartData.PieData">
+        <div v-for="item in 4" :key="item" class="annular-item " :class="'pie'+item" />
       </div>
       <div class="home-line-bar">
         <div class="left">
-          <div class="top">1</div>
-          <div class="bottom">1</div></div>
+          <div class="top" />
+          <div class="bottom">
+            涓磋繎30澶╁簱瀛�
+            <div>
+              <el-table
+                :data="exceedThirtyDay"
+                stripe
+                style="width: 100%"
+              >
+                <el-table-column
+                  prop="product_name"
+                  label="浜у搧鍚嶇О"
+                />
+                <el-table-column
+                  prop="RemainingDays"
+                  label="浜у搧搴撳瓨"
+                />
+                <el-table-column
+                  prop="product_code"
+                  label="浜у搧缂栫爜"
+                />
+                <el-table-column
+                  prop="product_model"
+                  label="浜у搧瑙勬牸"
+                />
+                <el-table-column
+                  prop="unit"
+                  label="鍗曚綅"
+                />
+              </el-table>
+            </div>
+          </div>
+        </div>
         <div class="right">
-         1
+          <div />
         </div>
       </div>
+    </template>
+
   </div>
 </template>
 
 <script>
+import { getList } from '@/api/home'
 import { mapGetters } from 'vuex'
 import * as echarts from 'echarts'
 export default {
   name: 'Home',
+  data() {
+    return {
+      exceedThirtyDay: [],
+      show: true,
+      chartData: {}
+    }
+  },
   computed: {
     ...mapGetters([
       'name'
     ])
   },
   mounted() {
-    console.log(echarts)
+    // console.log(echarts)
+    this.echartsInit()
+
+    // 鍒锋柊鏃朵互褰撳墠璺敱鍋氫负tab鍔犲叆tabs
+    // 褰撳墠璺敱涓嶆槸棣栭〉鏃讹紝娣诲姞棣栭〉浠ュ強鍙︿竴椤靛埌store閲岋紝骞惰缃縺娲荤姸鎬�
+    // 褰撳綋鍓嶈矾鐢辨槸棣栭〉鏃讹紝娣诲姞棣栭〉鍒皊tore锛屽苟璁剧疆婵�娲荤姸鎬�
+    if (this.$route.path !== '/' && this.$route.path !== '/home') {
+      console.log('1')
+      this.$store.commit('ADD_TAB', { route: '/home', name: '涓婚〉' })
+      this.$store.commit('ADD_TAB', { route: this.$route.path, name: this.$route.name })
+      this.$store.commit('SET_ACTIVE_INDEX', this.$route.path)
+    }
+    // else {
+    //   console.log('2');
+    //   this.$store.commit('ADD_TAB', {route: '/home', name: 'home'});
+    //   this.$store.commit('SET_ACTIVE_INDEX', '/home');
+    //   this.$router.push('/');
+    // }
+
+    console.log(this.$store.state)
+  },
+  created() {
     this.echartsInit()
   },
   methods: {
-    echartsInit() {
-      let boxArr = document.querySelectorAll(".annular-item")
-      boxArr.forEach((item) => {
-        echarts.init(item).setOption({
-          legend: {
-            type: 'scroll',
-            align: 'left',
-            orient: 'vertical',
-            x: 'right',
-            y: 'center'
-          },
-          title: {
-            text: '楗煎浘绾圭悊',
-            textStyle: {
-              color: '#235894'
-            }
-          },
-          tooltip: {
-            trigger: 'item'
-          },
-  series: [
-    {
-      name: 'Access From',
-      type: 'pie',
-      radius: ['40%', '70%'],
-      center: ['25%', '50%'],
-      avoidLabelOverlap: false,
-      itemStyle: {
-        borderRadius: 5,
-        borderColor: '#fff',
-        borderWidth: 2
-      },
-      label: {
-        show: false,
-        position: 'left'
-      },
-      labelLine: {
-        show: false
-      },
-      data: [
-        { value: 1048, name: 'Search Engine' },
-        { value: 735, name: 'Direct' },
-        { value: 580, name: 'Email' },
-        { value: 484, name: 'Union Ads' },
-        { value: 300, name: 'Video Ads' }
-      ]
-    }
-  ]
-})
+    getData() {
+    },
+    getPie(PieData, className) {
+      console.log(className)
+      const box = document.querySelector(className)
+      echarts.init(box).setOption({
+        legend: {
+          type: 'scroll',
+          align: 'left',
+          orient: 'vertical',
+          x: 'right',
+          y: 'center'
+        },
+        title: {
+          text: '楗煎浘绾圭悊',
+          textStyle: {
+            color: '#235894'
+          }
+        },
+        tooltip: {
+          trigger: 'item'
+        },
+        series: [
+          {
+            name: PieData.datetime,
+            type: 'pie',
+            radius: ['40%', '70%'],
+            center: ['25%', '50%'],
+            avoidLabelOverlap: false,
+            itemStyle: {
+              borderRadius: 5,
+              borderColor: '#fff',
+              borderWidth: 2
+            },
+            label: {
+              show: false,
+              position: 'left'
+            },
+            labelLine: {
+              show: false
+            },
+            data: [
+              { value: PieData.addNum, name: '鍏ュ簱鏁扮洰' },
+              { value: PieData.outNum, name: '鍑哄簱鏁扮洰' },
+              { value: PieData.beginningMonth, name: '鏈堝垵搴撳瓨' },
+              { value: PieData.endOfMonth, name: '鏈堟湯搴撳瓨' }
+            ]
+          }
+        ]
       })
-    
-      let letTop = document.querySelector(".top")
+    },
+    getLine(DailyTotal) {
+      const right = document.querySelector('.right')
+      echarts.init(right).setOption({
+        legend: {
+
+          x: 'center',
+          slected: true
+        },
+        title: {
+          text: '浠撳簱缁熻',
+          textStyle: {
+            color: '#235894'
+          }
+        },
+        tooltip: {
+          trigger: 'item'
+        },
+        xAxis: {
+          type: 'category',
+          boundaryGap: false,
+          data: DailyTotal?.xList
+        },
+        yAxis: {
+          type: 'value'
+        },
+        series: [
+          {
+            data: DailyTotal?.yList,
+            type: 'line',
+            smooth: true,
+            name: '姣忔棩鎬昏',
+            areaStyle: {}
+          }
+
+        ]
+      })
+    },
+    getBar(WeekNumData) {
+      const letTop = document.querySelector('.top')
       echarts.init(letTop).setOption({
         grid: {
           left: '3%',
@@ -90,75 +197,52 @@
           containLabel: true
         },
         legend: {
-            x: 'center',
-            y: 'top'
+          x: 'center',
+          y: 'top'
+        },
+        title: {
+          text: '浠撳簱缁熻',
+          textStyle: {
+            color: '#235894'
+          }
+        },
+        tooltip: {
+          trigger: 'item'
+        },
+        xAxis: {
+          type: 'category',
+          data: WeekNumData.xList
+        },
+        yAxis: {
+          type: 'value'
+        },
+        series: [
+          {
+            data: WeekNumData.yOutList,
+            name: '鍑哄簱鏁伴噺',
+            type: 'bar'
           },
-          title: {
-            text: '浠撳簱缁熻',
-            textStyle: {
-              color: '#235894'
-            }
-          },
-          tooltip: {
-            trigger: 'item'
-          },
-  xAxis: {
-    type: 'category',
-    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-  },
-  yAxis: {
-    type: 'value'
-  },
-  series: [
-    {
-      data: [120, 200, 150, 80, 70, 110, 130],
-      name: '鍑哄簱鏁伴噺',
-      type: 'bar'
+          {
+            data: WeekNumData.yEnterList,
+            name: '鍏ュ簱鏁伴噺',
+            type: 'bar'
+          }
+        ]
+      })
     },
-    {
-      data: [220, 210, 80, 110, 30, 80, 130],
-      name: '鍏ュ簱鏁伴噺',
-      type: 'bar'
-    }
-  ]
-})
-    
+    async echartsInit() {
+      const res = await getList()
+      const { data } = res
+      this.chartData = { ...data }
+      console.log(this.chartData)
+      data.PieData?.forEach((item, index) => {
+        console.log(item)
+        this.getPie(item, '.pie' + (index + 1))
+      })
 
-      let right = document.querySelector(".right")
-      echarts.init(right).setOption({
-        legend: {
-           
-            x: 'center',
-            slected: true
-          },
-          title: {
-            text: '浠撳簱缁熻',
-            textStyle: {
-              color: '#235894'
-            }
-          },
-          tooltip: {
-            trigger: 'item'
-          },
-  xAxis: {
-    type: 'category',
-    boundaryGap: false,
-    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-  },
-  yAxis: {
-    type: 'value'
-  },
-  series: [
-    {
-      data: [820, 932, 901, 934, 1290, 1330, 1320],
-      type: 'line',
-      smooth: true,
-      name: '鏁版嵁1',
-      areaStyle: {}
-    }
-    
-  ]
-})
+      this.getBar(data.WeekNumData)
+      this.getLine(data.DailyTotal)
+      this.exceedThirtyDay = data.ExceedThirtyDay
     }
   }
 }
@@ -178,15 +262,14 @@
   }
 }
 .home-annular-list{
-  
-  margin: 12px;
+  margin: 12px 0;
   display: flex;
   justify-content: space-between;
   .annular-item{
-    width:   350px;
-    height: 240px;
+    width:  300px;
+    height: 200px;
     border-radius: 10px;
-    padding: 25px;
+    padding: 20px;
     background: #fff;
     // margin: 0 12px;
   }
@@ -223,6 +306,8 @@
       background: #fff;
       padding: 25px;
       border-radius: 10px;
+      // max-width: 500px;
+      max-height: 328px;
     }
   }
 }
diff --git a/src/views/login/index.vue b/src/views/login/index.vue
index 238a78d..1dc390b 100644
--- a/src/views/login/index.vue
+++ b/src/views/login/index.vue
@@ -4,65 +4,71 @@
       <div class="logo">
         <img src="../../assets/images/logo.png" alt="">
       </div>
-      <div>
-        |
-      </div>
       <div class="logo-title">
-        涓ぉ绉戞妧WMS绯荤粺
+        WMS绯荤粺
       </div>
     </div>
-    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
-
-      <div class="title-container">
-        <div>
-        <div class="title">绯荤粺鐧诲綍</div>
-        <div class="scan-icon">灏忓浘鏍�</div>
+    <div class="logo-main">
+      <div class="main-img">
+        <img src="@/assets/images/loginbg.png" alt="">
+      </div>
+      <!-- <el-form ref="loginForm" :model="loginForm" :rules="loginRules" :rules="loginRules" class="login-form" auto-complete="on" label-position="left"> -->
+      <el-form ref="loginForm" :status-icon="true" :model="loginForm"  class="login-form" auto-complete="on" label-position="left">
+        <div v-show="!showCode" class="title-container">
+          <div>
+            <div class="title">鐧诲綍</div>
+            <div class="scan-icon iconfont icon-saoyisao" />
+          </div>
         </div>
-      </div>
+        <el-form-item v-show="!showCode" size="size" prop="username">
+          <span class="svg-container">
+            <i class="el-icon-user" />
+          </span>
+          <el-input
+            ref="username"
+            v-model.number="loginForm.username"
+            size="mini"
+            placeholder="璐﹀彿"
+            name="username"
 
-      <el-form-item prop="username">
-        <span class="svg-container">
-          <svg-icon icon-class="user" />
-        </span>
-        <el-input
-          ref="username"
-          v-model="loginForm.username"
-          placeholder="Username"
-          name="username"
-          type="text"
-          tabindex="1"
-          auto-complete="on"
-        />
-      </el-form-item>
+            tabindex="1"
+            auto-complete="on"
+          />
+        </el-form-item>
 
-      <el-form-item prop="password">
-        <span class="svg-container">
-          <svg-icon icon-class="password" />
-        </span>
-        <el-input
-          :key="passwordType"
-          ref="password"
-          v-model="loginForm.password"
-          :type="passwordType"
-          placeholder="Password"
-          name="password"
-          tabindex="2"
-          auto-complete="on"
-          @keyup.enter.native="handleLogin"
-        />
-        <span class="show-pwd" @click="showPwd">
-          <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
-        </span>
-      </el-form-item>
+        <el-form-item v-show="!showCode" size="size" prop="password">
+          <span class="svg-container">
+            <i class="el-icon-lock" />
+          </span>
+          <el-input
+            :key="passwordType"
+            ref="password"
+            v-model="loginForm.password"
+            size="mini"
+            :type="passwordType"
+            placeholder="瀵嗙爜"
+            name="password"
+            show-password
+            tabindex="2"
+            auto-complete="on"
+            @keyup.enter.native="handleLogin"
+          />
+          <span class="show-pwd" @click="showPwd">
+            <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
+          </span>
+        </el-form-item>
 
-      <el-form-item>
-        <el-checkbox v-model="checked">鑷姩鐧诲綍</el-checkbox>
-        <el-checkbox v-model="checked">蹇樿瀵嗙爜</el-checkbox>
-      </el-form-item>
-      <div class="login">
-        <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">鐧诲綍</el-button>
-      </div>
-    </el-form>
+        <el-form-item>
+          <div v-show="!showCode" class="login">
+            <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">鐧诲綍</el-button>
+          </div>
+        </el-form-item>
+
+        <div v-show="showCode" class="code">
+          <img src="../../assets/images/code.png">
+        </div>
+      </el-form>
+    </div>
   </div>
 </template>
 
@@ -73,23 +79,28 @@
   name: 'Login',
   data() {
     const validateUsername = (rule, value, callback) => {
-      if (!validUsername(value)) {
-        callback(new Error('璇疯緭鍏ユ纭殑璐﹀彿锛�'))
+      const reg = /^(?=.*\d).{6,11}$/
+      if (!reg.test(value)) {
+        callback(new Error('璐﹀彿鐢�6-10浣嶆暟瀛楃粍鎴愶紝璇疯緭鍏ユ纭殑璐﹀彿锛�'))
       } else {
         callback()
       }
     }
     const validatePassword = (rule, value, callback) => {
-      if (value.length < 6) {
-        callback(new Error('璇疯緭鍏�6浣嶅瘑鐮侊紒'))
+      // let reg= /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{4,20}$/
+      // let reg = /^(?![0-9]+$)(?![A-Z]+$)(?![a-z]+$)[0-9A-Za-z]{6,12}$/
+
+      const reg = /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{6,12}$/
+      if (!reg.test(value)) {
+        callback(new Error('瀵嗙爜蹇呴』鏄敱6-12浣嶅寘鍚ぇ灏忓啓瀛楁瘝锛屾暟瀛楃粍鍚�'))
       } else {
         callback()
       }
     }
     return {
       loginForm: {
-        username: 'admin',
-        password: '111111'
+        username: '',
+        password: ''
       },
       loginRules: {
         username: [{ required: true, trigger: 'blur', validator: validateUsername }],
@@ -97,7 +108,8 @@
       },
       loading: false,
       passwordType: 'password',
-      redirect: undefined
+      redirect: undefined,
+      showCode: false
     }
   },
   watch: {
@@ -109,6 +121,9 @@
     }
   },
   methods: {
+    openCode() {
+      this.showCode = true
+    },
     showPwd() {
       if (this.passwordType === 'password') {
         this.passwordType = ''
@@ -120,32 +135,35 @@
       })
     },
     handleLogin() {
-      this.$refs.loginForm.validate(valid => {
-        if (valid) {
-          this.loading = true
-          this.$store.dispatch('user/login', this.loginForm).then(() => {
-            this.$router.push({ path: this.redirect || '/' })
-            this.loading = false
-          }).catch(() => {
-            this.loading = false
-          })
-        } else {
-          console.log('error submit!!')
-          return false
-        }
+      console.log('寮�濮嬬櫥褰�')
+      // debugger
+      console.log(this)
+      this.loading = true
+      this.$store.dispatch('user/login', this.loginForm).then((res) => {
+        console.log(res)
+        this.$router.push({ path: this.redirect || '/' })
+        this.loading = false
+      }).catch(() => {
+        this.loading = false
       })
     }
   }
 }
 </script>
 
-<style lang="scss">
-
+<style lang="scss" >
+#app .login-container .el-input input:-webkit-autofill {
+  box-shadow: none !important;
+}
 /* 淇input 鑳屾櫙涓嶅崗璋� 鍜屽厜鏍囧彉鑹� */
 /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
 
 .login{
   text-align: center;
+  .el-button{
+    background: #285E77 ;
+    border: 2px solid #8AA0AC;
+  }
 }
 $bg:#283443;
 $light_gray:#fff;
@@ -161,7 +179,7 @@
 .login-container {
   .el-input {
     display: inline-block;
-    height: 47px;
+    height: 30px;
     width: 85%;
 
     input {
@@ -169,9 +187,9 @@
       border: 0px;
       -webkit-appearance: none;
       border-radius: 0px;
-      padding: 12px 5px 12px 15px;
+      padding: 6px 2px 6px 7px;
       color: $cursor;
-      height: 47px;
+      height: 30px;
       // caret-color: $cursor;
 
       &:-webkit-autofill {
@@ -186,6 +204,10 @@
     background: rgba(255, 255, 255);
     border-radius: 5px;
     color: #454545;
+    margin-bottom: 40px;
+    margin-right: 40px;
+    margin-left: 40px;
+    height: 40px;
     &:nth-child(4){
       // width: 100%;
       // display: flex;
@@ -205,44 +227,81 @@
 $bg:#2d3a4b;
 $dark_gray:#889aa4;
 $light_gray:#eee;
+::v-deep .el-form-item__content{
+  .svg-container{
+    text-align: center;
+    line-height: 32px;
+  }
+  // display: flex;
 
+}
 .login-container {
+  position: relative;
   min-height: 100%;
   width: 100%;
-  background: url("../../assets/images/loginbg.png");
+  background: #134666;
   background-size: cover;
   overflow: hidden;
   .login-logo{
-    position: absolute;
-    width: 520px;
-    left: 60%;
-    top: 25%;
+    position: fixed;
+    width: 100%;
+    left: 0;
+    top: 0;
     color: #fff;
-    font-size: 30px;
+    font-size: 20px;
     display: flex;
     align-items: center;
-    justify-content: space-between;
+    padding: 10px;
+    background: #0E3757;
     .logo{
       img{
-        width: 150px;
-        height: 50px;
+        width: 80px;
+        height: 30px;
       }
     }
+    .logo-title{
+      margin-left: 20px;
+    }
   }
-  .login-form {
+  .logo-main{
     position: absolute;
-    background: #fff;
-    border-radius: 25px;
-    width: 520px;
-    height: 370px;
-    padding: 40px;
-    max-width: 100%;
+    left: 50%;
     top: 50%;
-    transform: translateY(-50%);
-    left: 60%;
+    transform: translate(-50%,-50%);
+    width: 1000px;
+    height: 400px;
+    border-radius: 25px;
+    overflow:hidden;
+    display: flex;
+    // border: 2px solid red;
+    .main-img{
+      // width: 550px;
+      // height: 300px;
+      flex: 1;
+      height: 400px;
+      text-align: center;
+      background: #0D3155;
+      img{
+        width: 400px;
+        height: 400px;
+      }
+    }
+    .login-form {
+    background: #285E77;
+    width: 450px;
+    height: 400px;
+    padding: 30px;
     overflow: hidden;
+    color: #fff;
+    .code{
+      text-align: center;
+      img{
+        width: 200px;
+        height: 200px;
+      }
+    }
+   }
   }
-
   .tips {
     font-size: 14px;
     color: #fff;
@@ -256,7 +315,7 @@
   }
 
   .svg-container {
-    padding: 6px 5px 6px 15px;
+    padding: 3px 2px 3px 7px;
     color: $dark_gray;
     vertical-align: middle;
     width: 30px;
@@ -265,20 +324,25 @@
 
   .title-container {
     position: relative;
-
+    // height: 70px;
+    // line-height: 70px;
+    margin-bottom: 40px;
     .title {
+      height: 30px;
+      line-height: 30px;
       position: relative;
       // position: absolute;
       left: 50%;
       transform: translate(-50%);
       font-size: 20px;
-      color: #454545;
-      margin: 0px auto 24px auto;
+      color: #fff;
+      margin: 0px auto 0 auto;
       display: inline-block;
       // font-weight: bold;
     }
     .scan-icon{
       float: right;
+      font-size: 30px;
     }
   }
 
diff --git a/src/views/out_operation/index.vue b/src/views/out_operation/index.vue
index f13290b..0a66a7f 100644
--- a/src/views/out_operation/index.vue
+++ b/src/views/out_operation/index.vue
@@ -1,90 +1,285 @@
 <template>
-  <div class="addOperation">
-    <div class="addOperation-main">
-      <!-- <el-form v-model="statusType" ref="queryForm" size="small" :inline="true" label-width="68px">
-            <el-form-item label="鍏ュ簱鐘舵��">
-           <el-radio-group v-model="inStatus">
-            <el-radio-button label="鍏ㄩ儴"></el-radio-button>
-            <el-radio-button label="宸插叆搴�"></el-radio-button>
-            <el-radio-button label="宸插嚭搴�"></el-radio-button>
-          </el-radio-group>
-            </el-form-item>
-            <el-form-item label="鍏ュ簱绫诲瀷" prop="phonenumber">
-             <el-radio-group v-model="inType">
-            <el-radio-button label="鏉$爜鎵撳嵃"></el-radio-button>
-          </el-radio-group>
-          </el-form-item>
-          <el-form-item label="鏉$爜鎵撳嵃">
-            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鏂板鏉$爜鎵撳嵃</el-button>
-          </el-form-item>
-      </el-form> -->
-     <el-row type="flex" align="middle" class="main-top">
-      <el-col :span="2"><el-button type="primary">鎵弿鍑哄簱</el-button></el-col>
-      <el-col :span="20">
-        <TableSearch></TableSearch>
-      </el-col>
-      <el-col :span="2"><el-button>鎶艰繍鍗曟墦鍗�</el-button></el-col>
-     </el-row>
-    <el-table
-      :stripe="true"
-      :data="tableData"
-      :cell-style="{ textAlign: 'center' }"
-      :header-cell-style="{ textAlign: 'center' }"
-      :border="true"
-      header-row-class-name="table-header"
-    >
-      <el-table-column
-        prop="date"
-        label="搴忓彿">
-      </el-table-column>
-      <el-table-column
-        prop="name"
-        label="浜у搧缂栫爜">
-      </el-table-column>
-      <el-table-column
-        prop="address"
-        label="浜у搧鍚嶇О">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="瑙勬牸鍨嬪彿">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="鍗曚綅">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="鍏ュ簱鏁伴噺">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="鍏ュ簱浜�">
-      </el-table-column>
-      <el-table-column
-        prop="date"
-        label="鍏ュ簱鏃ユ湡">
-      </el-table-column>
-    </el-table>
-    </div>
-    <div class="addOperation-foot">
-      <el-pagination
-      :current-page="searchModel.pageNo"
-      :page-sizes="[10, 15, 20, 25]"
-      :page-size="searchModel.pageSize"
-      layout="->, total, sizes, prev, pager, next, jumper"
-      :total="total"
-      @size-change="handleSizeChange"
-      @current-change="handleCurrentChange"
+  <div class="outOperation">
+    <div class="outOperation-main">
+      <el-row type="flex" align="middle" class="main-top">
+        <el-col :span="2"><el-button type="primary" icon="iconfont icon-saoyisao" @click="scan">鏂板鍑哄簱</el-button></el-col>
+        <el-col :span="20">
+          <TableSearch :show="true" :excel-name="'搴撳瓨琛�'" :file="outFile" :get-list="getList" :search-data="searchData" :search-params="searchModel" :options="options" />
+        </el-col>
+        <!-- <el-col :span="2"><el-button type="primary" @click="printOrder ">鎵撳嵃鎶艰繍鍗�</el-button></el-col> -->
+        <el-col :span="2"><el-button type="primary" :disabled="outTable.length==0" @click="printOrder ">鎵撳嵃鎶艰繍鍗�</el-button></el-col>
+      </el-row>
+      <el-table
+        class="tableData"
+        :row-class-name="onTableRowClassName"
+        :row-style="{height:0+'px'}"
+        :cell-style="{padding:8+'px',textAlign: 'center'}"
+        :header-cell-style="{borderRight:'0px',textAlign: 'center',background:'#52626F',color:'#fff', height:'10px', padding:'0px'}"
+        :stripe="true"
+        :data="tableData"
+        :border="true"
+        header-row-class-name="table-header"
+        @selection-change="handleSelectionChange"
       >
-    </el-pagination>
+        <el-table-column
+          label="澶氶��"
+          type="selection"
+          width="55"
+        >
+        <!-- <el-checkbox></el-checkbox> -->
+        </el-table-column>
+        <el-table-column
+          prop="productCode"
+          label="浜у搧缂栫爜"
+        />
+        <el-table-column
+          prop="productName"
+          label="浜у搧鍚嶇О"
+        />
+        <el-table-column
+          prop="productModel"
+          label="瑙勬牸鍨嬪彿"
+        >
+          <template slot="header" slot-scope="scope">
+            <span>瑙勬牸鍨嬪彿</span>
+            <span :class="isMerge?'el-icon-sort-up':'el-icon-sort-down'" :style="{marginLeft:'5px'}" @click="merge" />
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="unit"
+          label="鍗曚綅"
+        />
+        <el-table-column
+          prop="incomingQuantity"
+          label="鍏ュ簱鏁伴噺"
+        />
+        <el-table-column
+          prop="addPerson"
+          label="鍏ュ簱浜�"
+        />
+        <el-table-column
+          v-if="!isMerge"
+          prop="createTime"
+          label="鍑哄簱鏃ユ湡"
+        />
+      </el-table>
+      <div class="outOperation-foot">
+        <el-pagination
+          :current-page="searchModel.pageNo"
+          :page-sizes="[10, 15, 20, 25]"
+          :page-size="searchModel.pageSize"
+          layout="->, total, sizes, prev, pager, next, jumper"
+          :total="total"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
     </div>
+
+    <el-dialog title="鎵弿鍑哄簱" :visible.sync="outFormVisible">
+      <el-form :model="outParams" label-position="left">
+        <el-table
+          :height="250"
+          :max-height="250"
+          :row-class-name="onTableRowClassName"
+          :row-style="{height:0+'px'}"
+          :cell-style="{padding:8+'px',textAlign: 'center'}"
+          :header-cell-style="{borderRight:'0px',textAlign: 'center',background:'#52626F',color:'#fff', height:'10px', padding:'0px'}"
+          :stripe="true"
+          :border="true"
+          header-row-class-name="table-header"
+          :data="this.outTable.slice(0,outPageParams.length)"
+        >
+          <el-table-column property="addPerson" label="搴忓彿" />
+          <el-table-column property="productCode" label="浜у搧缂栫爜" />
+          <el-table-column property="productNameId" label="浜у搧鍚嶇О" />
+          <el-table-column property="productModelId" label="瑙勬牸鍨嬪彿" />
+          <el-table-column property="unit" label="鍗曚綅" />
+          <el-table-column property="incomingQuantity" label="鍏ュ簱鏁伴噺" />
+          <el-table-column property="addPerson" label="鍏ュ簱浜�" />
+          <!-- <el-table-column property="address" label="鍏ュ簱鏃ユ湡"></el-table-column> -->
+        </el-table>
+        <div :style="{display: 'flex',justifyContent:'center',marginTop: '10px'}">
+          <el-pagination
+            :current-page="outPageParams.pageNo"
+            :page-sizes="[3, 4, 5, 6]"
+            :page-size="outPageParams.pageSize"
+            layout="->, total, sizes, prev, pager, next, jumper"
+            :total="outTable.length"
+            @size-change="outHandleSizeChange"
+            @current-change="outHandleCurrentChange"
+          />
+        </div>
+
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="orderFormVisible = true">鐢熸垚鎶艰繍鍗�</el-button>
+        <el-button @click="outFormVisible = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog title="鎶艰繍鍗曟墦鍗�" :visible.sync="orderFormVisible" @close="orderFormClose">
+      <div id="order">
+        <el-form label-position="right" :model="orderParams">
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="璁㈠崟鍙�:" :label-width="formLabelWidth">
+                <el-input v-model="orderParams.orderNumber" autocomplete="off" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鎶艰繍鍗曠紪鍙�:" :label-width="formLabelWidth">
+                <el-input v-model="orderParams.escortNoteNumber" autocomplete="off" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="瀹㈡埛璁㈠崟鍙�:" :label-width="formLabelWidth">
+                <el-input v-model="orderParams.customerOrderNumber" autocomplete="off" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍙戣揣鏃ユ湡:" :label-width="formLabelWidth">
+                <el-date-picker
+                  v-model="orderParams.createTime"
+                  format="yyyy-MM-dd HH:mm"
+                  type="datetime"
+                  placeholder="閫夋嫨鏃ユ湡鏃堕棿"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="瀹㈡埛鍚嶇О:" :label-width="formLabelWidth">
+                <el-input v-model="orderParams.customerName" autocomplete="off" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍙戣揣浜�:" :label-width="formLabelWidth">
+                <el-input v-model="orderParams.consignor" autocomplete="off" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col>
+              <el-form-item label="鍒拌揣鍦板潃:" :label-width="formLabelWidth">
+                <el-input v-model="orderParams.arrivalAddress" autocomplete="off" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col>
+              <el-form-item label="鏀惰揣鑱旂郴浜�:" :label-width="formLabelWidth">
+                <el-input v-model="orderParams.receivingContact" autocomplete="off" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col>
+              <el-form-item label="鎵嬫満鍙�:" :label-width="formLabelWidth">
+                <el-input v-model="orderParams.cellPhoneNumber" autocomplete="off" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col>
+
+              <el-form-item>
+                <el-table
+                  :row-class-name="onTableRowClassName"
+                  :row-style="{height:0+'px'}"
+                  :cell-style="{padding:8+'px',textAlign: 'center'}"
+                  :header-cell-style="{borderRight:'0px',textAlign: 'center',background:'#52626F',color:'#fff', height:'10px', padding:'0px'}"
+                  :stripe="true"
+                  :border="true"
+                  :data="outTable"
+                >
+                  <el-table-column property="productName" label="浜у搧鍚嶇О" />
+                  <el-table-column property="productModel" label="瑙勬牸鍨嬪彿" />
+                  <el-table-column property="unit" label="鍗曚綅" />
+                  <el-table-column property="incomingQuantity" label="鍙戝簱鏁伴噺" />
+                </el-table>
+              </el-form-item>
+
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="goToPrint">鎵� 鍗�</el-button>
+        <el-button @click="orderFormVisible = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog title="鎶艰繍鍗曟墦鍗�" :visible.sync="templateOrderVisible" @close="templateOrderClose">
+      <div id="templateOrder" class="templateOrder">
+        <h3>鎶艰繍鍗�</h3>
+        <div class="templateOrder-main">
+          <div class="main-row">
+            <div class="flex-2">璁㈠崟鍙凤細</div>
+            <div class="flex-8">{{ orderParams.orderNumber }}</div>
+            <div class="flex-2">鎶艰繍鍗曠紪鍙凤細</div>
+            <div class="flex-8">{{ orderParams.escortNoteNumber }}</div>
+          </div>
+          <div class="main-row">
+            <div class="flex-2">瀹㈡埛璁㈠崟鍙凤細</div>
+            <div class="flex-8">{{ orderParams.customerOrderNumber }}</div>
+            <div class="flex-2">鍙戣揣鏃ユ湡锛�</div>
+            <div class="flex-8">{{ orderParams.createTime }}</div>
+          </div>
+          <div class="main-row">
+            <div class="flex-2">瀹㈡埛鍚嶇О锛�</div>
+            <div class="flex-8">{{ orderParams.customerName }}</div>
+            <div class="flex-2">鍙戣揣浜猴細</div>
+            <div class="flex-8">{{ orderParams.consignor }}</div>
+          </div>
+          <div class="main-row">
+            <div class="flex-2">鍒拌揣鍦板潃锛�</div>
+            <div class="flex-18">{{ orderParams.arrivalAddress }}</div>
+          </div>
+          <div class="main-row">
+            <div class="flex-2">鏀惰揣鑱旂郴浜猴細</div>
+            <div class="flex-18">{{ orderParams.receivingContact }}</div>
+          </div>
+          <div class="main-row">
+            <div class="flex-2">鎵嬫満鍙凤細</div>
+            <div class="flex-18">{{ orderParams.cellPhoneNumber }}</div>
+          </div>
+          <div class="main-row">
+            <!-- <div class="flex-2">鎵嬫満鍙�</div> -->
+            <div class="flex-18" :style="{'textAlign': 'center'}">
+              <h4>浜у搧鍒楄〃</h4>
+            </div>
+          </div>
+          <div class="main-row">
+            <div class="flex-4">浜у搧鍚嶇О</div>
+            <div class="flex-4">瑙勬牸鍨嬪彿</div>
+            <div class="flex-4">鍗曚綅</div>
+            <div class="flex-4">鍙戣揣鏁伴噺</div>
+          </div>
+          <div v-for="item in outTable" :key="item.id" class="main-row">
+            <div class="flex-4">{{ item.productName }}</div>
+            <div class="flex-4">{{ item.productModel }}</div>
+            <div class="flex-4">{{ item.unit }}</div>
+            <div class="flex-4">{{ item.incomingQuantity }}</div>
+          </div>
+        </div>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button v-print="printObj" type="primary">鎸夋ā鏉挎墦鍗�</el-button>
+        <el-button @click="templateOrderVisible = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+
   </div>
 </template>
 
 <script>
-import { getList } from '@/api/table'
+import { getList, selectCacheOfIn, outOperation, outFile } from '@/api/addOperation'
+import { selectAllName } from '@/api/productName'
+import { selectAllModel } from '@/api/productModel'
 import TableSearch from '@/components/TableSearch'
+import { mapGetters } from 'vuex'
 export default {
   filters: {
     statusFilter(status) {
@@ -96,88 +291,302 @@
       return statusMap[status]
     }
   },
-  data() {
-    return {
-      pickerOptions: {
-          shortcuts: [{
-            text: '鏈�杩戜竴鍛�',
-            onClick(picker) {
-              const end = new Date();
-              const start = new Date();
-              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
-              picker.$emit('pick', [start, end]);
-            }
-          }, {
-            text: '鏈�杩戜竴涓湀',
-            onClick(picker) {
-              const end = new Date();
-              const start = new Date();
-              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
-              picker.$emit('pick', [start, end]);
-            }
-          }, {
-            text: '鏈�杩戜笁涓湀',
-            onClick(picker) {
-              const end = new Date();
-              const start = new Date();
-              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
-              picker.$emit('pick', [start, end]);
-            }
-          }]
-        },
-      inType: '',
-      inStatus: '',
-      deptName: '',
-      statusType: {},
-      queryParams: {
-        encode: '',
-        type: '',
-        depositor: ''
-      },
-      total: 0,
-      searchModel: {
-        pageNo: 1,
-        pageSize: 10
-      },
-      tableData: [{
-        date: '2016-05-02',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1518 寮�'
-      }, {
-        date: '2016-05-04',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1517 寮�'
-      }, {
-        date: '2016-05-01',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1519 寮�'
-      }, {
-        date: '2016-05-03',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1516 寮�'
-      }, {
-        date: '2016-05-03',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1516 寮�'
-      }, {
-        date: '2016-05-03',
-        name: '鐜嬪皬铏�',
-        address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1516 寮�'
-      }]
-    }
-  },
-  created() {
-    this.fetchData()
-  },
   components: {
     TableSearch
   },
+  data() {
+    return {
+      templateOrderVisible: false,
+      outFile,
+      printObj: {
+        id: 'templateOrder', // 鎵撳嵃鐨勫尯鍩�
+        // preview: true, // 棰勮宸ュ叿鏄惁鍚敤
+        previewTitle: '鎵撳嵃鎶艰繍鍗�', // 棰勮椤甸潰鐨勬爣棰�
+        previewBeforeOpenCallback(vue) {
+          console.log('姝e湪鍔犺浇棰勮绐楀彛')
+        },
+        previewOpenCallback(vue) {
+          console.log('宸茬粡鍔犺浇瀹岄瑙堢獥鍙�')
+        },
+        clickMounted: (vue) => {
+          console.log('瑙﹀彂鐐瑰嚮鎵撳嵃鍥炶皟')
+          vue.isShowPrint = true // 寮规鏄剧ず鏉$爜
+        },
+        beforeOpenCallback(vue) {
+          console.log('鎵撳紑涔嬪墠', vue.barcodeNum)
+        },
+        openCallback(vue) {
+          //  let time =vue.orderParams.createTime
+          // vue.orderParams.createTime =  `${time.getFullYear()}-${time.getMonth() + 1}-${time.getDate()} ${time.getHours()}:${time.getMinutes()}`
+          // vue.orderParams.listId = vue.outCodeTable
+          // vue.orderParams.outPerson = vue.name
+          // outOperation(vue.orderParams).then((res) => {
+          //   vue.$message.success("鎴愬姛鍑哄簱")
+          //   vue.isShowPrint = false  // 鍏抽棴鏉$爜鏄剧ず寮规
+          // })
+          console.log('鎵ц浜嗘墦鍗�', vue.barcodeNum)
+        },
+        clickMounted(vue) {
+          console.log(1111)
+          console.log(vue.orderParams.createTime)
+          outOperation({ ...vue.orderParams, outPerson: vue.name, listCode: vue.outCodeTable }).then((res) => {
+            vue.orderFormVisible = false
+            vue.outCodeTable = []
+            vue.outTable = []
+            vue.tableData = []
+            vue.fetchData()
+            console.log('娓呯┖鏁版嵁锛屽悓鏃跺埛鏂版暟鎹�')
+            vue.$message.success('鎴愬姛鍑哄簱')
+            vue.fetchData()
+            vue.isShowPrint = false // 鍏抽棴鏉$爜鏄剧ず寮规
+          }, () => {
+            vue.$message.err('璇烽噸鏂版墦鍗�')
+          }).finally(() => {
+            vue.templateOrderVisible = false
+            vue.orderParams = {}
+          })
+
+          console.log('鎵ц浜嗘墦鍗�', vue.barcodeNum)
+        }
+      },
+      outPageParams: {
+        pageNo: 1,
+        pageSize: 3
+      },
+      isMerge: false,
+      outTable: [],
+      outCodeTable: [],
+      outParams: {},
+      outFormVisible: false,
+      getList,
+      total: 0,
+      options: [],
+      searchModel: {
+        pageNo: 1,
+        pageSize: 10,
+        productModel: '',
+        endTime: '',
+        startTime: ''
+      },
+      formLabelWidth: '120px',
+      orderFormVisible: false,
+      orderParams: {
+        orderNumber: '',
+        escortNoteNumber: '',
+        customerOrderNumber: '',
+        createTime: '',
+        customerName: '',
+        consignor: '',
+        arrivalAddress: '',
+        receivingContact: '',
+        cellPhoneNumber: ''
+      },
+      total: 0,
+      tableData: [],
+      contentTable: [],
+      isScan: false
+    }
+  },
+  watch: {
+    isScan(to) {
+
+    }
+  },
+  created() {
+    
+    this.fetchData()
+    this.setOptions()
+  },
+  beforeDestroy() {
+    window.document.onkeypress = null
+  },
   methods: {
+    templateOrderClose() {
+      this.orderFormClose()
+    },
+    orderFormClose() {
+      // 鍏抽棴鎵撳嵃鎶艰繍鍗曡緭鍏ュ脊绐楁竻绌烘暟鎹�
+      for (const key in this.orderParams) {
+        this.orderParams[key] = ''
+      }
+      // this.outTable = []
+    },
+    goToPrint() {
+      let ok = false
+      for (const key in this.orderParams) {
+        if (!this.orderParams[key]) {
+          ok = true
+        }
+      }
+      if (ok) {
+        return this.$message.error('璇峰~鍐欏畬鏁村弬鏁�')
+      }
+
+      console.log('闇�瑕佹墦鍗扮殑鍙傛暟', this.orderParams)
+      const time = this.orderParams.createTime
+      this.orderParams.createTime = `${time.getFullYear()}-${time.getMonth() + 1 < 10 ? '0' + (time.getMonth() + 1) : time.getMonth() + 1}-${time.getDate() < 10 ? '0' + time.getDate() : time.getDate()} ${time.getHours() < 10 ? '0' + time.getHours() : time.getHours()}:${time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes()}`
+      console.log('闇�瑕佹墦鍗扮殑涓滆タ==>', this.outTable)
+      // this.orderFormVisible = false
+      this.templateOrderVisible = true
+    },
+    merge() {
+      this.isMerge = !this.isMerge
+      if (this.isMerge) {
+        this.contentTable = JSON.parse(JSON.stringify(this.tableData))
+      } else {
+        this.tableData = JSON.parse(JSON.stringify(this.contentTable))
+        return
+      }
+
+      this.tableData = this.tableData.reduce((arr, next) => {
+        for (const item of arr) {
+          if (item.productModel === next.productModel) {
+            item.children.push(next.id)
+            item.incomingQuantity = item.incomingQuantity + next.incomingQuantity
+            return arr
+          }
+        }
+        next.children = [next.id]
+        arr.push(next)
+        return arr
+        // arr.push(next)
+      }, [])
+      console.log(this.tableData)
+    },
+    printOrder() {
+      console.log(this.outCodeTable, this.outTable)
+      this.orderFormVisible = true
+    },
+    addScanMonitor() {
+      window.document.onkeypress = e => {
+        console.log(e)
+        if (window.event) { // IE
+          this.nextCode = e.keyCode
+        } else if (e.which) { // Netscape/Firefox/Opera
+          this.nextCode = e.which
+        }
+
+        if (e.which === 13) { // 閿洏鍥炶溅浜嬩欢
+          // if (this.code.length < 3) return // 鎵爜鏋殑閫熷害寰堝揩锛屾墜鍔ㄨ緭鍏ョ殑鏃堕棿涓嶄細璁ヽode鐨勯暱搴﹀ぇ浜�2锛屾墍浠ヨ繖閲屼笉浼氬鎵爜鏋湁鏁�
+          console.log(new Date().getTime())
+          if (new Date().getTime() - this.lastTime > 30) {
+            return this.$message.error('鎵爜鏃朵笉鍙�氳繃閿洏杈撳叆')
+          }
+          // if (this.code.length < 3) return // 鎵爜鏋殑閫熷害寰堝揩锛屾墜鍔ㄨ緭鍏ョ殑鏃堕棿涓嶄細璁ヽode鐨勯暱搴﹀ぇ浜�2锛屾墍浠ヨ繖閲屼笉浼氬鎵爜鏋湁鏁�
+          console.log('鎵爜缁撴潫,鏉″舰鐮侊細', this.code)
+          for (const item of this.tableData) {
+            if (item.id == this.code) {
+              this.$message.error('璇峰嬁閲嶅鎵弿')
+              this.handleSubmitScanning()
+              return
+            }
+          }
+          // 鍙戦�佽姹�
+          selectCacheOfIn({ code: this.code }).then(res => {
+            this.$message.success(`${this.code}鎵弿鎴愬姛`)
+            const { data } = res
+            if (data) this.tableData.push(data)
+          })
+          this.scanningForm.scanCode = this.code
+          this.lastCode = ''
+          this.lastTime = ''
+          this.handleSubmitScanning()
+          return
+        }
+
+        this.nextTime = new Date().getTime()
+        if (!this.lastTime && !this.lastCode) {
+          this.code = '' // 娓呯┖涓婃鐨勬潯褰㈢爜
+          // 缁х画鎵弿涓�涓嬫潯鍓嶅叧闂脊绐�
+          // this.handleCloseTipsVisible()
+          this.code = this.code + '' + e.key
+          console.log('鎵爜寮�濮�---', this.code)
+        }
+        if (this.lastCode && this.lastTime && this.nextTime - this.lastTime > 500) { // 褰撴壂鐮佸墠鏈塳eypress浜嬩欢鏃�,闃叉棣栧瓧缂哄け
+          this.code = e.key
+          console.log('闃叉棣栧瓧缂哄け銆傘�傘��', this.code)
+        } else if (this.lastCode && this.lastTime) {
+          this.code = this.code + '' + e.key
+          console.log('鎵爜涓�傘�傘��', this.code)
+        }
+        this.lastCode = this.nextCode
+        this.lastTime = this.nextTime
+      }
+    },
+    handleSelectionChange(val) {
+      if (this.isMerge) {
+        console.log(val)
+        const arrChildren = val.map((item) => item.children)
+        console.log(arrChildren)
+        this.outCodeTable = arrChildren.reduce((arr, next) => {
+          arr = [...arr, ...next]
+          return arr
+        }, [])
+        console.log(this.contentTable, this.outCodeTable)
+        this.contentTable.forEach(item => {
+          if (this.outCodeTable.indexOf(item.id) > -1) {
+            this.outTable.push(item)
+          }
+        })
+      } else {
+        this.outTable = val
+        this.outCodeTable = this.outTable.map(item => item.id)
+      }
+      console.log(this.outTable, this.outCodeTable)
+    },
+    scan(e) {
+      console.log('寮�濮嬫壂鐮佸嚭搴�')
+      this.$message.success('璇峰紑濮嬫壂鐮佸嚭搴�')
+      this.tableData = []
+      this.addScanMonitor()
+      e.srcElement.blur()
+    },
+    async setOptions() {
+      const { data: nameRes } = await selectAllName()
+      // console.log(nameRes)
+      const nameArr = nameRes.productNames.map(item => {
+        return { value: item.id, label: item.productName }
+      })
+      for (const nameItem of nameArr) {
+        const { data } = await selectAllModel({ productNameId: nameItem.value })
+
+        this.options = [...this.options, ...data.models]
+        /* nameItem.children = data.models.map(item => {
+          return { value: item.id, label: item.productModel }
+        }) */
+      }
+      this.options = this.options.map(item => {
+        return { label: item.productModel, value: item.productModel, productCode: item.productCode }
+      })
+      // console.log(this.options)
+    },
+    searchData(res) {
+      console.log(res)
+      const { row, total, productModel, startTime, endTime } = res
+      this.tableData = row
+      this.total = total
+      this.searchModel.productModel = productModel
+      this.searchModel.startTime = startTime
+      this.searchModel.endTime = endTime
+      window.document.onkeypress = undefined
+    },
+    onTableRowClassName({ row, rowIndex }) {
+      if (rowIndex % 2 != 0) {
+        return 'onAcitve'
+      } else {
+        return ''
+      }
+    },
     fetchData() {
       this.listLoading = true
-      getList().then(response => {
-        this.list = response.data.items
+      const obj = {}
+      const arr = Object.keys(this.searchModel).filter(key => this.searchModel[key])
+      arr.forEach(item => obj[item] = this.searchModel[item])
+      getList(obj).then(response => {
+        this.tableData = response.data.row
+        this.total = response.data.total
         this.listLoading = false
+        // console.log(this.tableData)
       })
     },
     handleSizeChange(val) {
@@ -185,31 +594,118 @@
     },
     handleCurrentChange(val) {
       console.log(`褰撳墠椤�: ${val}`)
+    },
+    outHandleSizeChange(val) {
+      console.log(`姣忛〉 ${val} 鏉)
+    },
+    outHandleCurrentChange(val) {
+      console.log(`褰撳墠椤�: ${val}`)
+      this.outPageParams.pageNo = val
+      // this.fetchData()
+      // console.log()
+
+      // console.log(this.addTable.slice((this.outPageParams.pageSize * (val - 1)), (this.outPageParams.pageSize * (val - 1)) + this.outPageParams.pageSize))
     }
+  },
+  computed: {
+    ...mapGetters([
+      'sidebar',
+      'avatar',
+      'name',
+      'allTab'
+    ])
   }
 }
 </script>
 
 <style lang="scss" scoped>
 @import '../../styles/variables.scss';
-.addOperation {
- min-height: calc(100vh - 50px);
+::v-deep .el-table__header .el-checkbox{
+	display:none;
+}
+::v-deep .tableData .el-table__header th:nth-child(1) .cell::before{
+content: '澶氶��';
+}
+.templateOrder{
+  border: 1px solid #000;
+  padding: 8px;
+  >h3{
+    text-align: center;
+  }
+  &-main{
+  border-top: 1px solid #000;
+  border-left: 1px solid #000;
+    .main-row{
+      display: flex;
+      font-size: 12px;
+        >div{
+        border-bottom: 1px solid #000;
+        border-right: 1px solid #000;
+        height: 40px;
+        line-height: 20px;
+        padding: 10px;
+        // margin: 24px;
+        >h4{
+          margin: 0;
+        }
+      }
+      .flex-2{
+        min-width: 110px;
+        max-width: 110px;
+        text-align: right;
+        padding: 10px 6px;
+      }
+      .flex-4{
+        flex: 1;
+        text-align: center;
+      }
+      .flex-8{
+        flex: 8;
+      }
+      .flex-18{
+        flex: 18;
+      }
+    }
+
+  }
+}
+
+.outOperation {
+ min-height: calc(100vh - 100px);
  padding: 25px;
  background: $mainBg;
- .addOperation-main{
+ display: flex;
+ flex-direction: column;
+ .dialog-footer{
+  text-align: center;
+  display: flex;
+  justify-content: space-around;
+ }
+ .outOperation-main{
   background: #fff;
   padding: 20px;
+  flex: 1;
+  display: flex;
+  flex-direction: column;
   .main-top{}
   .table-header{
     background: #6095FB;
   }
- }
- .addOperation-foot{
+  ::v-deep .el-table{
+    flex: 1;
+    // display: flex;
+    // flex-direction: column;
+   ::v-deep .onAcitve td{
+    background-color: #F2F2F2 !important;
+  }
+  }
+  .outOperation-foot{
   margin-top: 25px;
   .el-pagination{
     display: flex;
-    justify-content: center;
+    justify-content: right;
   }
  }
+ }
 }
 </style>
diff --git a/src/views/out_operation/manual/index.vue b/src/views/out_operation/manual/index.vue
index 2013519..aed6df7 100644
--- a/src/views/out_operation/manual/index.vue
+++ b/src/views/out_operation/manual/index.vue
@@ -1,15 +1,330 @@
 <template>
-  <div class="manual">
-    鎵嬪姩鍑哄簱
+  <div class="outOperation">
+    <div class="outOperation-main">
+     <el-row type="flex" align="middle" class="main-top">
+      <el-col :span="2">鍑哄簱鍙拌处</el-col>
+      <el-col :span="20">
+        <div class="table-search">
+    <el-form
+      v-model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      label-width="68px"
+    >
+      <el-form-item label="鏃ユ湡锛�">
+        <el-date-picker
+          v-model="queryParams.date"
+          type="datetimerange"
+          :picker-options="pickerOptions"
+          range-separator="鑷�"
+          start-placeholder="寮�濮嬫棩鏈�"
+          end-placeholder="缁撴潫鏃ユ湡"
+          align="right"
+        >
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="瀹㈡埛鍚嶇О">
+        <el-select v-model="queryParams.type" placeholder="瑙勬牸鍨嬪彿" clearable style="width: 240px">
+          <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-item>
+        <el-button type="primary" icon="el-icon-search" size="mini"
+          @click="search">鎼滅储</el-button>
+        <el-button icon="el-icon-refresh" size="mini">瀵煎嚭</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+      </el-col>
+     </el-row>
+    <el-table
+      :stripe="true"
+      :data="tableData"
+      :cell-style="{ textAlign: 'center' }"
+      :header-cell-style="{ textAlign: 'center' }"
+      :border="true"
+      header-row-class-name="table-header"
+    >
+      <el-table-column
+        type="selection"
+        width="55">
+      </el-table-column>
+      <el-table-column
+        prop="name"
+        label="浜у搧缂栫爜">
+      </el-table-column>
+      <el-table-column
+        prop="address"
+        label="浜у搧鍚嶇О">
+      </el-table-column>
+      <el-table-column
+        prop="date"
+        label="瑙勬牸鍨嬪彿">
+      </el-table-column>
+      <el-table-column
+        prop="date"
+        label="鍗曚綅">
+      </el-table-column>
+      <el-table-column
+        prop="date"
+        label="鍑哄簱鏁伴噺">
+      </el-table-column>
+      <el-table-column
+        prop="date"
+        label="鍙戣揣浜�">
+      </el-table-column>
+      <el-table-column
+        prop="date"
+        label="鍑哄簱鏃ユ湡">
+      </el-table-column>
+    </el-table>
+    </div>
+    <div class="outOperation-foot">
+        <el-pagination
+        :current-page="searchModel.pageNo"
+        :page-sizes="[10, 15, 20, 25]"
+        :page-size="searchModel.pageSize"
+        layout="->, total, sizes, prev, pager, next, jumper"
+        :total="total"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        >
+      </el-pagination>
+    </div>
+    <el-dialog title="鎶艰繍鍗曟墦鍗�" :visible.sync="orderFormVisible">
+      <el-form label-position="left" :model="orderParams">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="璁㈠崟鍙�" :label-width="formLabelWidth">
+              <el-input v-model="orderParams.number" autocomplete="off"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎶艰繍鍗曠紪鍙�" :label-width="formLabelWidth">
+              <el-input v-model="orderParams.noId" autocomplete="off"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛璁㈠崟鍙�" :label-width="formLabelWidth">
+              <el-input v-model="orderParams.clientNumber" autocomplete="off"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍙戣揣鏃ユ湡" :label-width="formLabelWidth">
+              <el-input v-model="orderParams.date" autocomplete="off"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛鍚嶇О" :label-width="formLabelWidth">
+              <el-input v-model="orderParams.clientName" autocomplete="off"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍙戣揣浜�" :label-width="formLabelWidth">
+              <el-input v-model="orderParams.consigner" autocomplete="off"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col>
+            <el-form-item label="鍒拌揣鍦板潃" :label-width="formLabelWidth">
+              <el-input v-model="orderParams.address" autocomplete="off"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col>
+            <el-form-item label="鏀惰揣鑱旂郴浜�" :label-width="formLabelWidth">
+              <el-input v-model="orderParams.consignee" autocomplete="off"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col>
+            <el-form-item label="鎵嬫満鍙�" :label-width="formLabelWidth">
+              <el-input v-model="orderParams.phoneNumber" autocomplete="off"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col>
+            <el-form-item>
+              <el-table :data="tableData" header-row-class-name="table-header">
+                <el-table-column property="date" label="浜у搧鍚嶇О" ></el-table-column>
+                <el-table-column property="name" label="瑙勬牸鍨嬪彿"></el-table-column>
+                <el-table-column property="address" label="鍗曚綅"></el-table-column>
+                <el-table-column property="number" label="鍙戝簱鏁伴噺"></el-table-column>
+              </el-table>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer" >
+        <el-button type="primary" @click="print">纭� 瀹�</el-button>
+        <el-button @click="addFormVisible = false" >鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import { getList } from '@/api/table'
+import TableSearch from '@/components/TableSearch'
 export default {
-
+  filters: {
+    statusFilter(status) {
+      const statusMap = {
+        published: 'success',
+        draft: 'gray',
+        deleted: 'danger'
+      }
+      return statusMap[status]
+    }
+  },
+  data() {
+    return {
+      formLabelWidth: '120px',
+      orderFormVisible: false,
+      orderParams: {
+        number: '',//璁㈠崟鍙�
+        noId: '', //鎶艰繍鍗曠紪鍙�
+        orderParams: '', //瀹㈡埛璁㈠崟鍙�
+        date: '',
+        clientName: '',
+        consigner: '',
+        address: '',
+        consignee: '',
+        phoneNumber: ''
+      },
+      total: 0,
+      searchModel: {
+        pageNo: 1,
+        pageSize: 10
+      },
+      tableData: [
+        {
+          date: '2016-05-02',
+          name: '鐜嬪皬铏�',
+          address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1518 寮�',
+          number: ''
+        },
+        {
+          date: '2016-05-02',
+          name: '鐜嬪皬铏�',
+          address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1518 寮�',
+          number: ''
+        },
+        {
+          date: '2016-05-02',
+          name: '鐜嬪皬铏�',
+          address: '涓婃捣甯傛櫘闄�鍖洪噾娌欐睙璺� 1518 寮�',
+          number: ''
+        }
+      ],
+      queryParams: {
+        date: '',
+        type: ''
+      },
+      pickerOptions: {
+          shortcuts: [{
+            text: '鏈�杩戜竴鍛�',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '鏈�杩戜竴涓湀',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '鏈�杩戜笁涓湀',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+              picker.$emit('pick', [start, end]);
+            }
+          }]
+      },
+      options: [
+        {
+          value: '绗竴绉嶅瀷鍙�',
+          label: '绗竴绉嶅瀷鍙�'
+        }
+      ]
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  components: {
+    TableSearch
+  },
+  methods: {
+    print() {
+      //璐ц繍鍗曟墦鍗板弬鏁�
+      console.log(this.orderParams)
+    },
+    fetchData() {
+      this.listLoading = true
+      getList().then(response => {
+        this.list = response.data.items
+        this.listLoading = false
+      })
+    },
+    handleSizeChange(val) {
+      console.log(`姣忛〉 ${val} 鏉)
+    },
+    handleCurrentChange(val) {
+      console.log(`褰撳墠椤�: ${val}`)
+    },
+    search() {
+      // "鏌ヨ鏉′欢锛�"鏃堕棿闇�瑕佹牸寮忓寲鎴恲yyy-mm-dd hh-mm-ss
+      console.log(this.queryParams)
+    }
+  }
 }
 </script>
 
-<style>
-
-</style>
\ No newline at end of file
+<style lang="scss" scoped>
+@import '../../../styles/variables.scss';
+.outOperation {
+ min-height: calc(100vh - 50px);
+ padding: 25px;
+ background: $mainBg;
+ .dialog-footer{
+  text-align: center;
+ }
+ .outOperation-main{
+  background: #fff;
+  padding: 20px;
+  .main-top{}
+  .table-header{
+    background: #6095FB;
+  }
+ }
+ .outOperation-foot{
+  margin-top: 25px;
+  .el-pagination{
+    display: flex;
+    justify-content: center;
+  }
+ }
+}
+</style>
diff --git a/src/views/out_operation/outboundLedger/index.vue b/src/views/out_operation/outboundLedger/index.vue
deleted file mode 100644
index a04fc19..0000000
--- a/src/views/out_operation/outboundLedger/index.vue
+++ /dev/null
@@ -1,15 +0,0 @@
-<template>
-  <div class="outboundLedger">
-    鍑哄簱鍙拌处
-  </div>
-</template>
-
-<script>
-export default {
-
-}
-</script>
-
-<style>
-
-</style>
\ No newline at end of file
diff --git a/src/views/outbound/index.vue b/src/views/outbound/index.vue
index 21721e5..e61de1c 100644
--- a/src/views/outbound/index.vue
+++ b/src/views/outbound/index.vue
@@ -1,6 +1,241 @@
 <template>
-  <div style="padding:30px;">
-    搴撳瓨鍙拌处
-    <el-alert :closable="false" title="menu 2" />
+  <div class="out-bound">
+    <div class="out-bound-main">
+      <el-row type="flex" align="middle" class="main-top">
+        <el-col :span="2" :style="{color:'#409EFF'}"> <span class="iconfont icon-taizhangzhangbuxinxichaxun" /> 鏀跺彂瀛樼鐞�</el-col>
+        <el-col :span="20">
+          <TableSearch :excel-name="'鏀跺彂瀛樼鐞嗚〃'" :show="false" :file="file" :get-list="getInventoryList" :search-data="searchData" :search-params="searchModel" />
+        </el-col>
+        <el-col :span="2">
+        <!-- <el-button @click="goToOutboundLedger" icon="iconfont icon-caiwushoufacunguanli">鏌ョ湅鍙拌处</el-button> -->
+        </el-col>
+      </el-row>
+      <el-table
+        :row-class-name="onTableRowClassName"
+        :row-style="{height:0+'px'}"
+        :cell-style="{padding:8+'px',textAlign: 'center'}"
+        :header-cell-style="{borderRight:'0px',textAlign: 'center',background:'#52626F',color:'#fff', height:'10px', padding:'0px'}"
+        :stripe="true"
+        :data="tableData"
+        :border="true"
+        header-row-class-name="table-header"
+      >
+        <!-- <el-table-column
+        type="selection"
+        width="55">
+      </el-table-column> -->
+        <el-table-column
+          type="index"
+          label="搴忓彿"
+        />
+        <el-table-column
+          prop="productCode"
+          label="浜у搧缂栫爜"
+        />
+        <el-table-column
+          prop="productName"
+          label="浜у搧鍚嶇О"
+        />
+        <el-table-column
+          prop="productModel"
+          label="瑙勬牸鍨嬪彿"
+        />
+        <el-table-column
+          prop="productUnit"
+          label="鍗曚綅"
+        />
+        <el-table-column
+          prop="beginningInventory"
+          label="鍒濇湡搴撳瓨鏁伴噺"
+        />
+        <el-table-column
+          prop="issueInCurrentPeriod"
+          label="鏈湡鍑哄簱鏁伴噺"
+        />
+        <el-table-column
+          prop="currentPeriod"
+          label="鏈湡鍏ュ簱鏁伴噺"
+        />
+        <el-table-column
+          prop="closingInventory"
+          label="鏈熸湯搴撳瓨鏁伴噺"
+        />
+      <!-- <el-table-column
+        label="鎿嶄綔">
+
+        <el-button size="mini" type="text" @click="delItem()">鍒犻櫎</el-button>
+      </el-table-column> -->
+      </el-table>
+      <div class="out-bound-foot">
+        <el-pagination
+          :current-page="searchModel.pageNo"
+          :page-sizes="[10, 15, 20, 25]"
+          :page-size="searchModel.pageSize"
+          layout="->, total, sizes, prev, pager, next, jumper"
+          :total="total"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+
   </div>
 </template>
+
+<script>
+import { getInventoryList, file } from '@/api/outbound'
+import TableSearch from '@/components/TableSearch'
+export default {
+  filters: {
+    statusFilter(status) {
+      const statusMap = {
+        published: 'success',
+        draft: 'gray',
+        deleted: 'danger'
+      }
+      return statusMap[status]
+    }
+  },
+  components: {
+    TableSearch
+  },
+  data() {
+    return {
+      file,
+      getInventoryList,
+      pickerOptions: {
+        shortcuts: [{
+          text: '鏈�杩戜竴鍛�',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '鏈�杩戜竴涓湀',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '鏈�杩戜笁涓湀',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+            picker.$emit('pick', [start, end])
+          }
+        }]
+      },
+      inType: '',
+      inStatus: '',
+      deptName: '',
+      statusType: {},
+      queryParams: {
+        encode: '',
+        type: '',
+        depositor: ''
+      },
+      total: 0,
+      searchModel: {
+        pageNo: 1,
+        pageSize: 10,
+        endTime: '',
+        startTime: ''
+      },
+      tableData: []
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  methods: {
+    delItem() {
+      console.log('鍒犻櫎')
+    },
+    searchData(res) {
+      console.log(res)
+      const { row, total, startTime, endTime } = res
+      this.tableData = row
+      this.total = total
+      this.searchModel.startTime = startTime
+      this.searchModel.endTime = endTime
+    },
+    onTableRowClassName({ row, rowIndex }) {
+      if (rowIndex % 2 != 0) {
+        return 'onAcitve'
+      } else {
+        return ''
+      }
+    },
+    goToOutboundLedger() {
+    },
+    fetchData() {
+      this.listLoading = true
+      this.listLoading = true
+      const obj = {}
+      const arr = Object.keys(this.searchModel).filter(key => this.searchModel[key])
+      arr.forEach(item => obj[item] = this.searchModel[item])
+      console.log(obj)
+      getInventoryList(obj).then(response => {
+        this.tableData = response.data.row
+        this.total = response.data.total
+        this.listLoading = false
+      })
+    },
+    handleSizeChange(val) {
+      console.log(`姣忛〉 ${val} 鏉)
+    },
+    handleCurrentChange(val) {
+      console.log(`褰撳墠椤�: ${val}`)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../styles/variables.scss';
+
+.out-bound {
+ min-height: calc(100vh - 100px);
+ padding: 25px;
+ background: $mainBg;
+ display: flex;
+ flex-direction: column;
+ .out-bound-main{
+  background: #fff;
+  flex: 1;
+  padding: 20px;
+  display: flex;
+  flex-direction: column;
+//  .el-table--striped .el-table__body tr.el-table__row--striped td {
+//     background: #F2F2F2 !important;
+// }
+  .main-top{}
+  .table-header{
+    background: #6095FB;
+  }
+  .el-table{
+    flex: 1;
+   ::v-deep .onAcitve td{
+    background-color: #F2F2F2 !important;
+  }
+  }
+  .out-bound-foot{
+  margin-top: 25px;
+  .el-pagination{
+    display: flex;
+    justify-content: right;
+  }
+ }
+ }
+ 
+}
+
+// /deep/.el-table--striped .el-table__body tr.el-table__row--striped td {
+// 	background: #1e116d;
+// }
+</style>
diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue
index 748db5d..180b134 100644
--- a/src/views/system/dict/index.vue
+++ b/src/views/system/dict/index.vue
@@ -1,14 +1,34 @@
 <template>
   <div class="systemDict">
-    杩欐槸瀛楀吀绠$悊
+    <vue-barcode
+  :value="value()"
+  >涓嶆敮鎸乿ue-barcode</vue-barcode>
+
+
   </div>
 </template>
 
 <script>
-export default {
+import VueBarcode from 'vue-barcode'
 
+export default{
+    components: { VueBarcode },
+    data () {
+        return {
+           //鏉″舰鐮佸唴瀹�
+        }
+    },
+    methods: {
+      value() {
+        let obj = {name:'jack'}
+        return JSON.stringify(obj)
+      }
+    }
 }
+
 </script>
+ 
+
 
 <style>
 
diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue
index 5f04e63..1eb5ef4 100644
--- a/src/views/system/user/index.vue
+++ b/src/views/system/user/index.vue
@@ -1,15 +1,414 @@
 <template>
   <div class="system-user">
-    <SettingTitle left="浣犵殑鐢ㄦ埛閰嶇疆" right="灏忓浘鏍�"></SettingTitle>
-    <div class="user-info"></div>
+    <SettingTitle v-if="authority" left="浣犵殑鐢ㄦ埛閰嶇疆" :click-fun="showAdd" right="鏂板鐢ㄦ埛" icon="el-icon-plus" />
+    <SettingTitle v-else left="浣犵殑鐢ㄦ埛閰嶇疆" />
+    <div class="user-info">
+      <div class="info-avatar">
+        <el-upload
+          :headers="{'X-Token':token}"
+          class="avatar-uploader"
+          :action="baseUrl+'/user/update'"
+          :show-file-list="false"
+          :on-success="handleAvatarSuccess"
+        >
+          <img v-if="avatar" :src="baseUrl+'/img'+avatar" class="avatar">
+          <i v-else class="el-icon-plus avatar-uploader-icon" />
+        </el-upload>
+      </div>
+      <div class="info-msg">
+        <div>{{ msgInfo.name }}</div>
+        <div>璐﹀彿锛歿{ msgInfo.account }}</div>
+      </div>
+      <div class="info-logout">
+        <el-button type="primary" plain @click="logout">閫�鍑虹櫥褰�</el-button>
+      </div>
+    </div>
+    <div class="setting-list">
+      <div v-for="(item,index) in serviceArr" :key="index" class="setting-item">
+        <div class="item-icon  iconfont" :class="item.icon" />
+        <div class="item-msg">{{ item.name }}</div>
+        <div class="item-right" :class="item.right" @click="showDialog(item.name)" />
+      </div>
+    </div>
+    <!-- 鍚屾椂鐢ㄦ埛鍒楄〃涓�0涔熶笉灞曠ず -->
+    <template v-if="userList.length>1">
+      <SettingTitle left="鐢ㄦ埛鍒楄〃" />
+      <div class="setting-list">
+        <div v-for="item in userList" v-if="name !== item.username" :key="item.id" class="setting-item">
+          <div class="item-icon">
+            <el-avatar :size="40" :src="baseUrl+'/img'+item.avatar" />
+          </div>
+          <div class="item-msg">{{ item.username }}</div>
+          <div class="item-right">
+            <el-button v-if="authority" type="text" :style="{color:'red'}" @click="clear(item)">鍒犻櫎</el-button>
+          </div>
+        </div>
+      </div>
+    </template>
+    <template>
+      <SettingTitle left="琛ㄦ牸" />
+      <div class="setting-list">
+        <div class="setting-item">
+          <div class="item-icon iconfont icon-biaogeziduan" />
+          <div class="item-msg">淇敼鏌ョ湅琛ㄥご</div>
+          <el-dropdown trigger="click" @command="showTableDialog($event)">
+            <span class="el-dropdown-link">
+              <i class="el-icon-arrow-down el-icon--right" />
+            </span>
+            <el-dropdown-menu slot="dropdown">
+
+              <el-dropdown-item v-for="(item ,index) in allTab" :key="index" :command="item">{{ item.name }}</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        <!-- <div class="item-right  el-icon-arrow-down" @click="showDialog('淇敼琛ㄥ崟')"></div> -->
+        </div>
+      </div>
+    </template>
+    <SettingTitle left="娣诲姞鍨嬪彿" />
+
+    <div class="setting-model">
+      <el-row :gutter="20">
+        <el-col :span="4">
+          <div :style="{display:'flex'}">
+            <el-input
+              v-model="filterText"
+              placeholder="杈撳叆鍏抽敭瀛楄繘琛岃繃婊�"
+            />
+            <!-- <el-button>娣诲姞鍚嶇О</el-button> -->
+          </div>
+          <el-tree
+            ref="tree"
+            :style="{marginTop:'20px'}"
+            class="filter-tree"
+            :data="treeData"
+            :props="defaultProps"
+            default-expand-all
+            :filter-node-method="filterNode"
+          >
+            <span slot-scope="{ node, data }" class="custom-tree-node">
+              <div :style="{height:'100%', display:'flex',alignItems: 'center'}">
+                <div :style="{marginRight: '8px',display:'flex',alignItem: 'center'}">
+                  <span>{{ node.label }}</span>
+                  <span :style="{marginLeft: '20px',fontSize: '10px'}" class="edit el-icon-edit" @click="changeName(node,data)">淇敼</span>
+                  <span :style="{marginLeft: '20px',fontSize: '10px'}" class="edit el-icon-delete" @click="deleteName(node,data)" />
+                </div>
+                <!-- 绮惧害涓嶉珮 瀵艰嚧鐨勯棶棰�-->
+              </div>
+            </span>
+          </el-tree>
+        </el-col>
+        <el-col :span="20">
+          <div class="addName">
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <div :style="{display: 'flex'}">
+                  <el-input v-model="newName" :style="{marginRight: '8px'}" />
+                  <el-button @click="addNewName">娣诲姞鍚嶇О</el-button>
+                </div>
+
+              </el-col>
+              <el-col :span="14">
+                <el-row :gutter="20">
+                  <el-col :span="4">
+
+                    <el-select v-model="checkNameId" clearable placeholder="璇烽�夋嫨">
+                      <el-option
+                        v-for="item in nameOptions"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value"
+                      />
+                    </el-select>
+                  </el-col>
+                  <el-col :span="10">
+                    <el-input v-model="newModel" :style="{marginLeft: '8px'}" placeholder="璇疯緭鍏ュ瀷鍙峰悕绉�" />
+                  </el-col>
+                  <el-col :span="10">
+                    <el-input v-model="newProductCode" :style="{marginLeft: '8px'}" placeholder="璇疯緭鍏ヤ骇鍝佺紪鐮�" />
+                  </el-col>
+                </el-row>
+
+              </el-col>
+              <el-col :span="2">
+                <el-button @click="addNewModel">娣诲姞鍨嬪彿</el-button>
+              </el-col>
+            </el-row>
+          </div>
+          <el-table
+            class="tableData"
+            :height="450"
+            :max-height="450"
+            :row-class-name="onTableRowClassName"
+            :row-style="{height:0+'px'}"
+            :cell-style="{padding:8+'px',textAlign: 'center'}"
+            :header-cell-style="{borderRight:'0px',textAlign: 'center',background:'#52626F',color:'#fff', height:'10px', padding:'0px'}"
+            :stripe="true"
+            :data="tableData"
+            :border="true"
+            header-row-class-name="table-header"
+          >
+            <el-table-column
+              type="index"
+              label="搴忓彿"
+            />
+            <el-table-column
+              prop="productCode"
+              label="浜у搧缂栫爜"
+            />
+            <el-table-column
+              prop="productModel"
+              label="鍨嬪彿鍚嶇О"
+            />
+            <el-table-column
+              prop="productName"
+              label="浜у搧鍚嶇О"
+            />
+            <el-table-column
+              label="鏇村鎿嶄綔"
+            >
+              <template slot-scope="scope">
+                <el-button type="text" @click="changeModel(scope.row)">淇敼</el-button>
+                <el-button type="text danger" @click="deleteModel(scope.row)">鍒犻櫎</el-button>
+              </template>
+
+            </el-table-column>
+          </el-table>
+        </el-col>
+      </el-row>
+    </div>
+    <el-dialog class="changePassword" :visible.sync="passwordFormVisible" @close="handleClose('passwordParams')">
+      <div slot="title" class="title">
+        <span />
+        <span>淇敼瀵嗙爜</span>
+      </div>
+      <el-form ref="passwordParams" :model="passwordParams" :rules="passwordRules">
+        <el-row>
+          <el-col>
+            <el-form-item prop="oldPassword">
+              <el-input v-model="passwordParams.oldPassword" :validate-event="false" show-password type="password" placeholder="璇疯緭鍏ユ棫瀵嗙爜" autocomplete="off" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col>
+            <el-form-item prop="newPassword">
+              <el-input v-model="passwordParams.newPassword" :validate-event="false" show-password type="password" placeholder="璇疯緭鍏ユ柊瀵嗙爜" autocomplete="off" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="changePwd">纭� 瀹�</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog class="tableHead" :visible.sync="tableFormVisible" @close="handleClose('userParams')">
+      <div slot="title" class="title">
+        <span />
+        <span>淇敼琛ㄥ崟</span>
+      </div>
+      <el-form ref="userParams" :model="userParams">
+        <el-row>
+          <el-col>
+            <el-checkbox-group v-model="checkList">
+              <el-checkbox v-for="(item, index) in commandList" :key="index" :label="item" :checked="item.show" @change="changeCheck(!item.show,item)">{{ item.name }}</el-checkbox>
+            </el-checkbox-group>
+          </el-col>
+        </el-row>
+
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="changeTable">纭� 瀹�</el-button>
+        <!-- <el-button @click="tableFormVisible = false" >鍙� 娑�</el-button> -->
+      </div>
+    </el-dialog>
+    <el-dialog class="userInfo" title="涓汉璧勬枡" :visible.sync="infoFormVisible" @close="handleClose('addUserForm')">
+      <div slot="title" class="title">
+        <span />
+        <span>涓汉璧勬枡</span>
+      </div>
+      <el-form ref="addUserForm" :model="infoParams" :rules="addUserRules">
+        <el-row>
+          <el-col>
+            <el-form-item prop="username">
+              <el-input v-model="infoParams.username" placeholder="鐢ㄦ埛鍚�" autocomplete="off" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col>
+            <el-form-item prop="account">
+              <el-input v-model="infoParams.account" placeholder="璐﹀彿" autocomplete="off" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col />
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="changeInfo">纭� 瀹�</el-button>
+        <!-- <el-button @click="infoFormVisible = false" >鍙� 娑�</el-button> -->
+      </div>
+    </el-dialog>
+    <el-dialog class="addUser" :visible.sync="addVisible" @close="handleClose('addParams')">
+      <div slot="title" class="title">
+        <span />
+        <span>鏂板鐢ㄦ埛</span>
+      </div>
+      <el-form ref="addParams" label-position="left" label-width="80px" :model="addParams" :rules="addUserRules">
+
+        <el-form-item prop="username" label="鐢ㄦ埛鍚嶏細">
+          <el-input v-model="addParams.username" placeholder="鐢ㄦ埛鍚�" autocomplete="off" />
+        </el-form-item>
+
+        <el-form-item prop="account" label="璐﹀彿">
+          <el-input v-model="addParams.account" placeholder="璐﹀彿" autocomplete="off" />
+        </el-form-item>
+
+        <el-form-item prop="password" label="瀵嗙爜锛�">
+
+          <el-input v-model="addParams.password" placeholder="瀵嗙爜" show-password type="password" autocomplete="off" />
+        </el-form-item>
+
+        <el-form-item prop="authority" label="韬唤锛�">
+          <el-select v-model="addParams.authority" placeholder="璇烽�夋嫨韬唤">
+            <el-option
+              v-for="item in powerOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </el-form-item>
+
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="addNewUser">纭� 瀹�</el-button>
+        <!-- <el-button @click="infoFormVisible = false" >鍙� 娑�</el-button> -->
+      </div>
+    </el-dialog>
+
+    <el-dialog width="30%" handle-close-change-name-params- class="changeName" :visible.sync="changeNameVisible">
+
+      <div slot="title" class="title">
+        <span />
+        <span>淇敼鍚嶇О</span>
+      </div>
+      <el-form>
+        <el-form-item ref="changeNameParams" :model="changeNameParams">
+          <el-input v-model="changeNameParams.productName" />
+        </el-form-item>
+        <div :style="{display: 'flex'}">
+          <el-button type="primary" :style="{flex:'1'}" @click="ConfirmChange">纭畾淇敼</el-button>
+        </div>
+      </el-form>
+    </el-dialog>
+    <el-dialog handle-close-change-model-params- width="30%" class="changeModel" :visible.sync="changeModelVisible">
+      <div slot="title" class="title">
+        <span />
+        <span>淇敼鍨嬪彿</span>
+      </div>
+      <el-form>
+        <el-form-item ref="changeModelParams" :model="changeModelParams">
+          <el-input v-model="changeModelParams.productModel" placeholder="璇疯緭鍏ユ柊鍨嬪彿" />
+        </el-form-item>
+        <el-form-item :model="changeModelParams">
+          <el-input v-model="changeModelParams.productCode" placeholder="璇疯緭鍏ョ紪鐮�" />
+        </el-form-item>
+        <div :style="{display: 'flex'}">
+          <el-button type="primary" :style="{flex:'1'}" @click="confirmChangeModel">纭畾淇敼</el-button>
+        </div>
+      </el-form>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import { mapGetters } from 'vuex'
+import { getInfo, addUser, getUserList, updateUserPwd, delUser, updateUserProfile } from '@/api/user'
+import { selectAllName, addName, updateName, delName } from '@/api/productName'
+import { selectAllModel, addModel, updateModel, delModel } from '@/api/productModel'
+import { getToken } from '@/utils/auth'
 import SettingTitle from '@/components/SettingTitle'
 export default {
   data() {
+    const validateAccount = (rule, value, callback) => {
+      const reg = /^(?=.*\d).{6,11}$/
+      if (!reg.test(value)) {
+        callback(new Error('璐﹀彿鐢�6-10浣嶆暟瀛楃粍鎴愶紝璇疯緭鍏ユ纭殑璐﹀彿锛�'))
+      } else {
+        callback()
+      }
+    }
+    const validatePassword = (rule, value, callback) => {
+      // console.log(value)
+      const reg = /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{6,12}$/
+      // console.log(!reg.test(value))
+      if (!reg.test(value)) {
+        callback(new Error('瀵嗙爜蹇呴』鏄敱6-12浣嶅寘鍚ぇ灏忓啓瀛楁瘝锛屾暟瀛楃粍鍚�'))
+      } else {
+        callback()
+      }
+    }
     return {
+      changeNameVisible: false,
+      changeModelVisible: false,
+      changeNameParams: {
+        id: '',
+        productName: ''
+      },
+      changeModelParams: {
+      },
+      newModel: '',
+      newProductCode: '',
+      newName: '',
+      checkNameId: '',
+      nameOptions: [
+        {
+          label: 'abc',
+          value: '1'
+        }
+      ],
+      tableData: [],
+      treeData: [],
+      defaultProps: {
+        children: 'children',
+        label: 'label'
+      },
+      filterText: '',
+      addModelFormVisible: false,
+      addVisible: false,
+      powerOptions: [
+        {
+          value: '1',
+          label: '绠$悊鍛�'
+        },
+        {
+          value: '0',
+          label: '鏅�氱敤鎴�'
+        }
+      ],
+      addParams: {
+        account: '',
+        authority: '',
+        password: '',
+        username: ''
+      },
+      checkList: [],
+      tableSelectVisible: false,
+      baseUrl: process.env.VUE_APP_BASE_API,
+      msgInfo: {},
+      infoParams: {
+
+      },
+      infoFormVisible: false,
+      userParams: {
+        user: '',
+        power: ''
+      },
+      tableFormVisible: false,
+      passwordParams: {},
+      passwordFormVisible: false,
       deptName: '',
       queryParams: {
         pageNum: 1,
@@ -20,26 +419,471 @@
         deptId: undefined
       },
       dateRange: [],
-      userList: null
+      serviceArr: [
+        { name: '淇敼瀵嗙爜', icon: 'icon-mima', right: 'el-icon-arrow-right' },
+        { name: '涓汉璧勬枡', icon: 'icon-gerenziliao', right: 'el-icon-arrow-right' }
+      ],
+      formLabelWidth: '120px',
+      userList: [],
+      commandList: [],
+      tableName: '',
+      addUserRules: {
+        account: [{ required: true, trigger: 'blur', validator: validateAccount }],
+        password: [{ required: true, trigger: 'blur', validator: validatePassword }]
+      },
+      passwordRules: {
+        oldPassword: [{ required: true, validator: validatePassword }],
+        newPassword: [{ required: true, validator: validatePassword }]
+      },
+      addNameParams: {}
     }
+  },
+  watch: {
+    filterText(val) {
+      this.$refs.tree.filter(val)
+    }
+  },
+  computed: {
+    ...mapGetters([
+      'sidebar',
+      'avatar',
+      'name',
+      'allTab',
+      'authority',
+      'token'
+    ])
+  },
+  created() {
+    this.getUserInfo()
+    this.getAllUser()
+    this.setOptions()
   },
   components: {
     SettingTitle
+  },
+  mounted() {
+  },
+  methods: {
+    handleClose(refName) {
+      // console.log(refName)
+      this.$refs[refName]?.resetFields()
+    },
+    ConfirmChange() {
+      console.log(this.changeNameParams)
+      if (!this.changeNameParams.productName) return this.$message.error('璇疯鐪熷~鍐欎笉鍙负绌�')
+
+      updateName(this.changeNameParams).then((res) => {
+        this.changeNameParams.id = ''
+        this.changeNameParams.productName = ''
+        console.log('娓呯┖淇敼鍚嶇О杈撳叆妗嗗唴瀹�')
+        this.changeNameVisible = false
+        this.$message.success(res)
+        this.setOptions()
+      })
+    },
+    confirmChangeModel() {
+      console.log('淇敼鍨嬪彿鍙傛暟', this.changeModelParams)
+      updateModel(this.changeModelParams).then((res) => {
+        this.changeModelVisible = false
+        this.changeModelParams = {}
+        this.$message.success(res)
+        this.setOptions()
+      })
+    },
+    addNewName() {
+      console.log(this.newName)
+      if (!this.newName) return this.$message.error('娣诲姞鍚嶇О涓嶈兘涓虹┖')
+      addName({ productName: this.newName }).then((res) => {
+        this.newName = ''
+        this.$message.success(res)
+        this.setOptions()
+      }, () => {
+        // this.$message.error('娣诲姞澶辫触璇烽噸鏂板皾璇�')
+
+      })
+    },
+    changeName(node, data) {
+      // console.log(node, data)
+      this.changeNameParams.id = data.value
+      this.changeNameParams.productName = data.label
+      console.log(this.changeNameParams)
+      this.changeNameVisible = true
+    },
+    deleteName(node, data) {
+      console.log(data)
+      this.$alert('纭畾鍒犻櫎', '鍒犻櫎鍚嶇О', {
+        confirmButtonText: '纭畾',
+        callback: action => {
+          delName({ id: data.value, productName: data.label }).then((res) => {
+            this.$message.success(res)
+            this.setOptions()
+          })
+        }
+      })
+    },
+    addNewModel() {
+      addModel({ productNameId: this.checkNameId, productModel: this.newModel, productCode: this.newProductCode }).then((res) => {
+        this.checkNameId = ''
+        this.newModel = ''
+        this.newProductCode = ''
+        this.$message.success(res)
+        this.setOptions()
+      })
+    },
+    deleteModel(row) {
+      delModel({ id: row.id, productModel: row.productModel }).then((res) => {
+        this.$message.success(res)
+        this.setOptions()
+      })
+    },
+    changeModel(row) {
+      this.changeModelVisible = true
+      const params = { ...row }
+      delete params.productName
+      this.changeModelParams = { ... params }
+    },
+    async setOptions() {
+      this.tableData = []
+      this.treeData = []
+      const { data: nameRes } = await selectAllName()
+      // console.log(nameRes)
+      const nameArr = nameRes.productNames.map(item => {
+        return { value: item.id, label: item.productName }
+      })
+      this.nameOptions = nameArr
+      // console.log(nameArr)
+      for (const nameItem of nameArr) {
+        const { data } = await selectAllModel({ productNameId: nameItem.value })
+
+        data.models = data.models.map(item => {
+          item.productNameId = nameItem.value
+          item.productName = nameItem.label
+          return item
+        })
+        this.tableData = [...this.tableData, ...data.models]
+        const children = data.models.map(item => {
+          return { id: item.id, label: item.productModel }
+        })
+        this.treeData.push({ ...nameItem, children })
+      }
+      this.tableData = this.tableData.map(item => {
+        return { id: item.id, productModel: item.productModel, productCode: item.productCode, productName: item.productName }
+      })
+      // console.log(this.tableData)
+    },
+    onTableRowClassName({ row, rowIndex }) {
+      if (rowIndex % 2 != 0) {
+        return 'onAcitve'
+      } else {
+        return ''
+      }
+    },
+    async logout() {
+      console.log(1)
+      await this.$store.dispatch('user/logout')
+      this.$router.push(`/login?redirect=/home`)
+    },
+    filterNode(value, data) {
+      if (!value) return true
+      return data.label.indexOf(value) !== -1
+    },
+    changeCheck(newShow, item) {
+      item.show = newShow
+    },
+    changeUser(item) {
+
+    },
+    clear(item) {
+      // console.log()
+      delUser(item).then(res => {
+        this.$message.success('鍒犻櫎鎴愬姛')
+        // this.logout()
+        this.getAllUser()
+      }, () => {
+        this.$message.error('鍒犻櫎澶辫触')
+      })
+    },
+    handleAvatarSuccess(res, file) {
+      this.$message.success('涓婁紶鎴愬姛')
+      // this.$router.go(0)
+    },
+    async getAllUser() {
+      const { data } = await getUserList()
+      this.userList = data.user
+      console.log(this.userList)
+    },
+    addNewUser() {
+      // 娣诲姞鏍¢獙瑙勫垯
+      this.$refs.addParams.validate(valid => {
+        if (valid) {
+          addUser(this.addParams).then(res => {
+            this.addParams.account = ''
+            this.addParams.authority = ''
+            this.addParams.password = ''
+            this.addParams.username = ''
+            this.addVisible = false
+            this.getAllUser()
+            this.$message({
+              message: '鎭枩浣狅紝娣诲姞鎴愬姛',
+              type: 'success'
+            })
+          }, () => {
+            this.$message.error({
+              message: '娣诲姞鐢ㄦ埛澶辫触璇烽噸鏂板皾璇�'
+            })
+          })
+        } else {
+          this.$message.error('閿欒鎻愪氦锛岃〃鏍兼牎楠屽嚭閿�')
+        }
+      })
+      console.log(this.addParams)
+    },
+    showAdd() {
+      this.addVisible = true
+    },
+    showTableDialog(command) {
+      this.commandList = command.keys
+      this.tableName = command.name
+      this.tableFormVisible = true
+    },
+    getUserInfo() {
+      getInfo(getToken()).then(res => {
+        this.msgInfo = res.data
+        // console.log(鐢ㄦ埛淇℃伅锛歳es)
+      })
+    },
+    showDialog(name) {
+      if (name == '淇敼瀵嗙爜') {
+        this.passwordFormVisible = true
+      } else if (name == '淇敼琛ㄥ崟') {
+        this.tableSelectVisible = true
+      } else if (name == '涓汉璧勬枡') {
+        this.infoFormVisible = true
+      }
+    },
+    async changePwd() {
+      // 淇敼瀵嗙爜鍙傛暟
+      // this.logout()
+
+      this.$refs.passwordParams.validate(valid => {
+        if (valid) {
+          updateUserPwd(this.passwordParams).then(async res => {
+            this.passwordFormVisible = false
+            await this.logout()
+            this.$message({
+              message: '鎭枩浣狅紝淇敼鎴愬姛',
+              type: 'success'
+            })
+          }, () => {
+            // this.$message.error({
+            //   message: '娣诲姞鐢ㄦ埛澶辫触璇烽噸鏂板皾璇�'
+            // })
+          })
+        } else {
+          this.$message.error('閿欒鎻愪氦锛岃妫�鏌ュ瘑鐮佹牸寮�')
+        }
+      })
+    },
+    changeTable() {
+      console.log(this.commandList)
+      this.$store.commit('CHANGE_TAB_KEY', { name: this.tableName, keys: this.commandList })
+      this.tableFormVisible = false
+      console.log(this.$store.state)
+    },
+    async changeInfo() {
+      console.log(this.infoParams)
+      const res = await updateUserProfile(this.infoParams)
+      console.log(res)
+      // this.$refs
+      this.infoFormVisible = false
+      this.getUserInfo()
+      this.getAllUser()
+      this.setOptions()
+    }
   }
 }
 </script>
 
-<style lang="scss" >
+<style lang="scss" scoped>
 @import '../../../styles/variables.scss';
+//  ::v-deep .el-tree-node__content{
+//   height: 70px;
+// }
+.changeName{
+  .el-dialog{
+     width: 30% !important;
+  }
+
+}
+.el-tree-node__children{
+  .edit{
+    display: none;
+  }
+}
+ ::v-deep .el-dropdown-menu__item {
+
+      padding: 0 40px;
+      font-size: 16px;
+      border-bottom: 1px solid #efeeee;
+  }
+.el-icon-plus,.el-icon-arrow-down,.el-icon-arrow-right,.el-icon-arrow-left,.el-icon-arrow-up{
+  color: #409EFF;
+}
 .system-user{
     min-height: calc(100vh - 50px);
     padding: 40px;
     background: $mainBg;
+    .changePassword,.tableHead,.userInfo{
+      .title{
+        display: flex;
+        align-items: center;
+        span:nth-child(1){
+          margin-right: 8px;
+          display: inline-block;
+          width: 4px;
+          height: 18px;
+          background: #409EFF;
+        }
+      }
+      ::v-deep >div{
+        width: 600px;
+        border-radius: 10px;
+      }
+      ::v-deep .el-dialog__body{
+        padding: 30px 100px;
+        input{
+          border: 0px;
+          background: #f3f4f5;
+        }
+      }
+      ::v-deep .el-dialog__footer{
+        padding: 10px 100px 30px 100px;
+        // margin-right: ;
+        .dialog-footer{
+          display: flex;
+          button{
+            flex: 1;
+          }
+        }
+      }
+    }
+    .tableHead{
+      ::v-deep >div{
+        width: 300px;
+
+      }
+      ::v-deep .el-dialog__body{
+        padding: 30px 50px;
+      }
+      ::v-deep .el-checkbox{
+        margin-right: 0;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+      ::v-deep .el-checkbox__label{
+        width: 140px;
+        margin: 5px 10px;
+        padding: 10px 40px;
+        background: #f3f4f5;
+        border-radius: 6px;
+
+      }
+    }
 }
 .user-info{
   width: 100%;
   height: 125px;
   border-radius: 10px;
   background: #fff;
+  padding: 25px;
+  display: flex;
+  align-items: center;
+  .info-avatar{
+
+     .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 75px;
+    height: 75px;
+    line-height: 75px;
+    text-align: center;
+  }
+  .avatar {
+    width: 75px;
+    height: 75px;
+    display: block;
+    border-radius: 50%;
+  }
+  }
+  .info-logout{
+    // width: 100px;
+    .el-button--primary.is-plain{
+          background: #fff;
+          color: #409EFF;
+          border-color: #b3d8ff;
+    }
+  }
+  .info-msg{
+    flex: 1;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    padding-left: 25px;
+    >div:nth-child(1){
+      font-weight: 700;
+      font-size: 24px;
+
+    }
+  }
 }
-</style>
\ No newline at end of file
+
+.setting-model{
+   margin-top: 24px;
+  border-radius: 10px;
+  background: #fff;
+  border: 1px solid #ddd;
+  padding: 15px;
+  .addName{
+    // display: flex;
+    margin-bottom: 20px;
+  }
+}
+.setting-list{
+  margin-top: 24px;
+  border-radius: 10px;
+  background: #fff;
+  border: 1px solid #ddd;
+  .setting-item{
+    height: 70px;
+    padding: 15px;
+    width: 100%;
+    display: flex;
+    align-items: center;
+    .item-icon{
+      // width: 40px;
+      // height: 40px;
+    }
+    .item-msg{
+      flex: 1;
+      padding-left: 15px;
+    }
+
+  }
+  .setting-item{
+    // border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+  }
+}
+</style>
diff --git a/vue.config.js b/vue.config.js
index 5e622b0..34c35cb 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -13,7 +13,7 @@
 // For example, Mac: sudo npm run
 // You can change the port by the following methods:
 // port = 9528 npm run dev OR npm run dev --port = 9528
-const port = process.env.port || process.env.npm_config_port || 9527 // dev port
+const port = process.env.port || process.env.npm_config_port || 8010 // dev port
 
 // All configuration item explanations can be find in https://cli.vuejs.org/config/
 module.exports = {

--
Gitblit v1.9.3