liuxiaolong
2019-05-06 c15226e1b58f255dbebf1bdca8d4e53b9277249c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
package com.basic.analy.controller;
 
 
import com.alibaba.fastjson.JSONObject;
import com.basic.analy.config.Result;
import com.basic.analy.dao.BbFaceDao;
import com.basic.analy.dao.UserRoleDao;
import com.basic.analy.entity.FaceResults;
import com.basic.analy.model.BbFace;
import com.basic.analy.model.BbPerson;
import com.basic.analy.service.FaceSdkTool;
import com.basic.analy.service.impl.BbPersonBaseServiceImpl;
import com.basic.analy.service.impl.BbPersonTemporaryServiceImpl;
import com.basic.analy.utils.*;
import com.cloud.common.model.FileInfos;
import com.cloud.common.utils.FastDFSUtil;
import com.cloud.common.utils.RestTemplateUtil;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
 
 
@Api(value = "FileController", description = "人员添加去重")
@RestController
@RequestMapping("/addPerson")
public class FileController {
 
    @Autowired
    private FastDFSUtil fastDFSUtil;
    @Autowired
    private BbPersonBaseServiceImpl baseServiceImpl;
    @Autowired
    private BbPersonTemporaryServiceImpl temporaryServiceImpl;
    @Autowired
    private BbFaceDao bbFaceDao;
    @Value("${imgPath.ip}")
    private String imgServerIp;    //图片服务器路径
    @Value("${clusterLocaltion.pathUrl}")
    private String clusterLocaltion;    //图片服务器路径
    @Autowired
    private RestTemplateUtil restTemplateUtil;
    @Autowired
    private UserRoleDao userRoleDao;
 
    private Logger log = Logger.getLogger(FileController.class);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    /**
     * 文件上传
     *
     * @param
     * @return
     * @throws Exception
     */
    @RequestMapping("/upload")
    @ApiOperation(value = "人员添加测试方法", notes = "人员添加测试方法", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Result uploadByFile(@ApiParam(value="files" ,required = true)MultipartFile[] files,HttpServletRequest request)
            throws Exception {
 
 
        List<Map> errorList=new ArrayList<>();
        String userName = (String) request.getSession().getAttribute("userName");
        //是否成功上传
        boolean isSuccess=true;
        //定义返回码,对应于前台不同的页面,成功的话200,有失败没有重复的话300,有重复的就400
        int returnCode=200;
        String msg="上传结束";
        //从底库拿到所有人的特征值(需要一个关联查询faceIDs  resourceId)
        List<Map> featureList = baseServiceImpl.selectAllAndFeature(null);
        log.info("底库中需要对比的人脸有:"+featureList.size()+"份数据");
        for(MultipartFile file :files){
            log.info("传进来的文件为"+file.getName());
            List<Map> baseList=new ArrayList<>();
            String fileName="";
            try {
                //将传进来的文件(图片)转化为byte[] imdata
                byte[] imgdata = file.getBytes();
                log.info("传进来的文件名称是"+fileName);
                //用C接口切出特征值,传进去的图片可能会是多人脸图(小概率),如果是的话,取出第一个作为他的人脸图。
                ArrayList<FaceResults> faceResults = FaceSdkTool.extractFace(imgdata);
                //log.info("切出了:"+faceResults.size()+"张人脸");
                if(faceResults.size()==0){
                    Map noFaceMap = new HashMap();
                    Map map1 = new HashMap();
                    map1.put("fileName",fileName);
                    noFaceMap.put("upload",map1);
                    noFaceMap.put("reason","未在您上传的图片中检测到人脸,请您核查");
                    errorList.add(noFaceMap);
                    isSuccess=false;
                    continue;
                }
                if(faceResults.size()>1){
                    Map manyFaceMap = new HashMap();
                    Map map1 = new HashMap();
                    map1.put("fileName",fileName);
                    manyFaceMap.put("upload",map1);
                    manyFaceMap.put("reason","在您上传的图片中检测到不止一张人脸,请您核查");
                    errorList.add(manyFaceMap);
                    isSuccess=false;
                    continue;
                }
 
                boolean flag=true;
                List<Map> resultList = new ArrayList<>();
                SearchImgThreadUtil.resultList = resultList;
                //用C接口去比对特征值,达到阈值(比如90)的取出这个对象以及比对的对象和比对值存到map中,map塞进list中,如果没有达到阈值的则插入数据库中。
                if(featureList.size()>0){
                    ForkJoinPool fjp = new ForkJoinPool(4); // 最大并发数4
                    ForkJoinTask<Integer> task = new SearchImgThreadUtil(imgdata,featureList,30,0,featureList.size());
                    long startTime = System.currentTimeMillis();
                    Integer result = fjp.invoke(task);
                    long endTime = System.currentTimeMillis();
                    log.info("时间为"+(endTime-startTime)+"毫秒");
                }
 
 
            } catch (Exception e) {
                isSuccess=false;
                Map errorMap=new HashMap();
                errorMap.put("upload",fileName);
                errorMap.put("reason","程序或者网络出现异常!");
                errorList.add(errorMap);
                e.printStackTrace();
            }
        }
 
        if(errorList.size()>0&&returnCode!=400){
            returnCode=300;
        }
 
        return Result.custom("上传结束", returnCode,isSuccess,errorList);
    }
 
    /**
     * 来自人员管理的http请求(多张导入),把图片路径传过来
     * @param jsonMap
     * @return
     * @throws Exception
     */
    @RequestMapping("/uploadByByte")
    @ApiOperation(value = "底库人员图片上传方法", notes = "底库页面上传去重", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Map uploadByByte(@RequestBody Map jsonMap, HttpServletRequest request)
            throws Exception {
        List<FileInfos> list =   (List<FileInfos>)jsonMap.get("list");
        Object org = jsonMap.get("orgId");
        Object office = jsonMap.get("officeId");
 
        List<Map> errorList=new ArrayList<>();
        String userName = (String) request.getSession().getAttribute("userName");
        //是否成功上传
        boolean isSuccess=true;
        //定义返回码,对应于前台不同的页面,成功的话200,有失败没有重复的话300,有重复的就400
        int returnCode=200;
        String msg="上传结束";
        //从底库拿到所有人的特征值(需要一个关联查询faceIDs  resourceId)
        List<Map> featureList = baseServiceImpl.selectAllAndFeature(null);
        //定义一个计数器,计数上传成功的数量
        int successNum = 0;
        int failNum = 0;
        log.info("底库中需要对比的人脸有:"+featureList.size()+"份数据");
 
        for(Object obj :list){
            String s = JSONObject.toJSONString(obj);
            FileInfos fileInfo=JSONObject.parseObject(s,FileInfos.class);
            log.info("传进来的文件为"+fileInfo.getName());
            log.info("传进来的文件路径为"+fileInfo.getPath());
            List<Map> baseList=new ArrayList<>();
            String fileName="";
            try {
                //将传进来的文件(图片)转化为byte[] imdata
                String imgUrl = imgServerIp+fileInfo.getPath();
                System.out.println("图片完整下载地址"+imgUrl);
                //byte[] imgdata = Base64Utils.ImageToByteByOnline(imgUrl);
                byte[] imgdata = fastDFSUtil.downloadFDFS(fileInfo.getPath());
                fileName= fileInfo.getName();
                log.info("传进来的文件名称是"+fileName);
                //用C接口切出特征值,传进去的图片可能会是多人脸图(小概率),如果是的话,取出第一个作为他的人脸图。
                ArrayList<FaceResults> faceResults = FaceSdkTool.extractFace(imgdata);
                log.info("切出了:"+faceResults.size()+"张人脸");
                if(faceResults.size()==0){
                    Map noFaceMap = new HashMap();
                    Map map1 = new HashMap();
                    map1.put("fileName",fileName);
                    map1.put("path",fileInfo.getPath());
                    noFaceMap.put("upload",map1);
                    noFaceMap.put("reason","未在您上传的图片中检测到人脸,请您核查");
                    errorList.add(noFaceMap);
                    isSuccess=false;
                    failNum++;
                    continue;
                }
                if(faceResults.size()>1){
                    Map manyFaceMap = new HashMap();
                    Map map1 = new HashMap();
                    map1.put("fileName",fileName);
                    map1.put("path",fileInfo.getPath());
                    manyFaceMap.put("upload",map1);
                    manyFaceMap.put("reason","在您上传的图片中检测到不止一张人脸,请您核查");
                    errorList.add(manyFaceMap);
                    isSuccess=false;
                    failNum++;
                    continue;
                }
 
                boolean flag=true;
 
                //用C接口去比对特征值,达到阈值(比如90)的取出这个对象以及比对的对象和比对值存到map中,map塞进list中,如果没有达到阈值的则插入数据库中。
 
                if(featureList.size()>0){
                    for(Map featureMap:featureList){
                        Float liker =0.0f;
                        if((byte[])featureMap.get("feature")!=null&&!"".equals((byte[])featureMap.get("feature"))){
                            liker = FaceSdkTool.compareFeature((byte[])featureMap.get("feature"),faceResults.get(0).getFeature());
                            //log.info("相似值liker是:"+liker);
                        }
 
                        if(liker>0.7){
                            flag=false;
                            isSuccess=false;
                            returnCode=400;
                            featureMap.put("liker",Math.round(liker*100));
                            featureMap.remove("feature");
                            String colonyIdStr = (String)featureMap.get("distributionIds");
                            log.info("集群id为"+colonyIdStr);
                            if(colonyIdStr!=null&&!"".equals(colonyIdStr)){
                                JSONObject paramMap = new JSONObject();
                                paramMap.put("clusterIds",colonyIdStr);
                                String post = restTemplateUtil.post(clusterLocaltion, paramMap , MediaType.APPLICATION_JSON_UTF8, true);
                                JSONObject jsonMap1 = JSONObject.parseObject(post);
                                featureMap.put("colonys",jsonMap1.get("data"));
                            }
                            String userIdStr = featureMap.get("userId")!=null?(featureMap.get("userId")+""):"";
                            if(userIdStr!=null&&!"".equals(userIdStr)){
                                Long userId = Long.valueOf(userIdStr);
                                log.info("用户id为"+colonyIdStr);
                                List<Integer> roleIds = null;
                                if(userId!=null&&!"".equals(userId)){
                                    roleIds = userRoleDao.findRolesIds(userId);
                                    featureMap.put("roleIds",roleIds);
                                }
                            }
 
                            baseList.add(featureMap);
                        }
                    }
 
                }
 
                //跟库里所有的比完之后仍为true的证明没有相似的,可以入库
                if(flag){
                    FileInfos fileInfos =  fastDFSUtil.uploadByByte(imgdata,fileName.split("\\.")[1]);//FastDFS上的图片地址
                    if(StringUtils.isNotEmpty(fileInfos.getPath())){
                        //构造BbPerson对象,往数据库中插入此条数据
                        BbPerson bbPersonBase =new BbPerson();
                        bbPersonBase.setPhotos(fileInfos.getPath());
                        bbPersonBase.setCreateBy(userName);
                        if(org!=null){
                            Integer orgId = (Integer) org;
                            bbPersonBase.setOrgId(orgId);
                        }
                        if(office!=null){
                            Integer officeId = (Integer) office;
                            bbPersonBase.setOfficeId(officeId);
                        }
 
                        bbPersonBase.setId("PSSVR0101"+sdf.format(new Date()));
                        BbFace bbFace = new BbFace();
                        bbFace.setFeature(faceResults.get(0).getFeature());
                        baseServiceImpl.insert(bbPersonBase,bbFace);
                        successNum++;
                        //okList.add(fileName);
                    }
                }else{
                    //有重复的
                    Map<String, Object> failMap = new HashMap<>();
                    Map map1 = new HashMap();
                    map1.put("fileName",fileName);
                    map1.put("path",fileInfo.getPath());
                    failMap.put("upload",map1);
                    failMap.put("baseList",baseList);
                    failMap.put("reason","在底库中查到相似图片");
                    errorList.add(failMap);
                    failNum++;
                }
            } catch (Exception e) {
                isSuccess=false;
                Map errorMap=new HashMap();
                errorMap.put("upload",fileName);
                errorMap.put("reason","程序或者网络出现异常!");
                errorList.add(errorMap);
                failNum++;
                log.error("多人导入异常");
                e.printStackTrace();
            }
        }
 
        if(errorList.size()>0&&returnCode!=400){
            returnCode=300;
        }
        Map result = new HashMap();
        result.put("msg","上传结束,成功"+successNum+"人。");
        result.put("code",returnCode);
        result.put("success",isSuccess);
        result.put("data",errorList);
        result.put("successNum",successNum);
        result.put("failNum",failNum);
        return result;
        //return Result.custom("上传结束", returnCode,isSuccess,errorList);
    }
 
    /**
     * 来自图片编辑的http请求(单张导入)
     *
     * @param jsonMap
     * @return
     * @throws Exception
     */
    @RequestMapping("/singleEdit")
    @ApiOperation(value = "编辑单张图片", notes = "编辑单张图片", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Result singleEdit(@RequestBody Map jsonMap, HttpServletRequest request) {
        Object obj = jsonMap.get("fileInfos");
        String exPersonId = (String) jsonMap.get("exPersonId");  // 排除当前编辑人员照片,因为要更换当前人员
        //从底库拿到所有人的特征值(需要一个关联查询faceIDs  resourceId)
        List<Map> featureList = baseServiceImpl.selectAllAndFeature(exPersonId);
        log.info("底库中"+(StringUtils.isBlank(exPersonId)?"所有":("排除"+exPersonId))+"需要对比的人脸有:"+featureList.size()+"份数据");
        String s = JSONObject.toJSONString(obj);
        FileInfos fileInfo=JSONObject.parseObject(s,FileInfos.class);
        log.info("传进来的文件为"+fileInfo.getName());
        List<Map> baseList=new ArrayList<>();
        String fileName=fileInfo.getName();
        try {
            //将传进来的文件(图片)转化为byte[] imdata
            String imgUrl = imgServerIp+fileInfo.getPath();
            byte[] imgdata = Base64Utils.ImageToByteByOnline(imgUrl);
            log.info("传进来的文件名称是"+fileName);
            //用C接口切出特征值,传进去的图片可能会是多人脸图(小概率),如果是的话,取出第一个作为他的人脸图。
            ArrayList<FaceResults> faceResults = FaceSdkTool.extractFace(imgdata);
            log.info("切出了:"+faceResults.size()+"张人脸");
            if(faceResults.size()==0){
                Map noFaceMap = new HashMap();
                Map map1 = new HashMap();
                map1.put("fileName",fileName);
                map1.put("path",fileInfo.getPath());
                noFaceMap.put("upload",map1);
                noFaceMap.put("reason","未在您上传的图片中检测到人脸,请您核查");
                return Result.custom("上传结束", 400,false,noFaceMap);
            }
            if(faceResults.size()>1){
                Map manyFaceMap = new HashMap();
                Map map1 = new HashMap();
                map1.put("fileName",fileName);
                map1.put("path",fileInfo.getPath());
                manyFaceMap.put("upload",map1);
                manyFaceMap.put("reason","在您上传的图片中检测到不止一张人脸,请您核查");
                return Result.custom("上传结束", 400,false,manyFaceMap);
            }
 
            boolean flag=true;
 
            //用C接口去比对特征值,达到阈值(比如90)的取出这个对象以及比对的对象和比对值存到map中,map塞进list中,如果没有达到阈值的则插入数据库中。
            if(featureList.size()>0){
                for(Map featureMap:featureList){
                    Float liker =0.0f;
                    if((byte[])featureMap.get("feature")!=null&&!"".equals((byte[])featureMap.get("feature"))){
                        liker = FaceSdkTool.compareFeature((byte[])featureMap.get("feature"),faceResults.get(0).getFeature());
                        log.info("相似值liker是:"+liker);
                    }
 
                    if(liker>0.7){
                        flag=false;
                        Map repeatFaceMap = new HashMap();
                        Map map1 = new HashMap();
                        map1.put("fileName",fileName);
                        map1.put("path",fileInfo.getPath());
                        repeatFaceMap.put("upload",map1);
                        repeatFaceMap.put("reason","跟底库中已有图片重复,请更换");
                        return Result.custom("上传结束", 400,false,repeatFaceMap);
 
                    }
                }
 
            }
 
        } catch (Exception e) {
            Map errorFaceMap = new HashMap();
            Map map1 = new HashMap();
            map1.put("fileName",fileName);
            map1.put("path",fileInfo.getPath());
            errorFaceMap.put("upload",map1);
            errorFaceMap.put("reason","程序或者网络出现异常!");
            log.info("单张比对出现异常");
            e.printStackTrace();
            return Result.custom("上传结束", 400,true,errorFaceMap);
        }
        Map map1 = new HashMap();
        Map okMap = new HashMap();
        map1.put("fileName",fileName);
        map1.put("path",fileInfo.getPath());
 
        okMap.put("reason","经检测,可以上传");
        okMap.put("upload",map1);
        return Result.custom("经检测,可以上传", 200,true,okMap);
    }
 
    /**
     * web往临时库添加时使用,pad往临时库添加时使用
     *
     * @param list
     * @return
     * @throws Exception
     */
    @RequestMapping("/uploadToTemporary")
    @ApiOperation(value = "web,pad往底库添加方法", notes = "web,pad往底库添加方法", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "list", value = "BbPerson对象集合", required = true, dataType = "list", paramType = "body")
    })
    @ResponseBody
    public Result uploadWebToTemporary(@RequestBody List<BbPerson> list, HttpSession session)
             {
 
 
        Map<String, Object> map = new HashMap<>();
        List<String> okIds=new ArrayList<>();
        List<String> failIds=new ArrayList<>();
        String userName = (String) session.getAttribute("userName");
 
        for(BbPerson bbPersonTemporary :list){
                try{
                if(bbPersonTemporary.getDeviceId().substring(2,5)=="VAD"||bbPersonTemporary.getDeviceId().substring(2,5).equals("VAD")){
                    log.info("从分析设备进来的数据");
                }else{
                    log.info("从进出入设备进来的数据");
                }
                boolean flag = temporaryServiceImpl.isContainId(bbPersonTemporary.getId());
                if(flag){
                    //临时库有此条数据,应更新
                    log.info("临时库有此条数据,更新操作");
                    bbPersonTemporary.setCreateBy(userName);
 
                    temporaryServiceImpl.save(bbPersonTemporary);
                    okIds.add(bbPersonTemporary.getId());
                }else{
                    //临时库已无此条数据(我看八成进了总库),应插入
                    log.info("临时库无此条数据,新增操作");
 
                    bbPersonTemporary.setCreateBy(userName);
 
                    BbFace bbFace = new BbFace();
                    log.info("收到的特征值为    "+bbPersonTemporary.getFeatureBase64());
                    byte[] feature = Base64Utils.Base64Tobyte(bbPersonTemporary.getFeatureBase64());
                    bbFace.setFeature(feature);
                    temporaryServiceImpl.insert(bbPersonTemporary,bbFace);
                    okIds.add(bbPersonTemporary.getId());
                }
 
            }catch (Exception e){
                failIds.add(bbPersonTemporary.getId());
                e.printStackTrace();
            }
 
        }
        map.put("successList",okIds);
        map.put("failList",failIds);
        return Result.custom("上传完成", HttpStatus.OK.value(),true,map);
 
    }
 
    /**
     * 人员导入去重核定后保存
     *
     * @param
     * @return
     * @throws Exception
     */
    @RequestMapping("/uploadToSave")
    @ApiOperation(value = "人员导入去重核定后保存", notes = "人员导入去重核定后保存", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "jsonMap", value = "决定要保存的对象", required = true, dataType = "list", paramType = "body")
    })
    @ResponseBody
    public Result  uploadToSave(@RequestBody Map jsonMap, HttpSession session)throws Exception{
        String userName = (String) session.getAttribute("userName");
        Object obj =jsonMap.get("bean");
        String s = JSONObject.toJSONString(obj);
        BbPerson bbPersonTemporary=JSONObject.parseObject(s,BbPerson.class);
        String isMerge = (String)jsonMap.get("isMerge");
        String mergeId = (String)jsonMap.get("mergeFrom");
        String[] mergeFrom = null;
        if(mergeId!=null&&!mergeId.equals("")){
            mergeFrom = mergeId.split(",");
        }
 
        log.info("isMerge的值为"+isMerge);
        if(isMerge.equals("0")){
            //如果是未合并。则无id无路径无特征值,图片方面需要处理
            log.info("人员导入,未合并,提取特征值并新增");
            String imgUrl = imgServerIp+bbPersonTemporary.getPhotos();
            byte[] imgdata = Base64Utils.ImageToByteByOnline(imgUrl);
            ArrayList<FaceResults> faceResults = FaceSdkTool.extractFace(imgdata);
            bbPersonTemporary.setId("PSSVR0101"+sdf.format(new Date()));
            bbPersonTemporary.setCreateBy(userName);
 
            BbFace bbFace = new BbFace();
            bbFace.setFeature(faceResults.get(0).getFeature());
            baseServiceImpl.insert(bbPersonTemporary,bbFace);
        }else{
            //是合并来的
            if(mergeFrom!=null&&mergeFrom.length>0){
                //跟右边多个相合并
                if(bbPersonTemporary.getFaceIds()!=null&&!"".equals(bbPersonTemporary.getFaceIds())){
                    log.info("人员导入,合并多个,并选用了底库的图片,删除底库多余的人并保存");
                    log.info("faceIds为"+bbPersonTemporary.getFaceIds());
                    //mergeFrom记录了被合并掉的人的id,有底库里的人被干掉了,需要在mergeFrom中添加一条记录以便待更新时使用
                    for (String s1 : mergeFrom) {
                        baseServiceImpl.delete(s1);
                    }
                    baseServiceImpl.merge(bbPersonTemporary.getId(),mergeId,userName);
                    //图片可能变了,faceids要跟图片路径始终保持一致,前台来控制一致
                    log.info("保存的对象id为"+bbPersonTemporary.getId());
                    baseServiceImpl.save(bbPersonTemporary);
                }else{
                    log.info("人员导入,合并多个,并选用了上传的图片,删除底库多余的人并保存");
                    //mergeFrom记录了被合并掉的人的id,有底库里的人被干掉了,需要在mergeFrom中添加一条记录以便待更新时使用
                    for (String s1 : mergeFrom) {
                        baseServiceImpl.delete(s1);
                    }
                    baseServiceImpl.merge(bbPersonTemporary.getId(),mergeId,userName);
 
                    String imgUrl = imgServerIp+bbPersonTemporary.getPhotos();
                    byte[] imgdata = Base64Utils.ImageToByteByOnline(imgUrl);
                    ArrayList<FaceResults> faceResults = FaceSdkTool.extractFace(imgdata);
                    String faceIds = UUID.randomUUID().toString();
                    bbPersonTemporary.setFaceIds(faceIds);
                    baseServiceImpl.save(bbPersonTemporary);
                    //face表里新建一条记录以存储特征值
                    BbFace bbFace = new BbFace();
                    bbFace.setResourceId(faceIds);
                    bbFace.setFeature(faceResults.get(0).getFeature());
                    bbFaceDao.insert(bbFace);
                }
 
            }else{
                //跟右边一个相合并
                //临时库来的数据不用区分最后用的是哪个图片,只要faceids与图片路径相一致就可以,但从导入接口里来的用上传图片来更新底库则需要更新图片和特征值
 
                if(bbPersonTemporary.getFaceIds()!=null&&!"".equals(bbPersonTemporary.getFaceIds())){
                    log.info("人员导入,合并一个,并选用了底库的图片,不需要提取特征值");
                    //证明有faceids,证明传过来的是底库的图片(图片跟faceIds绑定相传,所以没有faceIds就不是底库原有图片)
                    baseServiceImpl.save(bbPersonTemporary);
                }else{
                    log.info("人员导入,合并一个,并选用了上传的图片,提取特征值并保存");
                    String imgUrl = imgServerIp+bbPersonTemporary.getPhotos();
                    byte[] imgdata = Base64Utils.ImageToByteByOnline(imgUrl);
                    ArrayList<FaceResults> faceResults = FaceSdkTool.extractFace(imgdata);
                    String faceIds = UUID.randomUUID().toString();
                    bbPersonTemporary.setFaceIds(faceIds);
                    log.info("有没有到这儿哦");
                    baseServiceImpl.save(bbPersonTemporary);
                    //face表里新建一条记录以存储特征值
                    BbFace bbFace = new BbFace();
                    bbFace.setResourceId(faceIds);
                    bbFace.setFeature(faceResults.get(0).getFeature());
                    bbFaceDao.insert(bbFace);
                }
 
 
            }
        }
 
 
        return Result.custom("上传结束",HttpStatus.OK.value(),true,"");
    }
 
    /**
     * 临时库编辑去重核定后保存
     *
     * @param
     * @return
     * @throws Exception
     */
    @RequestMapping("/editToSave")
    @ApiOperation(value = "临时库编辑去重核定后保存", notes = "临时库编辑去重核定后保存", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "jsonMap", value = "决定要保存的对象", required = true, dataType = "list", paramType = "body")
    })
    @ResponseBody
    public Result  editToSave(@RequestBody Map jsonMap, HttpSession session)throws Exception{
        String userName = (String) session.getAttribute("userName");
        return baseServiceImpl.editToSave(jsonMap,userName);
//        Object obj =jsonMap.get("bean");
//        String s = JSONObject.toJSONString(obj);
//        BbPerson bbPersonTemporary=JSONObject.parseObject(s,BbPerson.class);
//        String isMerge = (String)jsonMap.get("isMerge");
//        String mergeId = (String)jsonMap.get("mergeFrom");
//        String[] mergeFrom = null;
//        if(mergeId!=null&&!mergeId.equals("")){
//            mergeFrom = mergeId.split(",");
//        }
 
 
        //临时库来的数据
//        if(isMerge.equals("0")){
//            //未合并,确定要新增
//            log.info("临时库,未合并,直接新增");
//            bbPersonTemporary.setCreateBy(userName);
//            bbPersonTemporary.setCreateTime(new Date());
//            baseServiceImpl.insert1(bbPersonTemporary);
//
//        }else{
//            //要保存的是合并后的人
//            //如果是临时库里来的,则有路径有特征值和总库一样,但某id所对应的图片变了则其对应的特征值也要变,需要由图片路径查到faceids,更新保存人员的faceids
//
//            if(mergeFrom!=null&&mergeFrom.length>0){
//                //跟右边多个合并,
//                log.info("临时库,合并多个,保存并删除底库多余的人");
//                // 底库里的人被干掉了,需要在mergeFrom中添加一条记录以便待更新时使用
//                for (String s1 : mergeFrom) {
//                    log.info("删除了这个id的人"+s1);
//                    baseServiceImpl.delete(s1);
//                }
//                baseServiceImpl.merge(bbPersonTemporary.getId(),mergeId,userName);
//                //图片可能变了,faceids要跟图片路径始终保持一致,前台来控制一致
//                baseServiceImpl.save(bbPersonTemporary);
//
//
//            }else{
//                //只跟右边一个合并,底库里不需要删除人
//                log.info("临时库,合并一个,保存");
//                //图片可能变了,faceids要跟图片路径始终保持一致,前台来控制一致
//                baseServiceImpl.save(bbPersonTemporary);
//            }
//
//        }
 
    }
    /**
     * 单人添加
     *
     * @param
     * @return
     * @throws Exception
     */
    @RequestMapping("/addSingle")
    @ApiOperation(value = "addSingle", notes = "单人添加", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "jsonMap", value = "决定要保存的对象", required = true, dataType = "list", paramType = "body")
    })
    @ResponseBody
    public Result addSingle(@RequestBody Map jsonMap, HttpSession session){
        String userName = (String) session.getAttribute("userName");
        Object obj =jsonMap.get("bean");
        String s = JSONObject.toJSONString(obj);
        BbPerson bbPersonTemporary=JSONObject.parseObject(s,BbPerson.class);
 
        log.info("单人添加来的数据,提取特征值并新增");
        String imgUrl = imgServerIp+bbPersonTemporary.getPhotos();
        byte[] imgdata = Base64Utils.ImageToByteByOnline(imgUrl);
        ArrayList<FaceResults> faceResults = FaceSdkTool.extractFace(imgdata);
        String faceIds = UUID.randomUUID().toString();
        String id = "PSSVR0101"+sdf.format(new Date());
        bbPersonTemporary.setId(id);
        bbPersonTemporary.setFaceIds(faceIds);
        bbPersonTemporary.setCreateBy(userName);
        bbPersonTemporary.setCreateTime(new Date());
        baseServiceImpl.insert1(bbPersonTemporary);
        //face表里新建一条记录以存储特征值
        BbFace bbFace = new BbFace();
        bbFace.setResourceId(faceIds);
        bbFace.setCreateTime(new Date());
        bbFace.setFeature(faceResults.get(0).getFeature());
        bbFaceDao.insert(bbFace);
        log.info("添加人员成功");
 
        return Result.custom("添加成功",HttpStatus.OK.value(),true,id);
    }
 
    /**
     * 一般性的编辑保存
     *
     * @param
     * @return
     * @throws Exception
     */
    @RequestMapping("/anyThingToSave")
    @ApiOperation(value = "anyThingToSave", notes = "一般性的编辑保存", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "jsonMap", value = "决定要保存的对象", required = true, dataType = "list", paramType = "body")
    })
    @ResponseBody
    public Result anyThingToSave(@RequestBody Map jsonMap, HttpSession session){
        String userName = (String) session.getAttribute("userName");
        Object obj =jsonMap.get("bean");
        String s = JSONObject.toJSONString(obj);
        BbPerson bbPersonTemporary=JSONObject.parseObject(s,BbPerson.class);
 
 
        if(bbPersonTemporary.getFaceIds()!=null&&!bbPersonTemporary.getFaceIds().equals("")){
            log.info("一般性保存来的数据,没换图片直接保存");
            //证明有faceids,证明传过来的是底库的图片(图片跟faceIds绑定相传,所以没有faceIds就不是底库原有图片)
            bbPersonTemporary.setUpdateBy(userName);
            baseServiceImpl.save(bbPersonTemporary);
        }else{
            log.info("一般性保存来的数据,换了图片,提取特征值并保存");
            String imgUrl = imgServerIp+bbPersonTemporary.getPhotos();
            byte[] imgdata = Base64Utils.ImageToByteByOnline(imgUrl);
            ArrayList<FaceResults> faceResults = FaceSdkTool.extractFace(imgdata);
            String faceIds = UUID.randomUUID().toString();
            bbPersonTemporary.setFaceIds(faceIds);
            bbPersonTemporary.setUpdateBy(userName);
            baseServiceImpl.save(bbPersonTemporary);
            //face表里新建一条记录以存储特征值
            BbFace bbFace = new BbFace();
            bbFace.setResourceId(faceIds);
            bbFace.setFeature(faceResults.get(0).getFeature());
            bbFaceDao.insert(bbFace);
        }
 
 
        return Result.custom("保存成功",HttpStatus.OK.value(),true,"");
    }
 
    /**
     * 供人员管理模块临时库编辑时查重使用
     * 查出相似对象数据
     * @param map
     * @return
     * @throws Exception
     */
    @RequestMapping("/getAlikePerson")
    @ResponseBody
    public Result getAlikePerson(@RequestBody Map<String, byte[]> map)
            throws Exception{
        List<Map> okList = new ArrayList<>();
        List<Map> featureList = baseServiceImpl.selectAllAndFeature(null);
        byte[] feature = map.get("feature");
        log.info("底库中一共有"+featureList.size()+"份数据需要比对");
        try {
 
            //用C接口去比对特征值,达到阈值(比如90)的取出这个对象以及比对的对象和比对值存到map中,map塞进list中,如果没有达到阈值的则插入数据库中。
            if(featureList.size()>0){
                for(Map featureMap:featureList){
                    Float liker =0.0f;
                    if((byte[])featureMap.get("feature")!=null && !"".equals((byte[])featureMap.get("feature"))){
                        liker = FaceSdkTool.compareFeature((byte[])featureMap.get("feature"),feature);
                        log.info("相似值liker是:"+liker);
                    }
 
                    if(liker>0.7){
                        featureMap.put("liker",Math.round(liker*100));
                        featureMap.remove("feature");
 
                        String colonyIdStr = (String)featureMap.get("distributionIds");
                        log.info("集群id为"+colonyIdStr);
                        if(colonyIdStr!=null&&!"".equals(colonyIdStr)){
                            JSONObject paramMap = new JSONObject();
                            paramMap.put("clusterIds",colonyIdStr);
                            String post = restTemplateUtil.post(clusterLocaltion, paramMap , MediaType.APPLICATION_JSON_UTF8, true);
                            JSONObject jsonMap1 = JSONObject.parseObject(post);
                            featureMap.put("colonys",jsonMap1.get("data"));
                        }
                        String userIdStr = featureMap.get("userId")!=null?(featureMap.get("userId")+""):"";
                        if(userIdStr!=null&&!"".equals(userIdStr)){
                            Long userId = Long.valueOf(userIdStr);
                            log.info("用户id为"+userId);
                            List<Integer> roleIds = null;
                            if(userId!=null&&!"".equals(userId)){
                                roleIds = userRoleDao.findRolesIds(userId);
                                featureMap.put("roleIds",roleIds);
                            }
                        }
                        okList.add(featureMap);
                    }
                }
            }
 
        } catch (Exception e) {
            log.info("编辑比对异常");
            e.printStackTrace();
        }
 
        return Result.custom("比对结束",HttpStatus.OK.value(),true,okList);
    }
 
}