123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- <style>
- </style>
- <template>
- <div style='height: 100%;'>
- <div id='import-header'>
- <img src='../assets/images/nav_images.png' alt=''>照片批量上传工具
- <button id='exit-btn' @click='logout' title="退出"></button>
- </div>
- <div id='import-body'>
- <div id='import-div'>
- <a href='javascript:;' class='file'>
- <!-- webkitdirectory-->
- <input id='photos' :disabled='uploadDisabled' multiple="true" title=' ' name='files' type='file' v-on:change='importPhotos'/>
- <button id='import-btn'>
- 上传照片
- </button>
- </a>
- <div id='progressDiv'>
- <span>
- 成功:
- <span style="color:green;">{{successNum}}</span>/{{allNum}}
- </span>
- <span>
- 失败:<span style="color:red;">{{errorNum}}</span>/{{allNum}}
- </span>
- <span v-show="completeShow" style="color: green;font-weight: bold;">全部处理完成</span>
- <span v-show="!completeShow&&(successNum>0||errorNum>0)" style="color: red;font-weight: bold;">处理中...</span>
- </div>
- </div>
- <div id='progress-div'>
- <div id='console-panel'>
- <div v-for='msgInfo in returnMsgList'>
- <p class='console-line' v-if='msgInfo.success'>
- <span><img src='../assets/images/icon_sucess.png'></span>
- <span>{{msgInfo.fileName}}:{{msgInfo.msg}}</span>
- </p>
- <p class='console-line' v-if='!msgInfo.success'>
- <span><img src='../assets/images/icon_failed.png'></span>
- <span>{{msgInfo.fileName}}:{{msgInfo.msg}}</span>
- </p>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- const CryptoJS = require('crypto-js');
- const Base64 = require('js-base64').Base64;
- export default {
- data() {
- return {
- photoQuantityLimit:10000,//单次上传限制
- photoList:[],//总的照片队列
- photoLine:[],//正在处理的照片队列
- concurrency:8,//同时处理的照片数量
- returnMsgList:[],//返回信息
- successNum:0, //成功数量
- errorNum:0, //失败数量
- allNum:0, //总数
- completeShow:false,
- uploadDisabled:false,
- seconds:0 // 耗时 秒
- }
- },
- methods: {
- init(){
- this.photoList = [];
- this.photoLine = [];
- this.returnMsgList = [];
- this.successNum = 0;
- this.errorNum = 0;
- this.allNum = 0;
- this.completeShow = false;
- },
- importPhotos() {
- this.init();
- var photos = document.getElementById('photos');
- for(var i = 0;i<photos.files.length;i++){
- this.photoList.push(photos.files[i]);
- }
- this.allNum = this.photoList.length;
- if(this.allNum > this.photoQuantityLimit){
- alert("单次上传文件数量不能大于"+this.photoQuantityLimit+",当前数量为"+this.allNum);
- photos.files = null;
- return;
- }
- //初始化this.concurrency个到photoLine中,开始处理
- this.photoLine = this.photoList.splice(0,this.concurrency);
- for(var i = 0;i<this.photoLine.length;i++){
- this.processStudentPhoto(this.photoLine[i]);
- }
- var _this = this;
- /**
- * 启动检查,看photoLine中是否有已完成的,如果有,从photoList中取出第一个将其替换
- * 队列中一直保持this.concurrency个正在处理的照片
- */
- var uploadTime = setInterval(function(){
- for (let i = 0; i < _this.photoLine.length; i++) {
- if (_this.photoLine[i].finished) {
- if (_this.photoList.length > 0) {
- _this.photoLine[i] = _this.photoList.shift();
- _this.processStudentPhoto(_this.photoLine[i]);
- }
- }
- }
- if (_this.photoList.length < 1) {
- console.log('photoList处理完毕');
- clearInterval(uploadTime);
- }
- },500);
- },
- processStudentPhoto(photo) {
- let photoNameArr = photo.name.split('.');
- let fileName = photoNameArr[0];//文件名就是身份证号码
- let fileSuffix = photoNameArr[1];//文件后缀
- //生成新名称
- let md5Hash = CryptoJS.MD5(Base64.encode(photo.name+new Date().getTime())).toString();
- let rootOrgId = localStorage.getItem('rootOrgId');
- //根据身份证号码查询学生信息
- this.$http.get('/api/ecs_core/studentFaceInfo/identityNumber?orgId='+rootOrgId+'&identityNumber='+fileName, {})
- .then((response) => {
- var studentFaceInfo = response.body;
- if (studentFaceInfo.student && studentFaceInfo.student.id) {
- this.detectFace(photo).then((res)=>{
- if(res.body.faces.length>=1){
- let face_token = res.body.faces[0].face_token;
- this.getFaceSetToken().then((res)=>{
- //var face_set_token = res.bodyText;
- var face_set_token = 'ee564a7abbde7f1287f668ddd945ccfa';
- this.addFaceToSet(face_set_token, face_token).then((res)=>{
- this.saveStudentFaceInfo({
- 'studentFaceInfoId':studentFaceInfo.id,
- 'studentId':studentFaceInfo.student.id,
- 'face_set_token':face_set_token,
- 'face_token':face_token,
- 'fileName':fileName,
- 'file':photo,
- 'fileSuffix':fileSuffix,
- 'photoNewName':md5Hash+'.'+fileSuffix
- });
- },(err)=>{
- this.finishOne(false,fileName,'addFaceToSet失败',photo);
- });
- },(err)=>{
- this.finishOne(false,fileName,'获取FaceSetToken失败',photo);
- });
- }else{
- this.finishOne(false,fileName,'face++没有检测到人脸',photo);
- }
- },(err)=>{
- this.finishOne(false,fileName,'调用face++检测人脸失败',photo);
- });
- }else{
- this.finishOne(false,fileName,'查询身份证不存在',photo);
- }
- },(err)=>{
- this.finishOne(false,fileName,'根据身份证号码查询失败',photo);
- });
- },
- //保存照片信息
- saveStudentFaceInfo(photoInfo){
- this.saveImageToUpyun(photoInfo).then((res)=>{
- //调用core后台接口,对数据进行保存
- if(!photoInfo.studentFaceInfoId){
- this.saveStudentFaceInfoByPost(photoInfo);
- }else{
- this.saveStudentFaceInfoByPut(photoInfo);
- }
- },(err)=>{
- this.finishOne(false,photoInfo.fileName,'saveImageToUpyun失败',photoInfo.file);
- });
- },
- //保存文件至又拍云
- saveImageToUpyun(photoInfo){
- var url = process.env.VUE_APP_UPYUN_BUCKETURL+'/student_base_photo/'+photoInfo.fileName+'/'+photoInfo.photoNewName;
- var authorization = 'Basic '+Base64.encode(process.env.VUE_APP_UPYUN_OPERATOR+':'+process.env.VUE_APP_UPYUN_PASSWORD);
- var headers = {headers:{'Authorization':authorization,'Content-Type': 'image/jpeg'}};
- return this.$http.put(url,photoInfo.file,headers);
- },
- //获取faceSetToken
- getFaceSetToken(){
- return this.$http.get('/api/ecs_core/faceSet/enableFaceSet');
- },
- //faceToken加入faceSetToken
- addFaceToSet(faceset_token,face_token){
- let formData_addface = new FormData();
- formData_addface.append('api_key', process.env.VUE_APP_FACEPP_API_KEY);
- formData_addface.append('api_secret',process.env.VUE_APP_FACEPP_API_SECRET);
- formData_addface.append('faceset_token', faceset_token);
- formData_addface.append('face_tokens', face_token);
- return this.$http.post('/facepp/v3/faceset/addface', formData_addface);
- },
- //face++分析人脸
- detectFace(file){
- let fileBlob = new Blob([file]);
- let formData_face_token = new FormData();
- formData_face_token.append('api_key',process.env.VUE_APP_FACEPP_API_KEY);
- formData_face_token.append('api_secret',process.env.VUE_APP_FACEPP_API_SECRET);
- formData_face_token.append('image_file', fileBlob);
- return this.$http.post('/facepp/v3/detect', formData_face_token);
- },
- saveStudentFaceInfoByPost(photoInfo){
- this.$http.post('/api/ecs_core/studentFaceInfo', {
- 'faceSetToken': photoInfo.face_set_token,
- 'faceToken': photoInfo.face_token,
- 'photoMD5': photoInfo.photoNewName,
- 'student': {
- 'id': photoInfo.studentId
- },
- 'createUser':localStorage.getItem('userName'),
- 'updateUser':localStorage.getItem('userName'),
- 'createType':'IMPORT_TOOL'
- }).then((res)=>{
- this.finishOne(true,photoInfo.fileName,'处理成功',photoInfo.file);
- },(err)=>{
- this.finishOne(false,photoInfo.fileName,'saveStudentFaceInfoByPost失败',photoInfo.file);
- });
- },
- saveStudentFaceInfoByPut(photoInfo){
- this.$http.put('/api/ecs_core/studentFaceInfo', {
- 'faceSetToken': photoInfo.face_set_token,
- 'faceToken': photoInfo.face_token,
- 'photoMD5': photoInfo.photoNewName,
- 'student': {
- 'id': photoInfo.studentId
- },
- 'createUser':localStorage.getItem('userName'),
- 'updateUser':localStorage.getItem('userName'),
- 'createType':'IMPORT_TOOL'
- }).then((res)=>{
- this.finishOne(true,photoInfo.fileName,'处理成功',photoInfo.file);
- },(err)=>{
- this.finishOne(false,photoInfo.fileName,'saveStudentFaceInfoByPut失败',photoInfo.file);
- });
- },
- //成功或失败处理
- finishOne(isSuccess,fileName,msg,file){
- file.finished = true;
- this.returnMsgList.push({'success':isSuccess,'fileName':fileName,'msg':msg});
- if(isSuccess){
- this.successNum++;
- }else{
- this.errorNum++;
- //如果存在nodejs环境
- if(typeof(nodeRequire) != "undefined"){
- var fs = nodeRequire("fs");
- if(fs){
- var errorfilePath = file.path.substring(0,file.path.lastIndexOf("\\"))+"\\errorfiles";
- if (!fs.existsSync(errorfilePath)) {
- fs.mkdirSync(errorfilePath);
- }
- var readStream = fs.createReadStream(file.path);
- var writeStream = fs.createWriteStream(errorfilePath+"\\"+file.name);
- readStream.pipe(writeStream);
- fs.appendFile(errorfilePath+'\\errorPhotos.txt',fileName+":"+msg+'\n',function (){});
- }
- }
- }
- if(this.errorNum+this.successNum == this.allNum){
- var photos = document.getElementById('photos');
- photos.files = null;
- this.completeShow = true;
- }
- },
- logout() {
- localStorage.removeItem("rootOrgId");
- localStorage.removeItem("userName");
- localStorage.removeItem("user_token");
- this.$router.push({path:'/login'});
- }
- }
- };
- </script>
|