员工excel导入
This commit is contained in:
		
							parent
							
								
									4c5b831c22
								
							
						
					
					
						commit
						00099ed8c2
					
				@ -23,7 +23,8 @@
 | 
			
		||||
    "path-to-regexp": "2.4.0",
 | 
			
		||||
    "vue": "2.6.10",
 | 
			
		||||
    "vue-router": "3.0.6",
 | 
			
		||||
    "vuex": "3.1.0"
 | 
			
		||||
    "vuex": "3.1.0",
 | 
			
		||||
    "xlsx": "^0.16.9"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@vue/cli-plugin-babel": "4.4.4",
 | 
			
		||||
 | 
			
		||||
@ -36,3 +36,15 @@ export function addEmployee(data) {
 | 
			
		||||
    data
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** *
 | 
			
		||||
 *  批量导入员工的接口
 | 
			
		||||
 *
 | 
			
		||||
 * ***/
 | 
			
		||||
export function importEmployee(data) {
 | 
			
		||||
  return request({
 | 
			
		||||
    url: '/sys/user/batch',
 | 
			
		||||
    method: 'post',
 | 
			
		||||
    data
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										147
									
								
								src/components/UploadExcel/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/components/UploadExcel/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="upload-excel">
 | 
			
		||||
    <div class="btn-upload">
 | 
			
		||||
      <el-button :loading="loading" size="mini" type="primary" @click="handleUpload">
 | 
			
		||||
        点击上传
 | 
			
		||||
      </el-button>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick">
 | 
			
		||||
    <div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">
 | 
			
		||||
      <i class="el-icon-upload" />
 | 
			
		||||
      <span>将文件拖到此处</span>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import XLSX from 'xlsx'
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    beforeUpload: Function, // eslint-disable-line
 | 
			
		||||
    onSuccess: Function// eslint-disable-line
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      loading: false,
 | 
			
		||||
      excelData: {
 | 
			
		||||
        header: null,
 | 
			
		||||
        results: null
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    generateData({ header, results }) {
 | 
			
		||||
      this.excelData.header = header
 | 
			
		||||
      this.excelData.results = results
 | 
			
		||||
      this.onSuccess && this.onSuccess(this.excelData)
 | 
			
		||||
    },
 | 
			
		||||
    handleDrop(e) {
 | 
			
		||||
      e.stopPropagation()
 | 
			
		||||
      e.preventDefault()
 | 
			
		||||
      if (this.loading) return
 | 
			
		||||
      const files = e.dataTransfer.files
 | 
			
		||||
      if (files.length !== 1) {
 | 
			
		||||
        this.$message.error('Only support uploading one file!')
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      const rawFile = files[0] // only use files[0]
 | 
			
		||||
      if (!this.isExcel(rawFile)) {
 | 
			
		||||
        this.$message.error('Only supports upload .xlsx, .xls, .csv suffix files')
 | 
			
		||||
        return false
 | 
			
		||||
      }
 | 
			
		||||
      this.upload(rawFile)
 | 
			
		||||
      e.stopPropagation()
 | 
			
		||||
      e.preventDefault()
 | 
			
		||||
    },
 | 
			
		||||
    handleDragover(e) {
 | 
			
		||||
      e.stopPropagation()
 | 
			
		||||
      e.preventDefault()
 | 
			
		||||
      e.dataTransfer.dropEffect = 'copy'
 | 
			
		||||
    },
 | 
			
		||||
    handleUpload() {
 | 
			
		||||
      this.$refs['excel-upload-input'].click()
 | 
			
		||||
    },
 | 
			
		||||
    handleClick(e) {
 | 
			
		||||
      const files = e.target.files
 | 
			
		||||
      const rawFile = files[0] // only use files[0]
 | 
			
		||||
      if (!rawFile) return
 | 
			
		||||
      this.upload(rawFile)
 | 
			
		||||
    },
 | 
			
		||||
    upload(rawFile) {
 | 
			
		||||
      this.$refs['excel-upload-input'].value = null // fix can't select the same excel
 | 
			
		||||
      if (!this.beforeUpload) {
 | 
			
		||||
        this.readerData(rawFile)
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      const before = this.beforeUpload(rawFile)
 | 
			
		||||
      if (before) {
 | 
			
		||||
        this.readerData(rawFile)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    readerData(rawFile) {
 | 
			
		||||
      this.loading = true
 | 
			
		||||
      return new Promise((resolve, reject) => {
 | 
			
		||||
        const reader = new FileReader()
 | 
			
		||||
        reader.onload = e => {
 | 
			
		||||
          const data = e.target.result
 | 
			
		||||
          const workbook = XLSX.read(data, { type: 'array' })
 | 
			
		||||
          const firstSheetName = workbook.SheetNames[0]
 | 
			
		||||
          const worksheet = workbook.Sheets[firstSheetName]
 | 
			
		||||
          const header = this.getHeaderRow(worksheet)
 | 
			
		||||
          const results = XLSX.utils.sheet_to_json(worksheet)
 | 
			
		||||
          this.generateData({ header, results })
 | 
			
		||||
          this.loading = false
 | 
			
		||||
          resolve()
 | 
			
		||||
        }
 | 
			
		||||
        reader.readAsArrayBuffer(rawFile)
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    getHeaderRow(sheet) {
 | 
			
		||||
      const headers = []
 | 
			
		||||
      const range = XLSX.utils.decode_range(sheet['!ref'])
 | 
			
		||||
      let C
 | 
			
		||||
      const R = range.s.r
 | 
			
		||||
      /* start in the first row */
 | 
			
		||||
      for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
 | 
			
		||||
        const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
 | 
			
		||||
        /* find the cell in the first row */
 | 
			
		||||
        let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
 | 
			
		||||
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
 | 
			
		||||
        headers.push(hdr)
 | 
			
		||||
      }
 | 
			
		||||
      return headers
 | 
			
		||||
    },
 | 
			
		||||
    isExcel(file) {
 | 
			
		||||
      return /\.(xlsx|xls|csv)$/.test(file.name)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
.upload-excel {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
   margin-top: 100px;
 | 
			
		||||
   .excel-upload-input{
 | 
			
		||||
       display: none;
 | 
			
		||||
        z-index: -9999;
 | 
			
		||||
     }
 | 
			
		||||
   .btn-upload , .drop{
 | 
			
		||||
      border: 1px dashed #bbb;
 | 
			
		||||
      width: 350px;
 | 
			
		||||
      height: 160px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      line-height: 160px;
 | 
			
		||||
   }
 | 
			
		||||
   .drop{
 | 
			
		||||
       line-height: 80px;
 | 
			
		||||
       color: #bbb;
 | 
			
		||||
      i {
 | 
			
		||||
        font-size: 60px;
 | 
			
		||||
        display: block;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@ -1,10 +1,12 @@
 | 
			
		||||
// 该文件负责所有的公共的组件的全局注册   Vue.use
 | 
			
		||||
import PageTools from './PageTools'
 | 
			
		||||
import UploadExcel from './UploadExcel'
 | 
			
		||||
export default {
 | 
			
		||||
  // 为vue准备的第三方包, 必须有install方法
 | 
			
		||||
  // 这里方法可以自动接收一个形参, 就是Vue包
 | 
			
		||||
  install(Vue) {
 | 
			
		||||
    //  注册全局的通用栏组件对象
 | 
			
		||||
    Vue.component('PageTools', PageTools)
 | 
			
		||||
    Vue.component('UploadExcel', UploadExcel)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,16 @@ export const constantRoutes = [
 | 
			
		||||
    hidden: true
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    path: '/import',
 | 
			
		||||
    component: Layout,
 | 
			
		||||
    hidden: true, // 隐藏在左侧菜单中
 | 
			
		||||
    children: [{
 | 
			
		||||
      path: '', // 二级路由path什么都不写 表示二级默认路由
 | 
			
		||||
      component: () => import('@/views/import')
 | 
			
		||||
    }]
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // 404 page must be placed at the end !!!
 | 
			
		||||
  { path: '*', redirect: '/404', hidden: true }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
      <page-tools :show-before="true">
 | 
			
		||||
        <span slot="before">共166条记录</span>
 | 
			
		||||
        <template slot="after">
 | 
			
		||||
          <el-button size="small" type="warning">导入</el-button>
 | 
			
		||||
          <el-button size="small" type="warning" @click="$router.push('/import?type=employees')">导入</el-button>
 | 
			
		||||
          <el-button size="small" type="danger">导出</el-button>
 | 
			
		||||
          <el-button size="small" type="primary" @click="showDialog = true">新增员工</el-button>
 | 
			
		||||
        </template>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										72
									
								
								src/views/import/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/views/import/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <!-- 公共导入组件 -->
 | 
			
		||||
  <upload-excel :on-success="onSuccess" />
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { importEmployee } from '@/api/employees'
 | 
			
		||||
export default {
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    async onSuccess(data) {
 | 
			
		||||
      try {
 | 
			
		||||
        console.log(data)
 | 
			
		||||
        if (this.$route.query.type === 'employees') {
 | 
			
		||||
          const oldUserDate = data.results
 | 
			
		||||
          // 字典
 | 
			
		||||
          const dict = {
 | 
			
		||||
            '入职日期': 'timeOfEntry',
 | 
			
		||||
            '手机号': 'mobile',
 | 
			
		||||
            '姓名': 'username',
 | 
			
		||||
            '转正日期': 'correctionTime',
 | 
			
		||||
            '工号': 'workNumber'
 | 
			
		||||
          }
 | 
			
		||||
          // 遍历数组, 每次操作一个对象
 | 
			
		||||
          const userData = oldUserDate.map(user => {
 | 
			
		||||
            // 空对象存放新数据
 | 
			
		||||
            const obj = {}
 | 
			
		||||
            // 遍历一个对象, 对key进行替换
 | 
			
		||||
            for (const cnKey in user) {
 | 
			
		||||
              const enKey = dict[cnKey]
 | 
			
		||||
              let value = user[cnKey]
 | 
			
		||||
              // 特殊: 日期转换
 | 
			
		||||
              if (enKey === 'timeOfEntry' || enKey === 'correctionTime') {
 | 
			
		||||
                value = new Date(this.formatDate(value, '/'))
 | 
			
		||||
              }
 | 
			
		||||
              obj[enKey] = value
 | 
			
		||||
            }
 | 
			
		||||
            return obj
 | 
			
		||||
          })
 | 
			
		||||
          console.log(userData)
 | 
			
		||||
          await importEmployee(userData)
 | 
			
		||||
          this.$message.success('导入成功')
 | 
			
		||||
          this.$router.back()
 | 
			
		||||
        }
 | 
			
		||||
      } catch (error) {
 | 
			
		||||
        console.log(error)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    // 转换excel日期
 | 
			
		||||
    formatDate(numb, format) {
 | 
			
		||||
      const time = new Date((numb - 1) * 24 * 3600000 + 1)
 | 
			
		||||
      time.setYear(time.getFullYear() - 70)
 | 
			
		||||
      const year = time.getFullYear() + ''
 | 
			
		||||
      const month = time.getMonth() + 1 + ''
 | 
			
		||||
      const date = time.getDate() - 1 + ''
 | 
			
		||||
      if (format && format.length === 1) {
 | 
			
		||||
        return year + format + month + format + date
 | 
			
		||||
      }
 | 
			
		||||
      return year + (month < 10 ? '0' + month : month) + (date < 10 ? '0' + date : date)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user