|
@@ -0,0 +1,328 @@
|
|
|
|
+// 批量上传
|
|
|
|
+<template>
|
|
|
|
+ <div>
|
|
|
|
+ <el-dialog
|
|
|
|
+ title="批量导入"
|
|
|
|
+ width="500px"
|
|
|
|
+ :visible.sync="dialogVisible"
|
|
|
|
+ :destroy-on-close="false"
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
+ @close="dialogClose"
|
|
|
|
+ >
|
|
|
|
+ <el-form ref="form" :rules="rules" :model="form" label-position="left" label-width="120px">
|
|
|
|
+ <el-form-item v-if="checkRole([1])" label="绑定账号" prop="adminId" required>
|
|
|
|
+ <el-select v-model="form.adminId" class="filter-item" placeholder="请选择账号" clearable filterable>
|
|
|
|
+ <el-option
|
|
|
|
+ v-for="item in userList"
|
|
|
|
+ :key="item.adminId"
|
|
|
|
+ :label="item.username"
|
|
|
|
+ :value="item.adminId"
|
|
|
|
+ />
|
|
|
|
+ </el-select>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="上传文件" prop="correctList">
|
|
|
|
+ <batch-file-upload ref="batchUploadRef" :range="1" @getFileList="batchUploadResult" />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-form>
|
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
|
+ <el-button @click="dialogVisible = false">
|
|
|
|
+ 取消
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button type="primary" @click="submit">
|
|
|
|
+ 确定
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </el-dialog>
|
|
|
|
+ <!-- 批量注册-抽屉 -->
|
|
|
|
+ <el-drawer
|
|
|
|
+ :title="hasCompleted ? '导入已完成' : '正在处理中..'"
|
|
|
|
+ :visible.sync="drawerVisible"
|
|
|
|
+ :wrapper-closable="false"
|
|
|
|
+ size="50%"
|
|
|
|
+ direction="rtl"
|
|
|
|
+ >
|
|
|
|
+ <div style="padding: 50px">
|
|
|
|
+ <div>
|
|
|
|
+ 已处理条数;{{ hasDealNumber }}; 待处理条数:{{ waitDealNumber }};
|
|
|
|
+ 总共条数:{{ allNumber }}
|
|
|
|
+ </div>
|
|
|
|
+ <el-progress
|
|
|
|
+ :percentage="makePercent"
|
|
|
|
+ :format="formatProgress"
|
|
|
|
+ style="margin-top: 10px"
|
|
|
|
+ />
|
|
|
|
+ <el-table
|
|
|
|
+ ref="batch_upload_result"
|
|
|
|
+ v-loading="false"
|
|
|
|
+ :data="batchUploadResultList"
|
|
|
|
+ class="table"
|
|
|
|
+ element-loading-text="Loading"
|
|
|
|
+ border
|
|
|
|
+ fit
|
|
|
|
+ highlight-current-row
|
|
|
|
+ height="500"
|
|
|
|
+ >
|
|
|
|
+ <el-table-column label="错误序号" align="center" width="100px">
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
+ {{ scope.$index + 1 }}
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="楼层" align="center">
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
+ {{ scope.row.floor }}
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="显示标题" align="center">
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
+ {{ scope.row.showTitle }}
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="身份证号" align="center">
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
+ {{ scope.row.idNumber }}
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="错误描述" align="center">
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
+ {{ scope.row.err }}
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+ <div style="text-align: center; margin: 20px 0">
|
|
|
|
+ <el-button type="primary" @click="drawerVisible = false">
|
|
|
|
+ 我已知晓
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button type="warning" @click="downloadBatchUploadErrorList">
|
|
|
|
+ 下载错误列表文件
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-drawer>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import { checkRole } from '@/utils/checkRole'
|
|
|
|
+import { addOrUpdate } from '@/api/visitee'
|
|
|
|
+import BatchFileUpload from '@/components/BatchFileUpload'
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ components: { BatchFileUpload },
|
|
|
|
+ props: {
|
|
|
|
+ userList: {
|
|
|
|
+ type: Array,
|
|
|
|
+ default: () => []
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ form: {
|
|
|
|
+ adminId: null,
|
|
|
|
+ correctList: {
|
|
|
|
+ correct: [],
|
|
|
|
+ incorrect: []
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ rules: {
|
|
|
|
+ adminId: [
|
|
|
|
+ { required: true, type: 'number', whitespace: true, message: '不能为空!', trigger: ['change', 'blur'] }
|
|
|
|
+ ],
|
|
|
|
+ correctList: [
|
|
|
|
+ { required: true, type: 'object', message: '模板不能为空!', trigger: ['change', 'blur'], validator: (rule, value, callback) => {
|
|
|
|
+ if (Object.keys(value).length > 0 && ((value.correct && value.correct.length > 0) || (value.incorrect && value.incorrect.length > 0))) {
|
|
|
|
+ return callback()
|
|
|
|
+ }
|
|
|
|
+ return callback('数据不能为空!')
|
|
|
|
+ } }
|
|
|
|
+ ]
|
|
|
|
+ },
|
|
|
|
+ dialogVisible: false,
|
|
|
|
+ // 批量注册-处理提示值
|
|
|
|
+ hasDealNumber: 0,
|
|
|
|
+ waitDealNumber: 0,
|
|
|
|
+ allNumber: 0,
|
|
|
|
+ hasCompleted: false,
|
|
|
|
+ // 批量注册-抽屉控制值
|
|
|
|
+ drawerVisible: false,
|
|
|
|
+ batchUploadResultList: []
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ // 批量注册-返回向下取整,减少渲染次数
|
|
|
|
+ makePercent() {
|
|
|
|
+ return Math.floor((this.hasDealNumber / this.allNumber) * 100)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ created() {},
|
|
|
|
+ methods: {
|
|
|
|
+ checkRole,
|
|
|
|
+ open() {
|
|
|
|
+ this.dialogVisible = true
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.$refs.form.resetFields()
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ dialogClose() {
|
|
|
|
+ this.$refs.batchUploadRef.clearFile()
|
|
|
|
+ },
|
|
|
|
+ batchUploadResult(correctList) {
|
|
|
|
+ this.form.correctList = correctList
|
|
|
|
+ },
|
|
|
|
+ // 批量注册-操作
|
|
|
|
+ getFileList(correctList) {
|
|
|
|
+ this.hasCompleted = false
|
|
|
|
+ this.drawerVisible = true
|
|
|
|
+ this.hasDealNumber = correctList.incorrect.length
|
|
|
|
+ this.waitDealNumber = correctList.correct.length
|
|
|
|
+ this.allNumber = correctList.incorrect.length + correctList.correct.length
|
|
|
|
+ this.batchUploadResultList = correctList.incorrect.map((item) => {
|
|
|
|
+ return { name: item.name, err: item.reason }
|
|
|
|
+ })
|
|
|
|
+ this.makeScrollDown()
|
|
|
|
+ this.doSubmitUrl(correctList, 0)
|
|
|
|
+ },
|
|
|
|
+ // 批量注册-并提交至添加到接口
|
|
|
|
+ async doSubmitUrl(correctList, index) {
|
|
|
|
+ if (index <= correctList.correct.length - 1) {
|
|
|
|
+ const item = correctList.correct[index]
|
|
|
|
+ if (item['楼层'] && item['显示标题']) {
|
|
|
|
+ // 组装数据上传
|
|
|
|
+ const data = JSON.parse(JSON.stringify(this.form))
|
|
|
|
+ data.name = item['姓名'] || null
|
|
|
|
+ data.phone = item['手机号'] || null
|
|
|
|
+ data.idNumber = item['身份证号'] || null
|
|
|
|
+ data.company = item['单位名称'] || null
|
|
|
|
+ data.unitName = item['部门'] || null
|
|
|
|
+ data.floor = item['楼层']
|
|
|
|
+ data.room = item['房间号'] || null
|
|
|
|
+ data.showTitle = item['显示标题']
|
|
|
|
+ delete data.correctList
|
|
|
|
+
|
|
|
|
+ let hasValidate = true
|
|
|
|
+ if (data.idNumber) {
|
|
|
|
+ if (data.idNumber === 15) {
|
|
|
|
+ const idreg = /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/
|
|
|
|
+ if (!idreg.test(data.idNumber)) {
|
|
|
|
+ this.batchUploadResultList.push({
|
|
|
|
+ floor: data.floor,
|
|
|
|
+ showTitle: data.showTitle,
|
|
|
|
+ idNumber: data.idNumber,
|
|
|
|
+ err: '身份证号格式错误'
|
|
|
|
+ })
|
|
|
|
+ hasValidate = false
|
|
|
|
+ }
|
|
|
|
+ } else if (data.idNumber === 18) {
|
|
|
|
+ const idreg = /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/
|
|
|
|
+ if (!idreg.test(data.idNumber)) {
|
|
|
|
+ this.batchUploadResultList.push({
|
|
|
|
+ floor: data.floor,
|
|
|
|
+ showTitle: data.showTitle,
|
|
|
|
+ idNumber: data.idNumber,
|
|
|
|
+ err: '身份证号格式错误'
|
|
|
|
+ })
|
|
|
|
+ hasValidate = false
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ this.batchUploadResultList.push({
|
|
|
|
+ floor: data.floor,
|
|
|
|
+ showTitle: data.showTitle,
|
|
|
|
+ idNumber: data.idNumber,
|
|
|
|
+ err: '身份证号位数错误'
|
|
|
|
+ })
|
|
|
|
+ hasValidate = false
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (hasValidate) {
|
|
|
|
+ try {
|
|
|
|
+ await addOrUpdate(data)
|
|
|
|
+ } catch (err) {
|
|
|
|
+ this.batchUploadResultList.push({
|
|
|
|
+ floor: data.floor,
|
|
|
|
+ showTitle: data.showTitle,
|
|
|
|
+ idNumber: data.idNumber,
|
|
|
|
+ err: err
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ this.batchUploadResultList.push({
|
|
|
|
+ name: item['姓名'] || '',
|
|
|
|
+ phone: item['手机号'] || '',
|
|
|
|
+ idNumber: item['身份证号'] || '',
|
|
|
|
+ company: item['单位名称'] || '',
|
|
|
|
+ unitName: item['部门'] || '',
|
|
|
|
+ floor: item['楼层'] || '',
|
|
|
|
+ room: item['房间号'] || '',
|
|
|
|
+ showTitle: item['显示标题'] || '',
|
|
|
|
+ err: '不包含 "楼层" 或 "显示标题" 字段'
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ this.hasDealNumber += 1
|
|
|
|
+ this.waitDealNumber -= 1
|
|
|
|
+ this.makeScrollDown()
|
|
|
|
+ // 继续调用
|
|
|
|
+ this.doSubmitUrl(correctList, ++index)
|
|
|
|
+ } else {
|
|
|
|
+ this.hasCompleted = true
|
|
|
|
+ this.$emit('finish')
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 批量注册人员-保持滚动条在最底部
|
|
|
|
+ makeScrollDown() {
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.$refs.batch_upload_result.$refs.bodyWrapper.scrollTop = this.$refs.batch_upload_result.$refs.bodyWrapper.scrollHeight
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ // 批量注册-返回进度条尾部显示值
|
|
|
|
+ formatProgress(percent) {
|
|
|
|
+ return percent === 100 ? '已完成' : ''
|
|
|
|
+ },
|
|
|
|
+ // 批量注册-导出错误名单
|
|
|
|
+ downloadBatchUploadErrorList() {
|
|
|
|
+ const list = this.batchUploadResultList
|
|
|
|
+ let string = '序号\t楼层\t显示标题\t身份证号\t错误原因\n'
|
|
|
|
+ for (let i = 0; i < this.batchUploadResultList.length; i++) {
|
|
|
|
+ string +=
|
|
|
|
+ (i + 1).toString() +
|
|
|
|
+ '\t' +
|
|
|
|
+ list[i].floor +
|
|
|
|
+ '\t' +
|
|
|
|
+ list[i].showTitle +
|
|
|
|
+ '\t' +
|
|
|
|
+ list[i].idNumber || '' +
|
|
|
|
+ '\t' +
|
|
|
|
+ list[i].err +
|
|
|
|
+ '\t' +
|
|
|
|
+ '\n'
|
|
|
|
+ }
|
|
|
|
+ const blob = new Blob([string], { type: 'text/plain;charset=utf-8' })
|
|
|
|
+ const excel_url = window.URL.createObjectURL(blob)
|
|
|
|
+ const link = document.createElement('a')
|
|
|
|
+ link.href = excel_url
|
|
|
|
+ link.download = '批量注册结果错误名单.xls'
|
|
|
|
+ document.body.appendChild(link)
|
|
|
|
+ link.click()
|
|
|
|
+ document.body.removeChild(link)
|
|
|
|
+ },
|
|
|
|
+ submit(e) {
|
|
|
|
+ e.preventDefault()
|
|
|
|
+ this.$refs.form.validate((valid) => {
|
|
|
|
+ if (!valid) {
|
|
|
|
+ return false
|
|
|
|
+ }
|
|
|
|
+ this.dialogVisible = false
|
|
|
|
+ this.getFileList(this.form.correctList)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style scoped>
|
|
|
|
+::v-deep .el-select {
|
|
|
|
+ width: 100%;
|
|
|
|
+}
|
|
|
|
+.table {
|
|
|
|
+ margin-top: 15px;
|
|
|
|
+}
|
|
|
|
+</style>
|