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

news2024/11/16 15:34:13

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

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

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

一、前端

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

<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.coloradmin.cn/o/930637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

性能测试报告-用于项目的性能验证、性能调优、发现性能缺陷等应用场景

性能测试报告 性能测试报告是一种重要的报告类型&#xff0c;旨在评估软件系统的性能、稳定性和安全性。在这篇文章中&#xff0c;我们将详细介绍性能测试报告的应用场景、测试方法和性能指标&#xff0c;以及如何撰写一份有效的性能测试报告。 一、概述 性能测试报告的目的是…

贪吃蛇是怎么实现的,循环数组的魔力

贪吃蛇是怎么实现的&#xff0c;比如有5个结点的蛇&#xff0c;1,2,3,4,5&#xff0c;1是头&#xff0c;5是尾&#xff0c;结点的坐标用(x,y)表示&#xff0c;蛇要移动x,y怎么变化&#xff1f;没有转向的时候好理解&#xff0c;如果是在水平方向直着走,所有结点的横坐标x1&…

stm32之9.中断优先级配置

主函数main.c #include <stm32f4xx.h> #include "led.h" #include "key.h"#define PAin(n) (*(volatile uint32_t *)(0x42000000 (GPIOA_BASE0x10-0x40000000)*32 (n)*4)) #define PEin(n) (*(volatile uint32_t *)(0x42000000 (GP…

Spring Cloud Alibaba-Sentinel-Sentinel入门

1 什么是Sentinel Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。Sentinel 具有以下特征: 丰富的应用场景&#xff1a;Sentinel 承接了阿里…

开始MySQL之路——MySQL约束概述详解

MySQL约束 create table [if not exists] 表名(字段名1 类型[(宽度)] [约束条件] [comment 字段说明],字段名2 类型[(宽度)] [约束条件] [comment 字段说明],字段名3 类型[(宽度)] [约束条件] [comment 字段说明] )[表的一些设置]; 概念 约束英文&#xff1a;constraint 约束实…

【详解】文本检测OCR模型的评价指标

关于文本检测OCR模型的评价指标 前言&#xff1a;网上关于评价标准乱七八糟的&#xff0c;有关于单词的&#xff0c;有关于段落的&#xff0c;似乎没见过谁解释一下常见论文中常用的评价指标具体是怎么计算的&#xff0c;比如DBNet&#xff0c;比如RCNN&#xff0c;这似乎好像…

6种限流实现,附代码![通俗易懂]

作者 | 磊哥 来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09; 转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone 限流是一种控制访问速率的策略&#xff0c;用于限制系统、服务或API接口的请求频率或数量。它的目的是为了保护系统免受过多请求的影响…

人体行走电压测试仪的特点

人体行走电压测试仪是一种用于测量人体行走时身体所受到的电压的设备。当人体行走时&#xff0c;我们身体与地面之间会形成电位差&#xff0c;这个电位差通常是很小的&#xff0c;但可能会对人体产生影响。通过使用行走电压测试仪&#xff0c;可以精确地测量这种电位差的大小。…

Leetcode-每日一题【剑指 Offer 36. 二叉搜索树与双向链表】

题目 输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点&#xff0c;只能调整树中节点指针的指向。 为了让您更好地理解问题&#xff0c;以下面的二叉搜索树为例&#xff1a; 我们希望将这个二叉搜索树转化为双向循环链表…

(mybatis与spring集合

mybatis与spring集合 一、Spring集成MyBatis1.1. pom依赖1.2. 配置文件1.3. Spring整合MyBatis1.3.1. 配置自动扫描JavaBean1.3.2. 配置数据源1.3.3. 配置session工厂1.3.4. 配置mapper扫描接口1.3.5. 配置事务管理器1.3.6. 配置AOP自动代理1.4. 测试 二、Spring集成PageHelper…

Nodejs+vue+elementui幼儿园管理系统5umt6

本课题主要研究如何用信息化技术改善传统幼儿园行业的经营和管理模式&#xff0c;简化幼儿园管理的难度&#xff0c;根据幼儿园管理实际业务需求&#xff0c;调研、分析和编写系统需求文档&#xff0c;设计编写符合企业需要的系统说明书&#xff0c;绘制数据库结构模型&#xf…

AI驱动的大数据创新:探索软件开发中的机会和挑战

文章目录 机会数据驱动的决策自动化和效率提升智能预测和优化个性化体验 挑战数据隐私与安全技术复杂性数据质量和清洗伦理和社会问题 案例&#xff1a;智能代码生成工具总结 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &…

SpringBoot使用@Scheduled实现定时任务

前言 Spring3.0版本之后就自带定时任务&#xff0c;提供了EnableScheduling和Scheduled这两个注解来实现定时任务的功能。 创建定时任务也变得尤为简单。 创建过程 步骤一&#xff1a;在SpringBoot的启动类上加上EnableScheduling注解&#xff0c;开启定时任务管理。 步骤二…

2023-08-26 LeetCode每日一题(汇总区间)

2023-08-26每日一题 一、题目编号 228. 汇总区间二、题目链接 点击跳转到题目位置 三、题目描述 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖…

五、多表查询-4.外连接

一、语法 二、演示-左外连接 【例】查询emp1表的所有数据&#xff08;17条&#xff09;&#xff0c;和对应的部门信息&#xff08;左外连接&#xff09; 【 左外连接和内连接区别】 内连接只能查到16条数据&#xff0c;dept_id为null的值查不到 左外连接可以查到17条所有数据…

中文乱码处理

&#x1f600;前言 中文乱码处理 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x1f609;&#x1f609; 在csdn获奖荣誉: &#x1f3c…

改进探索性数据分析的实用技巧!

Datawhale干货 译者&#xff1a;张峰&#xff0c;Datawhale成员 让 EDA 更简单&#xff08;更美观&#xff09;的实用指南&#xff01; 原文链接&#xff1a;https://towardsdatascience.com/practical-tips-for-improving-exploratory-data-analysis-1c43b3484577 介绍 探索性…

fastadmin iis伪静态应用入口文件index.php

<?xml version"1.0" encoding"UTF-8"?> <configuration><system.webServer><rewrite><rules><rule name"OrgPage" stopProcessing"true"><match url"^(.*)$" /><conditions…

骨传导耳机哪款比较好,几款骨传导耳机品牌推荐

相对于传统耳机&#xff0c;骨传导耳机的佩戴方式更加舒适。传统耳机需要插入耳道&#xff0c;可能会造成不适甚至痛感&#xff0c;而骨传导耳机则不需要直接接触耳朵&#xff0c;大大提高了佩戴的舒适度。并且骨传导耳机可以实现外界环境的感知。传统耳机会将耳朵与外界隔绝&a…

Java智慧工地源码:进度、质量、 成本、安全尽在掌握

智慧工地是一种崭新的工程全生命周期管理理念。智慧工地是智慧城市在建筑施工领域的延伸&#xff0c;是智慧城市的“基石”。随着工程信息化管理技术的发展&#xff0c;移动互联网、物联网、AI、大数据等新技术与施工现场业务场景深度融合&#xff0c;智慧工地已成为建筑工地信…