因为原先平台绑定设备是通过一个界面进行人工选择绑定或一个人一个人绑定设备。如下:
但有时候需要在几千个里选择出几百个,那这种方式就不大现实了,需要另外一种方法。
目前相到可以通过导入批量数据进行绑定的方式。
一、前端
主要是显示选择文件与设备
<template><div class="import-bind" v-loading="fullscreenLoading" element-loading-text="文件上传中"><div class="detail">导入说明:本功能为批量导入用户绑定设备用,每次导入名单建议100名左右,要求导入的用户已经存在了。</div><div class="form-row"><div class="name">资料导入</div><input id="file" style="display:none" type="file" @change="fileChosen" /><el-input v-model="fileName" :disabled="true" style="width:260px;margin-left:20px"></el-input><el-button type="primary" @click="getFile()" style="width:130px;margin-left:20px">选择文件</el-button><ahref="http://face.oss-cn-qingdao.aliyuncs.com/FRS/data_template/201709/fabc5813-e589-4e99-9bd7-22b3c09a54.xlsx"><el-button type="primary" style="width:150px;margin-left:15px">资料模版下载</el-button></a></div><span v-show="fileTip1" style="color:red;margin-left:30px;">文件格式错误,请提交xls或xlsx格式文件</span><div class="form-row"><div class="name">识别设备</div><select-devices-popup v-model="devId"></select-devices-popup></div><el-button type="primary" @click="uploadFirstFile()"style="width:120px;margin-left:137px;margin-top:50px;">确定</el-button><el-dialog title="提示" :visible.sync="dialogVisible" :before-close="handleClose"><div v-if="portReady"><span>导入成功!</span></div><div v-else=""><span>导入失败!</span><span>导入数据存在问题,请修改后重新上传。查看</span><span style="color:#00A1E9;cursor:pointer"@click="gotoErrorDetail">错误明细</span></div><el-button type="primary" @click="dialogVisible = false" style="width:120px;margin-top:50px;">确 定</el-button><el-button type="cancel" @click="dialogVisible = false" style="width:120px;margin-top:50px;">取 消</el-button></el-dialog></div>
</template>
<script>
import appApi from '@/common/js/allApi.js'
import $ from 'jquery'
import selectDevicesPopup from '@/components/select-devices-popup.vue'export default {components: {selectDevicesPopup,},data() {return {fileList: [],fileName: '',largeFile: '',singleFile: 1024 * 1024, //单次上传大小tempPath: '',counter: 0,missTimeMax: 0, //单次上传最大丢包次数devId: '',excelPath: '',fileTip1: false,dialogVisible: false,portReady: false,fullscreenLoading: false}},mounted() {},methods: {getFile: function() {document.getElementById('file').click()},fileChosen: function() {var fname = document.getElementById('file').files[0].namethis.fileName = fnamevar type = fname.split('.')var filetype = type[type.length - 1]if (filetype != 'xls' && filetype != 'xlsx') {this.fileTip1 = true} else {this.fileTip1 = false}},//先传小文件uploadFirstFile: function() {var vm = thisif (this.fileName != '') {if (this.fileTip1 == true) {} else {var file = document.getElementById('file').files[0]var size = file.sizevar data = new FormData()data.append('file', file)data.append('fileName', file.name)data.append('filePath', '')data.append('isFirst', 'true')data.append('start', '0')data.append('fileSplitSize', size)// data.append('loginId', sessionStorage.getItem('birdloginid'));vm.fullscreenLoading = true$.ajax({processData: false, // 告诉jquery不要处理发送的数据contentType: false, // 告诉jquery不要设置content-Type请求头url: appApi.importStaff, //员工管理里更改的,从大文件上传-》上传文件type: 'POST',headers: { token: sessionStorage.token },data: data,success: function(msg) {console.log("uploadFirstFile msg=",msg);if (msg.code == '1') {vm.excelPath = msg.data.filePathif (msg.data.currentSize == size) {vm.tempPath = ''vm.counter = 0vm.importBind()} else {vm.tempPath = msg.data.filePathvm.missTimeMax = 0vm.counter++vm.uploadFirstFile()}} else {if (vm.missTimeMax < 10) {vm.missTimeMax++vm.uploadFirstFile()} else {vm.fullscreenLoading = falsevm.$message({type: 'warning',message: '当前网络不稳定,请重试!'})}}},error: function(error) {vm.fullscreenLoading = false}})}} else {vm.$message({type: 'error',message: '请同时上传基础资料和头像!'})}},//后台输入绑定解析文件importBind: function() {var vm = thisvar data = {companyId: sessionStorage.companyId,excelPath: this.excelPath,devId: this.devId,}$.ajax({url: appApi.importBind,type: 'POST',data: data,headers: { token: sessionStorage.token },success: function(msg) {vm.fullscreenLoading = falseif (msg.code == '0') {//文件内容错误vm.$message({type: 'error',message: msg.message})} else if (msg.code == '1') {//成功vm.dialogVisible = truevm.portReady = true} else if (msg.code == '2') {if(!msg.data) {vm.$message({type: 'error',message: msg.message})} else {//有错误数据vm.dialogVisible = truevm.portReady = falsewindow.dataList = msg.data.dataListwindow.imgList = msg.data.imgMap}}},error: function(xhr, type, errorThrown) {}})},gotoErrorDetail() {this.$router.push({path: '/error-log'})},handleClose() {}}
}
</script><style scoped lang='stylus'>
.import-bindpadding-left 15px.detailpadding-top 15px.form-rowmargin-left 30pxmargin-top 50px.namedisplay inline-blockwidth 90pxtext-align right.select-devices-popupdisplay inline-blockmargin-left 20px.list {list-style: none;
}ul li {margin-bottom: 10px;
}.head-submit {cursor: pointer;height: 140px;width: 140px;border: 2px dashed #ccc;border-radius: 3px;margin-left: 110px;margin-top: -70px;text-align: center;line-height: 140px;
}.el-dialog__body > .el-button--primary {margin-left: calc(50% - 130px);
}
</style>
界面如下:
二、后端代码
接口代码
@PostMapping("/importBind")@ApiOperation("批量导入员工数据绑定设备")public ResultBean<?> importBind(@ApiParam(name = "excelPath", value = "基础信息文件存储URL", required = true) @RequestParam String excelPath,@ApiParam(name = "companyId", value = "企业ID", required = true) @RequestParam Integer companyId,@ApiParam(name = "devId", value = "设备ID(','分隔)") @RequestParam(required = false) String devId) {// 错误信息存储列表List<UserErrorInfo> userErrorList = new ArrayList<>();List<String> imgErrorList = new ArrayList<>();Assert.notNull(companyId, ReturnCode.Params_Error);userService.importBind(companyId, getLoginId(), excelPath, userErrorList, imgErrorList, devId);// 返回结果if (userErrorList.size() == 0 && imgErrorList.size() == 0) {return Results.success();} else {Map<String, Object> errorLists = new HashMap<>();errorLists.put("dataList", userErrorList);errorLists.put("imgMap", imgErrorList);return new ResultBean<>(2, ReturnCode.File_Exist_Error_Data.getDetail(), errorLists);}}
绑定的主要逻辑如下:
@Overridepublic void importBind(Integer companyId, Integer loginId, String excelPath, List<UserErrorInfo> userErrorList,List<String> imgErrorList, String devId) {// 1. 解析EXCEL数据映射成原始数据信息列表List<Map<String, Object>> dataList = parseExcelToRawdata(excelPath);// 2. 过滤原始数据信息, 并转换成员工信息列表List<User> users = filterToUsersForBind(companyId, loginId, dataList, userErrorList);// 3. 批量绑定设备if(users.size()>0){batchBind(users,devId);}}@Transactional@OperLogInject("批量绑定员工信息")public void batchBind(List<User> users, String devId) {if (!devId.isEmpty() && !users.isEmpty()) {String userId = String.join(",", users.stream().map(u -> u.getId().toString()).collect(Collectors.toList()));try {ResultBean<?> bindResult = devService.bindUser(devId,null, userId, true,1);Assert.isTrue(bindResult.getCode() == 1, ReturnCode.User_Bind_Error);} catch (Exception e) {throw new CustomException(ReturnCode.User_Bind_Error);}}}