diff --git a/shapelight-admin/pom.xml b/shapelight-admin/pom.xml
index f48540b..a21f5ba 100644
--- a/shapelight-admin/pom.xml
+++ b/shapelight-admin/pom.xml
@@ -226,7 +226,15 @@
2.0.0
-
+
+ com.arcsoft.face
+ arcsoft-sdk-face
+ 4.1.1.0
+
+
+
+
+
${project.artifactId}
diff --git a/shapelight-admin/src/main/java/net/shapelight/AdminApplication.java b/shapelight-admin/src/main/java/net/shapelight/AdminApplication.java
index 4754793..f08c491 100644
--- a/shapelight-admin/src/main/java/net/shapelight/AdminApplication.java
+++ b/shapelight-admin/src/main/java/net/shapelight/AdminApplication.java
@@ -4,8 +4,8 @@ package net.shapelight;
//import net.shapelight.modules.dev.mqtt.MqttClientUtil;
import lombok.extern.slf4j.Slf4j;
-import net.shapelight.commons.engine.sdk.PalmSDK;
-import org.mybatis.spring.annotation.MapperScan;
+/*import net.shapelight.commons.engine.sdk.PalmSDK;
+import org.mybatis.spring.annotation.MapperScan;*/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@@ -29,8 +29,8 @@ public class AdminApplication {
SpringApplication.run(AdminApplication.class, args);
//初始化掌静脉sdk
- int initCode = PalmSDK.init();
- log.debug("掌静脉sdk初始化。。。。。。。。。。:"+initCode);
+ //int initCode = PalmSDK.init();
+ //log.debug("掌静脉sdk初始化。。。。。。。。。。:"+initCode);
// //mqtt服务启动
// MqttClientUtil.createClient();
//
@@ -38,8 +38,8 @@ public class AdminApplication {
@Override
public void run() {
try {
- int code = PalmSDK.release();
- log.debug("掌静脉sdk释放。。。。。。。。。。:"+code);
+ //int code = PalmSDK.release();
+ //log.debug("掌静脉sdk释放。。。。。。。。。。:"+code);
} catch (Throwable e) {
e.printStackTrace();
}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppApiController.java b/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppApiController.java
index 7f8e462..b9c5bdc 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppApiController.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppApiController.java
@@ -346,16 +346,14 @@ public class AppApiController {
tenPerson.setStatus(2);
tenPerson.setPersonType(Constant.PERSON_TYPE_GUEST);
tenPerson.setTenantId(user.getTenantId());
- int res;
+ String res;
try {
res = tenPersonService.save(tenPerson);
} catch (Exception e) {
return R.error(e.getMessage());
}
- if (res==2) {
- return R.error("照片未检测到人脸");
- }else if(res == 10){
- return R.error("文件不存在");
+ if (res!=null) {
+ return R.error(res);
}
return R.ok();
}
@@ -566,14 +564,14 @@ public class AppApiController {
tenPerson.setCreateTime(new Date());
tenPerson.setRegisterType(Constant.RESGISTER_TYPE_APP);
tenPerson.setStatus(Constant.PESON_SUATUS_NOMOR);
- int res = 10;
+ String res;
try {
res = tenPersonService.save(tenPerson);
} catch (Exception e) {
return R.error(e.getMessage());
}
- if (res==2) {
- return R.error("照片未检测到人脸");
+ if (res!=null) {
+ return R.error(res);
}
return R.ok();
}
@@ -662,14 +660,14 @@ public class AppApiController {
- int res;
+ String res;
try {
res = tenPersonService.save(tenPerson);
} catch (Exception e) {
return R.error(e.getMessage());
}
- if (res==2) {
- return R.error("照片未检测到人脸");
+ if (res!=null) {
+ return R.error(res);
}
return R.ok();
}
@@ -975,7 +973,12 @@ public class AppApiController {
.eq(TenRelation::getParentId,user.getUserId())
.eq(TenRelation::getStudentId,entity.getPersonId()));
if(tenRelation!=null) {
- return R.error("该学生已和您绑定");
+ if(tenRelation.getStatus()==2) {
+ return R.error("您已提交绑定审批,请耐心等待");
+ }
+ if(tenRelation.getStatus()==1) {
+ return R.error("该学生已和您绑定");
+ }
}
TenRelation relation = new TenRelation();
relation.setParentId(user.getUserId());
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppInfoApiController.java b/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppInfoApiController.java
index 44733d0..e82082b 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppInfoApiController.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppInfoApiController.java
@@ -314,10 +314,10 @@ public class AppInfoApiController {
//业主
else if(scope.getRoleId() == Constant.PERSON_TYPE_PARENT){
List relationList = relationService.list(new LambdaQueryWrapper()
- .eq(TenRelation::getParentId,user.getUserId()));
+ .eq(TenRelation::getParentId,user.getUserId()).eq(TenRelation::getStatus,1));
if(!relationList.isEmpty()) {
List list = relationList.stream().map(TenRelation::getStudentId).collect(Collectors.toList());
- params.put("cellId",scope.getCellId());
+ params.put("tenantId",user.getTenantId());
params.put("personIds",list);
PageUtils page = tenRecordService.getByPersonIds(params);
return R.ok().put("data", page);
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppLoginController.java b/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppLoginController.java
index 3bb1854..784b42d 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppLoginController.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/app/controller/AppLoginController.java
@@ -1,6 +1,7 @@
package net.shapelight.modules.app.controller;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import net.shapelight.common.utils.IpUtils;
import net.shapelight.common.utils.R;
import net.shapelight.common.utils.ServletUtils;
@@ -15,6 +16,8 @@ import net.shapelight.modules.app.utils.JwtUtils;
//import net.shapelight.modules.sys.service.PushService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
+import net.shapelight.modules.ten.entity.TenParent;
+import net.shapelight.modules.ten.service.TenParentService;
import net.shapelight.modules.vo.TokenVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -37,6 +40,8 @@ public class AppLoginController {
private JwtUtils jwtUtils;
// @Autowired
// PushService pushService;
+ @Autowired
+ TenParentService parentService;
/**
* 登录
@@ -76,6 +81,8 @@ public class AppLoginController {
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
user.setLoginTime(new Date());
user.setLoginIp(ip);
+ TenParent parent = parentService.getOne(new LambdaQueryWrapper().eq(TenParent::getUserId,user.getUserId()));
+ user.setParent(parent);
userService.saveOrUpdate(user);
return R.ok().put("data", user);
}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/app/entity/AppUserEntity.java b/shapelight-admin/src/main/java/net/shapelight/modules/app/entity/AppUserEntity.java
index a88cbb5..0d27d52 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/app/entity/AppUserEntity.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/app/entity/AppUserEntity.java
@@ -1,5 +1,6 @@
package net.shapelight.modules.app.entity;
+import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -10,6 +11,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
+import net.shapelight.modules.ten.entity.TenParent;
/**
* App用户
@@ -76,5 +78,8 @@ public class AppUserEntity implements Serializable {
@JsonSerialize(using = ToStringSerializer.class)
private Long sysUserId;
+ @TableField(exist = false)
+ TenParent parent;
+
}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/excel/listener/PersonExcelListener.java b/shapelight-admin/src/main/java/net/shapelight/modules/excel/listener/PersonExcelListener.java
index 4bd4d80..4a6c4b1 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/excel/listener/PersonExcelListener.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/excel/listener/PersonExcelListener.java
@@ -8,7 +8,6 @@ import io.minio.PutObjectOptions;
import lombok.Getter;
import net.shapelight.common.utils.R;
import net.shapelight.common.utils.UUIDUtil;
-import net.shapelight.commons.engine.sdk.PicSDK;
import net.shapelight.modules.excel.model.PersonModel;
import net.shapelight.modules.ten.entity.*;
import net.shapelight.modules.ten.service.TenCellDeptService;
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/FaceEngineAutoRun.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/FaceEngineAutoRun.java
new file mode 100644
index 0000000..f68757c
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/FaceEngineAutoRun.java
@@ -0,0 +1,117 @@
+package net.shapelight.modules.face;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import lombok.extern.slf4j.Slf4j;
+import net.shapelight.common.config.GlobalValue;
+import net.shapelight.modules.face.entity.UserCompareInfo;
+import net.shapelight.modules.face.service.FaceEngineService;
+import net.shapelight.modules.face.util.Base64Util;
+import net.shapelight.modules.face.util.UserInfo;
+import net.shapelight.modules.face.util.UserRamGroup;
+import net.shapelight.modules.sys.controller.AbstractController;
+import net.shapelight.modules.ten.entity.TenCellEntity;
+import net.shapelight.modules.ten.entity.TenPersonEntity;
+import net.shapelight.modules.ten.service.TenCellService;
+import net.shapelight.modules.ten.service.TenPersonService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+@Order(1)
+@Slf4j
+public class FaceEngineAutoRun extends AbstractController implements ApplicationRunner {
+ @Autowired
+ private FaceEngineService faceEngineService;
+ @Autowired
+ private TenPersonService tenPersonService;
+ @Autowired
+ private TenCellService tenCellService;
+ @Autowired
+ private GlobalValue globalValue;
+
+ @Override
+ public void run(ApplicationArguments args) throws Exception {
+ // 任务初始化
+ log.debug("服务启动。。。。。初始化人脸库");
+// Map fileMap = Maps.newHashMap();
+// fileMap.put("zhao1", "赵丽颖");
+// fileMap.put("yang1", "杨紫");
+// fileMap.put("baixue", "白雪");
+// fileMap.put("chenchuang", "陈创");
+// for (String f : fileMap.keySet()) {
+// ClassPathResource resource = new ClassPathResource("static/images/" + f + ".jpg");
+// InputStream inputStream = resource.getInputStream();
+// ImageInfo rgbData = ImageFactory.getRGBData(inputStream);
+// List faceInfoList = faceEngineService.detectFaces(rgbData);
+// if (CollectionUtil.isNotEmpty(faceInfoList)) {
+// byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfoList.get(0), ExtractType.REGISTER);
+// UserRamCache.UserInfo userInfo = new UserCompareInfo();
+// userInfo.setFaceId(f);
+// userInfo.setName(fileMap.get(f));
+// userInfo.setFaceFeature(feature);
+// //这边注册到内存缓存中,也可以根据业务,注册到数据库中
+// UserRamCache.addUser(userInfo);
+// }
+// }
+
+// int count = tenPersonService.findCount();
+// int pageSize = 1000;
+// int page = count/pageSize;
+// if(count%1000!=0){
+// page = page+1;
+// }
+// int faceCount = 0;
+// for (int i = 0; i < page; i++) {
+// int start = i*1000;
+// List listPage = tenPersonService.listPage(start,1000);
+// for(TenPersonEntity personEntity: listPage){
+// if(personEntity.getFeature()!=null && personEntity.getFeature().length()>0){
+// UserRamCache.UserInfo userInfo = new UserCompareInfo();
+// userInfo.setFaceId(personEntity.getPersonId()+"");
+// userInfo.setName(personEntity.getName());
+// userInfo.setFaceFeature(Base64Util.base64ToBytes(personEntity.getFeature()));
+// //这边注册到内存缓存中
+// UserRamCache.addUser(userInfo);
+// faceCount++;
+// }
+// }
+// }
+
+
+ List cellList = tenCellService.list(new QueryWrapper()
+ .eq("tenant_id","1298283126102949890")
+ .eq("delete_flag",0));
+ for(TenCellEntity cellEntity: cellList){
+ String cellId = cellEntity.getCellId()+"";
+ UserRamGroup.addCell(cellId);
+ int count = tenPersonService.findCellCount(Long.valueOf(cellId));
+ int pageSize = 1000;
+ int page = count/pageSize;
+ if(count%1000!=0){
+ page = page+1;
+ }
+ int faceCount = 0;
+ for (int i = 0; i < page; i++) {
+ int start = i*1000;
+ List listPage = tenPersonService.listPage(start,1000, cellId);
+ for(TenPersonEntity personEntity: listPage){
+ if(personEntity.getFeature()!=null && personEntity.getFeature().length()>0){
+ UserInfo userInfo = new UserCompareInfo();
+ userInfo.setFaceId(personEntity.getPersonId()+"");
+ userInfo.setName(personEntity.getName());
+ userInfo.setFaceFeature(Base64Util.base64ToBytes(personEntity.getFeature()));
+ //这边注册到内存缓存中
+ UserRamGroup.addUser(userInfo,cellId);
+ faceCount++;
+ }
+ }
+ }
+ log.debug(cellEntity.getName()+":初始化人脸库完成,共 "+faceCount+" 人");
+ }
+ }
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/config/ArcFaceAutoConfiguration.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/config/ArcFaceAutoConfiguration.java
new file mode 100644
index 0000000..605c24e
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/config/ArcFaceAutoConfiguration.java
@@ -0,0 +1,133 @@
+package net.shapelight.modules.face.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.LinkedList;
+import java.util.List;
+
+@Slf4j
+@Configuration
+public class ArcFaceAutoConfiguration implements InitializingBean, DisposableBean {
+
+
+ private static final String PLATFORM;
+
+ private static final String USER_HOME;
+
+ public static String CACHE_LIB_FOLDER;
+
+ @Value("${config.arcface-sdk.version}")
+ public String ARC_FACE_VERSION;
+
+ static {
+ String jvmName = System.getProperty("java.vm.name", "").toLowerCase();
+ String osName = System.getProperty("os.name", "").toLowerCase();
+ String osArch = System.getProperty("os.arch", "").toLowerCase();
+ String abiType = System.getProperty("sun.arch.abi", "").toLowerCase();
+ String libPath = System.getProperty("sun.boot.library.path", "").toLowerCase();
+ USER_HOME = System.getProperty("user.home");
+ if (jvmName.startsWith("dalvik") && osName.startsWith("linux")) {
+ osName = "android";
+ } else if (jvmName.startsWith("robovm") && osName.startsWith("darwin")) {
+ osName = "ios";
+ osArch = "arm";
+ } else if (osName.startsWith("mac os x") || osName.startsWith("darwin")) {
+ osName = "macosx";
+ } else {
+ int spaceIndex = osName.indexOf(' ');
+ if (spaceIndex > 0) {
+ osName = osName.substring(0, spaceIndex);
+ }
+ }
+ if (osArch.equals("i386") || osArch.equals("i486") || osArch.equals("i586") || osArch.equals("i686")) {
+ osArch = "x86";
+ } else if (osArch.equals("amd64") || osArch.equals("x86-64") || osArch.equals("x64")) {
+ osArch = "x86_64";
+ } else if (osArch.startsWith("aarch64") || osArch.startsWith("armv8") || osArch.startsWith("arm64")) {
+ osArch = "arm64";
+ } else if ((osArch.startsWith("arm")) && ((abiType.equals("gnueabihf")) || (libPath.contains("openjdk-armhf")))) {
+ osArch = "armhf";
+ } else if (osArch.startsWith("arm")) {
+ osArch = "arm";
+ }
+ PLATFORM = osName + "-" + osArch;
+
+ }
+
+
+ @Override
+ public void afterPropertiesSet() throws IOException {
+ CACHE_LIB_FOLDER = USER_HOME + "/.arcface/cache/" + ARC_FACE_VERSION + "/" + PLATFORM + "/";
+ loadLibrary();
+ }
+
+ public void loadLibrary() throws IOException {
+ String baseFolder = "";
+ String suffix = ".dll";
+ if ("windows-x86_64".equals(PLATFORM)) {
+ baseFolder = "WIN64";
+ } else if ("windows-x86".equals(PLATFORM)) {
+ baseFolder = "WIN32";
+ } else if ("linux-x86_64".equals(PLATFORM)) {
+ baseFolder = "LINUX64";
+ suffix = ".so";
+ }
+
+ if ("".equals(baseFolder)) {
+ throw new RuntimeException("ArcFace不支持该操作系统");
+ }
+
+
+ File file = new File(CACHE_LIB_FOLDER);
+ if (!file.exists()) {
+ file.mkdirs();
+ }
+
+ List libList = new LinkedList<>();
+ libList.add("libarcsoft_face");
+ libList.add("libarcsoft_face_engine");
+ libList.add("libarcsoft_face_engine_jni");
+
+ for (String lib : libList) {
+ ClassPathResource resource = new ClassPathResource("libs/" + ARC_FACE_VERSION + "/" + baseFolder + "/" + lib + suffix);
+ InputStream inputStream = resource.getInputStream();
+ int faceLength = inputStream.available();
+ File facePath = new File(CACHE_LIB_FOLDER + lib + suffix);
+ if (facePath.exists()) {
+ if (facePath.length() == faceLength) {
+ continue;
+ }
+ facePath.delete();
+ }
+ writeToLocal(CACHE_LIB_FOLDER + lib + suffix, inputStream);
+ }
+ }
+
+ private void writeToLocal(String destination, InputStream input)
+ throws IOException {
+ int index;
+ byte[] bytes = new byte[1024 * 100];
+ FileOutputStream fileOutputStream = new FileOutputStream(destination);
+ while ((index = input.read(bytes)) != -1) {
+ fileOutputStream.write(bytes, 0, index);
+ }
+ fileOutputStream.flush();
+ fileOutputStream.close();
+ input.close();
+ }
+
+
+ @Override
+ public void destroy() throws Exception {
+ }
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/CompareFacesReqDTO.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/CompareFacesReqDTO.java
new file mode 100644
index 0000000..c4971fb
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/CompareFacesReqDTO.java
@@ -0,0 +1,14 @@
+package net.shapelight.modules.face.dto;
+
+import lombok.Data;
+
+/**
+ * @author shentao
+ * @desc
+ * @date 2022/3/30
+ */
+@Data
+public class CompareFacesReqDTO {
+ private String image1;
+ private String image2;
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceAddReqDTO.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceAddReqDTO.java
new file mode 100644
index 0000000..b438dfb
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceAddReqDTO.java
@@ -0,0 +1,12 @@
+package net.shapelight.modules.face.dto;
+
+import lombok.Data;
+
+@Data
+public class FaceAddReqDTO {
+
+ private String name;
+
+ private String image;
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceDetectReqDTO.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceDetectReqDTO.java
new file mode 100644
index 0000000..30bf032
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceDetectReqDTO.java
@@ -0,0 +1,10 @@
+package net.shapelight.modules.face.dto;
+
+import lombok.Data;
+
+@Data
+public class FaceDetectReqDTO {
+
+ private String image;
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceDetectResDTO.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceDetectResDTO.java
new file mode 100644
index 0000000..45e2ca2
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceDetectResDTO.java
@@ -0,0 +1,14 @@
+package net.shapelight.modules.face.dto;
+
+import com.arcsoft.face.Rect;
+import lombok.Data;
+
+@Data
+public class FaceDetectResDTO {
+ private Rect rect;
+ private int orient;
+ private int faceId = -1;
+ private int age = -1;
+ private int gender = -1;
+ private int liveness = -1;
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceRecognitionReqDTO.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceRecognitionReqDTO.java
new file mode 100644
index 0000000..5d4dd52
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceRecognitionReqDTO.java
@@ -0,0 +1,10 @@
+package net.shapelight.modules.face.dto;
+
+import lombok.Data;
+
+@Data
+public class FaceRecognitionReqDTO {
+
+ private String image;
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceRecognitionResDTO.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceRecognitionResDTO.java
new file mode 100644
index 0000000..3d77ef9
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/FaceRecognitionResDTO.java
@@ -0,0 +1,15 @@
+package net.shapelight.modules.face.dto;
+
+
+import com.arcsoft.face.Rect;
+import lombok.Data;
+
+@Data
+public class FaceRecognitionResDTO {
+
+ private Rect rect;
+ private String personId;
+ private String name;
+ private float similar;
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/GetFaceListResDTO.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/GetFaceListResDTO.java
new file mode 100644
index 0000000..beecd7a
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/dto/GetFaceListResDTO.java
@@ -0,0 +1,14 @@
+package net.shapelight.modules.face.dto;
+
+import lombok.Data;
+
+@Data
+public class GetFaceListResDTO {
+
+ private String id;
+
+ private String name;
+
+ private String url;
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/entity/ProcessInfo.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/entity/ProcessInfo.java
new file mode 100644
index 0000000..01e0fe9
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/entity/ProcessInfo.java
@@ -0,0 +1,12 @@
+package net.shapelight.modules.face.entity;
+
+
+import lombok.Data;
+
+@Data
+public class ProcessInfo {
+ private int age;
+ private int gender;
+ private int liveness;
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/entity/UserCompareInfo.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/entity/UserCompareInfo.java
new file mode 100644
index 0000000..c7bc271
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/entity/UserCompareInfo.java
@@ -0,0 +1,10 @@
+package net.shapelight.modules.face.entity;
+
+
+import lombok.Data;
+import net.shapelight.modules.face.util.UserInfo;
+
+@Data
+public class UserCompareInfo extends UserInfo {
+ private Float similar;
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/enums/ErrorCodeEnum.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/enums/ErrorCodeEnum.java
new file mode 100644
index 0000000..50795eb
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/enums/ErrorCodeEnum.java
@@ -0,0 +1,49 @@
+package net.shapelight.modules.face.enums;
+
+
+import lombok.Getter;
+import net.shapelight.modules.face.rpc.ErrorCode;
+
+@Getter
+public enum ErrorCodeEnum implements ErrorCode {
+
+ /**
+ * 成功
+ */
+ SUCCESS(0, "success", "成功"),
+ FAIL(1, "fail", "失败"),
+ PARAM_ERROR(2, "param error", "参数错误"),
+ SYSTEM_ERROR(999, "system error", "系统错误"),
+
+ ;
+ private Integer code;
+ private String desc;
+ private String descCN;
+
+ ErrorCodeEnum(Integer code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ ErrorCodeEnum(Integer code, String desc, String descCN) {
+ this.code = code;
+ this.desc = desc;
+ this.descCN = descCN;
+ }
+
+ @Override
+ public Integer getCode() {
+ return code;
+ }
+
+ @Override
+ public String getDesc() {
+ return desc;
+ }
+
+ @Override
+ public String getDescCN() {
+ return descCN;
+ }
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/face/FaceRecognize.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/face/FaceRecognize.java
new file mode 100644
index 0000000..6e9f829
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/face/FaceRecognize.java
@@ -0,0 +1,292 @@
+package net.shapelight.modules.face.face;
+
+import com.arcsoft.face.*;
+import com.arcsoft.face.enums.DetectMode;
+import com.arcsoft.face.enums.ErrorInfo;
+import com.arcsoft.face.enums.ExtractType;
+import com.arcsoft.face.toolkit.ImageFactory;
+import com.arcsoft.face.toolkit.ImageInfo;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import net.shapelight.modules.face.config.ArcFaceAutoConfiguration;
+import net.shapelight.modules.face.factory.FaceEngineFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+
+import java.io.File;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Slf4j
+public class FaceRecognize {
+
+ /**
+ * VIDEO模式人脸检测引擎,用于预览帧人脸追踪
+ */
+ private FaceEngine ftEngine;
+
+ /**
+ * 人脸注册引擎
+ */
+ private FaceEngine regEngine;
+
+ /**
+ * 用于人脸识别的引擎池
+ */
+ private GenericObjectPool frEnginePool;
+
+
+ private volatile ConcurrentHashMap faceResultRegistry = new ConcurrentHashMap<>();
+
+ private ExecutorService frService = Executors.newFixedThreadPool(20);
+
+ public ConcurrentHashMap faceFeatureRegistry = new ConcurrentHashMap<>();
+
+ /**
+ * 初始化引擎
+ */
+ public void initEngine(String appId, String sdkKey, String activeKey, String activeFile) {
+
+ //引擎配置
+ ftEngine = new FaceEngine(ArcFaceAutoConfiguration.CACHE_LIB_FOLDER);
+ int activeCode;
+ if (StringUtils.isNotEmpty(activeFile)) {
+ activeCode = ftEngine.activeOffline(activeFile);
+ } else {
+ activeCode = ftEngine.activeOnline(appId, sdkKey, activeKey);
+ }
+
+ EngineConfiguration ftEngineCfg = new EngineConfiguration();
+ ftEngineCfg.setDetectMode(DetectMode.ASF_DETECT_MODE_VIDEO);
+ ftEngineCfg.setFunctionConfiguration(FunctionConfiguration.builder().supportFaceDetect(true).build());
+ int ftInitCode = ftEngine.init(ftEngineCfg);
+
+ //引擎配置
+ regEngine = new FaceEngine(ArcFaceAutoConfiguration.CACHE_LIB_FOLDER);
+
+ EngineConfiguration regEngineCfg = new EngineConfiguration();
+ regEngineCfg.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
+ regEngineCfg.setFunctionConfiguration(FunctionConfiguration.builder().supportFaceDetect(true).supportFaceRecognition(true).build());
+ int regInitCode = regEngine.init(regEngineCfg);
+
+
+ GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
+ poolConfig.setMaxIdle(5);
+ poolConfig.setMaxTotal(5);
+ poolConfig.setMinIdle(5);
+ poolConfig.setLifo(false);
+ EngineConfiguration frEngineCfg = new EngineConfiguration();
+ frEngineCfg.setFunctionConfiguration(FunctionConfiguration.builder().supportFaceRecognition(true).build());
+ frEnginePool = new GenericObjectPool(new FaceEngineFactory(appId, sdkKey, activeKey,activeFile, frEngineCfg), poolConfig);//底层库算法对象池
+
+
+ if (!(activeCode == ErrorInfo.MOK.getValue() || activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue())) {
+ log.error("activeCode: " + activeCode);
+ throw new RuntimeException("activeCode: " + activeCode);
+ }
+ if (ftInitCode != ErrorInfo.MOK.getValue()) {
+ log.error("ftInitEngine: " + ftInitCode);
+ throw new RuntimeException("ftInitEngine: " + ftInitCode);
+ }
+
+ if (regInitCode != ErrorInfo.MOK.getValue()) {
+ log.error("regInitEngine: " + regInitCode);
+ throw new RuntimeException("regInitEngine: " + regInitCode);
+ }
+
+ }
+
+
+ public void registerFace(String imagePath) {
+
+ log.info("正在注册人脸");
+
+ int count = 0;
+ if (regEngine != null) {
+ File file = new File(imagePath);
+ File[] files = file.listFiles();
+
+ for (File file1 : files) {
+ ImageInfo imageInfo = ImageFactory.getRGBData(file1);
+ if (imageInfo != null) {
+ List faceInfoList = new ArrayList<>();
+ int code = regEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(),
+ imageInfo.getImageFormat(), faceInfoList);
+
+ if (code == 0 && faceInfoList.size() > 0) {
+ FaceFeature faceFeature = new FaceFeature();
+ int resCode = regEngine.extractFaceFeature(imageInfo, faceInfoList.get(0), ExtractType.REGISTER, 0, faceFeature);
+ if (resCode == 0) {
+ int lastIndexOf = file1.getName().lastIndexOf(".");
+ String name = file1.getName().substring(0, file1.getName().length() - lastIndexOf - 1);
+ faceFeatureRegistry.put(name, faceFeature.getFeatureData());
+ log.info("成功注册人脸:" + name);
+ count++;
+ }
+ }
+ }
+ }
+ log.info("人脸注册完成,共注册:" + count + "张人脸");
+ } else {
+ throw new RuntimeException("注册失败,引擎未初始化或初始化失败");
+ }
+
+
+ }
+
+ public void registerFace(Map face) {
+ face.forEach((k, v) -> {
+ faceFeatureRegistry.put(k, v.clone());
+ });
+ }
+
+ public void removeFace(String name) {
+ faceFeatureRegistry.remove(name);
+ }
+
+ public void clearFace() {
+ faceFeatureRegistry.clear();
+ }
+
+ public FaceResult getFaceResult(FaceInfo faceInfo, ImageInfo imageInfo) {
+ FaceResult faceResult = faceResultRegistry.get(faceInfo.getFaceId());
+ if (faceResult == null) {
+ faceResult = new FaceResult();
+ faceResultRegistry.put(faceInfo.getFaceId(), faceResult);
+ frService.submit(new FaceInfoRunnable(faceInfo, imageInfo, faceResult));
+ } else if (faceResult.isFlag()) {
+ return faceResult;
+ }
+ return null;
+ }
+
+ public List detectFaces(ImageInfo imageInfo) {
+ if (ftEngine != null) {
+ List faceInfoList = new ArrayList<>();
+ int code = ftEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(),
+ imageInfo.getImageFormat(), faceInfoList);
+
+ List previewInfoList = new LinkedList<>();
+ for (FaceInfo faceInfo : faceInfoList) {
+ FacePreviewInfo facePreviewInfo = new FacePreviewInfo();
+ facePreviewInfo.setFaceInfo(faceInfo);
+ previewInfoList.add(facePreviewInfo);
+ }
+
+ clearFaceResultRegistry(faceInfoList);
+ return previewInfoList;
+
+ }
+ return null;
+ }
+
+
+ private long lastClearTime = System.currentTimeMillis();
+
+ //清理过时的人脸
+ private void clearFaceResultRegistry(List faceInfoList) {
+ if (System.currentTimeMillis() - lastClearTime > 5000) {
+ Iterator iterator = faceResultRegistry.keySet().iterator();
+ for (; iterator.hasNext(); ) {
+ Integer next = iterator.next();
+ boolean flag = false;
+ for (FaceInfo faceInfo : faceInfoList) {
+ if (next.equals(faceInfo.getFaceId())) {
+ flag = true;
+ }
+ }
+ if (!flag) {
+ iterator.remove();
+ }
+
+ }
+ lastClearTime = System.currentTimeMillis();
+ }
+
+
+ }
+
+
+ @Data
+ public class FaceResult {
+ private boolean flag = false;
+ private String name;
+ private float score;
+
+
+ }
+
+ @Data
+ public class FacePreviewInfo {
+
+ private FaceInfo faceInfo;
+ private int age;
+ private boolean liveness;
+
+ }
+
+
+ private class FaceInfoRunnable implements Runnable {
+ private FaceInfo faceInfo;
+ private ImageInfo imageInfo;
+ private FaceResult faceResult;
+
+ public FaceInfoRunnable(FaceInfo faceInfo, ImageInfo imageInfo, FaceResult faceResult) {
+ this.faceInfo = faceInfo;
+ this.imageInfo = imageInfo;
+ this.faceResult = faceResult;
+ }
+
+ @Override
+ public void run() {
+ FaceEngine frEngine = null;
+ try {
+ frEngine = frEnginePool.borrowObject();
+ if (frEngine != null) {
+ FaceFeature faceFeature = new FaceFeature();
+ int resCode = frEngine.extractFaceFeature(imageInfo, faceInfo, ExtractType.RECOGNIZE, 0, faceFeature);
+ if (resCode == 0) {
+
+ float score = 0.0F;
+ Iterator> iterator = faceFeatureRegistry.entrySet().iterator();
+ for (; iterator.hasNext(); ) {
+ Map.Entry next = iterator.next();
+ FaceFeature faceFeatureTarget = new FaceFeature();
+ faceFeatureTarget.setFeatureData(next.getValue());
+
+ FaceSimilar faceSimilar = new FaceSimilar();
+ frEngine.compareFaceFeature(faceFeatureTarget, faceFeature, faceSimilar);
+ if (faceSimilar.getScore() > score) {
+ score = faceSimilar.getScore();
+ faceResult.setName(next.getKey());
+ }
+ }
+
+ log.info("相似度:" + score);
+ if (score >= 0.8f) {
+ faceResult.setScore(score);
+ faceResult.setFlag(true);
+ faceResultRegistry.put(faceInfo.getFaceId(), faceResult);
+ } else {
+ faceResultRegistry.remove(faceInfo.getFaceId());
+ }
+
+ }
+ }
+ } catch (Exception e) {
+
+ } finally {
+ if (frEngine != null) {
+ frEnginePool.returnObject(frEngine);
+ }
+ }
+
+
+ }
+ }
+
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/factory/FaceEngineFactory.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/factory/FaceEngineFactory.java
new file mode 100644
index 0000000..bc90db4
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/factory/FaceEngineFactory.java
@@ -0,0 +1,73 @@
+package net.shapelight.modules.face.factory;
+
+import com.arcsoft.face.EngineConfiguration;
+import com.arcsoft.face.FaceEngine;
+import com.arcsoft.face.enums.ErrorInfo;
+import lombok.extern.slf4j.Slf4j;
+import net.shapelight.modules.face.config.ArcFaceAutoConfiguration;
+import net.shapelight.modules.face.enums.ErrorCodeEnum;
+import net.shapelight.modules.face.rpc.BusinessException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.pool2.BasePooledObjectFactory;
+import org.apache.commons.pool2.PooledObject;
+import org.apache.commons.pool2.impl.DefaultPooledObject;
+
+@Slf4j
+public class FaceEngineFactory extends BasePooledObjectFactory {
+
+ private String appId;
+ private String sdkKey;
+ private String activeKey;
+ private String activeFile;
+ private EngineConfiguration engineConfiguration;
+
+
+ public FaceEngineFactory(String appId, String sdkKey, String activeKey, String activeFile, EngineConfiguration engineConfiguration) {
+ this.appId = appId;
+ this.sdkKey = sdkKey;
+ this.activeKey = activeKey;
+ this.activeFile=activeFile;
+ this.engineConfiguration = engineConfiguration;
+ }
+
+
+ @Override
+ public FaceEngine create() {
+
+
+ FaceEngine faceEngine = new FaceEngine(ArcFaceAutoConfiguration.CACHE_LIB_FOLDER);
+
+// FaceEngine faceEngine = new FaceEngine("/home/huangyifang/gb/咸阳师范/ArcSoft_ArcFacePro_linux_java_V4.1/libs/LINUX64/");
+ int activeCode;
+ if (StringUtils.isNotEmpty(activeFile)) {
+ activeCode = faceEngine.activeOffline(activeFile);
+ } else {
+ activeCode = faceEngine.activeOnline(appId, sdkKey, activeKey);
+ }
+ log.debug("引擎激活errorCode:" + activeCode);
+ if (activeCode != ErrorInfo.MOK.getValue() && activeCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
+ log.error("引擎激活失败" + activeCode);
+ throw new BusinessException(ErrorCodeEnum.FAIL, "引擎激活失败" + activeCode);
+ }
+ int initCode = faceEngine.init(engineConfiguration);
+ if (initCode != ErrorInfo.MOK.getValue()) {
+ log.error("引擎初始化失败" + initCode);
+ throw new BusinessException(ErrorCodeEnum.FAIL, "引擎初始化失败" + initCode);
+ }
+ log.debug("初始化引擎errorCode:" + initCode);
+ return faceEngine;
+ }
+
+ @Override
+ public PooledObject wrap(FaceEngine faceEngine) {
+ return new DefaultPooledObject<>(faceEngine);
+ }
+
+
+ @Override
+ public void destroyObject(PooledObject p) throws Exception {
+ FaceEngine faceEngine = p.getObject();
+ int result = faceEngine.unInit();
+ super.destroyObject(p);
+ }
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/BusinessException.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/BusinessException.java
new file mode 100644
index 0000000..4675a16
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/BusinessException.java
@@ -0,0 +1,64 @@
+package net.shapelight.modules.face.rpc;
+
+import lombok.Data;
+
+/**
+ * @Author: st7251
+ * @Date: 2018/11/23 14:18
+ */
+@Data
+public class BusinessException extends RuntimeException {
+ private ErrorCode errorCode;
+ private String msg;
+ private String msgCN;
+
+ public BusinessException(Response response) {
+ this.errorCode = new ErrorCode() {
+ @Override
+ public Integer getCode() {
+ return response.getCode();
+ }
+
+ @Override
+ public String getDesc() {
+ return response.getMsg();
+ }
+
+ @Override
+ public String getDescCN() {
+ return response.getMsg();
+ }
+ };
+ this.msg=response.getMsg();
+ this.msgCN=response.getMsg();
+ }
+
+ public BusinessException(ErrorCode errorCode) {
+ super(errorCode.getDesc());
+ this.errorCode = errorCode;
+ this.msg= errorCode.getDesc();
+ this.msgCN=errorCode.getDescCN();
+ }
+
+ public BusinessException(ErrorCode errorCode, String msg) {
+ super(errorCode.getDesc());
+ this.errorCode = errorCode;
+ this.msg = msg;
+ this.msgCN=msg;
+ }
+
+ public BusinessException(Throwable cause, ErrorCode errorCode) {
+ super(cause);
+ this.errorCode = errorCode;
+ this.msg= errorCode.getDesc();
+ this.msgCN=errorCode.getDescCN();
+ }
+
+
+ public BusinessException(Throwable cause, ErrorCode errorCode, String msg) {
+ super(cause);
+ this.errorCode = errorCode;
+ this.msg = msg;
+ this.msgCN=msg;
+ }
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/ErrorCode.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/ErrorCode.java
new file mode 100644
index 0000000..e22ec67
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/ErrorCode.java
@@ -0,0 +1,12 @@
+package net.shapelight.modules.face.rpc;
+
+public interface ErrorCode {
+
+
+ Integer getCode();
+
+ String getDesc();
+
+ String getDescCN();
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/GlobalExceptionHandler.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/GlobalExceptionHandler.java
new file mode 100644
index 0000000..ddd04ef
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/GlobalExceptionHandler.java
@@ -0,0 +1,47 @@
+package net.shapelight.modules.face.rpc;
+
+
+import lombok.extern.slf4j.Slf4j;
+import net.shapelight.modules.face.enums.ErrorCodeEnum;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+@Slf4j
+public class GlobalExceptionHandler{
+
+
+ /**
+ * 自定义异常
+ */
+ @ExceptionHandler(BusinessException.class)
+ public Response businessException(BusinessException e) {
+ log.error(e.getMessage(), e);
+ Response response = new Response();
+ response.setCode(e.getErrorCode().getCode());
+ response.setMsg(e.getMsgCN());
+ return response;
+ }
+
+ @ExceptionHandler(IllegalArgumentException.class)
+ public Response handleIllegalArgumentException(IllegalArgumentException e) {
+ log.error(e.getMessage(), e);
+ Response response = new Response();
+ response.setCode(ErrorCodeEnum.PARAM_ERROR.getCode());
+ response.setMsg(e.getMessage());
+ return response;
+ }
+
+ @ExceptionHandler(Exception.class)
+ public Response handleException(Exception e) {
+ log.error(e.getMessage(), e);
+ Response response = new Response();
+ response.setCode(ErrorCodeEnum.SYSTEM_ERROR.getCode());
+ response.setMsg(ErrorCodeEnum.SYSTEM_ERROR.getDescCN());
+ return response;
+ }
+
+
+
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/Response.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/Response.java
new file mode 100644
index 0000000..926d866
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/rpc/Response.java
@@ -0,0 +1,39 @@
+package net.shapelight.modules.face.rpc;
+
+import lombok.Data;
+
+@Data
+public class Response {
+
+ private int code = -1;
+ private String msg = "success";
+ private T data;
+
+ public static Response newSuccessResponse(T data) {
+ return newResponse(data, 0, "success");
+ }
+
+ public static Response newFailedResponse(Integer code, String message) {
+ return newResponse(null, code, message);
+ }
+
+ public static Response newFailedResponse(ErrorCode ErrorCode) {
+ return newResponse(null, ErrorCode.getCode(), ErrorCode.getDesc());
+ }
+
+ public static Response newFailedResponse(ErrorCode ErrorCode, String message) {
+ return newResponse(null, ErrorCode.getCode(), message);
+ }
+
+ public static Response newResponse(T data, Integer code, String message) {
+ Response response = new Response();
+ response.setCode(code);
+ response.setMsg(message);
+ if (data != null && data instanceof String && "".equals(data)) {
+ response.setData(null);
+ } else {
+ response.setData(data);
+ }
+ return response;
+ }
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/service/FaceEngineService.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/service/FaceEngineService.java
new file mode 100644
index 0000000..04d1b02
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/service/FaceEngineService.java
@@ -0,0 +1,28 @@
+package net.shapelight.modules.face.service;
+
+
+import com.arcsoft.face.FaceInfo;
+import com.arcsoft.face.enums.ExtractType;
+import com.arcsoft.face.toolkit.ImageInfo;
+import net.shapelight.modules.face.entity.ProcessInfo;
+import net.shapelight.modules.face.entity.UserCompareInfo;
+import net.shapelight.modules.face.util.UserInfo;
+
+import java.util.List;
+
+
+public interface FaceEngineService {
+
+ List detectFaces(ImageInfo imageInfo);
+
+ Float compareFace(ImageInfo imageInfo1, ImageInfo imageInfo2) ;
+
+ byte[] extractFaceFeature(ImageInfo imageInfo, FaceInfo faceInfo, ExtractType extractType);
+
+ List faceRecognition(byte[] faceFeature, List userInfoList, float passRate) ;
+
+ List process(ImageInfo imageInfo, List faceInfoList);
+
+
+
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/service/impl/FaceEngineServiceImpl.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/service/impl/FaceEngineServiceImpl.java
new file mode 100644
index 0000000..411f541
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/service/impl/FaceEngineServiceImpl.java
@@ -0,0 +1,349 @@
+package net.shapelight.modules.face.service.impl;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.arcsoft.face.*;
+import com.arcsoft.face.enums.DetectMode;
+import com.arcsoft.face.enums.DetectOrient;
+import com.arcsoft.face.enums.ExtractType;
+import com.arcsoft.face.toolkit.ImageInfo;
+import com.google.common.collect.Lists;
+import lombok.extern.slf4j.Slf4j;
+import net.shapelight.modules.face.entity.ProcessInfo;
+import net.shapelight.modules.face.entity.UserCompareInfo;
+import net.shapelight.modules.face.enums.ErrorCodeEnum;
+import net.shapelight.modules.face.factory.FaceEngineFactory;
+import net.shapelight.modules.face.rpc.BusinessException;
+import net.shapelight.modules.face.service.FaceEngineService;
+import net.shapelight.modules.face.util.UserInfo;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.*;
+
+
+@Service("faceEngineService")
+@Slf4j
+public class FaceEngineServiceImpl implements FaceEngineService {
+
+ public final static Logger logger = LoggerFactory.getLogger(FaceEngineServiceImpl.class);
+
+ @Value("${config.arcface-sdk.app-id}")
+ public String appId;
+
+ @Value("${config.arcface-sdk.sdk-key}")
+ public String sdkKey;
+
+ @Value("${config.arcface-sdk.active-key}")
+ public String activeKey;
+
+ @Value("${config.arcface-sdk.active-file}")
+ public String activeFile;
+
+ @Value("${config.arcface-sdk.detect-pool-size}")
+ public Integer detectPooSize;
+
+ @Value("${config.arcface-sdk.compare-pool-size}")
+ public Integer comparePooSize;
+
+ private ExecutorService compareExecutorService;
+
+ //通用人脸识别引擎池
+ private GenericObjectPool faceEngineGeneralPool;
+
+ //人脸比对引擎池
+ private GenericObjectPool faceEngineComparePool;
+
+ @PostConstruct
+ public void init() {
+
+
+ GenericObjectPoolConfig detectPoolConfig = new GenericObjectPoolConfig();
+ detectPoolConfig.setMaxIdle(detectPooSize);
+ detectPoolConfig.setMaxTotal(detectPooSize);
+ detectPoolConfig.setMinIdle(detectPooSize);
+ detectPoolConfig.setLifo(false);
+ EngineConfiguration detectCfg = new EngineConfiguration();
+ FunctionConfiguration detectFunctionCfg = new FunctionConfiguration();
+ detectFunctionCfg.setSupportFaceDetect(true);//开启人脸检测功能
+ detectFunctionCfg.setSupportFaceRecognition(true);//开启人脸识别功能
+ detectFunctionCfg.setSupportAge(true);//开启年龄检测功能
+ detectFunctionCfg.setSupportGender(true);//开启性别检测功能
+ detectFunctionCfg.setSupportLiveness(true);//开启活体检测功能
+ detectCfg.setFunctionConfiguration(detectFunctionCfg);
+ detectCfg.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);//图片检测模式,如果是连续帧的视频流图片,那么改成VIDEO模式
+ detectCfg.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);//人脸旋转角度
+ faceEngineGeneralPool = new GenericObjectPool(new FaceEngineFactory(appId, sdkKey, activeKey, activeFile, detectCfg), detectPoolConfig);//底层库算法对象池
+
+
+ //初始化特征比较线程池
+ GenericObjectPoolConfig comparePoolConfig = new GenericObjectPoolConfig();
+ comparePoolConfig.setMaxIdle(comparePooSize);
+ comparePoolConfig.setMaxTotal(comparePooSize);
+ comparePoolConfig.setMinIdle(comparePooSize);
+ comparePoolConfig.setLifo(false);
+ EngineConfiguration compareCfg = new EngineConfiguration();
+ FunctionConfiguration compareFunctionCfg = new FunctionConfiguration();
+ compareFunctionCfg.setSupportFaceRecognition(true);//开启人脸识别功能
+ compareCfg.setFunctionConfiguration(compareFunctionCfg);
+ compareCfg.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);//图片检测模式,如果是连续帧的视频流图片,那么改成VIDEO模式
+ compareCfg.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);//人脸旋转角度
+ faceEngineComparePool = new GenericObjectPool(new FaceEngineFactory(appId, sdkKey, activeKey, activeFile, compareCfg), comparePoolConfig);//底层库算法对象池
+ compareExecutorService = Executors.newFixedThreadPool(comparePooSize);
+ }
+
+
+ @Override
+ public List detectFaces(ImageInfo imageInfo) {
+
+ FaceEngine faceEngine = null;
+ try {
+ faceEngine = faceEngineGeneralPool.borrowObject();
+ if (faceEngine == null) {
+ throw new BusinessException(ErrorCodeEnum.FAIL, "获取引擎失败");
+ }
+
+ //人脸检测得到人脸列表
+ List faceInfoList = new ArrayList();
+ //人脸检测
+ int errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
+ if (errorCode == 0) {
+ return faceInfoList;
+ } else {
+ log.error("人脸检测失败,errorCode:" + errorCode);
+ }
+
+ } catch (Exception e) {
+ log.error("", e);
+ } finally {
+ if (faceEngine != null) {
+ //释放引擎对象
+ faceEngineGeneralPool.returnObject(faceEngine);
+ }
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public Float compareFace(ImageInfo imageInfo1, ImageInfo imageInfo2) {
+
+ List faceInfoList1 = detectFaces(imageInfo1);
+ List faceInfoList2 = detectFaces(imageInfo2);
+
+ if (CollectionUtil.isEmpty(faceInfoList1)) {
+ throw new BusinessException(ErrorCodeEnum.FAIL, "照片1未检测到人脸");
+ }
+ if (CollectionUtil.isEmpty(faceInfoList2)) {
+ throw new BusinessException(ErrorCodeEnum.FAIL, "照片2未检测到人脸");
+ }
+
+ byte[] feature1 = extractFaceFeature(imageInfo1, faceInfoList1.get(0), ExtractType.REGISTER);
+ byte[] feature2 = extractFaceFeature(imageInfo2, faceInfoList2.get(0), ExtractType.RECOGNIZE);
+
+ FaceEngine faceEngine = null;
+ try {
+ faceEngine = faceEngineGeneralPool.borrowObject();
+ if (faceEngine == null) {
+ throw new BusinessException(ErrorCodeEnum.FAIL, "获取引擎失败");
+ }
+
+ FaceFeature faceFeature1 = new FaceFeature();
+ faceFeature1.setFeatureData(feature1);
+ FaceFeature faceFeature2 = new FaceFeature();
+ faceFeature2.setFeatureData(feature2);
+ //提取人脸特征
+ FaceSimilar faceSimilar = new FaceSimilar();
+ int errorCode = faceEngine.compareFaceFeature(faceFeature1, faceFeature2, faceSimilar);
+ if (errorCode == 0) {
+ return faceSimilar.getScore();
+ } else {
+ log.error("特征提取失败,errorCode:" + errorCode);
+ }
+
+ } catch (Exception e) {
+ log.error("", e);
+ } finally {
+ if (faceEngine != null) {
+ //释放引擎对象
+ faceEngineGeneralPool.returnObject(faceEngine);
+ }
+ }
+
+ return null;
+
+ }
+
+ /**
+ * 人脸特征
+ *
+ * @param imageInfo
+ * @return
+ */
+ @Override
+ public byte[] extractFaceFeature(ImageInfo imageInfo, FaceInfo faceInfo, ExtractType extractType) {
+
+ FaceEngine faceEngine = null;
+ try {
+ faceEngine = faceEngineGeneralPool.borrowObject();
+ if (faceEngine == null) {
+ throw new BusinessException(ErrorCodeEnum.FAIL, "获取引擎失败");
+ }
+
+ FaceFeature faceFeature = new FaceFeature();
+ //提取人脸特征
+ int errorCode = faceEngine.extractFaceFeature(imageInfo, faceInfo, extractType, 0, faceFeature);
+ if (errorCode == 0) {
+ return faceFeature.getFeatureData();
+ } else {
+ log.error("特征提取失败,errorCode:" + errorCode);
+ }
+
+ } catch (Exception e) {
+ log.error("", e);
+ } finally {
+ if (faceEngine != null) {
+ //释放引擎对象
+ faceEngineGeneralPool.returnObject(faceEngine);
+ }
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public List faceRecognition(byte[] faceFeature, List userInfoList, float passRate) {
+ List resultUserInfoList = Lists.newLinkedList();//识别到的人脸列表
+
+ FaceFeature targetFaceFeature = new FaceFeature();
+ targetFaceFeature.setFeatureData(faceFeature);
+
+ List> faceUserInfoPartList = Lists.partition(userInfoList, 1000);//分成1000一组,多线程处理
+ CompletionService> completionService = new ExecutorCompletionService(compareExecutorService);
+ for (List part : faceUserInfoPartList) {
+ completionService.submit(new CompareFaceTask(part, targetFaceFeature, passRate));
+ }
+ for (int i = 0; i < faceUserInfoPartList.size(); i++) {
+ List faceUserInfoList = null;
+ try {
+ faceUserInfoList = completionService.take().get();
+ } catch (InterruptedException | ExecutionException e) {
+ }
+ if (CollectionUtil.isNotEmpty(userInfoList)) {
+ resultUserInfoList.addAll(faceUserInfoList);
+ }
+ }
+
+ resultUserInfoList.sort((h1, h2) -> h2.getSimilar().compareTo(h1.getSimilar()));//从大到小排序
+
+ return resultUserInfoList;
+ }
+
+
+
+ @Override
+ public List process(ImageInfo imageInfo, List faceInfoList) {
+ FaceEngine faceEngine = null;
+ try {
+ //获取引擎对象
+ faceEngine = faceEngineGeneralPool.borrowObject();
+ if (faceEngine == null) {
+ throw new BusinessException(ErrorCodeEnum.FAIL, "获取引擎失败");
+ }
+
+
+ int errorCode = faceEngine.process(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList, FunctionConfiguration.builder().supportAge(true).supportGender(true).supportLiveness(true).build());
+ if (errorCode == 0) {
+ List processInfoList = Lists.newLinkedList();
+
+ //性别列表
+ List genderInfoList = new ArrayList();
+ faceEngine.getGender(genderInfoList);
+
+ //年龄列表
+ List ageInfoList = new ArrayList();
+ faceEngine.getAge(ageInfoList);
+ //活体结果列表
+ List livenessInfoList = new ArrayList();
+ faceEngine.getLiveness(livenessInfoList);
+
+
+ for (int i = 0; i < genderInfoList.size(); i++) {
+ ProcessInfo processInfo = new ProcessInfo();
+ processInfo.setGender(genderInfoList.get(i).getGender());
+ processInfo.setAge(ageInfoList.get(i).getAge());
+ processInfo.setLiveness(livenessInfoList.get(i).getLiveness());
+ processInfoList.add(processInfo);
+ }
+ return processInfoList;
+
+ }
+
+
+ } catch (Exception e) {
+ logger.error("", e);
+ } finally {
+ if (faceEngine != null) {
+ //释放引擎对象
+ faceEngineGeneralPool.returnObject(faceEngine);
+ }
+ }
+
+ return null;
+
+ }
+
+
+ private class CompareFaceTask implements Callable> {
+
+ private List userInfoList;
+ private FaceFeature targetFaceFeature;
+ private float passRate;
+
+
+ public CompareFaceTask(List userInfoList, FaceFeature targetFaceFeature, float passRate) {
+ this.userInfoList = userInfoList;
+ this.targetFaceFeature = targetFaceFeature;
+ this.passRate = passRate;
+ }
+
+ @Override
+ public List call() throws Exception {
+ FaceEngine faceEngine = null;
+ List resultUserInfoList = Lists.newLinkedList();//识别到的人脸列表
+ try {
+ faceEngine = faceEngineComparePool.borrowObject();
+ for (UserInfo userInfo : userInfoList) {
+ FaceFeature sourceFaceFeature = new FaceFeature();
+ sourceFaceFeature.setFeatureData(userInfo.getFaceFeature());
+ FaceSimilar faceSimilar = new FaceSimilar();
+ faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
+ if (faceSimilar.getScore() > passRate) {//相似值大于配置预期,加入到识别到人脸的列表
+ UserCompareInfo info = new UserCompareInfo();
+ info.setName(userInfo.getName());
+ info.setFaceId(userInfo.getFaceId());
+ info.setSimilar(faceSimilar.getScore());
+ resultUserInfoList.add(info);
+ }
+ }
+ } catch (Exception e) {
+ logger.error("", e);
+ } finally {
+ if (faceEngine != null) {
+ faceEngineComparePool.returnObject(faceEngine);
+ }
+ }
+
+ return resultUserInfoList;
+ }
+
+ }
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/util/Base64Util.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/Base64Util.java
new file mode 100644
index 0000000..29db3c6
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/Base64Util.java
@@ -0,0 +1,33 @@
+package net.shapelight.modules.face.util;
+
+import org.springframework.util.ObjectUtils;
+
+import java.util.Base64;
+
+public class Base64Util {
+ public static String base64Process(String base64Str) {
+ if (!ObjectUtils.isEmpty(base64Str)) {
+ String photoBase64 = base64Str.substring(0, 30).toLowerCase();
+ int indexOf = photoBase64.indexOf("base64,");
+ if (indexOf > 0) {
+ base64Str = base64Str.substring(indexOf + 7);
+ }
+ base64Str = base64Str.replaceAll(" ", "+");
+ base64Str = base64Str.replaceAll("\r|\n", "");
+ return base64Str;
+ }
+ return "";
+ }
+
+ public static byte[] base64ToBytes(String base64) {
+ if (ObjectUtils.isEmpty(base64)) {
+ return null;
+ }
+ String base64Process = base64Process(base64);
+
+ byte[] decode = Base64.getDecoder().decode(base64Process);
+ return decode;
+
+
+ }
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/util/FaceEngineTest.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/FaceEngineTest.java
new file mode 100644
index 0000000..4e4fa7d
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/FaceEngineTest.java
@@ -0,0 +1,225 @@
+package net.shapelight.modules.face.util;
+
+import com.arcsoft.face.*;
+import com.arcsoft.face.enums.*;
+import com.arcsoft.face.toolkit.ImageFactory;
+import com.arcsoft.face.toolkit.ImageInfo;
+import com.arcsoft.face.toolkit.ImageInfoEx;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FaceEngineTest {
+
+
+ public static void main(String[] args) {
+
+ //激活码,从官网获取
+ String appId = "DEnAZa1bWXcaAxyWUg33QZaKCmMkNmrQxuKZJQGmZsHJ";
+ String sdkKey = "vWbvUyStZeartSaM6QoTzPYWFpSaj4uhfDmRifSzCd6";
+ String activeKey = "82G1-11QA-713Y-8NB4";
+
+ System.err.println("注意,如果返回的errorCode不为0,可查看com.arcsoft.face.enums.ErrorInfo类获取相应的错误信息");
+
+ //人脸识别引擎库存放路径
+ FaceEngine faceEngine = new FaceEngine("/home/huangyifang/gb/咸阳师范/ArcSoft_ArcFacePro_linux_java_V4.1/libs/LINUX64");
+ //激活引擎
+ int errorCode = faceEngine.activeOnline(appId, sdkKey, activeKey);
+ System.out.println("引擎激活errorCode:" + errorCode);
+
+ ActiveDeviceInfo activeDeviceInfo = new ActiveDeviceInfo();
+ //采集设备信息(可离线)
+ errorCode = faceEngine.getActiveDeviceInfo(activeDeviceInfo);
+ System.out.println("采集设备信息errorCode:" + errorCode);
+ System.out.println("设备信息:" + activeDeviceInfo.getDeviceInfo());
+
+// faceEngine.activeOffline("d:\\ArcFacePro64.dat.offline");
+
+ ActiveFileInfo activeFileInfo = new ActiveFileInfo();
+ errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
+ System.out.println("获取激活文件errorCode:" + errorCode);
+ System.out.println("激活文件信息:" + activeFileInfo.toString());
+
+ //引擎配置
+ EngineConfiguration engineConfiguration = new EngineConfiguration();
+ engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
+ engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
+ engineConfiguration.setDetectFaceMaxNum(10);
+ //功能配置
+ FunctionConfiguration functionConfiguration = new FunctionConfiguration();
+ functionConfiguration.setSupportAge(true);
+ functionConfiguration.setSupportFaceDetect(true);
+ functionConfiguration.setSupportFaceRecognition(true);
+ functionConfiguration.setSupportGender(true);
+ functionConfiguration.setSupportLiveness(true);
+ functionConfiguration.setSupportIRLiveness(true);
+ functionConfiguration.setSupportImageQuality(true);
+ functionConfiguration.setSupportMaskDetect(true);
+ functionConfiguration.setSupportUpdateFaceData(true);
+ engineConfiguration.setFunctionConfiguration(functionConfiguration);
+
+ //初始化引擎
+ errorCode = faceEngine.init(engineConfiguration);
+ System.out.println("初始化引擎errorCode:" + errorCode);
+ VersionInfo version = faceEngine.getVersion();
+ System.out.println(version);
+
+ //人脸检测
+ ImageInfo imageInfo = ImageFactory.getRGBData(new File("/home/huangyifang/gb/咸阳师范/10.jpg"));
+ List faceInfoList = new ArrayList();
+ errorCode = faceEngine.detectFaces(imageInfo, faceInfoList);
+ System.out.println("人脸检测errorCode:" + errorCode);
+ System.out.println("检测到人脸数:" + faceInfoList.size());
+
+ ImageQuality imageQuality = new ImageQuality();
+ errorCode = faceEngine.imageQualityDetect(imageInfo, faceInfoList.get(0), 0, imageQuality);
+ System.out.println("图像质量检测errorCode:" + errorCode);
+ System.out.println("图像质量分数:" + imageQuality.getFaceQuality());
+
+ //特征提取
+ FaceFeature faceFeature = new FaceFeature();
+ errorCode = faceEngine.extractFaceFeature(imageInfo, faceInfoList.get(0), ExtractType.REGISTER, 0, faceFeature);
+ System.out.println("特征提取errorCode:" + errorCode);
+
+ //人脸检测2
+ ImageInfo imageInfo2 = ImageFactory.getRGBData(new File("/home/huangyifang/gb/咸阳师范/10.jpg"));
+ List faceInfoList2 = new ArrayList();
+ errorCode = faceEngine.detectFaces(imageInfo2, faceInfoList2);
+ System.out.println("人脸检测errorCode:" + errorCode);
+ System.out.println("检测到人脸数:" + faceInfoList.size());
+
+ //特征提取2
+ FaceFeature faceFeature2 = new FaceFeature();
+ errorCode = faceEngine.extractFaceFeature(imageInfo2, faceInfoList2.get(0), ExtractType.RECOGNIZE, 0, faceFeature2);
+ System.out.println("特征提取errorCode:" + errorCode);
+
+ //特征比对
+ FaceFeature targetFaceFeature = new FaceFeature();
+ targetFaceFeature.setFeatureData(faceFeature.getFeatureData());
+ FaceFeature sourceFaceFeature = new FaceFeature();
+ sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData());
+ FaceSimilar faceSimilar = new FaceSimilar();
+
+ errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
+ System.out.println("特征比对errorCode:" + errorCode);
+ System.out.println("人脸相似度:" + faceSimilar.getScore());
+
+
+ //人脸属性检测
+ FunctionConfiguration configuration = new FunctionConfiguration();
+ configuration.setSupportAge(true);
+ configuration.setSupportGender(true);
+ configuration.setSupportLiveness(true);
+ configuration.setSupportMaskDetect(true);
+ errorCode = faceEngine.process(imageInfo, faceInfoList, configuration);
+ System.out.println("图像属性处理errorCode:" + errorCode);
+
+ //性别检测
+ List genderInfoList = new ArrayList();
+ errorCode = faceEngine.getGender(genderInfoList);
+ System.out.println("性别:" + genderInfoList.get(0).getGender());
+
+ //年龄检测
+ List ageInfoList = new ArrayList();
+ errorCode = faceEngine.getAge(ageInfoList);
+ System.out.println("年龄:" + ageInfoList.get(0).getAge());
+
+ //活体检测
+ List livenessInfoList = new ArrayList();
+ errorCode = faceEngine.getLiveness(livenessInfoList);
+ System.out.println("活体:" + livenessInfoList.get(0).getLiveness());
+
+ //口罩检测
+ List maskInfoList = new ArrayList();
+ errorCode = faceEngine.getMask(maskInfoList);
+ System.out.println("口罩:" + maskInfoList.get(0).getMask());
+
+
+ //IR属性处理
+ ImageInfo imageInfoGray = ImageFactory.getGrayData(new File("/home/huangyifang/gb/咸阳师范/10.jpg"));
+ List faceInfoListGray = new ArrayList();
+ errorCode = faceEngine.detectFaces(imageInfoGray, faceInfoListGray);
+
+ FunctionConfiguration configuration2 = new FunctionConfiguration();
+ configuration2.setSupportIRLiveness(true);
+ errorCode = faceEngine.processIr(imageInfoGray, faceInfoListGray, configuration2);
+ //IR活体检测
+ List irLivenessInfo = new ArrayList<>();
+ errorCode = faceEngine.getLivenessIr(irLivenessInfo);
+ System.out.println("IR活体:" + irLivenessInfo.get(0).getLiveness());
+
+ //获取激活文件信息
+ ActiveFileInfo activeFileInfo2 = new ActiveFileInfo();
+ errorCode = faceEngine.getActiveFileInfo(activeFileInfo2);
+
+ //更新人脸数据
+ errorCode = faceEngine.updateFaceData(imageInfo, faceInfoList);
+
+ //高级人脸图像处理接口
+ ImageInfoEx imageInfoEx = new ImageInfoEx();
+ imageInfoEx.setHeight(imageInfo.getHeight());
+ imageInfoEx.setWidth(imageInfo.getWidth());
+ imageInfoEx.setImageFormat(imageInfo.getImageFormat());
+ imageInfoEx.setImageDataPlanes(new byte[][]{imageInfo.getImageData()});
+ imageInfoEx.setImageStrides(new int[]{imageInfo.getWidth() * 3});
+ List faceInfoList1 = new ArrayList<>();
+ errorCode = faceEngine.detectFaces(imageInfoEx, DetectModel.ASF_DETECT_MODEL_RGB, faceInfoList1);
+ ImageQuality imageQuality1 = new ImageQuality();
+ errorCode = faceEngine.imageQualityDetect(imageInfoEx, faceInfoList1.get(0), 0, imageQuality1);
+ FunctionConfiguration fun = new FunctionConfiguration();
+ fun.setSupportAge(true);
+ errorCode = faceEngine.process(imageInfoEx, faceInfoList1, fun);
+ List ageInfoList1 = new ArrayList<>();
+ int age = faceEngine.getAge(ageInfoList1);
+ FaceFeature feature = new FaceFeature();
+ errorCode = faceEngine.extractFaceFeature(imageInfoEx, faceInfoList1.get(0), ExtractType.REGISTER, 0, feature);
+ errorCode = faceEngine.updateFaceData(imageInfoEx, faceInfoList1);
+
+ //设置活体测试
+ errorCode = faceEngine.setLivenessParam(0.5f, 0.7f, 0.3f);
+ System.out.println("设置活体活体阈值errorCode:" + errorCode);
+
+ LivenessParam livenessParam=new LivenessParam();
+ errorCode = faceEngine.getLivenessParam(livenessParam);
+
+ //注册人脸信息1
+ FaceFeatureInfo faceFeatureInfo = new FaceFeatureInfo();
+ faceFeatureInfo.setSearchId(5);
+ faceFeatureInfo.setFaceTag("FeatureData1");
+ faceFeatureInfo.setFeatureData(faceFeature.getFeatureData());
+ errorCode = faceEngine.registerFaceFeature(faceFeatureInfo);
+
+ //注册人脸信息2
+ FaceFeatureInfo faceFeatureInfo2 = new FaceFeatureInfo();
+ faceFeatureInfo2.setSearchId(6);
+ faceFeatureInfo2.setFaceTag("FeatureData2");
+ faceFeatureInfo2.setFeatureData(faceFeature2.getFeatureData());
+ errorCode = faceEngine.registerFaceFeature(faceFeatureInfo2);
+
+ //获取注册人脸个数
+ FaceSearchCount faceSearchCount = new FaceSearchCount();
+ errorCode = faceEngine.getFaceCount(faceSearchCount);
+ System.out.println("注册人脸个数:" + faceSearchCount.getCount());
+
+ //搜索最相似人脸
+ SearchResult searchResult = new SearchResult();
+ errorCode = faceEngine.searchFaceFeature(faceFeature, CompareModel.LIFE_PHOTO, searchResult);
+ System.out.println("最相似人脸Id:" + searchResult.getFaceFeatureInfo().getSearchId());
+
+ //更新人脸信息
+ FaceFeatureInfo faceFeatureInfo3 = new FaceFeatureInfo();
+ faceFeatureInfo3.setSearchId(6);
+ faceFeatureInfo3.setFaceTag("FeatureData2Update");
+ faceFeatureInfo3.setFeatureData(faceFeature2.getFeatureData());
+ errorCode = faceEngine.updateFaceFeature(faceFeatureInfo3);
+
+ //移除人脸信息
+ errorCode = faceEngine.removeFaceFeature(6);
+
+ //引擎卸载
+ errorCode = faceEngine.unInit();
+
+
+ }
+}
\ No newline at end of file
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/util/UserInfo.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/UserInfo.java
new file mode 100644
index 0000000..07781f5
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/UserInfo.java
@@ -0,0 +1,11 @@
+package net.shapelight.modules.face.util;
+
+
+import lombok.Data;
+
+@Data
+public class UserInfo {
+ private String faceId;
+ private String name;
+ private byte[] faceFeature;
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/util/UserRamCache.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/UserRamCache.java
new file mode 100644
index 0000000..f1ab06b
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/UserRamCache.java
@@ -0,0 +1,66 @@
+package net.shapelight.modules.face.util;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+public class UserRamCache {
+
+ private final ConcurrentHashMap USER_INFO_MAP = new ConcurrentHashMap<>();
+
+ private final Set REGISTER = new CopyOnWriteArraySet<>();
+
+ public void addUser(UserInfo userInfo) {
+ USER_INFO_MAP.put(userInfo.getFaceId(), userInfo);
+ for (Listener listener : REGISTER) {
+ listener.onAdd(userInfo);
+ }
+ }
+
+ public void removeUser(String faceId) {
+ UserInfo userInfo = USER_INFO_MAP.remove(faceId);
+ for (Listener listener : REGISTER) {
+ listener.onRemove(userInfo);
+ }
+ }
+
+ public List getUserList() {
+ List userInfoList = Lists.newLinkedList();
+ userInfoList.addAll(USER_INFO_MAP.values());
+ return userInfoList;
+ }
+
+ public void clear(){
+ USER_INFO_MAP.clear();
+ REGISTER.clear();
+ }
+
+ public void addListener(Listener listener) {
+ REGISTER.add(listener);
+ }
+
+ public void removeListener(Listener listener) {
+ REGISTER.remove(listener);
+ }
+
+// @Data
+// public class UserInfo {
+//
+// private String faceId;
+// private String name;
+// private byte[] faceFeature;
+//
+// }
+
+ public interface Listener {
+ default void onAdd(UserInfo userInfo) {
+ }
+
+ default void onRemove(UserInfo userInfo) {
+
+ }
+ }
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/face/util/UserRamGroup.java b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/UserRamGroup.java
new file mode 100644
index 0000000..a54789c
--- /dev/null
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/face/util/UserRamGroup.java
@@ -0,0 +1,34 @@
+package net.shapelight.modules.face.util;
+
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class UserRamGroup {
+
+ private static final ConcurrentHashMap USER_RAM_GROUP_MAP = new ConcurrentHashMap<>();
+
+ public static void addCell(String cellId){
+ UserRamCache cell = new UserRamCache();
+ USER_RAM_GROUP_MAP.put(cellId,cell);
+ }
+
+ public static void removeCell(String cellId){
+ USER_RAM_GROUP_MAP.remove(cellId);
+ }
+
+ public static void addUser(UserInfo userInfo, String cellId) {
+ USER_RAM_GROUP_MAP.get(cellId).addUser(userInfo);
+ }
+
+ public static void removeUser(String faceId, String cellId) {
+ USER_RAM_GROUP_MAP.get(cellId).removeUser(faceId);
+ }
+
+ public static List getUserList(String cellId) {
+ return USER_RAM_GROUP_MAP.get(cellId).getUserList();
+ }
+
+ public static void clear(){
+ USER_RAM_GROUP_MAP.clear();
+ }
+}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/job/task/EmpowerTask.java b/shapelight-admin/src/main/java/net/shapelight/modules/job/task/EmpowerTask.java
index b02d96e..ea89891 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/job/task/EmpowerTask.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/job/task/EmpowerTask.java
@@ -32,6 +32,8 @@ public class EmpowerTask implements ITask{
KeysEntity.passKey = json.getString("passKey");
KeysEntity.empowerText = json.getString("empowerText");
log.debug("TokenResponse:{}", json.getString("passKey"));
+ } else {
+
}
}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/ten/controller/TenPersonController.java b/shapelight-admin/src/main/java/net/shapelight/modules/ten/controller/TenPersonController.java
index 3f23fb2..e41df50 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/ten/controller/TenPersonController.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/ten/controller/TenPersonController.java
@@ -426,12 +426,12 @@ public class TenPersonController extends AbstractController {
tenPerson.setCreateTime(new Date());
tenPerson.setRegisterType(Constant.RESGISTER_TYPE_WEB);
- int res;
+ String res;
tenPerson.setStatus(0);
res = tenPersonService.save(tenPerson);
- if (res==2) {
- return R.error("照片未检测到人脸");
+ if (res!=null) {
+ return R.error(res);
}
return R.ok();
@@ -1303,11 +1303,11 @@ public class TenPersonController extends AbstractController {
//----------------------------------掌静脉特征压缩包封装--------------------------------------
- int res;
+ String res;
res = tenPersonService.save(tenPerson);
- if (res==2) {
- return R.error("照片未检测到人脸");
+ if (res!=null) {
+ return R.error(res);
}
return R.ok();
}
@@ -1361,7 +1361,7 @@ public class TenPersonController extends AbstractController {
AppUserScopeEntity userScopeEntity = appUserScopeService.getOne(new LambdaQueryWrapper()
.eq(AppUserScopeEntity::getUserId, params.get("userId")));
List relationList = relationService.list(new LambdaQueryWrapper()
- .eq(TenRelation::getParentId,userScopeEntity.getUserId()));
+ .eq(TenRelation::getParentId,userScopeEntity.getUserId()).eq(TenRelation::getStatus,1));
if(!relationList.isEmpty()) {
List list = relationList.stream().map(TenRelation::getStudentId).collect(Collectors.toList());
params.put("cellId",userScopeEntity.getCellId());
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/ten/dao/TenPersonDao.java b/shapelight-admin/src/main/java/net/shapelight/modules/ten/dao/TenPersonDao.java
index bc3b380..27ccef9 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/ten/dao/TenPersonDao.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/ten/dao/TenPersonDao.java
@@ -124,6 +124,8 @@ public interface TenPersonDao {
IPage getByPersonIds(Page page,@Param("personIds")List personIds, @Param("cellId")Long cellId);
+ List listPage(@Param("start")int start, @Param("count")int count, @Param("cellId")String cellId);
+
}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/ten/entity/TenPersonEntity.java b/shapelight-admin/src/main/java/net/shapelight/modules/ten/entity/TenPersonEntity.java
index d1d3a52..86ce9aa 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/ten/entity/TenPersonEntity.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/ten/entity/TenPersonEntity.java
@@ -347,6 +347,8 @@ public class TenPersonEntity extends BaseEntity implements Serializable {
//-----------------v5http-----
private String thdFeature;
+ //人脸特征
+ private String feature;
@JsonSerialize(using = ToStringSerializer.class)
@ApiModelProperty("部门ID")
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/TenPersonService.java b/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/TenPersonService.java
index cdfaa87..29b1104 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/TenPersonService.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/TenPersonService.java
@@ -27,7 +27,7 @@ public interface TenPersonService {
PageUtils queryVerify(Map params);
- int save(TenPersonEntity entity);
+ String save(TenPersonEntity entity);
int save3d(TenPersonEntity entity);
int update3d(TenPersonEntity entity);
boolean saveOtherRoom(TenPersonEntity entity);
@@ -154,5 +154,7 @@ public interface TenPersonService {
TenPersonEntity getByRyId(String ryId,Long cellId,String idCard);
+ List listPage(int start, int count, String cellId);
+
}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenParentServiceImpl.java b/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenParentServiceImpl.java
index b2c1d60..b7fb16d 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenParentServiceImpl.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenParentServiceImpl.java
@@ -38,7 +38,7 @@ public class TenParentServiceImpl extends ServiceImpl page = parentMapper.getParentVoList(pageParam,params);
page.getRecords().forEach(item -> {
int count = relationService.count(new LambdaQueryWrapper()
- .eq(TenRelation::getParentId,item.getUserId()));
+ .eq(TenRelation::getParentId,item.getUserId()).eq(TenRelation::getStatus,1));
item.setCount(count);
});
return new PageUtils(page);
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenPersonServiceImpl.java b/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenPersonServiceImpl.java
index 349cc78..06e9da4 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenPersonServiceImpl.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenPersonServiceImpl.java
@@ -1,9 +1,14 @@
package net.shapelight.modules.ten.service.impl;
+import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
+import com.arcsoft.face.FaceInfo;
+import com.arcsoft.face.enums.ExtractType;
+import com.arcsoft.face.toolkit.ImageFactory;
+import com.arcsoft.face.toolkit.ImageInfo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
@@ -21,6 +26,8 @@ import net.shapelight.modules.app.service.AppUserService;
import net.shapelight.modules.app.service.impl.AppUserScopeServiceImpl;
import net.shapelight.modules.excel.listener.PersonExcelListener;
import net.shapelight.modules.excel.model.PersonModel;
+import net.shapelight.modules.face.dto.FaceRecognitionResDTO;
+import net.shapelight.modules.face.service.FaceEngineService;
import net.shapelight.modules.job.entity.KeysEntity;
import net.shapelight.modules.nettyapi.service.ServerApiService;
import net.shapelight.modules.sys.entity.SysDictEntity;
@@ -106,6 +113,8 @@ public class TenPersonServiceImpl implements TenPersonService {
private String imagBaseUrl;
@Value("${global.minio.bucketName}")
private String bucketName;
+ @Autowired
+ private FaceEngineService faceEngineService;
@Override
@@ -253,18 +262,17 @@ public class TenPersonServiceImpl implements TenPersonService {
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = "TenPerson", allEntries = true)
- public int save(TenPersonEntity entity) {
- String userFileUrl = globalValue.getImagesDir() + "/" +
- entity.getCellId().toString() + "/" +
- entity.getPersonId().toString() + "/";
+ public String save(TenPersonEntity entity) {
+ String userFileUrl = globalValue.getImagesDir() + "/org/";
+ //保存原始图片
+ String tempOrgImageFile = entity.getOrgImageTemp();
+ String tempIdFrontImage = entity.getIdFrontImage();
+ String tempIdBackImage = entity.getIdBackImage();
try {
- //保存原始图片
- String tempOrgImageFile = entity.getOrgImageTemp();
- String tempIdFrontImage = entity.getIdFrontImage();
- String tempIdBackImage = entity.getIdBackImage();
+
if (tempOrgImageFile != null && !tempOrgImageFile.isEmpty()) {
String orgImageFileName = userFileUrl + "o_" + UUIDUtil.uuid() + ".jpg";
- String faceImageFileName = userFileUrl + "s_" + UUIDUtil.uuid() + ".jpg";
+// String faceImageFileName = userFileUrl + "s_" + UUIDUtil.uuid() + ".jpg";
//MinioClient minioClient = MinioUtil.getMinioClient();
try {
// 调用statObject()来判断对象是否存在。
@@ -275,47 +283,40 @@ public class TenPersonServiceImpl implements TenPersonService {
//判断人脸照片是否合格
//1.保存到本地
InputStream tempInputStream = minioClient.getObject(minioConfig.getBucketName(), tempOrgImageFile);
- String tempPath = globalValue.getStaticLocations() + "/";//+globalValue.getTempDir()+"/";
- String tempOrgFilePath = tempPath + tempOrgImageFile;
- int index;
- byte[] bytes = new byte[1024];
- File outFile = new File(tempOrgFilePath);
- FileOutputStream downloadFile = new FileOutputStream(outFile);
- while ((index = tempInputStream.read(bytes)) != -1) {
- downloadFile.write(bytes, 0, index);
- downloadFile.flush();
+ //----------------算法检测----------------------------------------------
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = tempInputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, length);
}
- downloadFile.close();
- tempInputStream.close();
- //2.测试上传的文件
- String tempFaceFileName = UUIDUtil.uuid() + ".jpg";
- String tempFaceFilePath = tempPath + tempFaceFileName;
- String osName = System.getProperty("os.name");//获取指定键(即os.name)的系统属性,如:Windows 7。
- if (Pattern.matches("Windows.*", osName)) {
-// if (Pattern.matches("Windows.*", osName)) {
- int res = PicSDK.getFace(tempOrgFilePath, tempFaceFilePath);
- if (res != 0) {
+ byte[] bytes = outputStream.toByteArray();
+ outputStream.close();
+ tempInputStream.close();
+ //-------------------------------------------------------------------------
+ ImageInfo rgbData = ImageFactory.getRGBData(bytes);
+ List faceInfoList = faceEngineService.detectFaces(rgbData);
+ if (CollectionUtil.isNotEmpty(faceInfoList)) {
+ FaceInfo faceInfo = faceInfoList.get(0);
+ FaceRecognitionResDTO faceRecognitionResDTO = new FaceRecognitionResDTO();
+ faceRecognitionResDTO.setRect(faceInfo.getRect());
+ byte[] featureBytes = faceEngineService.extractFaceFeature(rgbData, faceInfo, ExtractType.REGISTER);
+ if (featureBytes != null) {
+// UserRamCache.UserInfo userInfo = new UserCompareInfo();
+// userInfo.setFaceId(faceAddReqDTO.getName());
+// userInfo.setName(faceAddReqDTO.getName());
+// userInfo.setFaceFeature(feature);
+// //这边注册到内存缓存中,也可以根据业务,注册到数据库中
+// UserRamCache.addUser(userInfo);
+ entity.setFeature(Base64.getEncoder().encodeToString(featureBytes));
+ }else{
log.error("图片不合格,未检测到人脸");
- return 2;
+ return "图片不合格,未检测到人脸";
}
- //保存底片文件到oss
- InputStream inputStream = new FileInputStream(tempFaceFilePath);
- PutObjectOptions putObjectOptions = new PutObjectOptions(inputStream.available(), -1);
- putObjectOptions.setContentType("image/jpeg");
- minioClient.putObject(
- minioConfig.getBucketName(), faceImageFileName, inputStream, putObjectOptions);
- inputStream.close();
- } else {
- minioClient.copyObject(
- minioConfig.getBucketName(),
- faceImageFileName,
- null,
- null,
- minioConfig.getBucketName(),
- tempOrgImageFile,
- null,
- null);
+ }else{
+ log.error("图片不合格,未检测到人脸");
+ return "图片不合格,未检测到人脸";
}
//拷贝临时文件正式文件
minioClient.copyObject(
@@ -329,16 +330,15 @@ public class TenPersonServiceImpl implements TenPersonService {
null);
entity.setOrgImage(orgImageFileName);
- entity.setFaceImage(faceImageFileName);
- //删除临时文件oss
- minioClient.removeObject(minioConfig.getBucketName(), tempOrgImageFile);
+ entity.setFaceImage(orgImageFileName);
+// entity.setFaceImage(faceImageFileName);
//删除本地临时文件
- new File(tempFaceFilePath).delete();
+// new File(tempFaceFilePath).delete();
} catch (Exception e) {
entity.setOrgImage("");
entity.setFaceImage("");
e.printStackTrace();
- return 10;
+ return "文件不存在";
}
}
@@ -474,7 +474,7 @@ public class TenPersonServiceImpl implements TenPersonService {
appUserService.updateById(appUser);
}
- //发送设备通知
+ /*//发送设备通知
List devList = tenDeviceService.findByCellId(entity.getCellId());
//状态是0正常,发送推送
if (entity.getStatus().intValue() == Constant.PESON_SUATUS_NOMOR) {
@@ -498,41 +498,52 @@ public class TenPersonServiceImpl implements TenPersonService {
list.add(vo);
serverApiService.personOperation(dev.getSn(), list);
}
+ }*/
+ if(entity.getPersonType()!=Constant.PERSON_TYPE_GUEST) {
+ List dictList = sysDictService.queryByType("optype");
+ Map optypeMap = new HashMap<>();
+ dictList.forEach(dict -> {
+ optypeMap.put(dict.getValue(),dict.getCode());
+ });
+ Map personParams = new HashMap<>();
+ personParams.put("operation","editUserData");
+ personParams.put("accountNumber",globalValue.accountNumber);
+ personParams.put("passKey", KeysEntity.passKey);
+ personParams.put("empowerText",KeysEntity.empowerText);
+ JSONArray jsonArray = new JSONArray();
+ Map student = new HashMap<>();
+ student.put("objectUuid",String.valueOf(entity.getPersonId()));
+ student.put("userCode",entity.getRyid());
+ student.put("userName",entity.getName());
+ student.put("userType",optypeMap.get(entity.getLabelName()));
+ student.put("studentType","0"+entity.getLabelId());
+ student.put("gender",entity.getGender()==0?"WOMAN":"MAN");
+ student.put("cardNumber","");
+ student.put("idCard",entity.getIdCard());
+ student.put("fileUrl",imagBaseUrl+"/"+bucketName+"/"+entity.getOrgImage());
+ student.put("fileName",entity.getOrgImage().substring(entity.getOrgImage().lastIndexOf("/")));
+ jsonArray.add(student);
+ personParams.put("dataInfo",jsonArray);
+ JSONObject jsonObject = opFeignClient.submitData(personParams);
+ if(!jsonObject.getString("shrgStatus").equals("S")) {
+ log.error(jsonObject.toJSONString());
+ return jsonObject.getString("shrgMsg");
+ }
+ if(!jsonObject.getJSONArray("errInfo").isEmpty()) {
+ log.error(jsonObject.toJSONString());
+ return jsonObject.getJSONArray("errInfo").toJSONString();
+ }
}
- List dictList = sysDictService.queryByType("optype");
- Map optypeMap = new HashMap<>();
- dictList.forEach(dict -> {
- optypeMap.put(dict.getValue(),dict.getCode());
- });
- Map personParams = new HashMap<>();
- personParams.put("operation","editUserData");
- personParams.put("accountNumber",globalValue.accountNumber);
- personParams.put("passKey", KeysEntity.passKey);
- personParams.put("empowerText",KeysEntity.empowerText);
- JSONArray jsonArray = new JSONArray();
- Map student = new HashMap<>();
- student.put("objectUuid",String.valueOf(entity.getPersonId()));
- student.put("userCode",entity.getRyid());
- student.put("userName",entity.getName());
- student.put("userType",optypeMap.get(entity.getLabelName()));
- student.put("studentType","0"+entity.getLabelId());
- student.put("gender",entity.getGender()==0?"WOMAN":"MAN");
- student.put("cardNumber","");
- student.put("idCard",entity.getIdCard());
- student.put("fileUrl",imagBaseUrl+"/"+bucketName+"/"+entity.getOrgImage());
- student.put("fileName",entity.getOrgImage().substring(entity.getOrgImage().lastIndexOf("/")));
- jsonArray.add(student);
- personParams.put("dataInfo",jsonArray);
- JSONObject jsonObject = opFeignClient.submitData(personParams);
- if(!jsonObject.getString("shrgStatus").equals("S")) {
- log.error(jsonObject.toJSONString());
- }
- if(!jsonObject.getJSONArray("errInfo").isEmpty()) {
- log.error(jsonObject.toJSONString());
- }
- return 0;
+
}
- return 1;
+ //删除临时文件oss
+ try {
+ minioClient.removeObject(minioConfig.getBucketName(), tempOrgImageFile);
+ } catch (Exception e) {
+ return "删除失败";
+ }
+
+ return null;
}
@@ -2527,4 +2538,9 @@ public class TenPersonServiceImpl implements TenPersonService {
IPage page = tenPersonDao.getByPersonIds(pageParam, list,cellId);
return new PageUtils(page);
}
+
+ @Override
+ public List listPage(int start, int count, String cellId) {
+ return tenPersonDao.listPage(start, count, cellId);
+ }
}
diff --git a/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenRecordServiceImpl.java b/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenRecordServiceImpl.java
index 9ff9960..a8bb0c4 100644
--- a/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenRecordServiceImpl.java
+++ b/shapelight-admin/src/main/java/net/shapelight/modules/ten/service/impl/TenRecordServiceImpl.java
@@ -482,8 +482,27 @@ public class TenRecordServiceImpl implements TenRecordService {
pageParam.setCurrent(Long.parseLong((String) params.get("page")));
pageParam.setSize(Long.parseLong((String) params.get("limit")));
List list = (List) params.get("personIds");
- Long cellId = Long.parseLong(params.get("cellId").toString());
- IPage page = tenRecordDao.getByPersonIds(pageParam,params);
+ Long cellId = Long.parseLong(params.get("tenantId").toString());
+ int during = Integer.parseInt((String)params.get("during"));
+ String recordTimeStart = null;
+ String recordTimeEnd = null;
+ if(during == 0){ //当天
+ recordTimeStart = MyDateUtils.getCurrentDayStartTime();
+ recordTimeEnd = MyDateUtils.getCurrentDayEndTime();
+ }else if(during == 1){ //本周
+ recordTimeStart = MyDateUtils.getCurrentWeekStartTime();
+ recordTimeEnd = MyDateUtils.getCurrentWeekEndTime();
+ }else if(during == 2){ //本月
+ recordTimeStart = MyDateUtils.getCurrentMonthStartTime();
+ recordTimeEnd = MyDateUtils.getCurrentMonthEndTime();
+ }
+ params.put("recordTimeStart",recordTimeStart);
+ params.put("recordTimeEnd",recordTimeEnd);
+ IPage page = tenRecordDao.getByPersonIds(pageParam,params);
+ page.getRecords().forEach(item-> {
+ TenPersonEntity person = tenPersonService.getById(item.getPersonId(),item.getCellId());
+ item.setPerson(person);
+ });
return new PageUtils(page);
}
}
diff --git a/shapelight-admin/src/main/resources/application.yml b/shapelight-admin/src/main/resources/application.yml
index ca7f46a..261b9c3 100644
--- a/shapelight-admin/src/main/resources/application.yml
+++ b/shapelight-admin/src/main/resources/application.yml
@@ -133,6 +133,19 @@ shapelight:
# token有效时长,180天,单位秒
#expire: 15552000
header: token
+# sdk配置---------------------------------------
+config:
+ arcface-sdk:
+ version: 4.1
+ app-id: SUQLGn78W5o7StEEbm6WTTfaMgAxSsN8HwJziApVyNN
+ sdk-key: 7dJ9RqEhc3mPCatuUceKjgYwRR6QtyMsxLUiL7JYAkrt
+ active-key: 82K1-11TT-K136-FFVW
+ active-file:
+ detect-pool-size: 16
+ compare-pool-size: 16
+ rec-face-thd: 0.8
+ rec-id-thd: 0.5
+
#mybatis
diff --git a/shapelight-admin/src/main/resources/libs/4.1/WIN64/libarcsoft_face.dll b/shapelight-admin/src/main/resources/libs/4.1/WIN64/libarcsoft_face.dll
new file mode 100644
index 0000000..d0a4c97
Binary files /dev/null and b/shapelight-admin/src/main/resources/libs/4.1/WIN64/libarcsoft_face.dll differ
diff --git a/shapelight-admin/src/main/resources/libs/4.1/WIN64/libarcsoft_face_engine.dll b/shapelight-admin/src/main/resources/libs/4.1/WIN64/libarcsoft_face_engine.dll
new file mode 100644
index 0000000..db65b00
Binary files /dev/null and b/shapelight-admin/src/main/resources/libs/4.1/WIN64/libarcsoft_face_engine.dll differ
diff --git a/shapelight-admin/src/main/resources/libs/4.1/WIN64/libarcsoft_face_engine_jni.dll b/shapelight-admin/src/main/resources/libs/4.1/WIN64/libarcsoft_face_engine_jni.dll
new file mode 100644
index 0000000..0266b32
Binary files /dev/null and b/shapelight-admin/src/main/resources/libs/4.1/WIN64/libarcsoft_face_engine_jni.dll differ
diff --git a/shapelight-admin/src/main/resources/mapper/ten/TenPersonDao.xml b/shapelight-admin/src/main/resources/mapper/ten/TenPersonDao.xml
index 01cf4a3..85d86f7 100644
--- a/shapelight-admin/src/main/resources/mapper/ten/TenPersonDao.xml
+++ b/shapelight-admin/src/main/resources/mapper/ten/TenPersonDao.xml
@@ -1333,5 +1333,12 @@
+
+
diff --git a/shapelight-admin/src/main/resources/mapper/ten/TenRecordDao.xml b/shapelight-admin/src/main/resources/mapper/ten/TenRecordDao.xml
index 3c837b1..d12a8af 100644
--- a/shapelight-admin/src/main/resources/mapper/ten/TenRecordDao.xml
+++ b/shapelight-admin/src/main/resources/mapper/ten/TenRecordDao.xml
@@ -639,14 +639,22 @@