Просмотр исходного кода

fix: 消费服务
1.新消费机接口
2.生成所有人的人脸特征数据
3.上传照片时同步生成人脸特征数据

luo.yibo@datuai.com 1 год назад
Родитель
Сommit
3d16690a15
15 измененных файлов с 203 добавлено и 42 удалено
  1. 1 1
      ArcFace64.dat
  2. 9 0
      ruoyi-api/ruoyi-api-consume/src/main/java/org/dromara/consume/api/RemoteConsumeService.java
  3. 8 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/api/ReturnResult.java
  4. 6 0
      ruoyi-modules/ruoyi-backstage/pom.xml
  5. 8 5
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/controller/PtUserAccountController.java
  6. 7 6
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/wx/service/impl/WxServiceImpl.java
  7. 97 10
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/ArcFaceBusiness.java
  8. 13 13
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/controller/v1/FaceCollectController.java
  9. 2 0
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/PtArcFaceFeature.java
  10. 4 1
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/bo/PtArcFaceFeatureBo.java
  11. 2 1
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/convert/YcFaceFeatureVoConvert.java
  12. 5 3
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/vo/PtArcFaceFeatureVo.java
  13. 5 0
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/vo/YcFaceFeatureVo.java
  14. 21 0
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/dubbo/RemoteConsumeServiceImpl.java
  15. 15 2
      ruoyi-server/ruoyi-server-consume/src/main/resources/mapper/consume/PtArcFaceFeatureMapper.xml

+ 1 - 1
ArcFace64.dat

@@ -1 +1 @@
-EWEPEPEOGMGTELIZJUGECKIUJDBCJTCNISGPBNHLJTJUBHEWGNAKGEGAIOHJDQAJGNCFDRFZJEDMJTGGFTAIBMBXGNJCCHAXDXHZILJMIACUGAGUCQAGAVILIXDAACGZERCWISFQGTGQEYDHCKESBCICFNDLDVGYFKAFIEFXAGGXCSFFCRIDCQIPISIRJBFTDAFJBAAAALFFEBHWGLIQJEBNHLFJBLBJCDETGKBLESHCAMEDCUADBTJQJHIAGRFCINHNHGGYBZEKBLDLCHCBDNJLAJFWECAHHXJRFYEDJMARCRFYGXAQGOJFJMJUJADQHCFDHPJNECHOCRILHVGMICEIBCGJJPCPBPHKGUBZAIGFCYJDGEHGIKFEGWANADGSHWHIELCPJAJUEMAGCDEGDYFZCHEWGWBOHNBJFRGJGMEXBFIADEJOAFFEADBNJUBFAMGACNDBGCCMEPHICYHCHWDZBGBRIRCBDCAAHVAPELHRASJCEAAWFMBBEUCVISGHDAEFDVGXCYBCAADSBAINFNFXEUFHFGGLJHELDMGUFRHBHKDQJSINIPEBABHNHAJMCGBYCEDUFHGDCOHFEKDPJBCKDGAKFNJEHTBNIPJUGNDLBUAYDBFQGMABHHIJDIGJFGGAIVIQIXGFGJJDJKAXAPGIJFBFBBIYGLGUEOJJDSJSHTIIIYHKHJCQBMECCLECGEHPINHAISBCCCFLFFDUGXBFDIGVFVDGBREMHAASDQEEAZDAFUALAHJIALHLFXCTDSBFJIFEDYGLINITEUAQGJBTIRELJIIIIFDRFCDJGEISAAGGDFAGABCSFCAPBLARIUEVDGDZFYEEHUEWIFERGZAMEDFYIZBRCADNGOBZDSBYHRBZGBJDFTCTFXCDIFFPGDFEBDJVIUGSEIHRBHDIBBEZBNBDBDFYGXCEBYHIEDETAVCBAMHQEAFMASDUDXHZGGFCGSEZIQHSCTILEGHJIJBDDAFGJMELDJIQHTFJDCCMDTCKFQFMFJDFEFGXJDIFJDDZFPFXBJJNHJFGHDANHVEFGUANIKBADHFSDFGSHBEYEMDZJAEXGTBDJNAPDVESCQDBEVETAWHIFKDDFRGMBTJPBKDDIZBTGPADHCHHJIADBIEYDUEVIHBEBKHXCYFHANALEUIUDSBHDOJMDEEFARBACLHQHQDQCBBDAEEEHAALES
+EWEPEPEOGMGTELIZJUGECKIUJDBCJTCNISGPBNHLJTJUBHEWGNAKGEGAIOHJDQAJGNCFDRFZJEDMJTGGFTAIBMBXGNJCCHAXDXHZILJMIACUGAGUCQAGAVILIXDAACGZERCWISFQGTGQEYDHCKESBCICFNDLDVGYFKAFIEFXAGGXCSFFCRIDCQIPISIRJBFTDAFJBAAAALFFEBHWGLIQJEBNHLFJBLBJCDETGKBLESHCAMEDCUADBTJQJHIAGRFCINHNHGGYBZEKBLDLCHCBDNJLAJFWECAHHXJRFYEDJMARCRFYGXAQGOJFJMJUJADQHCFDHPJNECHOCRILHVGMICEIBCGJJPCPBPHKGUBZAIGFCYJDGEHGIKFEGWANADGSHWHIELCPJAJUEMAGCDEGDYFZCHEWGWBOHNBJFRGJGMEXBFIADEJOAFFEADBNJUBFAMGACNDBGCCMEPHICYHCHWDZBGBRIRCBDCAAHVAPELHRASJCEAAWFMAFBHAEFCIPHIIPHHDFCYILIMAQFSEBCWFVJEHAACIUGJHSIJBKBPAOJCEKHKCNJIHAGLAIIRGBBJEPIPHRJDFEFYFGEUERHZECEZIMJOBGGQHKFCHCDEBOBAENHUDTJNCCCHFWCQBGHZAYGDILELIADOEDEEACAUAGAZEYCWBGEDAOEYDNHVJTGZHPEBJODFEDCFDNFQCOJSFJJOBJAEFIIMGVCQHAIQEOJGHYEWGAIZIJEKHTFKEAEOBZDWELHLAFBZGGDQCLAYIMALCKCJACEPIBETBJCSGJBEDKEYDBCDITFTIWIRJRJOGWHSIFCXAQHWCUGREQCFBWAUIODZEHFAGFDXECGIHUJAJVBEJLFOJFDIIZHGFLFCIFDZCQIZEXGQCFCGIBBTFYFBBWHYHAAQEUCUEQICFMCVBZHOENCIABCPFNJHDXBKBHHUBGFBDUCODLHAGVJAEEBPDYAAHPHDDHHAGXFKFABZCOIYAGGOCMHHFGAVEKJJAQICBUHVGPHPANCAJTCUFUEPJHEZCNBIDRISALBVHBCGGLIJBGIKGIAPBWHXGICCEIHGALBZCIBMIYFIIDFEGADHCRCPIGIVCADAJDCGILGIHQBUISCGHNCKDIDBGPJTGBFOBPFDIAJRIRHYDCAEFUHDEYFCDLFUFJHRBBCKAUAZCXGHDEAIGKIQJADYJDCA

+ 9 - 0
ruoyi-api/ruoyi-api-consume/src/main/java/org/dromara/consume/api/RemoteConsumeService.java

@@ -20,4 +20,13 @@ public interface RemoteConsumeService {
      * @return 处理结果
      * @return 处理结果
      */
      */
     R<ErrorInfo>  dealKafkaConsumeData(RemoteConsumeBo bo);
     R<ErrorInfo>  dealKafkaConsumeData(RemoteConsumeBo bo);
+
+    /**
+     * 创建特征数据一
+     *
+     * @param userId   用户ID
+     * @param photoUrl 照片URL
+     * @return 返回一个包含错误信息的响应对象,如果操作成功则data为null,如果失败则data包含具体的错误信息
+     */
+    R<ErrorInfo> createFeatureDataOne(Long userId, String photoUrl);
 }
 }

+ 8 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/api/ReturnResult.java

@@ -6,6 +6,8 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.NoArgsConstructor;
 import org.dromara.common.core.enums.ResultCodeEnum;
 import org.dromara.common.core.enums.ResultCodeEnum;
 
 
+import java.io.Serial;
+
 /**
 /**
  * @ClassName ReturnResult
  * @ClassName ReturnResult
  * @Description 通用返回结果
  * @Description 通用返回结果
@@ -19,6 +21,7 @@ import org.dromara.common.core.enums.ResultCodeEnum;
 @AllArgsConstructor
 @AllArgsConstructor
 @Data
 @Data
 public class ReturnResult implements IResult{
 public class ReturnResult implements IResult{
+    @Serial
     private static final long serialVersionUID = 874200365941306385L;
     private static final long serialVersionUID = 874200365941306385L;
 
 
     /**
     /**
@@ -41,6 +44,11 @@ public class ReturnResult implements IResult{
      */
      */
     private Object data;
     private Object data;
 
 
+    /**
+     * 当前时间戳
+     */
+    private Long currentTime = System.currentTimeMillis();
+
     /**
     /**
      * 返回成功
      * 返回成功
      * <p>
      * <p>

+ 6 - 0
ruoyi-modules/ruoyi-backstage/pom.xml

@@ -167,6 +167,12 @@
             <artifactId>arcsoft-sdk-face</artifactId>
             <artifactId>arcsoft-sdk-face</artifactId>
             <version>1.1.1.0</version>
             <version>1.1.1.0</version>
         </dependency>
         </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-consume</artifactId>
+            <version>2.2.0</version>
+            <scope>compile</scope>
+        </dependency>
 
 
 
 
     </dependencies>
     </dependencies>

+ 8 - 5
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/controller/PtUserAccountController.java

@@ -1,21 +1,19 @@
 package org.dromara.backstage.payment.controller;
 package org.dromara.backstage.payment.controller;
 
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.hutool.core.lang.UUID;
 import cn.hutool.core.lang.tree.Tree;
 import cn.hutool.core.lang.tree.Tree;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.annotation.DubboReference;
-import org.dromara.common.message.kafka.aop.annotation.SyncDataToLocal;
 import org.dromara.backstage.cardCenter.domain.bo.PtCardBo;
 import org.dromara.backstage.cardCenter.domain.bo.PtCardBo;
-import org.dromara.backstage.domain.vo.card.PtCardVo;
 import org.dromara.backstage.cardCenter.service.IPtCardService;
 import org.dromara.backstage.cardCenter.service.IPtCardService;
+import org.dromara.backstage.domain.vo.card.PtCardVo;
+import org.dromara.backstage.payment.domain.PtUserAccount4SelectVo;
 import org.dromara.backstage.payment.domain.bo.PtBagBo;
 import org.dromara.backstage.payment.domain.bo.PtBagBo;
 import org.dromara.backstage.payment.domain.bo.PtUserAccountBo;
 import org.dromara.backstage.payment.domain.bo.PtUserAccountBo;
 import org.dromara.backstage.payment.domain.vo.PtBagVo;
 import org.dromara.backstage.payment.domain.vo.PtBagVo;
-import org.dromara.backstage.payment.domain.PtUserAccount4SelectVo;
 import org.dromara.backstage.payment.domain.vo.PtUserAccountInfoVo;
 import org.dromara.backstage.payment.domain.vo.PtUserAccountInfoVo;
 import org.dromara.backstage.payment.domain.vo.PtUserAccountVo;
 import org.dromara.backstage.payment.domain.vo.PtUserAccountVo;
 import org.dromara.backstage.payment.service.IPtBagService;
 import org.dromara.backstage.payment.service.IPtBagService;
@@ -30,9 +28,11 @@ import org.dromara.common.excel.utils.ExcelUtil;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
 import org.dromara.common.log.annotation.Log;
 import org.dromara.common.log.annotation.Log;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.message.kafka.aop.annotation.SyncDataToLocal;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.common.web.core.BaseController;
+import org.dromara.consume.api.RemoteConsumeService;
 import org.dromara.system.api.RemoteDeptService;
 import org.dromara.system.api.RemoteDeptService;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.MediaType;
 import org.springframework.http.MediaType;
@@ -67,6 +67,9 @@ public class PtUserAccountController extends BaseController {
     @DubboReference
     @DubboReference
     private final RemoteDeptService remoteDeptService;
     private final RemoteDeptService remoteDeptService;
 
 
+    @DubboReference
+    private final RemoteConsumeService remoteConsumeService;
+
     @Value("${upload.upload-path}/")    // 文件上传路径
     @Value("${upload.upload-path}/")    // 文件上传路径
     private String uploadPath;
     private String uploadPath;
     @Value("${upload.image.user}/")     // 用户头像路径
     @Value("${upload.image.user}/")     // 用户头像路径
@@ -165,7 +168,7 @@ public class PtUserAccountController extends BaseController {
             //4.保存图片路径到数据库
             //4.保存图片路径到数据库
 //            String photoUrl = userPath + newFileName;
 //            String photoUrl = userPath + newFileName;
             ptUserAccountService.updateByBo(PtUserAccountBo.builder().userId(userId).photo(newFileName).build());
             ptUserAccountService.updateByBo(PtUserAccountBo.builder().userId(userId).photo(newFileName).build());
-
+            remoteConsumeService.createFeatureDataOne(userId, newFileName);
             return R.ok("上传图片成功");
             return R.ok("上传图片成功");
         }
         }
         return R.fail("上传图片异常,请联系管理员");
         return R.fail("上传图片异常,请联系管理员");

+ 7 - 6
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/wx/service/impl/WxServiceImpl.java

@@ -16,13 +16,11 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.time.DateFormatUtils;
 import org.apache.commons.lang3.time.DateFormatUtils;
-import org.dromara.backstage.business.payments.ThirdPayBusiness;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.backstage.cardCenter.domain.PtCard;
 import org.dromara.backstage.cardCenter.domain.PtCard;
 import org.dromara.backstage.cardCenter.mapper.PtCardMapper;
 import org.dromara.backstage.cardCenter.mapper.PtCardMapper;
-import org.dromara.backstage.config.ThirdPayConfig;
 import org.dromara.backstage.consumption.mapper.XfCreditAccountMapper;
 import org.dromara.backstage.consumption.mapper.XfCreditAccountMapper;
 import org.dromara.backstage.payment.domain.PtUserAccount;
 import org.dromara.backstage.payment.domain.PtUserAccount;
-import org.dromara.backstage.payment.domain.bo.PayOrderBo;
 import org.dromara.backstage.payment.domain.bo.PtUserAccountBo;
 import org.dromara.backstage.payment.domain.bo.PtUserAccountBo;
 import org.dromara.backstage.payment.domain.vo.PtUserAccountVo;
 import org.dromara.backstage.payment.domain.vo.PtUserAccountVo;
 import org.dromara.backstage.payment.mapper.PtUserAccountMapper;
 import org.dromara.backstage.payment.mapper.PtUserAccountMapper;
@@ -30,15 +28,13 @@ import org.dromara.backstage.wx.domain.vo.WxCreditAccountVo;
 import org.dromara.backstage.wx.service.FaceEngineService;
 import org.dromara.backstage.wx.service.FaceEngineService;
 import org.dromara.backstage.wx.service.IWxService;
 import org.dromara.backstage.wx.service.IWxService;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.domain.R;
-import org.dromara.common.core.enums.CreditTypeEnum;
-import org.dromara.common.core.enums.PayStatusEnum;
-import org.dromara.common.core.enums.PayStyleEnum;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.ByteArrayUtilByYC;
 import org.dromara.common.core.utils.ByteArrayUtilByYC;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtilsByYC;
 import org.dromara.common.core.utils.StringUtilsByYC;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.consume.api.RemoteConsumeService;
 import org.dromara.system.api.RemoteDictService;
 import org.dromara.system.api.RemoteDictService;
 import org.dromara.system.api.domain.vo.RemoteDictDataVo;
 import org.dromara.system.api.domain.vo.RemoteDictDataVo;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
@@ -70,6 +66,9 @@ public class WxServiceImpl implements IWxService {
     private final RemoteDictService dictService;
     private final RemoteDictService dictService;
     private final FaceEngineService faceEngineService;
     private final FaceEngineService faceEngineService;
 
 
+    @DubboReference
+    private final RemoteConsumeService remoteConsumeService;
+
     @Value("${upload.upload-path}/")    // 文件上传路径
     @Value("${upload.upload-path}/")    // 文件上传路径
     private String uploadPath;
     private String uploadPath;
     @Value("${upload.image.user}/")     // 用户头像路径
     @Value("${upload.image.user}/")     // 用户头像路径
@@ -234,6 +233,8 @@ public class WxServiceImpl implements IWxService {
         String photoUrl = userId + ".jpg";
         String photoUrl = userId + ".jpg";
         PtUserAccountBo bo = PtUserAccountBo.builder().userId(userId).photo(photoUrl).build();
         PtUserAccountBo bo = PtUserAccountBo.builder().userId(userId).photo(photoUrl).build();
         accountMapper.updateById(MapstructUtils.convert(bo, PtUserAccount.class));
         accountMapper.updateById(MapstructUtils.convert(bo, PtUserAccount.class));
+        // 生成人脸特征库
+        remoteConsumeService.createFeatureDataOne(userId, photoUrl);
     }
     }
     /**
     /**
      * 图片压缩
      * 图片压缩

+ 97 - 10
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/ArcFaceBusiness.java

@@ -5,9 +5,13 @@ import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.arcsoft.face.toolkit.ImageInfo;
 import com.arcsoft.face.toolkit.ImageInfo;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.backstage.api.RemoteUserAccountService;
 import org.dromara.backstage.api.RemoteUserAccountService;
 import org.dromara.backstage.api.domain.vo.RemoteUserAccountVo;
 import org.dromara.backstage.api.domain.vo.RemoteUserAccountVo;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.domain.model.ErrorInfo;
+import org.dromara.common.core.enums.ResultCodeEnum;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.server.consume.domain.bo.PtArcFaceFeatureBo;
 import org.dromara.server.consume.domain.bo.PtArcFaceFeatureBo;
 import org.dromara.server.consume.domain.vo.PtArcFaceFeatureVo;
 import org.dromara.server.consume.domain.vo.PtArcFaceFeatureVo;
@@ -20,8 +24,10 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import java.io.File;
 import java.io.File;
+import java.text.MessageFormat;
 import java.util.Date;
 import java.util.Date;
 import java.util.List;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 
 import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;
 import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;
 
 
@@ -37,19 +43,18 @@ import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;
  */
  */
 @RequiredArgsConstructor
 @RequiredArgsConstructor
 @Service
 @Service
+@Slf4j
 public class ArcFaceBusiness {
 public class ArcFaceBusiness {
-    @Value("${upload.upload-path}/")    // 文件上传路径
-    private String uploadPath;
-    @Value("${upload.image.user}/")     // 用户头像路径
-    private String userPath;
-
     private final IPtTermFaceVersionService termFaceVersionService;
     private final IPtTermFaceVersionService termFaceVersionService;
     private final IPtArcFaceFeatureService arcFaceFeatureService;
     private final IPtArcFaceFeatureService arcFaceFeatureService;
     private final IPtArcFaceKeyService arcFaceKeyService;
     private final IPtArcFaceKeyService arcFaceKeyService;
     private final FaceEngineService faceEngineService;
     private final FaceEngineService faceEngineService;
-
     @DubboReference
     @DubboReference
     private final RemoteUserAccountService remoteUserAccountService;
     private final RemoteUserAccountService remoteUserAccountService;
+    @Value("${upload.upload-path}/")    // 文件上传路径
+    private String uploadPath;
+    @Value("${upload.image.user}/")     // 用户头像路径
+    private String userPath;
 
 
     /**
     /**
      * 全量下载人脸特征数据
      * 全量下载人脸特征数据
@@ -96,7 +101,7 @@ public class ArcFaceBusiness {
 
 
         // 如果不存在或者已更新,则重新生成特征码
         // 如果不存在或者已更新,则重新生成特征码
         if (ObjectUtil.isEmpty(vo) || ObjectUtil.notEqual(photoUrl, vo.getPhotoUrl())) {
         if (ObjectUtil.isEmpty(vo) || ObjectUtil.notEqual(photoUrl, vo.getPhotoUrl())) {
-            String fileUrl = uploadPath + userPath +photoUrl;
+            String fileUrl = uploadPath + userPath + photoUrl;
             File imageFile = new File(fileUrl);
             File imageFile = new File(fileUrl);
             if (!imageFile.exists()) {
             if (!imageFile.exists()) {
                 return null;
                 return null;
@@ -123,6 +128,8 @@ public class ArcFaceBusiness {
         // 重新从数据中获取数据
         // 重新从数据中获取数据
         vo = arcFaceFeatureService.getOneFeatureDataUser(userId);
         vo = arcFaceFeatureService.getOneFeatureDataUser(userId);
         vo.setUserNo(accountVo.getUserNo().toString());
         vo.setUserNo(accountVo.getUserNo().toString());
+        vo.setUserNumb(accountVo.getUserNumb());
+        vo.setRealName(accountVo.getRealName());
         return MapstructUtils.convert(vo, YcFaceFeatureVo.class);
         return MapstructUtils.convert(vo, YcFaceFeatureVo.class);
     }
     }
 
 
@@ -158,12 +165,92 @@ public class ArcFaceBusiness {
         return termFaceVersionService.updateFaceVersionByTerm(termNo, versionTime);
         return termFaceVersionService.updateFaceVersionByTerm(termNo, versionTime);
     }
     }
 
 
-    public void createAllFeatureDataUser(){
+    /**
+     * 创建所有用户的人脸特征数据。
+     * 该方法会从远程用户账户服务获取所有用户账户信息,并为每个用户生成人脸特征数据。
+     * 如果用户的照片不为空,则尝试为其生成人脸特征码。此过程是并行执行的。
+     * 方法会统计总处理人数、成功人数和失败人数,并在完成后返回结果信息。
+     *
+     * @return 返回一个包含操作结果信息的R对象。如果没有任何需要生成人脸特征的人员,将返回相应的提示信息;
+     * 否则,返回生成特征码的结果摘要信息。
+     */
+    public R<Void> createAllFeatureDataUser() {
         List<RemoteUserAccountVo> userAccountVoList = remoteUserAccountService.getAllUserAccountVo();
         List<RemoteUserAccountVo> userAccountVoList = remoteUserAccountService.getAllUserAccountVo();
+        AtomicInteger totalCount = new AtomicInteger();
+        AtomicInteger okCount = new AtomicInteger();
+        AtomicInteger failCount = new AtomicInteger();
         if (CollectionUtil.isNotEmpty(userAccountVoList)) {
         if (CollectionUtil.isNotEmpty(userAccountVoList)) {
-            userAccountVoList.parallelStream().forEach(p->{
-                YcFaceFeatureVo vo = this.getOneFeatureDataUser(p.getUserId());
+            userAccountVoList.parallelStream().forEach(p -> {
+                if (ObjectUtil.isNotEmpty(p.getPhoto())) {
+                    totalCount.getAndIncrement();
+                    try {
+                        R<ErrorInfo> result = createFeatureDataOne(p.getUserId(), p.getPhoto());
+                        if (R.isError(result)) {
+                            log.error("[生成特征码失败]-[{}]", result.getData());
+                            failCount.getAndIncrement();
+                        } else {
+                            okCount.getAndIncrement();
+                        }
+                    } catch (Exception e) {
+                        log.error("生成特征码失败", e);
+                        failCount.getAndIncrement();
+                    }
+                }
             });
             });
+            String msg = MessageFormat.format("[生成人脸特征码完成]-[共:{0}人,成功:{1}人,失败:{2}人]", totalCount, okCount.get(), failCount.get());
+            return R.ok(msg);
+        }
+        return R.ok("没有需要生成人脸特征的人员");
+    }
+
+    /**
+     * 创建人脸特征数据。
+     *
+     * @param userId 用户ID,不能为空。
+     * @param photoUrl 照片URL,不能为空。
+     * @return 返回一个包含错误信息的Result对象。如果操作成功,则返回成功的结果;如果失败,则返回相应的错误信息。
+     */
+    public R<ErrorInfo> createFeatureDataOne(Long userId, String photoUrl) {
+        if (ObjectUtil.isEmpty(photoUrl)) {
+            return R.fail(new ErrorInfo(ResultCodeEnum.PARAM_IS_BLANK.code(), "", "照片路径不能为空"));
+        }
+        if (ObjectUtil.isEmpty(userId)) {
+            return R.fail(new ErrorInfo(ResultCodeEnum.PARAM_IS_BLANK.code(), "", "照片路径不能为空"));
+        }
+        String fileUrl = uploadPath + userPath + photoUrl;
+        File imageFile = new File(fileUrl);
+        if (!imageFile.exists()) {
+            return R.fail(new ErrorInfo(ResultCodeEnum.RESOURCE_NOT_EXISTED.code(), "", "无人脸照片文件"));
+        }
+        ImageInfo imageInfo = getRGBData(imageFile);
+        if (imageInfo == null) {
+            return R.fail(new ErrorInfo(ResultCodeEnum.RESOURCE_NOT_EXISTED.code(), "", "生成人脸图片信息失败"));
+        }
+        String featureData = faceEngineService.createFeatureData(imageInfo);
+        if (ObjectUtil.isEmpty(featureData)) {
+            return R.fail(new ErrorInfo(ResultCodeEnum.RESOURCE_NOT_EXISTED.code(), "", "生成人脸特征信息失败"));
+        }
+        insertFaceFeatureInfo(userId, photoUrl, featureData);
+        return R.ok();
+    }
+
+    /**
+     * 人脸特征信息入库
+     *
+     * @param userId      用户Id.
+     * @param photoUrl    照片地址
+     * @param featureData 人脸特征数据
+     */
+    public void insertFaceFeatureInfo(Long userId, String photoUrl, String featureData) {
+        PtArcFaceFeatureVo vo = arcFaceFeatureService.getOneFeatureDataUser(userId);
+        if (ObjectUtil.isEmpty(vo)) {
+            PtArcFaceFeatureBo bo = new PtArcFaceFeatureBo();
+            bo.setUserId(userId);
+            bo.setPhotoUrl(photoUrl);
+            bo.setFeatureData(featureData);
+            arcFaceFeatureService.insertByBo(bo);
+        } else {
+            arcFaceFeatureService.updateFeatureDataByUserId(userId, featureData, photoUrl);
         }
         }
     }
     }
 }
 }

+ 13 - 13
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/controller/v1/FaceCollectController.java

@@ -3,7 +3,6 @@ package org.dromara.server.consume.controller.v1;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.api.ReturnResult;
 import org.dromara.common.core.api.ReturnResult;
-import org.dromara.common.core.domain.R;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.server.consume.business.ArcFaceBusiness;
 import org.dromara.server.consume.business.ArcFaceBusiness;
 import org.dromara.server.consume.domain.vo.YcFaceFeatureVo;
 import org.dromara.server.consume.domain.vo.YcFaceFeatureVo;
@@ -43,7 +42,7 @@ public class FaceCollectController {
             featureData = new ArrayList<>();
             featureData = new ArrayList<>();
         }
         }
 
 
-        return new ReturnResult(true,1, "获取增量数据成功!", featureData);
+        return new ReturnResult(true, 1, "获取增量数据成功!", featureData, System.currentTimeMillis());
     }
     }
 
 
     /**
     /**
@@ -58,7 +57,7 @@ public class FaceCollectController {
             featureData = new ArrayList<>();
             featureData = new ArrayList<>();
         }
         }
 
 
-        return new ReturnResult(true, 1, "获取全量数据成功!", featureData);
+        return new ReturnResult(true, 1, "获取全量数据成功!", featureData, System.currentTimeMillis());
     }
     }
 
 
     /**
     /**
@@ -73,9 +72,9 @@ public class FaceCollectController {
                                                 @PathVariable("versionTime") Long versionTime) {
                                                 @PathVariable("versionTime") Long versionTime) {
         int iCount = faceBusiness.updateFaceVersionByTerm(termNo, versionTime);
         int iCount = faceBusiness.updateFaceVersionByTerm(termNo, versionTime);
         if (iCount < 0) {
         if (iCount < 0) {
-            return new ReturnResult(false, 1, "更新设备授权版本失败!", iCount);
+            return new ReturnResult(false, 1, "更新设备授权版本失败!", iCount, System.currentTimeMillis());
         }
         }
-        return new ReturnResult(true, 1, "更新设备授权版本失败!", iCount);
+        return new ReturnResult(true, 1, "更新设备授权版本失败!", iCount, System.currentTimeMillis());
     }
     }
 
 
     /**
     /**
@@ -91,9 +90,9 @@ public class FaceCollectController {
         String key = faceBusiness.getArcFaceKeyByTermSn(termSn);
         String key = faceBusiness.getArcFaceKeyByTermSn(termSn);
 
 
         if (StringUtils.isEmpty(key)) {
         if (StringUtils.isEmpty(key)) {
-            return new ReturnResult(false, 1, "获取人脸key失败!", null);
+            return new ReturnResult(false, 1, "获取人脸key失败!", null, System.currentTimeMillis());
         }
         }
-        return new ReturnResult(true, 1, "获取人脸key成功!", key);
+        return new ReturnResult(true, 1, "获取人脸key成功!", key, System.currentTimeMillis());
     }
     }
 
 
     /**
     /**
@@ -109,9 +108,9 @@ public class FaceCollectController {
 
 
         int result = faceBusiness.updateTermArcFaceKey(termSn, key);
         int result = faceBusiness.updateTermArcFaceKey(termSn, key);
         if (result <= 0) {
         if (result <= 0) {
-            return new ReturnResult(false, 1, "更新设备授权码失败!", result);
+            return new ReturnResult(false, 1, "更新设备授权码失败!", result, System.currentTimeMillis());
         }
         }
-        return new ReturnResult(true, 1, "更新设备授权码失败!", result);
+        return new ReturnResult(true, 1, "更新设备授权码失败!", result, System.currentTimeMillis());
     }
     }
 
 
     /**
     /**
@@ -124,11 +123,13 @@ public class FaceCollectController {
     @GetMapping("/singleFeature/{userId}")
     @GetMapping("/singleFeature/{userId}")
     public Object getOneFeatureDataUser(@PathVariable("userId") Long userId) {
     public Object getOneFeatureDataUser(@PathVariable("userId") Long userId) {
         if (ObjectUtil.isEmpty(userId)) {
         if (ObjectUtil.isEmpty(userId)) {
-            return new ResponseEntity<Object>(new ReturnResult(false, 1, "传入的userId为null", null), HttpStatus.NOT_FOUND);
+            return new ResponseEntity<Object>(new ReturnResult(false, 1, "传入的userId为null", null, System.currentTimeMillis()),
+                                              HttpStatus.NOT_FOUND);
         }
         }
         YcFaceFeatureVo vo = faceBusiness.getOneFeatureDataUser(userId);
         YcFaceFeatureVo vo = faceBusiness.getOneFeatureDataUser(userId);
         if (ObjectUtil.isEmpty(vo)) {
         if (ObjectUtil.isEmpty(vo)) {
-            return new ResponseEntity<Object>(new ReturnResult(false, 1, "图片信息有误,请重新上传", null), HttpStatus.NOT_FOUND);
+            return new ResponseEntity<Object>(new ReturnResult(false, 1, "图片信息有误,请重新上传", null, System.currentTimeMillis()),
+                                              HttpStatus.NOT_FOUND);
         }
         }
         return vo;
         return vo;
     }
     }
@@ -139,7 +140,6 @@ public class FaceCollectController {
      */
      */
     @GetMapping("/feature/create/all")
     @GetMapping("/feature/create/all")
     public Object createAllFeature(){
     public Object createAllFeature(){
-        faceBusiness.createAllFeatureDataUser();
-        return R.ok();
+        return faceBusiness.createAllFeatureDataUser();
     }
     }
 }
 }

+ 2 - 0
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/PtArcFaceFeature.java

@@ -46,5 +46,7 @@ public class PtArcFaceFeature extends TenantEntity {
      * 人脸特征数据
      * 人脸特征数据
      */
      */
     private String featureData;
     private String featureData;
+
+    private Integer faceSn;
 }
 }
 
 

+ 4 - 1
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/bo/PtArcFaceFeatureBo.java

@@ -1,13 +1,14 @@
 package org.dromara.server.consume.domain.bo;
 package org.dromara.server.consume.domain.bo;
 
 
 import io.github.linpeilie.annotations.AutoMapper;
 import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.server.consume.domain.PtArcFaceFeature;
 import org.dromara.server.consume.domain.PtArcFaceFeature;
-import jakarta.validation.constraints.*;
 /**
 /**
  * name: PtArcFaceFeatureBo
  * name: PtArcFaceFeatureBo
  * package: org.dromara.server.consume.domain.bo
  * package: org.dromara.server.consume.domain.bo
@@ -47,5 +48,7 @@ public class PtArcFaceFeatureBo extends BaseEntity {
     @NotBlank(message = "人脸特征数据不能为空", groups = { AddGroup.class, EditGroup.class })
     @NotBlank(message = "人脸特征数据不能为空", groups = { AddGroup.class, EditGroup.class })
     private String featureData;
     private String featureData;
 
 
+    private Integer faceSn;
+
 
 
 }
 }

+ 2 - 1
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/convert/YcFaceFeatureVoConvert.java

@@ -12,7 +12,8 @@ import org.mapstruct.*;
 @Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE)
 @Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE)
 public interface YcFaceFeatureVoConvert extends BaseMapper<PtArcFaceFeatureVo, YcFaceFeatureVo> {
 public interface YcFaceFeatureVoConvert extends BaseMapper<PtArcFaceFeatureVo, YcFaceFeatureVo> {
     @Mappings({
     @Mappings({
-        @Mapping(source = "realName", target = "name")
+        @Mapping(source = "realName", target = "name"),
+        @Mapping(source = "delFlag", target = "isDelete")
     })
     })
     YcFaceFeatureVo convert(PtArcFaceFeatureVo ptArcFaceFeatureVo);
     YcFaceFeatureVo convert(PtArcFaceFeatureVo ptArcFaceFeatureVo);
 }
 }

+ 5 - 3
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/vo/PtArcFaceFeatureVo.java

@@ -54,14 +54,16 @@ public class PtArcFaceFeatureVo  implements Serializable {
      /**
      /**
      * 用户流水号
      * 用户流水号
      */
      */
-    String userNo;
+     private String userNo;
     /**
     /**
      * 用户学工号
      * 用户学工号
      */
      */
-    String userNumb;
+    private String userNumb;
     /**
     /**
      * 用户姓名
      * 用户姓名
      */
      */
-    String realName;
+    private String realName;
+    private Integer faceSn;
+    private String delFlag;
 
 
 }
 }

+ 5 - 0
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/vo/YcFaceFeatureVo.java

@@ -48,4 +48,9 @@ public class YcFaceFeatureVo implements Serializable {
      * 主键id
      * 主键id
      */
      */
     String featureId;
     String featureId;
+    /**
+     * 删除标志
+     */
+    Integer isDelete;
+    Integer faceSn;
 }
 }

+ 21 - 0
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/dubbo/RemoteConsumeServiceImpl.java

@@ -8,6 +8,7 @@ import org.dromara.common.core.domain.model.ErrorInfo;
 import org.dromara.consume.api.RemoteConsumeService;
 import org.dromara.consume.api.RemoteConsumeService;
 import org.dromara.consume.api.domain.bo.RemoteConsumeBo;
 import org.dromara.consume.api.domain.bo.RemoteConsumeBo;
 import org.dromara.server.common.domain.consume.bo.ConsumptionBo;
 import org.dromara.server.common.domain.consume.bo.ConsumptionBo;
+import org.dromara.server.consume.business.ArcFaceBusiness;
 import org.dromara.server.consume.business.ConsumeBusiness;
 import org.dromara.server.consume.business.ConsumeBusiness;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
@@ -24,8 +25,28 @@ import org.springframework.stereotype.Service;
 @DubboService
 @DubboService
 public class RemoteConsumeServiceImpl implements RemoteConsumeService {
 public class RemoteConsumeServiceImpl implements RemoteConsumeService {
     private final ConsumeBusiness consumeBusiness;
     private final ConsumeBusiness consumeBusiness;
+    private final ArcFaceBusiness faceBusiness;
+
+    /**
+     * 消费处理.
+     *
+     * @param bo 消费业务对象
+     * @return an R<ErrorInfo> object, where ErrorInfo contains details about any errors that occurred during processing
+     */
     @Override
     @Override
     public R<ErrorInfo> dealKafkaConsumeData(RemoteConsumeBo bo) {
     public R<ErrorInfo> dealKafkaConsumeData(RemoteConsumeBo bo) {
         return consumeBusiness.fullOrder(BeanUtil.copyProperties(bo, ConsumptionBo.class), "", "");
         return consumeBusiness.fullOrder(BeanUtil.copyProperties(bo, ConsumptionBo.class), "", "");
     }
     }
+
+    /**
+     * 创建特征数据。
+     *
+     * @param userId   用户ID
+     * @param photoUrl 照片URL
+     * @return 返回一个R<ErrorInfo>对象,其中ErrorInfo包含在处理过程中发生的任何错误的详细信息
+     */
+    @Override
+    public R<ErrorInfo> createFeatureDataOne(Long userId, String photoUrl) {
+        return faceBusiness.createFeatureDataOne(userId, photoUrl);
+    }
 }
 }

+ 15 - 2
ruoyi-server/ruoyi-server-consume/src/main/resources/mapper/consume/PtArcFaceFeatureMapper.xml

@@ -15,10 +15,21 @@
         <result property="createTime"    column="create_time"    />
         <result property="createTime"    column="create_time"    />
         <result property="updateBy"    column="update_by"    />
         <result property="updateBy"    column="update_by"    />
         <result property="updateTime"    column="update_time"    />
         <result property="updateTime"    column="update_time"    />
+        <result property="faceSn" column="face_sn"/>
+        <result property="delFlag" column="del_flag"/>
     </resultMap>
     </resultMap>
 
 
     <select id="getIncrementFeatureDataUser" resultType="org.dromara.server.consume.domain.vo.PtArcFaceFeatureVo">
     <select id="getIncrementFeatureDataUser" resultType="org.dromara.server.consume.domain.vo.PtArcFaceFeatureVo">
-        SELECT tpua.user_id,tpua.user_no,tpua.user_numb,tpua.real_name,tpaff.photo_url,tpaff.feature_data,tpaff.feature_id FROM t_pt_arcFaceFeature tpaff
+        SELECT tpua.user_id,
+               tpua.user_no,
+               tpua.user_numb,
+               tpua.real_name,
+               tpaff.photo_url,
+               tpaff.feature_data,
+               tpaff.feature_id,
+               tpaff.face_sn,
+               tpaff.del_flag
+        FROM t_pt_arcFaceFeature tpaff
         INNER JOIN t_pt_userAccount tpua ON tpua.user_id=tpaff.user_id
         INNER JOIN t_pt_userAccount tpua ON tpua.user_id=tpaff.user_id
         WHERE tpaff.update_time > #{lastTime}
         WHERE tpaff.update_time > #{lastTime}
           AND tpua.del_flag = '0'
           AND tpua.del_flag = '0'
@@ -32,7 +43,9 @@
                tpua.real_name,
                tpua.real_name,
                tpaff.photo_url,
                tpaff.photo_url,
                tpaff.feature_data,
                tpaff.feature_data,
-               tpaff.feature_id
+               tpaff.feature_id,
+               tpaff.face_sn,
+               tpaff.del_flag
         FROM t_pt_arcFaceFeature tpaff
         FROM t_pt_arcFaceFeature tpaff
                  INNER JOIN t_pt_userAccount tpua ON tpua.user_id = tpaff.user_id
                  INNER JOIN t_pt_userAccount tpua ON tpua.user_id = tpaff.user_id
         WHERE tpua.del_flag = '0'
         WHERE tpua.del_flag = '0'