人脸识别平台批量导入绑定设备的一种方法

        因为原先平台绑定设备是通过一个界面进行人工选择绑定或一个人一个人绑定设备。如下:

 但有时候需要在几千个里选择出几百个,那这种方式就不大现实了,需要另外一种方法。

  目前相到可以通过导入批量数据进行绑定的方式。

一、前端

主要是显示选择文件与设备

<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><a
        href="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].name
      this.fileName = fname
      var 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 = this
      if (this.fileName != '') {
        if (
          this.fileTip1 == true
        ) {
        } else {
          var file = document.getElementById('file').files[0]
          var size = file.size
          var 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.filePath
                if (msg.data.currentSize == size) {
                  vm.tempPath = ''
                  vm.counter = 0
                  vm.importBind()
                } else {
                  vm.tempPath = msg.data.filePath
                  vm.missTimeMax = 0
                  vm.counter++
                  vm.uploadFirstFile()
                }
              } else {
                if (vm.missTimeMax < 10) {
                  vm.missTimeMax++
                  vm.uploadFirstFile()
                } else {
                  vm.fullscreenLoading = false
                  vm.$message({
                    type: 'warning',
                    message: '当前网络不稳定,请重试!'
                  })
                }
              }
            },
            error: function(error) {
              vm.fullscreenLoading = false
            }
          })
        }
      } else {
        vm.$message({
          type: 'error',
          message: '请同时上传基础资料和头像!'
        })
      }
    },
    //后台输入绑定解析文件
    importBind: function() {
      var vm = this
      var 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 = false
          if (msg.code == '0') {
            //文件内容错误
            vm.$message({
              type: 'error',
              message: msg.message
            })
          } else if (msg.code == '1') {
            //成功
            vm.dialogVisible = true
            vm.portReady = true
          } else if (msg.code == '2') {
            if(!msg.data) {
              vm.$message({
                type: 'error',
                message: msg.message
              })
            } else {
              //有错误数据
              vm.dialogVisible = true
              vm.portReady = false
              window.dataList = msg.data.dataList
              window.imgList = msg.data.imgMap
            }
          }
        },
        error: function(xhr, type, errorThrown) {}
      })
    },
    gotoErrorDetail() {
      this.$router.push({
        path: '/error-log'
      })
    },
    handleClose() {}
  }
}
</script>

<style scoped lang='stylus'>
.import-bind
  padding-left 15px
  .detail
    padding-top 15px
  .form-row
    margin-left 30px
    margin-top 50px
    .name
      display inline-block
      width 90px
      text-align right
    .select-devices-popup
      display inline-block
      margin-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);
        }
    }

绑定的主要逻辑如下:

@Override
	public 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);
            }
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/91504.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux操作系统--克隆虚拟机

1.概述 我们在搭建大数据或者是集群的过程中,需要使用到许多配置相同或者相类似的环境。这一个时候就需要使用到克隆虚拟机的功能。 2.克隆虚拟机过程 (1).从现有虚拟机(关机状态)克隆出新虚拟机,右键选择管理=>克隆,如下所示 (2).直接点击下一步。如下所示 (3).选择…

Android Studio中引入MagicIndicator

1.github中下载文件 GitHub - hackware1993/MagicIndicator: A powerful, customizable and extensible ViewPager indicator framework. As the best alternative of ViewPagerIndicator, TabLayout and PagerSlidingTabStrip —— 强大、可定制、易扩展的 ViewPager 指示器框…

【Unity3D赛车游戏】【五】Unity中汽车加速效果是如何优化的?

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

Python如何进行基本的数学运算

Python进行基本的数学运算 Python是一门功能强大且易于学习的编程语言&#xff0c;它不仅可以用于开发应用程序&#xff0c;还可以用于执行各种数学运算。让我们一起来看看如何在Python中进行基本的数学运算。 加法、减法、乘法和除法 Python支持常见的加法、减法、乘法和除…

Linux操作系统--包管理yum

1.概述 YUM(全称为 Yellow dog Updater, Modified)是一个在 Fedora 和 RedHat 以及 CentOS中的 Shell 前端软件包管理器。基于 RPM 包管理,能够从指定的服务器自动下载 RPM 包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。…

Redis数据结构全解析【超详细万字分析】

文章目录 前言一、SDS1、SDS的必要性2、SDS的数据结构3、SDS的优势O&#xff08;1&#xff09;复杂度获取字符串长度二进制安全不会发生缓冲区溢出节省空间 二、链表1、结构设计2、优缺点 三、压缩列表1、结构设计2、连续更新3、压缩列表的缺陷 四、哈希表1、结构设计2、哈希冲…

开发新能源的好处

风能无论是总装机容量还是新增装机容量&#xff0c;全球都保持着较快的发展速度&#xff0c;风能将迎来发展高峰。风电上网电价高于火电&#xff0c;期待价格理顺促进发展。生物质能有望在农业资源丰富的热带和亚热带普及&#xff0c;主要问题是降低制造成本&#xff0c;生物乙…

深入分析负载均衡情景

本文出现的内核代码来自Linux5.4.28&#xff0c;为了减少篇幅&#xff0c;我们尽量不引用代码&#xff0c;如果有兴趣&#xff0c;读者可以配合代码阅读本文。 一、有几种负载均衡的方式&#xff1f; 整个Linux的负载均衡器有下面的几个类型&#xff1a; 实际上内核的负载均衡…

C#_委托详解

委托是什么&#xff1f; 字面理解&#xff1a;例如A要建一栋别墅&#xff0c;找到B建筑施工队&#xff0c;请B来建筑别墅。 委托类型规定方法的签名&#xff08;方法类型&#xff09;&#xff1a;返回值类型、参数类型、个数、顺序。 委托变量可以用来存储方法的引用&#x…

基于微信小程序的垃圾分类系统设计与实现(2.0 版本,附前后端代码)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 1 简介 视频演示地址&#xff1a; 基于微信小程序的智能垃圾分类回收系统&#xff0c;可作为毕业设计 小…

【系统】win11怎么退回win10

根据微软官方提供的回滚方案显示&#xff0c;在升级Win11之后的10天之内&#xff0c;用户可以通过系统恢复选项将Win11还原Win10。操作方式也比较简单&#xff0c;大家可以打开系统设置&#xff0c;找到相应选项&#xff0c;选择并确认后即可轻松将Win11回退早期版本。详细操作…

darknet yolo make报错,缺少instance-segmenter.o的规则

文章目录 darknet yolo make报错&#xff0c;缺少instance-segmenter.o的规则报错原因解决办法新问题解决办法 补充g编译选项Makefile编译规则 darknet yolo make报错&#xff0c;缺少instance-segmenter.o的规则 报错原因 Makefile没有识别到对于instance-segmenter.o的编译…

Docker制作镜像

使用mysql:5.7和owncloud镜像&#xff0c;构建个人网盘&#xff1a; 首先&#xff0c;确保你已经安装了Docker。然后&#xff0c;使用以下命令拉取并运行mysql:5.7镜像&#xff1a; docker run -d --name mysql-server -e MYSQL_ROOT_PASSWORD123456 mysql:5.7 接下来&…

jvm开启远程调试功能;idea远程debug

概述 有时候一些问题本地调试无法复现&#xff0c;这个时候可以开启jvm的远程调试功能 jar包启动 jdk8 java -agentlib:jdwptransportdt_socket,address8787,servery,suspendn -jar xxx.jarjdk11/17 java -agentlib:jdwptransportdt_socket,address*:8787,servery,suspe…

【ArcGIS Pro二次开发】(62):复制字段

应网友需求&#xff0c;做了这么一个复制字段的小工具。 假定这样一个场景&#xff0c;手头有一个要素1&#xff0c;要素里有10个字段&#xff0c;另一个要素2&#xff0c;除了shape_area等图形字段外&#xff0c;没有其它字段。 现在的需求是&#xff0c;想把要素1中的8个字…

Docker容器与虚拟化技术:GitHub账户注册

目录 一、实验 1.GitHub 一、实验 1.GitHub &#xff08;1&#xff09;GitHub是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持Git作为唯一的版本库格式进行托管&#xff0c;故名GitHub。 &#xff08;2&#xff09;官网 GitHub: Let’s build from here …

Mac发现有的软件不能上网的破解之法

1、Mac上打开终端 terminal &#xff0c;获取 root 权限。 sudo -i 2、编辑 hosts 文件 vim /private/etc/hosts 3、找到被禁止软件的数据请求域名&#xff0c;然后删除相关行&#xff0c;快捷件dd&#xff0c;然后:wq保存退出 比如百度 127.0.0.1 pan.baidu.com ##sec 印…

为什么物联网和端点安全需要细化

组织和个人越来越关心&#xff1a;物联网 ( IoT ) 的激增以及这些设备创建的无数端点。预计到 2025 年将有 750 亿个物联网设备投入使用&#xff0c;确保这些设备的安全已经至关重要。 2019 年生产的设备预期寿命只有五年&#xff0c;现在存在大量制造商在生产过程中无法预见的…

一张表将DataFrame两列合并为一列

将年份和月份合并为一个新字段&#xff08;日期&#xff09; data["日期"] data["年份"].map(str) "-" data["月份"].map(str)map用法 如果需要把数据集中gender列的男替换为1&#xff0c;女替换为0&#xff0c;怎么做呢&#xff1f;绝…

Vue2向Vue3过度核心技术自定义指令

目录 1 自定义指令1.指令介绍2.自定义指令3.自定义指令语法4.指令中的配置项介绍5.代码示例6.总结 2 自定义指令-指令的值1.需求2.语法3.代码示例 3 自定义指令-v-loading指令的封装1.场景2.需求3.分析4.实现5.准备代码 1 自定义指令 1.指令介绍 内置指令&#xff1a;v-html、v…
最新文章