From 67dca0d4d43e2776348ba4d1241aeaa98f76756b Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Sat, 5 Apr 2025 13:21:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=BA=E8=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ycwl/basic/facebody/FaceBodyFactory.java | 59 ++++ .../facebody/adapter/AliFaceBodyAdapter.java | 333 ++++++++++++++++++ .../facebody/adapter/IFaceBodyAdapter.java | 29 ++ .../basic/facebody/entity/AddFaceResp.java | 8 + .../facebody/entity/AliFaceBodyConfig.java | 10 + .../basic/facebody/entity/SearchFaceResp.java | 13 + .../facebody/entity/SearchFaceResultItem.java | 12 + .../facebody/enums/FaceBodyAdapterType.java | 17 + .../exceptions/FaceBodyException.java | 7 + .../FaceBodyUnsupportedException.java | 7 + .../starter/FaceBodyAutoConfiguration.java | 32 ++ .../starter/config/FaceBodyConfig.java | 13 + .../starter/config/OverallFaceBodyConfig.java | 15 + src/main/resources/application-dev.yml | 15 +- src/main/resources/application-prod.yml | 22 +- 15 files changed, 579 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/ycwl/basic/facebody/FaceBodyFactory.java create mode 100644 src/main/java/com/ycwl/basic/facebody/adapter/AliFaceBodyAdapter.java create mode 100644 src/main/java/com/ycwl/basic/facebody/adapter/IFaceBodyAdapter.java create mode 100644 src/main/java/com/ycwl/basic/facebody/entity/AddFaceResp.java create mode 100644 src/main/java/com/ycwl/basic/facebody/entity/AliFaceBodyConfig.java create mode 100644 src/main/java/com/ycwl/basic/facebody/entity/SearchFaceResp.java create mode 100644 src/main/java/com/ycwl/basic/facebody/entity/SearchFaceResultItem.java create mode 100644 src/main/java/com/ycwl/basic/facebody/enums/FaceBodyAdapterType.java create mode 100644 src/main/java/com/ycwl/basic/facebody/exceptions/FaceBodyException.java create mode 100644 src/main/java/com/ycwl/basic/facebody/exceptions/FaceBodyUnsupportedException.java create mode 100644 src/main/java/com/ycwl/basic/facebody/starter/FaceBodyAutoConfiguration.java create mode 100644 src/main/java/com/ycwl/basic/facebody/starter/config/FaceBodyConfig.java create mode 100644 src/main/java/com/ycwl/basic/facebody/starter/config/OverallFaceBodyConfig.java diff --git a/src/main/java/com/ycwl/basic/facebody/FaceBodyFactory.java b/src/main/java/com/ycwl/basic/facebody/FaceBodyFactory.java new file mode 100644 index 0000000..811f79b --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/FaceBodyFactory.java @@ -0,0 +1,59 @@ +package com.ycwl.basic.facebody; + +import com.ycwl.basic.facebody.adapter.AliFaceBodyAdapter; +import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter; +import com.ycwl.basic.facebody.enums.FaceBodyAdapterType; +import com.ycwl.basic.facebody.exceptions.FaceBodyUnsupportedException; +import com.ycwl.basic.storage.exceptions.StorageConfigException; +import com.ycwl.basic.storage.exceptions.StorageUndefinedException; + +import java.util.HashMap; +import java.util.Map; + +public class FaceBodyFactory { + public static IFaceBodyAdapter getAdapter(String typeName) { + FaceBodyAdapterType adapterEnum; + try { + adapterEnum = FaceBodyAdapterType.valueOf(typeName); + } catch (Exception e) { + throw new FaceBodyUnsupportedException("不支持的Adapter类型"); + } + return getAdapter(adapterEnum); + } + + public static IFaceBodyAdapter getAdapter(FaceBodyAdapterType type) { + switch (type) { + case ALI: + return new AliFaceBodyAdapter(); + default: + throw new FaceBodyUnsupportedException("不支持的Adapter类型"); + } + } + + + protected static Map namedAdapter = new HashMap<>(); + protected static IFaceBodyAdapter defaultAdapter = null; + + public static void register(String name, IFaceBodyAdapter adapter) { + namedAdapter.put(name, adapter); + } + + public static IFaceBodyAdapter use(String name) { + IFaceBodyAdapter adapter = namedAdapter.get(name); + if (adapter == null) { + throw new StorageUndefinedException("未定义的存储方式:"+name); + } + return adapter; + } + + public static IFaceBodyAdapter use() { + if (defaultAdapter == null) { + throw new StorageConfigException("未定义默认存储方式"); + } + return defaultAdapter; + } + + public static void setDefault(String defaultName) { + FaceBodyFactory.defaultAdapter = use(defaultName); + } +} diff --git a/src/main/java/com/ycwl/basic/facebody/adapter/AliFaceBodyAdapter.java b/src/main/java/com/ycwl/basic/facebody/adapter/AliFaceBodyAdapter.java new file mode 100644 index 0000000..a969fa4 --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/adapter/AliFaceBodyAdapter.java @@ -0,0 +1,333 @@ +package com.ycwl.basic.facebody.adapter; + +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.exceptions.ClientException; +import com.aliyuncs.facebody.model.v20191230.AddFaceEntityRequest; +import com.aliyuncs.facebody.model.v20191230.AddFaceRequest; +import com.aliyuncs.facebody.model.v20191230.AddFaceResponse; +import com.aliyuncs.facebody.model.v20191230.CreateFaceDbRequest; +import com.aliyuncs.facebody.model.v20191230.DeleteFaceDbRequest; +import com.aliyuncs.facebody.model.v20191230.DeleteFaceEntityRequest; +import com.aliyuncs.facebody.model.v20191230.ListFaceDbsRequest; +import com.aliyuncs.facebody.model.v20191230.ListFaceDbsResponse; +import com.aliyuncs.facebody.model.v20191230.ListFaceEntitiesRequest; +import com.aliyuncs.facebody.model.v20191230.ListFaceEntitiesResponse; +import com.aliyuncs.facebody.model.v20191230.SearchFaceRequest; +import com.aliyuncs.facebody.model.v20191230.SearchFaceResponse; +import com.aliyuncs.profile.DefaultProfile; +import com.ycwl.basic.facebody.entity.AddFaceResp; +import com.ycwl.basic.facebody.entity.AliFaceBodyConfig; +import com.ycwl.basic.facebody.entity.SearchFaceResp; +import com.ycwl.basic.facebody.entity.SearchFaceResultItem; +import com.ycwl.basic.ratelimiter.FixedRateLimiter; +import com.ycwl.basic.ratelimiter.IRateLimiter; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +@Slf4j +public class AliFaceBodyAdapter implements IFaceBodyAdapter { + private static final Map addEntityLimiters = new ConcurrentHashMap<>(); + private static final Map addFaceLimiters = new ConcurrentHashMap<>(); + private static final Map searchFaceLimiters = new ConcurrentHashMap<>(); + private static final Map addDbLimiters = new ConcurrentHashMap<>(); + private static final Map deleteDbLimiters = new ConcurrentHashMap<>(); + private static final Map deleteEntityLimiters = new ConcurrentHashMap<>(); + + private AliFaceBodyConfig config; + + public boolean setConfig(AliFaceBodyConfig config) { + this.config = config; + return true; + } + + @Override + public boolean loadConfig(Map _config) { + AliFaceBodyConfig config = new AliFaceBodyConfig(); + config.setAccessKeyId(_config.get("accessKeyId")); + config.setAccessKeySecret(_config.get("accessKeySecret")); + config.setRegion(_config.get("region")); + this.config = config; + return true; + } + + private IRateLimiter getLimiter(LOCK_TYPE type) { + switch (type) { + case ADD_DB: + if (addDbLimiters.get(config.getAccessKeyId()) == null) { + addDbLimiters.put(config.getAccessKeyId(), new FixedRateLimiter(600, TimeUnit.MILLISECONDS)); + } + return addDbLimiters.get(config.getAccessKeyId()); + case ADD_ENTITY: + if (addEntityLimiters.get(config.getAccessKeyId()) == null) { + addEntityLimiters.put(config.getAccessKeyId(), new FixedRateLimiter(600, TimeUnit.MILLISECONDS)); + } + return addEntityLimiters.get(config.getAccessKeyId()); + case ADD_FACE: + if (addFaceLimiters.get(config.getAccessKeyId()) == null) { + addFaceLimiters.put(config.getAccessKeyId(), new FixedRateLimiter(600, TimeUnit.MILLISECONDS)); + } + return addFaceLimiters.get(config.getAccessKeyId()); + case SEARCH_FACE: + if (searchFaceLimiters.get(config.getAccessKeyId()) == null) { + searchFaceLimiters.put(config.getAccessKeyId(), new FixedRateLimiter(200, TimeUnit.MILLISECONDS)); + } + return searchFaceLimiters.get(config.getAccessKeyId()); + case DELETE_DB: + if (deleteDbLimiters.get(config.getAccessKeyId()) == null) { + deleteDbLimiters.put(config.getAccessKeyId(), new FixedRateLimiter(600, TimeUnit.MILLISECONDS)); + } + return deleteDbLimiters.get(config.getAccessKeyId()); + case DELETE_ENTITY: + if (deleteEntityLimiters.get(config.getAccessKeyId()) == null) { + deleteEntityLimiters.put(config.getAccessKeyId(), new FixedRateLimiter(600, TimeUnit.MILLISECONDS)); + } + return deleteEntityLimiters.get(config.getAccessKeyId()); + default: + return new FixedRateLimiter(600, TimeUnit.MILLISECONDS); + } + } + + @Override + public boolean addFaceDb(String dbName) { + IRateLimiter addDbLimiter = getLimiter(LOCK_TYPE.ADD_DB); + try (ClientWrapper clientWrapper = getClient()) { + IAcsClient client = clientWrapper.getClient(); + CreateFaceDbRequest request = new CreateFaceDbRequest(); + request.setName(dbName); + try { + addDbLimiter.acquire(); + } catch (InterruptedException ignored) { + } + client.getAcsResponse(request); + return true; + } catch (ClientException e) { + log.error("阿里云添加人脸数据库失败!", e); + return false; + } + } + + @Override + public boolean deleteFaceDb(String dbName) { + ListFaceEntitiesRequest request = new ListFaceEntitiesRequest(); + IRateLimiter deleteEntityLimiter = getLimiter(LOCK_TYPE.DELETE_ENTITY); + IRateLimiter deleteDbLimiter = getLimiter(LOCK_TYPE.DELETE_DB); + request.setDbName(dbName); + request.setLimit(200); + try (ClientWrapper clientWrapper = getClient()) { + IAcsClient client = clientWrapper.getClient(); + while (true) { + ListFaceEntitiesResponse response = client.getAcsResponse(request); + if (response.getData().getTotalCount() == 0) { + break; + } + response.getData().getEntities().forEach(entity -> { + DeleteFaceEntityRequest deleteFaceEntityRequest = new DeleteFaceEntityRequest(); + deleteFaceEntityRequest.setDbName(entity.getDbName()); + deleteFaceEntityRequest.setEntityId(entity.getEntityId()); + try { + deleteEntityLimiter.acquire(); + } catch (InterruptedException ignored) { + } + try { + client.getAcsResponse(deleteFaceEntityRequest); + } catch (ClientException e) { + log.error("删除人脸数据失败!", e); + } + }); + } + DeleteFaceDbRequest deleteFaceDbRequest = new DeleteFaceDbRequest(); + deleteFaceDbRequest.setName(dbName); + try { + deleteDbLimiter.acquire(); + } catch (InterruptedException ignored) { + } + client.getAcsResponse(deleteFaceDbRequest); + } catch (ClientException e) { + log.error("删除人脸数据库失败!", e); + return false; + } + return true; + } + + @Override + public List listFaceDb() { + ListFaceDbsRequest request = new ListFaceDbsRequest(); + try (ClientWrapper clientWrapper = getClient()) { + IAcsClient client = clientWrapper.getClient(); + ListFaceDbsResponse response = client.getAcsResponse(request); + return response.getData().getDbList().stream().map(ListFaceDbsResponse.Data.DbListItem::getName).collect(Collectors.toList()); + } catch (ClientException e) { + log.error("获取人脸数据库失败!", e); + return null; + } + } + + @Override + public AddFaceResp addFace(String dbName, String entityId, String faceUrl, String extData) { + IRateLimiter addEntityLimiter = getLimiter(LOCK_TYPE.ADD_ENTITY); + IRateLimiter addFaceLimiter = getLimiter(LOCK_TYPE.ADD_FACE); + AddFaceEntityRequest request = new AddFaceEntityRequest(); + request.setDbName(dbName); + request.setEntityId(entityId); + try (ClientWrapper clientWrapper = getClient()) { + IAcsClient client = clientWrapper.getClient(); + try { + addEntityLimiter.acquire(); + } catch (InterruptedException ignored) { + } + try { + client.getAcsResponse(request); + } catch (ClientException e) { + log.error("addFaceEntity, {}/{}", dbName, entityId, e); + return null; + } + AddFaceRequest addFaceRequest = new AddFaceRequest(); + addFaceRequest.setDbName(dbName); + addFaceRequest.setEntityId(entityId); + addFaceRequest.setImageUrl(faceUrl); + addFaceRequest.setExtraData(extData); + AddFaceResp respVo = new AddFaceResp(); + try { + addFaceLimiter.acquire(); + } catch (InterruptedException ignored) { + } + try { + AddFaceResponse acsResponse = client.getAcsResponse(addFaceRequest); + respVo.setScore(acsResponse.getData().getQualitieScore()); + return respVo; + } catch (ClientException e) { + log.error("addFace, {}/{}", dbName, entityId, e); + return null; + } + } + } + + @Override + public boolean deleteFace(String dbName, String entityId) { + IRateLimiter deleteEntityLimiter = getLimiter(LOCK_TYPE.DELETE_ENTITY); + DeleteFaceEntityRequest request = new DeleteFaceEntityRequest(); + request.setDbName(dbName); + request.setEntityId(entityId); + try (ClientWrapper clientWrapper = getClient()) { + IAcsClient client = clientWrapper.getClient(); + try { + deleteEntityLimiter.acquire(); + } catch (InterruptedException ignored) { + } + try { + client.getAcsResponse(request); + return true; + } catch (ClientException e) { + log.error("删除人脸数据失败!", e); + return false; + } + } + } + + @Override + public List listFace(String dbName, String prefix, Integer offset, Integer size) { + ListFaceEntitiesRequest listFaceEntitiesRequest = new ListFaceEntitiesRequest(); + listFaceEntitiesRequest.setDbName(dbName); + listFaceEntitiesRequest.setOrder("asc"); + if (offset != null) { + listFaceEntitiesRequest.setOffset(offset); + } + if (size != null) { + listFaceEntitiesRequest.setLimit(size); + } else { + listFaceEntitiesRequest.setLimit(200); + } + listFaceEntitiesRequest.setEntityIdPrefix(prefix); + try (ClientWrapper clientWrapper = getClient()) { + IAcsClient client = clientWrapper.getClient(); + try { + ListFaceEntitiesResponse response = client.getAcsResponse(listFaceEntitiesRequest); + return response.getData().getEntities().stream().map(ListFaceEntitiesResponse.Data.Entity::getEntityId).collect(Collectors.toList()); + } catch (ClientException e) { + log.error("获取人脸数据失败!", e); + return null; + } + } + } + + @Override + public SearchFaceResp searchFace(String dbName, String faceUrl) { + SearchFaceResp resp = new SearchFaceResp(); + IRateLimiter searchFaceLimiter = getLimiter(LOCK_TYPE.SEARCH_FACE); + try (ClientWrapper clientWrapper = getClient()) { + IAcsClient client = clientWrapper.getClient(); + SearchFaceRequest request = new SearchFaceRequest(); + request.setDbName(dbName); + request.setImageUrl(faceUrl); + request.setLimit(100); + try { + searchFaceLimiter.acquire(); + } catch (InterruptedException ignored) { + } + try { + SearchFaceResponse response = client.getAcsResponse(request); + List matchList = response.getData().getMatchList(); + if (matchList.isEmpty()) { + return resp; + } + SearchFaceResponse.Data.MatchListItem matchItem = matchList.get(0); + resp.setOriginalFaceScore(matchItem.getQualitieScore()); + resp.setResult(matchItem.getFaceItems().stream().map(item -> { + SearchFaceResultItem resultItem = new SearchFaceResultItem(); + resultItem.setDbName(dbName); + resultItem.setFaceId(item.getFaceId()); + resultItem.setExtData(item.getExtraData()); + resultItem.setScore(item.getScore()); + return resultItem; + }).collect(Collectors.toList())); + if (!resp.getResult().isEmpty()) { + resp.setFirstMatchRate(resp.getResult().get(0).getScore()); + } + return resp; + } catch (ClientException e) { + log.error("搜索人脸失败!", e); + return null; + } + } + } + + public ClientWrapper getClient() { + DefaultProfile profile = DefaultProfile.getProfile( + config.getRegion(), config.getAccessKeyId(), config.getAccessKeySecret()); + IAcsClient client = new DefaultAcsClient(profile); + return new ClientWrapper(client); + } + + @Getter + public static class ClientWrapper implements AutoCloseable { + private final IAcsClient client; + + public ClientWrapper(IAcsClient client) { + this.client = client; + } + + @Override + public void close() { + if (client == null) { + return; + } + client.shutdown(); + } + + } + protected enum LOCK_TYPE { + ADD_DB, + ADD_ENTITY, + ADD_FACE, + SEARCH_FACE, + DELETE_DB, + DELETE_ENTITY, + } +} diff --git a/src/main/java/com/ycwl/basic/facebody/adapter/IFaceBodyAdapter.java b/src/main/java/com/ycwl/basic/facebody/adapter/IFaceBodyAdapter.java new file mode 100644 index 0000000..5451440 --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/adapter/IFaceBodyAdapter.java @@ -0,0 +1,29 @@ +package com.ycwl.basic.facebody.adapter; + +import com.ycwl.basic.facebody.entity.AddFaceResp; +import com.ycwl.basic.facebody.entity.SearchFaceResp; + +import java.util.List; +import java.util.Map; + +public interface IFaceBodyAdapter { + boolean loadConfig(Map _config); + + default boolean assureFaceDb(String dbName) { + List faceDbs = listFaceDb(); + return faceDbs.contains(dbName) || addFaceDb(dbName); + } + + boolean addFaceDb(String dbName); + boolean deleteFaceDb(String dbName); + + List listFaceDb(); + + AddFaceResp addFace(String dbName, String entityId, String faceUrl, String extData); + + boolean deleteFace(String dbName, String entityId); + + List listFace(String dbName, String prefix, Integer offset, Integer size); + + SearchFaceResp searchFace(String dbName, String faceUrl); +} diff --git a/src/main/java/com/ycwl/basic/facebody/entity/AddFaceResp.java b/src/main/java/com/ycwl/basic/facebody/entity/AddFaceResp.java new file mode 100644 index 0000000..7428e69 --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/entity/AddFaceResp.java @@ -0,0 +1,8 @@ +package com.ycwl.basic.facebody.entity; + +import lombok.Data; + +@Data +public class AddFaceResp { + private Float score; +} diff --git a/src/main/java/com/ycwl/basic/facebody/entity/AliFaceBodyConfig.java b/src/main/java/com/ycwl/basic/facebody/entity/AliFaceBodyConfig.java new file mode 100644 index 0000000..ff59c36 --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/entity/AliFaceBodyConfig.java @@ -0,0 +1,10 @@ +package com.ycwl.basic.facebody.entity; + +import lombok.Data; + +@Data +public class AliFaceBodyConfig { + private String accessKeyId; + private String accessKeySecret; + private String region; +} diff --git a/src/main/java/com/ycwl/basic/facebody/entity/SearchFaceResp.java b/src/main/java/com/ycwl/basic/facebody/entity/SearchFaceResp.java new file mode 100644 index 0000000..2c46bae --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/entity/SearchFaceResp.java @@ -0,0 +1,13 @@ +package com.ycwl.basic.facebody.entity; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class SearchFaceResp { + private Float originalFaceScore; + private List result = new ArrayList<>(); + private Float firstMatchRate; +} diff --git a/src/main/java/com/ycwl/basic/facebody/entity/SearchFaceResultItem.java b/src/main/java/com/ycwl/basic/facebody/entity/SearchFaceResultItem.java new file mode 100644 index 0000000..c86fedb --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/entity/SearchFaceResultItem.java @@ -0,0 +1,12 @@ +package com.ycwl.basic.facebody.entity; + +import lombok.Data; + +@Data +public class SearchFaceResultItem { + private String dbName; + private String faceId; + private String extData; + /** 置信度,0~1 */ + private Float score; +} diff --git a/src/main/java/com/ycwl/basic/facebody/enums/FaceBodyAdapterType.java b/src/main/java/com/ycwl/basic/facebody/enums/FaceBodyAdapterType.java new file mode 100644 index 0000000..5cbd180 --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/enums/FaceBodyAdapterType.java @@ -0,0 +1,17 @@ +package com.ycwl.basic.facebody.enums; + +import lombok.Getter; + +@Getter +public enum FaceBodyAdapterType { + ALI("ALI") + ; + + private final String code; + + FaceBodyAdapterType(String code) { + this.code = code; + } + + +} diff --git a/src/main/java/com/ycwl/basic/facebody/exceptions/FaceBodyException.java b/src/main/java/com/ycwl/basic/facebody/exceptions/FaceBodyException.java new file mode 100644 index 0000000..459f2d0 --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/exceptions/FaceBodyException.java @@ -0,0 +1,7 @@ +package com.ycwl.basic.facebody.exceptions; + +public class FaceBodyException extends RuntimeException { + public FaceBodyException(String message) { + super(message); + } +} diff --git a/src/main/java/com/ycwl/basic/facebody/exceptions/FaceBodyUnsupportedException.java b/src/main/java/com/ycwl/basic/facebody/exceptions/FaceBodyUnsupportedException.java new file mode 100644 index 0000000..1963014 --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/exceptions/FaceBodyUnsupportedException.java @@ -0,0 +1,7 @@ +package com.ycwl.basic.facebody.exceptions; + +public class FaceBodyUnsupportedException extends RuntimeException { + public FaceBodyUnsupportedException(String message) { + super(message); + } +} diff --git a/src/main/java/com/ycwl/basic/facebody/starter/FaceBodyAutoConfiguration.java b/src/main/java/com/ycwl/basic/facebody/starter/FaceBodyAutoConfiguration.java new file mode 100644 index 0000000..d8a49dd --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/starter/FaceBodyAutoConfiguration.java @@ -0,0 +1,32 @@ +package com.ycwl.basic.facebody.starter; + +import com.ycwl.basic.facebody.FaceBodyFactory; +import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter; +import com.ycwl.basic.facebody.starter.config.FaceBodyConfig; +import com.ycwl.basic.facebody.starter.config.OverallFaceBodyConfig; +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FaceBodyAutoConfiguration { + private final OverallFaceBodyConfig config; + public FaceBodyAutoConfiguration(OverallFaceBodyConfig config) { + this.config = config; + if (config != null) { + if (config.getConfigs() != null) { + loadConfig(); + } + if (StringUtils.isNotBlank(config.getDefaultUse())) { + FaceBodyFactory.setDefault(config.getDefaultUse()); + } + } + } + + private void loadConfig() { + for (FaceBodyConfig item : config.getConfigs()) { + IFaceBodyAdapter adapter = FaceBodyFactory.getAdapter(item.getType()); + adapter.loadConfig(item.getConfig()); + FaceBodyFactory.register(item.getName(), adapter); + } + } +} diff --git a/src/main/java/com/ycwl/basic/facebody/starter/config/FaceBodyConfig.java b/src/main/java/com/ycwl/basic/facebody/starter/config/FaceBodyConfig.java new file mode 100644 index 0000000..2196b94 --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/starter/config/FaceBodyConfig.java @@ -0,0 +1,13 @@ +package com.ycwl.basic.facebody.starter.config; + +import com.ycwl.basic.facebody.enums.FaceBodyAdapterType; +import lombok.Data; + +import java.util.Map; + +@Data +public class FaceBodyConfig { + private String name; + private FaceBodyAdapterType type; + private Map config; +} diff --git a/src/main/java/com/ycwl/basic/facebody/starter/config/OverallFaceBodyConfig.java b/src/main/java/com/ycwl/basic/facebody/starter/config/OverallFaceBodyConfig.java new file mode 100644 index 0000000..7772603 --- /dev/null +++ b/src/main/java/com/ycwl/basic/facebody/starter/config/OverallFaceBodyConfig.java @@ -0,0 +1,15 @@ +package com.ycwl.basic.facebody.starter.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@ConfigurationProperties(prefix = "facebody") +@Data +public class OverallFaceBodyConfig { + private String defaultUse; + private List configs; +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index c77db07..20703da 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -158,11 +158,16 @@ storage: prefix: "user-video/" url: "https://wsaiphoto.obs-cq.cucloud.cn" region: "obs-cq" -#阿里云人脸检测 -aliFace: - accessKeyId: "LTAI5tMwrmxVcUEKoH5QzLHx" - accessKeySecret: "ZCIP8aKx1jwX1wkeYIPQEDZ8fPtN1c" - region: "cn-shanghai" +#人脸检测 +facebody: + default-use: "zt" + configs: + - name: "zt" + type: ALI + config: + accessKeyId: "LTAI5tMwrmxVcUEKoH5QzLHx" + accessKeySecret: "ZCIP8aKx1jwX1wkeYIPQEDZ8fPtN1c" + region: "cn-shanghai" notify: defaultUse: "" diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index ff29ffc..3ddc212 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -34,15 +34,16 @@ spring: port: 6379 # 密码过于复杂需要使用''引起来,要不可能导致项目无法启动,因为无法识别特殊字符 password: '' - timeout: 1000 + timeout: 2000 # 配置用户头像存放静态资源文件夹 - resources: - static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ # 配置请求文件大小 servlet: multipart: max-file-size: 500MB max-request-size: 500MB + web: + resources: + static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ # MyBatis mybatis-plus: @@ -160,11 +161,16 @@ storage: url: "https://wsaiphoto.obs-cq.cucloud.cn" region: "obs-cq" -#阿里云人脸检测 -aliFace: - accessKeyId: "LTAI5tMwrmxVcUEKoH5QzLHx" - accessKeySecret: "ZCIP8aKx1jwX1wkeYIPQEDZ8fPtN1c" - region: "cn-shanghai" +#人脸检测 +facebody: + default-use: "zt" + configs: + - name: "zt" + type: ALI + config: + accessKeyId: "LTAI5tMwrmxVcUEKoH5QzLHx" + accessKeySecret: "ZCIP8aKx1jwX1wkeYIPQEDZ8fPtN1c" + region: "cn-shanghai" # 通知到人 notify: