ソースを参照

Merge remote-tracking branch 'origin/master'

wujiefeng 1 年間 前
コミット
5b1bb3a5aa
19 ファイル変更613 行追加103 行削除
  1. 3 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/devices/DeviceUseRecordModel.java
  2. 22 0
      FullCardClient/src/main/java/com/zhongshu/card/client/type/permiss/PermissSendState.java
  3. 11 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/devices/DeviceSyncController.java
  4. 9 6
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/gateDoor/GateDoorController.java
  5. 29 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/devices/DevicePermissSendLogDao.java
  6. 2 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/OrganizationUserDao.java
  7. 12 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dataConfig/TtlConfig.java
  8. 83 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/devices/DevicePermissSendLog.java
  9. 5 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/devices/DeviceUseRecords.java
  10. 25 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/event/UserInfoChangeSyncEvent.java
  11. 67 4
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissEventService.java
  12. 39 15
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissIotService.java
  13. 95 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissSendLogService.java
  14. 7 5
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissService.java
  15. 5 64
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DeviceUseRecordService.java
  16. 163 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/gateDoor/GateDoorService.java
  17. 18 5
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/OrganizationUserServiceImpl.java
  18. 9 2
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/projectAbout/CardInfoServiceImpl.java
  19. 9 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/projectAbout/OrgUserFaceService.java

+ 3 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/devices/DeviceUseRecordModel.java

@@ -66,6 +66,9 @@ public class DeviceUseRecordModel extends SuperModel {
     @Schema(description = "卡片信息")
     private CardInfoStoreModel cardInfo;
 
+    @Schema(description = "人脸信息")
+    private String pic = "";
+
     //------------------用户信息 start-------------------
     @Schema(description = "用户userId")
     private String userId;

+ 22 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/type/permiss/PermissSendState.java

@@ -0,0 +1,22 @@
+package com.zhongshu.card.client.type.permiss;
+
+import lombok.Getter;
+
+/**
+ * 权限下发的状态
+ */
+public enum PermissSendState {
+    Send("已下发"),
+    SendSuccess("下发成功"),
+    SendFailed("下发失败"),
+    Success("成功"),
+    Failed("失败"),
+    ;
+
+    @Getter
+    private String remark;
+
+    PermissSendState(String remark) {
+        this.remark = remark;
+    }
+}

+ 11 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/devices/DeviceSyncController.java

@@ -1,9 +1,11 @@
 package com.zhongshu.card.server.core.controller.devices;
 
+import com.github.microservice.models.device.DevicePermissSendResponseParam;
 import com.github.microservice.models.device.DeviceSyncListParam;
 import com.github.microservice.models.device.GateWaySyncParam;
 import com.github.microservice.models.hxz.DevicePingInfoParam;
 import com.github.microservice.net.ResultContent;
+import com.zhongshu.card.server.core.service.devices.DevicePermissSendLogService;
 import com.zhongshu.card.server.core.service.devices.DeviceSyncFromIotService;
 import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.Operation;
@@ -28,6 +30,9 @@ public class DeviceSyncController {
     @Autowired
     DeviceSyncFromIotService deviceSyncFromIotService;
 
+    @Autowired
+    private DevicePermissSendLogService devicePermissSendLogService;
+
     @Operation(summary = "物联网同步设备接口", hidden = true)
     @RequestMapping(value = "syncDevices", method = {RequestMethod.POST})
     public ResultContent syncDevices(@RequestBody DeviceSyncListParam param) {
@@ -52,5 +57,11 @@ public class DeviceSyncController {
         return deviceSyncFromIotService.syncGateWays(param);
     }
 
+    @Operation(summary = "设备权限下发的响应")
+    @RequestMapping(value = "markSendResponse", method = {RequestMethod.POST})
+    public ResultContent markSendResponse(@RequestBody DevicePermissSendResponseParam param) {
+        return devicePermissSendLogService.markSendResponse(param);
+    }
+
 }
 

+ 9 - 6
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/gateDoor/GateDoorController.java

@@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.*;
 
 @Slf4j
 @RestController
-@RequestMapping("gateDoor/v1")
+@RequestMapping("openAPI/gateDoor/v1")
 @Tag(name = "门闸")
 @Hidden
 public class GateDoorController {
@@ -24,9 +24,6 @@ public class GateDoorController {
     @Autowired
     private GateDoorService gateDoorService;
 
-    @Autowired
-    private DeviceUseRecordService deviceUseRecordService;
-
     /**
      * 设备上线通知
      */
@@ -45,10 +42,16 @@ public class GateDoorController {
         return gateDoorService.offLine(param);
     }
 
-    @Operation(summary = "门闸 认证识别人员信息上传", description = "门闸 认证识别人员信息上传")
+    @Operation(summary = "门闸 认证识别人员信息上传消息", description = "门闸 认证识别人员信息上传消息")
     @RequestMapping(value = "recPush", method = {RequestMethod.POST})
     public ResultContent recPush(@RequestBody GateDoorIotParam param) {
-        return this.deviceUseRecordService.gateDoorUseRecord(param);
+        return this.gateDoorService.gateDoorUseRecord(param);
+    }
+
+    @Operation(summary = "门闸刷卡开门失败消息", description = "门闸刷卡开门失败消息")
+    @RequestMapping(value = "cardPush", method = {RequestMethod.POST})
+    public ResultContent cardPush(@RequestBody GateDoorIotParam param) {
+        return this.gateDoorService.gateDoorUseRecord(param);
     }
 
 }

+ 29 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/devices/DevicePermissSendLogDao.java

@@ -0,0 +1,29 @@
+package com.zhongshu.card.server.core.dao.devices;
+
+import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.card.client.type.DataState;
+import com.zhongshu.card.client.type.permiss.PermissSendState;
+import com.zhongshu.card.server.core.dao.devices.extend.DevicePermissDaoExtend;
+import com.zhongshu.card.server.core.domain.devices.DevicePermiss;
+import com.zhongshu.card.server.core.domain.devices.DevicePermissSendLog;
+import com.zhongshu.card.server.core.domain.org.OrganizationUser;
+
+import java.util.List;
+
+/**
+ * 用户设备权限
+ *
+ * @author TRX
+ * @date 2024/3/21
+ */
+public interface DevicePermissSendLogDao extends MongoDao<DevicePermissSendLog> {
+
+    List<DevicePermissSendLog> findByGroupId(String groupId);
+
+    long countByGroupId(String groupId);
+
+    long countByGroupIdAndSendState(String groupId, PermissSendState sendState);
+
+    long countByGroupIdAndIsResponse(String groupId, Boolean isResponse);
+
+}

+ 2 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/OrganizationUserDao.java

@@ -25,6 +25,8 @@ public interface OrganizationUserDao extends MongoDao<OrganizationUser>, Organiz
     // 查询用户在机构的信息
     OrganizationUser findTopByOrganizationAndUser(Organization organization, UserAccount user);
 
+    OrganizationUser findTopByUserAndProjectOid(UserAccount user, String projectOid);
+
     OrganizationUser findTopByOrganizationAndUserAndProjectOid(Organization organization, UserAccount user, String projectOid);
 
     OrganizationUser findTopByOrganizationAndUserAndState(Organization organization, UserAccount user, UserState state);

+ 12 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dataConfig/TtlConfig.java

@@ -0,0 +1,12 @@
+package com.zhongshu.card.server.core.dataConfig;
+
+/**
+ * @author TRX
+ * @date 2024/10/31
+ */
+public class TtlConfig {
+
+    // 权限下发的日志 保存时间
+    public static final Long permissLogTTl = 7 * 24 * 60 * 60 * 1000L;
+
+}

+ 83 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/devices/DevicePermissSendLog.java

@@ -0,0 +1,83 @@
+package com.zhongshu.card.server.core.domain.devices;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import com.zhongshu.card.client.type.permiss.PermissSendState;
+import com.zhongshu.card.server.core.domain.base.SuperMain;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.util.Date;
+
+/**
+ * 设备权限下发日志
+ *
+ * @author TRX
+ * @date 2024/10/31
+ */
+@Data
+@Document
+@NoArgsConstructor
+@AllArgsConstructor
+public class DevicePermissSendLog extends SuperMain {
+
+    @Schema(description = "下发对应的数据ID")
+    private String dataId;
+
+    @Schema(description = "所属批次ID")
+    private String groupId;
+
+    @Schema(description = "下发服务标志")
+    private String event;
+
+    @Schema(description = "设备ID")
+    private String deviceId;
+
+    @Schema(description = "设备名称")
+    private String deviceName;
+
+    @Schema(description = "设备类型")
+    private String deviceType;
+
+    @Schema(description = "设备所属网关ID")
+    private String gateWayId;
+
+    @Schema(description = "数据管理的用户id")
+    private String userId;
+
+    @Schema(description = "关联的用户名称")
+    private String userName;
+
+    @Schema(description = "下发时间")
+    private String sendTime;
+
+    @Schema(description = "下发的数据")
+    private Object data;
+
+    @Schema(description = "下发状态")
+    private PermissSendState sendState = PermissSendState.Send;
+
+    @Schema(description = "下发请求的结果")
+    private String sendMsg = "";
+    //----------------------------------响应数据 start ---------------------------
+
+    @Schema(description = "是否响应")
+    private Boolean isResponse = Boolean.FALSE;
+
+    @Schema(description = "下发后响应时间")
+    private Long responseTime;
+
+    @Schema(description = "下发后响应时间,可读")
+    private String responseTimeStr;
+
+    @Schema(description = "响应提示内容")
+    private String responseMsg = "";
+
+    @Schema(description = "过期时间")
+    @Indexed(expireAfterSeconds = 0)
+    private Date ttl;
+
+}

+ 5 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/devices/DeviceUseRecords.java

@@ -73,6 +73,9 @@ public class DeviceUseRecords extends SuperMain {
     @Schema(description = "卡片信息")
     private CardInfoStoreModel cardInfo;
 
+    @Schema(description = "人脸信息")
+    private String pic = "";
+
     //------------------用户信息 start-------------------
     @Schema(description = "用户userId")
     private String userId;
@@ -105,4 +108,6 @@ public class DeviceUseRecords extends SuperMain {
     @Schema(description = "关联的数据")
     private Object data;
 
+    @Schema(description = "操作类型")
+    private String operator;
 }

+ 25 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/event/UserInfoChangeSyncEvent.java

@@ -1,9 +1,13 @@
 package com.zhongshu.card.server.core.event;
 
+import com.zhongshu.card.server.core.util.CommonUtil;
 import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.ApplicationEvent;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 用户信息发送变化(如:姓名、人脸信息、绑定的卡片等)
@@ -19,9 +23,30 @@ public class UserInfoChangeSyncEvent extends ApplicationEvent {
     @Getter
     private String projectOid;
 
+    @Getter
+    private Map<String, Object> map = new HashMap<String, Object>();
+
     public UserInfoChangeSyncEvent(Object source, List<String> userIds, String projectOid) {
         super(source);
         this.userIds = userIds;
         this.projectOid = projectOid;
     }
+
+    public UserInfoChangeSyncEvent(Object source, List<String> userIds, String projectOid, Map<String, Object> map) {
+        super(source);
+        this.userIds = userIds;
+        this.projectOid = projectOid;
+        this.map = map;
+    }
+
+    public String getGroupId() {
+        String groupId = "";
+        if (map != null && map.containsKey("groupId")) {
+            groupId = (String) map.get("groupId");
+        }
+        if (StringUtils.isEmpty(groupId)) {
+            groupId = CommonUtil.UUID();
+        }
+        return groupId;
+    }
 }

+ 67 - 4
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissEventService.java

@@ -12,11 +12,16 @@ import com.github.microservice.models.iot.IotSendParam;
 import com.github.microservice.net.ResultContent;
 import com.github.microservice.types.FunctionType;
 import com.google.common.collect.Lists;
+import com.zhongshu.card.client.utils.DateUtils;
 import com.zhongshu.card.server.core.dao.devices.DeviceInfoDao;
+import com.zhongshu.card.server.core.dao.devices.DevicePermissSendLogDao;
+import com.zhongshu.card.server.core.dataConfig.TtlConfig;
 import com.zhongshu.card.server.core.domain.devices.DeviceInfo;
+import com.zhongshu.card.server.core.domain.devices.DevicePermissSendLog;
 import com.zhongshu.card.server.core.event.DevicePermissChangeEvent;
 import com.zhongshu.card.server.core.event.UserInfoChangeSyncEvent;
 import com.zhongshu.card.server.core.service.openAPI.OpenApiRequestService;
+import com.zhongshu.card.server.core.util.CommonUtil;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
@@ -27,9 +32,7 @@ import org.springframework.context.ApplicationContext;
 import org.springframework.context.event.EventListener;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
@@ -63,6 +66,12 @@ public class DevicePermissEventService {
     @Autowired
     private ApplicationContext applicationContext;
 
+    @Autowired
+    private DevicePermissSendLogDao devicePermissSendLogDao;
+
+    @Autowired
+    private DevicePermissSendLogService devicePermissSendLogService;
+
     @Autowired
     private void init(ApplicationContext applicationContext) {
         Runtime.getRuntime().addShutdownHook(new Thread(() -> {
@@ -81,6 +90,12 @@ public class DevicePermissEventService {
         applicationContext.publishEvent(event);
     }
 
+    public void sendUserInfoChangeEvent(String userId, String projectOid, Map<String, Object> map) {
+        UserInfoChangeSyncEvent event = new UserInfoChangeSyncEvent(
+                this, List.of(userId), projectOid, map);
+        applicationContext.publishEvent(event);
+    }
+
     /**
      * 通知用户关联信息发送变化
      *
@@ -153,20 +168,22 @@ public class DevicePermissEventService {
         log.info("userInfoChange; {} {}", projectOid);
         if (StringUtils.isNotEmpty(projectOid) && ObjectUtils.isNotEmpty(userIds[0])) {
             executorService.execute(() -> {
+                String groupId = event.getGroupId();
                 userIds[0] = userIds[0].stream().distinct().collect(Collectors.toList());
                 // 循环用户数据
                 for (String userId : userIds[0]) {
                     List<String> deviceIds = devicePermissService.getUserAllDeviceIds(
                             projectOid, List.of(userId));
+                    // 网关 对应的设备
                     HashMap<String, List<String>> map = deviceGroupByGateWayId(deviceIds);
                     if (!map.isEmpty()) {
                         // 遍历发送
                         map.keySet().stream().forEach(gateWayId -> {
                             DeviceUsersInfo deviceUsersInfo = new DeviceUsersInfo();
+                            deviceUsersInfo.setGroupId(groupId);
                             deviceUsersInfo.setGateWayId(gateWayId);
                             // 用户数据 (去重)
                             List<ProjectUserPermiss> userPermiss = devicePermissIotService.getUserPermiss(projectOid, userIds[0]);
-
                             deviceUsersInfo.setUsers(userPermiss);
                             // 下发用户数据
                             requestDevicesUsersData(deviceUsersInfo, projectOid);
@@ -233,6 +250,28 @@ public class DevicePermissEventService {
         IotSendParam param = new IotSendParam();
         param.setGateWayId(gateWayId);
         param.setIdentifier(IotIdentifierConfig.queryDeviceBindUsers);
+
+        String groupId = gateWayPermissModel.getGroupId();
+        if (ObjectUtils.isNotEmpty(gateWayPermissModel.getDevices())
+                && StringUtils.isNotEmpty(groupId)) {
+            List<DevicePermissSendLog> list = new ArrayList<>();
+            for (DeviceAboutPermiss deviceAboutPermiss : gateWayPermissModel.getDevices()) {
+                deviceAboutPermiss.setDataId(CommonUtil.UUID());
+
+                DevicePermissSendLog sendLog = new DevicePermissSendLog();
+                sendLog.setDataId(deviceAboutPermiss.getDataId());
+                sendLog.setGateWayId(gateWayId);
+                sendLog.setDeviceId(deviceAboutPermiss.getDeviceId());
+                sendLog.setGroupId(groupId);
+                sendLog.setData(gateWayPermissModel);
+                sendLog.setSendTime(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
+                sendLog.setEvent(IotIdentifierConfig.queryDeviceBindUsers);
+                sendLog.setTtl(new Date(System.currentTimeMillis() + TtlConfig.permissLogTTl));
+                list.add(sendLog);
+            }
+            devicePermissSendLogDao.saveAll(list);
+        }
+
         // 组装消息内容
         JSONObject jsonObject = gateWayPermissModel.toJson();
         param.setData(jsonObject);
@@ -242,6 +281,7 @@ public class DevicePermissEventService {
         } else {
             log.error("设备权限下发失败 网关ID:{} {}", gateWayId, resultContent.getMsg());
         }
+        devicePermissSendLogService.markPermissSend(groupId, resultContent.isSuccess(), resultContent.getMsg());
     }
 
     /**
@@ -270,6 +310,28 @@ public class DevicePermissEventService {
         IotSendParam param = new IotSendParam();
         param.setGateWayId(gateWayId);
         param.setIdentifier(IotIdentifierConfig.queryDeviceUsersInfo);
+
+        String groupId = deviceUsersInfo.getGroupId();
+        if (ObjectUtils.isNotEmpty(deviceUsersInfo.getUsers())
+                && StringUtils.isNotEmpty(groupId)) {
+            List<DevicePermissSendLog> list = new ArrayList<>();
+            for (ProjectUserPermiss projectUserPermiss : deviceUsersInfo.getUsers()) {
+                projectUserPermiss.setDataId(CommonUtil.UUID());
+                DevicePermissSendLog sendLog = new DevicePermissSendLog();
+                sendLog.setDataId(projectUserPermiss.getDataId());
+                sendLog.setGateWayId(gateWayId);
+                sendLog.setUserId(projectUserPermiss.getUid());
+                sendLog.setUserId(projectUserPermiss.getUn());
+                sendLog.setGroupId(groupId);
+                sendLog.setData(projectUserPermiss);
+                sendLog.setSendTime(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
+                sendLog.setEvent(IotIdentifierConfig.queryDeviceUsersInfo);
+                sendLog.setTtl(new Date(System.currentTimeMillis() + TtlConfig.permissLogTTl));
+                list.add(sendLog);
+            }
+            devicePermissSendLogDao.saveAll(list);
+        }
+
         // 组装消息内容
         JSONObject jsonObject = deviceUsersInfo.toJson();
         param.setData(jsonObject);
@@ -279,6 +341,7 @@ public class DevicePermissEventService {
         } else {
             log.error("用户信息下发失败 网关ID:{} {}", gateWayId, resultContent.getMsg());
         }
+        devicePermissSendLogService.markPermissSend(groupId, resultContent.isSuccess(), resultContent.getMsg());
     }
 
     /**

+ 39 - 15
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissIotService.java

@@ -1,6 +1,7 @@
 package com.zhongshu.card.server.core.service.devices;
 
 import cn.hutool.json.JSONUtil;
+import com.github.microservice.core.util.os.SystemUtil;
 import com.github.microservice.models.device.DevicePerQuery;
 import com.github.microservice.models.device.UserPerQuery;
 import com.github.microservice.models.devicePermiss.DeviceAboutPermiss;
@@ -23,16 +24,20 @@ import com.zhongshu.card.server.core.domain.school.CardInfo;
 import com.zhongshu.card.server.core.service.projectAbout.CardInfoServiceImpl;
 import com.zhongshu.card.server.core.service.projectAbout.OrgUserFaceService;
 import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
+import com.zhongshu.card.server.core.util.CommonUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.stream.Collectors;
 
 /**
@@ -66,6 +71,16 @@ public class DevicePermissIotService {
     @Autowired
     private UserAccountServiceImpl userAccountService;
 
+    //线程池
+    private ExecutorService executorService = Executors.newFixedThreadPool(SystemUtil.getCpuCoreCount() * 2);
+
+    @Autowired
+    private void init(ApplicationContext applicationContext) {
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            executorService.shutdownNow();
+        }));
+    }
+
     /**
      * 组装设备权限变更的数据
      *
@@ -73,23 +88,32 @@ public class DevicePermissIotService {
      * @param mark      0: 删除   1:新增、修改   2:全量
      * @return
      */
-    public ResultContent changeDeviceUser(List<DevicePermiss> permisses, int mark) {
+    public ResultContent changeDeviceUser(List<DevicePermiss> permisses, int mark, String groupId) {
         if (ObjectUtils.isNotEmpty(permisses)) {
-            Map<String, List<DevicePermiss>> map = permisses.stream().collect(Collectors.groupingBy(DevicePermiss::getGateWayId));
-            map.forEach((gateWayId, tempList) -> {
-                GateWayPermissModel gateWayPermissModel = new GateWayPermissModel();
-                gateWayPermissModel.setGateWayId(gateWayId);
+            executorService.execute(() -> {
+                Map<String, List<DevicePermiss>> map = permisses.stream().collect(Collectors.groupingBy(DevicePermiss::getGateWayId));
+                map.forEach((gateWayId, tempList) -> {
+                    GateWayPermissModel gateWayPermissModel = new GateWayPermissModel();
+                    gateWayPermissModel.setGateWayId(gateWayId);
+                    gateWayPermissModel.setGroupId(groupId);
+                    List<DeviceAboutPermiss> devices = tempList.stream().map(it -> {
+                        DeviceAboutPermiss permiss = new DeviceAboutPermiss();
+                        permiss.setDeviceId(it.getDeviceId());
+                        permiss.addUser(it.getUserId());
+                        //TODO
+                        List<String> ids = new ArrayList<>();
+                        for (int i = 0; i < 10000; i++) {
+//                            ids.add(CommonUtil.UUID());
+                        }
+                        permiss.addUsers(ids);
+                        permiss.setMark(mark);
+                        return permiss;
+                    }).collect(Collectors.toUnmodifiableList());
+                    gateWayPermissModel.setDevices(devices);
 
-                List<DeviceAboutPermiss> devices = tempList.stream().map(it -> {
-                    DeviceAboutPermiss permiss = new DeviceAboutPermiss();
-                    permiss.setDeviceId(it.getDeviceId());
-                    permiss.addUser(it.getUserId());
-                    permiss.setMark(mark);
-                    return permiss;
-                }).collect(Collectors.toUnmodifiableList());
-                gateWayPermissModel.setDevices(devices);
-                // 下发设备数据
-                devicePermissEventService.requestDeviceBindData(gateWayPermissModel, tempList.get(0).getProjectOid());
+                    // 下发设备数据
+                    devicePermissEventService.requestDeviceBindData(gateWayPermissModel, tempList.get(0).getProjectOid());
+                });
             });
         }
         return ResultContent.buildSuccess();

+ 95 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissSendLogService.java

@@ -0,0 +1,95 @@
+package com.zhongshu.card.server.core.service.devices;
+
+import cn.hutool.json.JSONUtil;
+import com.github.microservice.models.device.DevicePermissSendResponseParam;
+import com.github.microservice.models.device.DevicePermissSendResponseResult;
+import com.github.microservice.net.ResultContent;
+import com.zhongshu.card.client.type.permiss.PermissSendState;
+import com.zhongshu.card.server.core.dao.devices.DevicePermissSendLogDao;
+import com.zhongshu.card.server.core.domain.devices.DevicePermissSendLog;
+import com.zhongshu.card.server.core.service.base.CommonService;
+import com.zhongshu.card.server.core.service.base.SuperService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author TRX
+ * @date 2024/10/31
+ */
+@Slf4j
+@Service
+public class DevicePermissSendLogService extends SuperService {
+
+    @Autowired
+    private DevicePermissSendLogDao devicePermissSendLogDao;
+
+    @Autowired
+    private CommonService commonService;
+
+    /**
+     * 下发权限数据的响应
+     *
+     * @param param
+     * @return
+     */
+    public ResultContent markSendResponse(DevicePermissSendResponseParam param) {
+        DevicePermissSendResponseResult result = new DevicePermissSendResponseResult();
+        result.setSuccess();
+
+        return ResultContent.buildSuccess(JSONUtil.toJsonStr(result));
+    }
+
+    /**
+     * 得到下发 结果
+     *
+     * @param groupId
+     * @return
+     */
+    public ResultContent isAllResponseSuccess(String groupId) {
+
+        return ResultContent.buildSuccess();
+    }
+
+    /**
+     * 批次下发的权限是否都已响应
+     *
+     * @param groupId
+     * @return
+     */
+    public Boolean isAllResponse(String groupId) {
+        long all = devicePermissSendLogDao.countByGroupId(groupId);
+        long responseEd = devicePermissSendLogDao.countByGroupIdAndIsResponse(groupId, Boolean.TRUE);
+        if (all == responseEd) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param groupId
+     * @param isSuccess
+     */
+    public void markPermissSend(String groupId, Boolean isSuccess, String message) {
+        if (StringUtils.isNotEmpty(groupId)) {
+            Map<String, Object> where = new HashMap<>();
+            where.put("groupId", groupId);
+
+            Map<String, Object> standardData = new HashMap<>();
+            if (isSuccess != null && isSuccess) {
+                standardData.put("sendState", PermissSendState.SendSuccess);
+            } else {
+                standardData.put("sendState", PermissSendState.SendFailed);
+            }
+            standardData.put("sendMsg", message);
+            commonService.updateData(where, standardData, DevicePermissSendLog.class.getSimpleName());
+        }
+    }
+
+}

+ 7 - 5
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissService.java

@@ -27,6 +27,7 @@ import com.zhongshu.card.server.core.service.projectAbout.CardInfoServiceImpl;
 import com.zhongshu.card.server.core.service.projectAbout.OrgUserFaceService;
 import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
 import com.zhongshu.card.server.core.util.BeanUtils;
+import com.zhongshu.card.server.core.util.CommonUtil;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
@@ -137,7 +138,7 @@ public class DevicePermissService extends SuperService {
                 }
                 devicePermissDao.saveAll(permisses);
                 // 下发设备权限增加数据
-                devicePermissIotService.changeDeviceUser(permisses, 1);
+                devicePermissIotService.changeDeviceUser(permisses, 1, "");
 
                 // 因为是新增加,下发关联的用户信息
                 devicePermissIotService.changeUserInfo(permisses, 1);
@@ -204,7 +205,7 @@ public class DevicePermissService extends SuperService {
                         devicePermissEventService.sendUserInfoChangeEvent(userIds, projectOid);
                     } else if (dataOperationType == DataOperationType.Delete) {
                         // 下发移除权限
-                        devicePermissIotService.changeDeviceUser(list, 0);
+                        devicePermissIotService.changeDeviceUser(list, 0, "");
                         // 删除
                         devicePermissDao.deleteAll(list);
                     }
@@ -253,12 +254,13 @@ public class DevicePermissService extends SuperService {
         }
         entity.setDataState(dataState);
         devicePermissDao.save(entity);
+        String groupId = CommonUtil.UUID();
         if (dataState == DataState.Disable) {
             // 移除权限
-            devicePermissIotService.changeDeviceUser(List.of(entity), 0);
+            devicePermissIotService.changeDeviceUser(List.of(entity), 0, groupId);
         } else {
             // 启用
-            devicePermissIotService.changeDeviceUser(List.of(entity), 1);
+            devicePermissIotService.changeDeviceUser(List.of(entity), 1, groupId);
         }
         return ResultContent.buildSuccess();
     }
@@ -273,7 +275,7 @@ public class DevicePermissService extends SuperService {
         if (ObjectUtils.isNotEmpty(param.getIds())) {
             List<DevicePermiss> list = devicePermissDao.findByIdIn(param.getIds());
             // 1: 移除权限
-            devicePermissIotService.changeDeviceUser(list, 0);
+            devicePermissIotService.changeDeviceUser(list, 0, "");
             // 2:删除数据
             devicePermissDao.deleteAll(list);
         }

+ 5 - 64
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DeviceUseRecordService.java

@@ -73,70 +73,8 @@ public class DeviceUseRecordService extends SuperService {
     @Autowired
     private OrganizationDao organizationDao;
 
-    private static Long ttlTime = 60 * 24 * 60 * 60 * 1000L;
-
-    /**
-     * 门闸的开门使用的 参数
-     *
-     * @param param
-     * @return
-     */
-    public ResultContent gateDoorUseRecord(GateDoorIotParam param) {
-        GateDoorUseResult result = new GateDoorUseResult();
-        GateDoorInfoParam info = param.getInfo();
-        log.info("闸机使用记录 gateDoorUseRecord...");
-        if (ObjectUtils.isNotEmpty(info)) {
-            // 封装记录日志参数
-            GateDoorUseParam useParam = new GateDoorUseParam();
-            useParam.setMqttDataId(param.getMqttDataId());
-            useParam.setDeviceId(param.getDeviceId());
-            useParam.setGateWayId(param.getGateWayId());
-
-            String VerifyStatus = info.getVerifyStatus();
-            if (StringUtils.isNotEmpty(VerifyStatus)) {
-                if ("1".equals(VerifyStatus)) {
-                    // 成功
-                    useParam.setOperateState(OperateState.Success);
-                } else if ("2".equals(VerifyStatus)) {
-                    // 失败
-                    useParam.setOperateState(OperateState.Failed);
-                } else {
-                    // 未知
-                    useParam.setOperateState(OperateState.Unknown);
-                }
-            } else {
-                // 未知
-                useParam.setOperateState(OperateState.Unknown);
-            }
-            // 使用操作方式
-            if (StringUtils.isNotEmpty(info.getPic())) {
-                // 人脸形式
-                useParam.setOperateType(OperateType.Face);
-            } else {
-                String cardNum2 = info.getCardNum2();
-                if (StringUtils.isNotEmpty(cardNum2)) {
-                    useParam.setOperateType(OperateType.Card);
-                    useParam.setCardNo(cardNum2);
-                }
-            }
-            if (useParam.getOperateType() == null) {
-                useParam.setOperateType(OperateType.Unknown);
-            }
-            useParam.setTime(info.getTime());
-            useParam.setUserId(info.getCustomId());
-            useParam.setIsOffLine(param.getIsOffLine());
-            useParam.setData(param);
-            ResultContent<DeviceUseRecords> resultContent = saveDeviceLogs(useParam);
-            if (resultContent.isSuccess()) {
-                result.setSuccess("成功");
-            } else {
-                result.setFailed(resultContent.getMsg());
-            }
-        } else {
-            result.setFailed("数据为空");
-        }
-        return ResultContent.buildSuccess(JSONUtil.toJsonStr(result));
-    }
+    // 设备使用日志保存3个月
+    private static Long ttlTime = 90 * 24 * 60 * 60 * 1000L;
 
     /**
      * 设备使用日志 (物联网来的数据)
@@ -193,6 +131,9 @@ public class DeviceUseRecordService extends SuperService {
                 if (StringUtils.isNotEmpty(userId)) {
                     userAccount = userCountDao.findTopByUserId(userId);
                 }
+                if (ObjectUtils.isEmpty(userId)) {
+                    userId = "陌生人";
+                }
                 deviceUseRecord.setUserId(userId);
                 deviceUseRecord.setUserAccount(userAccountService.toSimpleModel(userAccount));
                 if (StringUtils.isNotEmpty(param.getTime())) {

+ 163 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/gateDoor/GateDoorService.java

@@ -1,20 +1,27 @@
 package com.zhongshu.card.server.core.service.gateDoor;
 
 import cn.hutool.json.JSONUtil;
-import com.github.microservice.core.util.random.RandomUtil;
 import com.github.microservice.models.gateDoor.OnLineAckInfoModel;
 import com.github.microservice.models.gateDoor.OnLineInfoParam;
 import com.github.microservice.models.gateDoor.OnLineModel;
 import com.github.microservice.models.gateDoor.OnLineParam;
+import com.github.microservice.models.gateDoor.gateDoor.GateDoorIotParam;
+import com.github.microservice.models.gateDoor.use.GateDoorFailCardInfo;
+import com.github.microservice.models.gateDoor.use.GateDoorInfoParam;
 import com.github.microservice.models.gateDoor.use.GateDoorUseParam;
 import com.github.microservice.models.gateDoor.use.GateDoorUseResult;
 import com.github.microservice.net.ResultContent;
+import com.github.microservice.types.deviceUse.OperateState;
+import com.github.microservice.types.deviceUse.OperateType;
 import com.zhongshu.card.client.type.payment.RequestType;
+import com.zhongshu.card.server.core.domain.devices.DeviceUseRecords;
 import com.zhongshu.card.server.core.service.base.SuperService;
+import com.zhongshu.card.server.core.service.devices.DeviceUseRecordService;
 import com.zhongshu.card.server.core.service.payment.RequestInfoService;
 import com.zhongshu.card.server.core.util.CommonUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -29,6 +36,9 @@ public class GateDoorService extends SuperService {
     @Autowired
     RequestInfoService requestInfoService;
 
+    @Autowired
+    private DeviceUseRecordService deviceUseRecordService;
+
     /**
      * 闸机方法 onLine
      *
@@ -65,4 +75,156 @@ public class GateDoorService extends SuperService {
         return ResultContent.buildSuccess(JSONUtil.toJsonStr(resultModel));
     }
 
+    /**
+     * 门闸的开门使用的 参数
+     *
+     * @param param
+     * @return
+     */
+    public ResultContent gateDoorUseRecord(GateDoorIotParam param) {
+        GateDoorUseResult result = new GateDoorUseResult();
+        GateDoorInfoParam info = param.getInfo();
+        log.info("闸机使用记录 gateDoorUseRecord...");
+        if (ObjectUtils.isNotEmpty(info)) {
+            // 封装记录日志参数
+            GateDoorUseParam useParam = new GateDoorUseParam();
+            useParam.setMqttDataId(param.getMqttDataId());
+            useParam.setDeviceId(param.getDeviceId());
+            useParam.setGateWayId(param.getGateWayId());
+
+            String VerifyStatus = info.getVerifyStatus();
+            if (StringUtils.isNotEmpty(VerifyStatus)) {
+                if ("1".equals(VerifyStatus)) {
+                    // 成功
+                    useParam.setOperateState(OperateState.Success);
+                } else if ("2".equals(VerifyStatus)) {
+                    // 失败
+                    useParam.setOperateState(OperateState.Failed);
+                } else {
+                    // 未知
+                    useParam.setOperateState(OperateState.Unknown);
+                }
+            } else {
+                // 未知
+                useParam.setOperateState(OperateState.Failed);
+            }
+            // 使用操作方式
+            if (StringUtils.isNotEmpty(info.getPic())) {
+                // 人脸形式
+                useParam.setOperateType(OperateType.Face);
+            } else {
+                String cardNum2 = info.getCardNum2();
+                if (StringUtils.isNotEmpty(cardNum2)) {
+                    useParam.setOperateType(OperateType.Card);
+                    useParam.setCardNo(cardNum2);
+                }
+            }
+            if (useParam.getOperateType() == null) {
+                useParam.setOperateType(OperateType.Unknown);
+            }
+            GateDoorFailCardInfo cardInfo = info.getCardInfo();
+            if (StringUtils.isEmpty(useParam.getCardNo()) && ObjectUtils.isNotEmpty(cardInfo)) {
+                useParam.setCardNo(cardInfo.getCardNum());
+                useParam.setOperateType(OperateType.Card);
+            }
+            useParam.setTime(info.getTime());
+            useParam.setUserId(info.getCustomId());
+            useParam.setIsOffLine(param.getIsOffLine());
+            useParam.setData(param);
+            useParam.setOperator(param.getOperator());
+            useParam.setPic(info.getPic());
+            info.setPic("");
+            ResultContent<DeviceUseRecords> resultContent = deviceUseRecordService.saveDeviceLogs(useParam);
+            if (resultContent.isSuccess()) {
+                DeviceUseRecords records = resultContent.getContent();
+                if (records.getOperateState() == OperateState.Success) {
+                    result.setSuccess("成功");
+                } else {
+                    result.setFailed(records.getMsg());
+                }
+            } else {
+                result.setFailed(resultContent.getMsg());
+            }
+        } else {
+            result.setFailed("数据为空");
+        }
+        return ResultContent.buildSuccess(JSONUtil.toJsonStr(result));
+    }
+
+    /**
+     * 检查设备使用的 参数验证
+     *
+     * @param entity
+     */
+    public void checkUseDeviceData(DeviceUseRecords entity) {
+//        // 主要是从设备、卡片等的基础信息验证
+//        if (ObjectUtils.isNotEmpty(entity)) {
+//            // 1. 检查设备
+//            if (ObjectUtils.isEmpty(entity.getDeviceInfo())) {
+//                entity.setIsPassed(Boolean.FALSE);
+//                entity.setMsg("设备信息未找到");
+//                return;
+//            }
+//            DeviceInfoStoreModel deviceInfo = entity.getDeviceInfo();
+//            if (deviceInfo.getState() == null || deviceInfo.getState() != DataState.Enable) {
+//                entity.setIsPassed(Boolean.FALSE);
+//                entity.setMsg("设备未启用");
+//                return;
+//            }
+//            //2. 验证用户信息
+//            UserCountSimpleModel userAccount = entity.getUserAccount();
+//            if (ObjectUtils.isEmpty(userAccount)) {
+//                entity.setIsPassed(Boolean.FALSE);
+//                entity.setMsg("用户信息未确定");
+//                return;
+//            }
+//            if (userAccount.getState() == null || userAccount.getState() != UserState.Normal) {
+//                entity.setIsPassed(Boolean.FALSE);
+//                entity.setMsg(String.format("用户已禁用"));
+//                return;
+//            }
+//            // 验证用户是否有设备申请权限
+//            if (deviceInfo.getIsOpenUse() == null || !deviceInfo.getIsOpenUse()) {
+//                DevicePermiss devicePermiss = devicePermissDao.findTopByUserIdAndDeviceIdAndProjectOid(entity.getUserId(), entity.getDeviceId(), entity.getProjectOid());
+//                if (ObjectUtils.isEmpty(devicePermiss)) {
+//                    entity.setIsPassed(Boolean.FALSE);
+//                    entity.setMsg("用户没有设备权限");
+//                    return;
+//                }
+//                if (devicePermiss.getDataState() == null || devicePermiss.getDataState() != DataState.Enable) {
+//                    entity.setIsPassed(Boolean.FALSE);
+//                    entity.setMsg("用户权限未启用");
+//                    return;
+//                }
+//            }
+//
+//            Integer mode = entity.getMode();
+//            if (mode == null) {
+//                entity.setIsPassed(Boolean.FALSE);
+//                entity.setMsg("使用模式未确定");
+//                return;
+//            }
+//            if (mode == 0) {
+//                // 刷卡
+//                if (ObjectUtils.isEmpty(entity.getCardInfo())) {
+//                    entity.setIsPassed(Boolean.FALSE);
+//                    entity.setMsg("卡片未找到");
+//                    return;
+//                }
+//                CardInfoStoreModel cardInfo = entity.getCardInfo();
+//                if (cardInfo.getIsCanceled() != null && cardInfo.getIsCanceled()) {
+//                    entity.setIsPassed(Boolean.FALSE);
+//                    entity.setMsg("卡片已作废");
+//                    return;
+//                }
+//
+//                if (cardInfo.getCardState() == null || cardInfo.getCardState() != CardState.Enable) {
+//                    entity.setIsPassed(Boolean.FALSE);
+//                    entity.setMsg(String.format("卡片%s", cardInfo.getCardState().getRemark()));
+//                    return;
+//                }
+//            }
+//        }
+    }
+
 }

+ 18 - 5
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/OrganizationUserServiceImpl.java

@@ -148,19 +148,32 @@ public class OrganizationUserServiceImpl extends SuperService {
                 return ResultContent.buildFail(String.format("数据不存在:%s", param.getId()));
             }
         }
+        String loginName = param.getPhone();
+        if (temp != null && temp.getUser() != null) {
+            loginName = temp.getUser().getLoginName();
+        }
 
-        // 用户基本信息维护
+        String projectOid = param.getProjectOid();
+        // 判断是否存在
+        UserAccount userAccount = userCountDao.findTopByLoginName(loginName);
+        if (ObjectUtils.isNotEmpty(userAccount)) {
+            OrganizationUser tempOrgUser = organizationUserDao.findTopByUserAndProjectOid(userAccount, projectOid);
+            if (ObjectUtils.isNotEmpty(tempOrgUser)) {
+                if (ObjectUtils.isEmpty(temp) || !temp.getId().equals(tempOrgUser.getId())) {
+                    return ResultContent.buildFail(String.format("用户已加入该项目:%s", loginName));
+                }
+            }
+        }
+
+        // 用户基本信息维护 电话号码为登录名
         RegisterUserAccountParam userAccountParam = new RegisterUserAccountParam();
-        userAccountParam.setLoginName(param.getPhone());
+        userAccountParam.setLoginName(loginName);
         userAccountParam.setPassword(param.getPassWord());
         userAccountParam.setPhone(param.getPhone());
         userAccountParam.setName(param.getName());
         userAccountParam.setCardNumber(param.getCardNumber());
         userAccountParam.setSex(param.getSex());
         userAccountParam.setProfilePic(param.getProfilePic());
-        if (temp != null && temp.getUser() != null) {
-            userAccountParam.setLoginName(temp.getUser().getLoginName());
-        }
         ResultContent<String> userAccountContent = userAccountService.registerUserAccount(userAccountParam);
         if (userAccountContent.isFailed()) {
             return ResultContent.buildFail(userAccountContent.getMsg());

+ 9 - 2
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/projectAbout/CardInfoServiceImpl.java

@@ -38,6 +38,7 @@ import com.zhongshu.card.server.core.service.org.OrganizationUserServiceImpl;
 import com.zhongshu.card.server.core.service.orgManager.OrganizationManagerServiceImpl;
 import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
 import com.zhongshu.card.server.core.util.BeanUtils;
+import com.zhongshu.card.server.core.util.CommonUtil;
 import com.zhongshu.card.server.core.util.ExcelUtils;
 import com.zhongshu.card.server.core.util.excel.CommonExeclParam;
 import com.zhongshu.card.server.core.util.excel.CommonExeclTd;
@@ -541,8 +542,11 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
         cardInfoLossRecord.setOperationType(CardOperationType.Loss);
         cardInfoLossRecordDao.save(cardInfoLossRecord);
 
+        String groupId = CommonUtil.UUID();
+        Map<String, Object> map = new HashMap<>();
+        map.put("groupId", groupId);
         // 卡片信息发送变化
-        devicePermissEventService.sendUserInfoChangeEvent(cardInfo.getUserId(), cardInfo.getProjectOid());
+        devicePermissEventService.sendUserInfoChangeEvent(cardInfo.getUserId(), cardInfo.getProjectOid(), map);
         return ResultContent.buildSuccess();
     }
 
@@ -640,8 +644,11 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
         cardInfoLossRecord.setOperationType(CardOperationType.Enable);
         cardInfoLossRecordDao.save(cardInfoLossRecord);
 
+        String groupId = CommonUtil.UUID();
+        Map<String, Object> map = new HashMap<>();
+        map.put("groupId", groupId);
         // 用户可用卡片发生变化
-        devicePermissEventService.sendUserInfoChangeEvent(cardInfo.getUserId(), cardInfo.getProjectOid());
+        devicePermissEventService.sendUserInfoChangeEvent(cardInfo.getUserId(), cardInfo.getProjectOid(), map);
         return ResultContent.buildSuccess();
     }
 

+ 9 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/projectAbout/OrgUserFaceService.java

@@ -12,6 +12,7 @@ import com.zhongshu.card.server.core.event.UserInfoChangeSyncEvent;
 import com.zhongshu.card.server.core.service.base.SuperService;
 import com.zhongshu.card.server.core.service.devices.DevicePermissEventService;
 import com.zhongshu.card.server.core.util.BeanUtils;
+import com.zhongshu.card.server.core.util.CommonUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -21,7 +22,9 @@ import org.springframework.context.ApplicationContext;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -80,8 +83,13 @@ public class OrgUserFaceService extends SuperService {
         }
         orgUserFaceDao.save(orgUserFace);
 
+        String groupId = CommonUtil.UUID();
+        Map<String, Object> map = new HashMap<>();
+        map.put("groupId", groupId);
         // 通知人脸信息发送变化
-        devicePermissEventService.sendUserInfoChangeEvent(orgUserFace.getUserId(), orgUserFace.getProjectOid());
+        devicePermissEventService.sendUserInfoChangeEvent(
+                orgUserFace.getUserId(), orgUserFace.getProjectOid(), map);
+
         return ResultContent.buildSuccess();
     }