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

Merge remote-tracking branch 'origin/master'

wujiefeng 1 год назад
Родитель
Сommit
ae40f711bd
22 измененных файлов с 471 добавлено и 180 удалено
  1. 80 22
      FullCardClient/src/main/java/com/zhongshu/card/client/model/devices/DeviceUseRecordModel.java
  2. 19 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/devices/DeviceUseRecordSearch.java
  3. 33 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseFlowAreaModel.java
  4. 2 5
      FullCardClient/src/main/java/com/zhongshu/card/client/service/payment/ExpenseFlowService.java
  5. 17 23
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/devices/DeviceUseRecordController.java
  6. 14 9
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/gateDoor/GateDoorController.java
  7. 0 12
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/openAPI/ProjectOpenAPIController.java
  8. 4 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/org/TestController.java
  9. 2 5
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/payment/ExpenseFlowController.java
  10. 24 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/devices/impl/DeviceUseRecordDaoImpl.java
  11. 1 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/OrganizationUserDao.java
  12. 4 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dataConfig/CardSystemDefault.java
  13. 15 9
      FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/devices/DeviceUseRecords.java
  14. 4 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/payment/ExpenseFlow.java
  15. 4 3
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/base/CommonService.java
  16. 8 13
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DeviceInfoServiceImpl.java
  17. 4 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissIotService.java
  18. 39 26
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissService.java
  19. 113 40
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DeviceUseRecordService.java
  20. 39 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/OrganizationUserServiceImpl.java
  21. 36 7
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/payment/ExpenseFlowServiceImpl.java
  22. 9 5
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/user/UserAccountServiceImpl.java

+ 80 - 22
FullCardClient/src/main/java/com/zhongshu/card/client/model/devices/DeviceUseRecordModel.java

@@ -1,12 +1,19 @@
 package com.zhongshu.card.client.model.devices;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.microservice.models.type.DeviceType;
+import com.github.microservice.types.deviceUse.OperateState;
+import com.github.microservice.types.deviceUse.OperateType;
 import com.zhongshu.card.client.model.base.SuperModel;
-import com.zhongshu.card.client.model.school.CardInfoModel;
+import com.zhongshu.card.client.model.org.UserCountSimpleModel;
+import com.zhongshu.card.client.model.school.CardInfoStoreModel;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.util.Date;
+
 /**
  * @author TRX
  * @date 2024/10/21
@@ -16,27 +23,78 @@ import lombok.NoArgsConstructor;
 @NoArgsConstructor
 public class DeviceUseRecordModel extends SuperModel {
 
+    @Schema(description = "mqtt推送生成的业务数据ID")
+    private String mqttDataId;
+
+    @Schema(description = "token")
+    private String token;
+
+    @Schema(description = "关联的项目名称")
+    private String projectName;
+
+    //----------------------------设备信息start ---------------------
+
+    @Schema(description = "操作模式,卡片、人脸、密码、指纹...")
+    private OperateType operateType;
+
+    @Schema(description = "操作记录结果")
+    private OperateState operateState;
+
+    @Schema(description = "设备ID")
+    private String deviceId;
+
+    @Schema(description = "设备类型")
+    private DeviceType deviceType;
+
+    @Schema(description = "设备信息")
+    private DeviceInfoStoreModel deviceInfo;
+
+    @Schema(description = "网关ID")
+    private String gateWayId;
+
+    @Schema(description = "设备所属机构oid")
+    private String beLongOid;
+
+    @Schema(description = "设备所属机构name")
+    private String beLongName;
+
+    //----------------------卡片信息 start-------------------
+
+    @Schema(description = "10进制卡序列号(实体卡号或虚拟卡号)")
+    private String cardNo;
+
     @Schema(description = "卡片信息")
-    private CardInfoModel cardInfoModel;
-
-    @Schema(description = "开门模式(0:刷卡 1:人脸认证 2:指纹 3:密码)")
-    private Integer mode;
-
-    private String modeStr;
-
-    public String getModeStr() {
-        if (mode != null) {
-            if (mode == 0) {
-                return "刷卡";
-            } else if (mode == 1) {
-                return "人脸认证";
-            } else if (mode == 2) {
-                return "指纹";
-            } else if (mode == 3) {
-                return "密码";
-            }
-        }
-        return "";
-    }
+    private CardInfoStoreModel cardInfo;
+
+    //------------------用户信息 start-------------------
+    @Schema(description = "用户userId")
+    private String userId;
+
+    @Schema(description = "用户信息")
+    public UserCountSimpleModel userAccount;
+
+    @Schema(description = "使用时间 2024-09-12 20:40:00")
+    private String time;
+
+    @Schema(description = "时间")
+    private Long timestamp;
+
+    //-----------------------验证是否通过
+
+    @Schema(description = "创建时间,可阅读的")
+    private String createTimeStr;
+
+    @Schema(description = "提示信息")
+    private String msg = "";
+
+    @JsonProperty("IsOffLine")
+    @Schema(description = "是否是离线使用")
+    private Boolean isOffLine = Boolean.FALSE;
+
+    @Schema(description = "过期时间")
+    private Date ttl;
+
+    @Schema(description = "关联的数据")
+    private Object data;
 
 }

+ 19 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/devices/DeviceUseRecordSearch.java

@@ -1,6 +1,8 @@
 package com.zhongshu.card.client.model.devices;
 
 import com.github.microservice.models.type.DeviceType;
+import com.github.microservice.types.deviceUse.OperateState;
+import com.github.microservice.types.deviceUse.OperateType;
 import com.zhongshu.card.client.model.base.SuperSearch;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
@@ -24,5 +26,22 @@ public class DeviceUseRecordSearch extends SuperSearch {
     @Schema(description = "设备类型")
     private DeviceType deviceType;
 
+    @Schema(description = "操作模式,卡片、人脸、密码、指纹...")
+    private OperateType operateType;
+
+    @Schema(description = "操作记录结果")
+    private OperateState operateState;
+
+    @Schema(description = "网关ID")
+    private String gateWayId;
+
+    @Schema(description = "设备所属机构oid")
+    private String beLongOid;
+
+    @Schema(description = "10进制卡序列号(实体卡号或虚拟卡号)")
+    private String cardNo;
+
+    @Schema(description = "用户userId")
+    private String userId;
 
 }

+ 33 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseFlowAreaModel.java

@@ -0,0 +1,33 @@
+package com.zhongshu.card.client.model.payment;
+
+import com.zhongshu.card.client.model.school.AreaSimpleModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.ObjectUtils;
+
+/**
+ * @author TRX
+ * @date 2024/6/17
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ExpenseFlowAreaModel extends ExpenseFlowModel {
+
+    @Schema(description = "设备所属区域信息")
+    private AreaSimpleModel area;
+
+    private String areaName = "";
+
+    public String getAreaName() {
+        if (ObjectUtils.isNotEmpty(area)) {
+            return area.getName();
+        }
+        return "";
+    }
+
+    @Schema(description = "")
+    private String areaNames = "";
+}

+ 2 - 5
FullCardClient/src/main/java/com/zhongshu/card/client/service/payment/ExpenseFlowService.java

@@ -1,9 +1,6 @@
 package com.zhongshu.card.client.service.payment;
 
-import com.zhongshu.card.client.model.payment.ExpenseFlowCount;
-import com.zhongshu.card.client.model.payment.ExpenseFlowModel;
-import com.zhongshu.card.client.model.payment.ExpenseFlowSearch;
-import com.zhongshu.card.client.model.payment.ExpenseRefundParam;
+import com.zhongshu.card.client.model.payment.*;
 import com.zhongshu.card.client.model.payment.statistic.BusinessMainStatisticModel;
 import com.zhongshu.card.client.model.payment.statistic.StatisticSearch;
 import com.github.microservice.net.ResultContent;
@@ -25,7 +22,7 @@ public interface ExpenseFlowService {
 
     ResultContent<ExpenseFlowCount> countBusPayment(ExpenseFlowSearch param);
 
-    ResultContent<ExpenseFlowModel> getDetail(String id);
+    ResultContent<ExpenseFlowAreaModel> getDetail(String id);
 
     ResultContent<ExpenseFlowModel> getDetailByPaymentNo(String paymentNo);
 

+ 17 - 23
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/devices/DeviceUseRecordController.java

@@ -2,11 +2,10 @@ package com.zhongshu.card.server.core.controller.devices;
 
 import com.github.microservice.auth.security.annotations.ResourceAuth;
 import com.github.microservice.auth.security.type.AuthType;
-import com.github.microservice.models.gateDoor.use.GateDoorUseParam;
 import com.github.microservice.net.ResultContent;
 import com.zhongshu.card.client.model.base.IDParam;
-import com.zhongshu.card.client.model.devices.*;
-import com.zhongshu.card.client.service.school.DeviceInfoService;
+import com.zhongshu.card.client.model.devices.DeviceUseRecordModel;
+import com.zhongshu.card.client.model.devices.DeviceUseRecordSearch;
 import com.zhongshu.card.server.core.service.devices.DeviceUseRecordService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -16,10 +15,10 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.web.PageableDefault;
 import org.springframework.util.Assert;
-import org.springframework.web.bind.annotation.*;
-
-import javax.validation.Valid;
-import java.util.List;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * 设备使用日志
@@ -32,34 +31,29 @@ import java.util.List;
 @Tag(name = "平台-设备使用日志")
 public class DeviceUseRecordController {
 
-    @Autowired
-    private DeviceInfoService deviceInfoService;
-
     @Autowired
     private DeviceUseRecordService deviceUseRecordService;
 
     @ResourceAuth(value = "user", type = AuthType.User)
-    @Operation(summary = "根据设备数据ID 设备详情", description = "根据设备数据ID 设备详情")
-    @RequestMapping(value = "getDeviceById", method = {RequestMethod.POST})
-    public ResultContent<DeviceInfoMoreModel> getDeviceById(@RequestBody IDParam param) {
-        return this.deviceInfoService.getDeviceDetail(param.getId());
+    @Operation(summary = "设备使用详情", description = "设备使用详情")
+    @RequestMapping(value = "getDetail", method = {RequestMethod.POST})
+    public ResultContent getDetail(@RequestBody IDParam param) {
+        return this.deviceUseRecordService.getDetail(param.getId());
     }
 
     @ResourceAuth(value = "user", type = AuthType.User)
-    @Operation(summary = "删除设备", description = "删除设备")
-    @RequestMapping(value = "deleteDeviceInfo", method = {RequestMethod.POST})
-    public ResultContent deleteDeviceInfo(@RequestBody IDParam param) {
-        return this.deviceInfoService.deleteDeviceInfo(param.getId());
+    @Operation(summary = "删除设备使用记录", description = "删除设备使用记录")
+    @RequestMapping(value = "deleteById", method = {RequestMethod.POST})
+    public ResultContent deleteById(@RequestBody IDParam param) {
+        return this.deviceUseRecordService.deleteById(param.getId());
     }
 
     @ResourceAuth(value = "user", type = AuthType.User)
-    @Operation(summary = "设备列表-分页查询", description = "设备列表-分页查询")
+    @Operation(summary = "设备使用记录列表-分页查询", description = "设备使用记录列表-分页查询")
     @RequestMapping(value = {"page"}, method = {RequestMethod.POST})
-    public ResultContent<Page<DeviceInfoModel>> page(
-            @Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
-            @Parameter(required = false) DeviceInfoSearch param) {
+    public ResultContent<Page<DeviceUseRecordModel>> page(@Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable, @Parameter(required = false) DeviceUseRecordSearch param) {
         Assert.hasText(param.getProjectOid(), "projectOid不能为空");
-        return deviceInfoService.page(param, pageable);
+        return deviceUseRecordService.page(param, pageable);
     }
 
 }

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

@@ -2,21 +2,17 @@ package com.zhongshu.card.server.core.controller.gateDoor;
 
 
 import com.github.microservice.models.gateDoor.OnLineParam;
-import com.github.microservice.models.gateDoor.use.GateDoorUseParam;
-import com.github.microservice.models.hxz.*;
+import com.github.microservice.models.gateDoor.gateDoor.GateDoorIotParam;
 import com.github.microservice.net.ResultContent;
+import com.zhongshu.card.server.core.service.devices.DeviceUseRecordService;
 import com.zhongshu.card.server.core.service.gateDoor.GateDoorService;
-import com.zhongshu.card.server.core.service.hxz.HxzService;
 import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 @Slf4j
 @RestController
@@ -26,8 +22,11 @@ import org.springframework.web.bind.annotation.RestController;
 public class GateDoorController {
 
     @Autowired
-    GateDoorService gateDoorService;
-    
+    private GateDoorService gateDoorService;
+
+    @Autowired
+    private DeviceUseRecordService deviceUseRecordService;
+
     /**
      * 设备上线通知
      */
@@ -46,4 +45,10 @@ public class GateDoorController {
         return gateDoorService.offLine(param);
     }
 
+    @Operation(summary = "门闸 认证识别人员信息上传", description = "门闸 认证识别人员信息上传")
+    @RequestMapping(value = "recPush", method = {RequestMethod.POST})
+    public ResultContent recPush(@RequestBody GateDoorIotParam param) {
+        return this.deviceUseRecordService.gateDoorUseRecord(param);
+    }
+
 }

+ 0 - 12
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/openAPI/ProjectOpenAPIController.java

@@ -53,16 +53,4 @@ public class ProjectOpenAPIController {
         return devicePermissIotService.getDeviceAboutUserInfos(param);
     }
 
-    @Operation(summary = "物联网添加设备使用日志(通用不带复杂的业务)", description = "物联网添加设备使用日志")
-    @RequestMapping(value = "saveDeviceLogs", method = {RequestMethod.POST})
-    public ResultContent saveDeviceLogs(@RequestBody GateDoorUseParam param) {
-        return this.deviceUseRecordService.saveDeviceLogs(param);
-    }
-
-    @Operation(summary = "门闸 认证识别人员信息上传", description = "认证识别人员信息上传")
-    @RequestMapping(value = "recPush", method = {RequestMethod.POST})
-    public ResultContent recPush(@RequestBody GateDoorUseParam param) {
-        return this.deviceUseRecordService.saveDeviceLogs(param);
-    }
-
 }

+ 4 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/org/TestController.java

@@ -3,6 +3,7 @@ package com.zhongshu.card.server.core.controller.org;
 import com.github.microservice.core.util.bytes.BytesUtil;
 import com.github.microservice.net.ResultContent;
 import com.zhongshu.card.server.core.service.TestService;
+import com.zhongshu.card.server.core.service.devices.DeviceInfoServiceImpl;
 import com.zhongshu.card.server.core.service.openAPI.OpenAPIRegisterService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -27,10 +28,12 @@ public class TestController {
     @Autowired
     OpenAPIRegisterService openAPIRegisterService;
 
+    @Autowired
+    DeviceInfoServiceImpl deviceInfoService;
+
     @Operation(summary = "测试接口", description = "测试接口")
     @RequestMapping(value = "text", method = {RequestMethod.GET})
     public ResultContent text() {
-
 //        openAPIRegisterService.initRegisterPAIS();
         try {
             byte[] bins = BytesUtil.longToBin(Long.parseLong("2152525002"), 4);

+ 2 - 5
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/payment/ExpenseFlowController.java

@@ -5,10 +5,7 @@ import com.github.microservice.auth.security.helper.AuthHelper;
 import com.github.microservice.auth.security.type.AuthType;
 import com.github.microservice.types.OrderModeType;
 import com.zhongshu.card.client.model.base.IDParam;
-import com.zhongshu.card.client.model.payment.ExpenseFlowCount;
-import com.zhongshu.card.client.model.payment.ExpenseFlowModel;
-import com.zhongshu.card.client.model.payment.ExpenseFlowSearch;
-import com.zhongshu.card.client.model.payment.ExpenseRefundParam;
+import com.zhongshu.card.client.model.payment.*;
 import com.zhongshu.card.client.model.payment.statistic.BusinessMainStatisticModel;
 import com.zhongshu.card.client.model.payment.statistic.StatisticSearch;
 import com.github.microservice.net.ResultContent;
@@ -66,7 +63,7 @@ public class ExpenseFlowController {
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "消费详情", description = "消费详情")
     @RequestMapping(value = "getDetail", method = {RequestMethod.POST})
-    public ResultContent<ExpenseFlowModel> getDetail(@RequestBody IDParam param) {
+    public ResultContent<ExpenseFlowAreaModel> getDetail(@RequestBody IDParam param) {
         return this.expenseFlowService.getDetail(param.getId());
     }
 

+ 24 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/devices/impl/DeviceUseRecordDaoImpl.java

@@ -50,6 +50,30 @@ public class DeviceUseRecordDaoImpl extends BaseImpl implements DeviceUseRecordD
             criteria.and("deviceType").is(param.getDeviceType());
         }
 
+        if (param.getOperateType() != null) {
+            criteria.and("operateType").is(param.getOperateType());
+        }
+
+        if (param.getOperateState() != null) {
+            criteria.and("operateState").is(param.getOperateState());
+        }
+
+        if (StringUtils.isNotEmpty(param.getGateWayId())) {
+            criteria.and("gateWayId").is(param.getGateWayId());
+        }
+
+        if (StringUtils.isNotEmpty(param.getBeLongOid())) {
+            criteria.and("beLongOid").is(param.getBeLongOid());
+        }
+
+        if (StringUtils.isNotEmpty(param.getCardNo())) {
+            criteria.and("cardNo").is(param.getCardNo());
+        }
+
+        if (StringUtils.isNotEmpty(param.getUserId())) {
+            criteria.and("userId").is(param.getUserId());
+        }
+
         // 模糊搜索
         List<Criteria> criterias = new ArrayList<>();
         if (StringUtils.isNotEmpty(param.getDeviceId())) {

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

@@ -50,4 +50,5 @@ public interface OrganizationUserDao extends MongoDao<OrganizationUser>, Organiz
 
     List<OrganizationUser> findByUserIdAndProjectOidAndIsOrg(String userId, String projectOid, Boolean isOrg);
 
+    List<OrganizationUser> findByUserId(String userId);
 }

+ 4 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dataConfig/CardSystemDefault.java

@@ -19,4 +19,8 @@ public class CardSystemDefault {
 
     // 平台默认角色名称
     public static final String DEFAULT_ROLE_NAME = "管理员";
+
+    // 系统默认头像 (闸机当头像为空时不能下发,所以设置个默认的)
+    public static final String defaultPermissFaceUrl = "https://zswl-dev.oss-cn-chengdu.aliyuncs.com/665fc0386b0724481afc56d9/store/665fc0386b0724481afc56d9/01457397-2a17-41ae-a6e3-118511e96d13" +
+            ".jpg/1730191730919.jpg";
 }

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

@@ -2,6 +2,8 @@ package com.zhongshu.card.server.core.domain.devices;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.github.microservice.models.type.DeviceType;
+import com.github.microservice.types.deviceUse.OperateState;
+import com.github.microservice.types.deviceUse.OperateType;
 import com.zhongshu.card.client.model.devices.DeviceInfoStoreModel;
 import com.zhongshu.card.client.model.org.UserCountSimpleModel;
 import com.zhongshu.card.client.model.school.CardInfoStoreModel;
@@ -34,7 +36,17 @@ public class DeviceUseRecords extends SuperMain {
     @Schema(description = "token")
     private String token;
 
+    @Schema(description = "关联的项目名称")
+    private String projectName;
+
     //----------------------------设备信息start ---------------------
+
+    @Schema(description = "操作模式,卡片、人脸、密码、指纹...")
+    private OperateType operateType;
+
+    @Schema(description = "操作记录结果")
+    private OperateState operateState;
+
     @Schema(description = "设备ID")
     private String deviceId;
 
@@ -68,26 +80,17 @@ public class DeviceUseRecords extends SuperMain {
     @Schema(description = "用户信息")
     public UserCountSimpleModel userAccount;
 
-    @Schema(description = "使用模式(0:刷卡 1:人脸认证 2:指纹 3:密码)")
-    private Integer mode;
-
     @Schema(description = "使用时间 2024-09-12 20:40:00")
     private String time;
 
     @Schema(description = "时间")
     private Long timestamp;
 
-    @Schema(description = "人脸内容")
-    private String pic;
-
     //-----------------------验证是否通过
 
     @Schema(description = "创建时间,可阅读的")
     private String createTimeStr;
 
-    @Schema(description = "使用是否验证通过")
-    private Boolean isPassed = Boolean.TRUE;
-
     @Schema(description = "提示信息")
     private String msg = "";
 
@@ -99,4 +102,7 @@ public class DeviceUseRecords extends SuperMain {
     @Indexed(expireAfterSeconds = 0)
     private Date ttl;
 
+    @Schema(description = "关联的数据")
+    private Object data;
+
 }

+ 4 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/payment/ExpenseFlow.java

@@ -5,6 +5,7 @@ import com.github.microservice.types.payment.PaymentDeviceType;
 import com.github.microservice.types.payment.PaymentType;
 import com.github.microservice.types.OrderModeType;
 import com.github.microservice.types.OrderState;
+import com.zhongshu.card.client.model.school.AreaSimpleModel;
 import com.zhongshu.card.client.type.RefundState;
 import com.zhongshu.card.server.core.domain.base.SuperMain;
 import com.zhongshu.card.server.core.domain.org.UserAccount;
@@ -69,6 +70,9 @@ public class ExpenseFlow extends SuperMain {
     @Schema(description = "消费机设备ID")
     private String deviceId;
 
+    @Schema(description = "设备所属区域信息")
+    private AreaSimpleModel area;
+
     @Schema(description = "所属项目的code")
     private String projectCode;
 

+ 4 - 3
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/base/CommonService.java

@@ -2,6 +2,7 @@ package com.zhongshu.card.server.core.service.base;
 
 import com.github.microservice.core.util.net.HttpClient;
 import com.mongodb.client.result.UpdateResult;
+import com.zhongshu.card.server.core.domain.devices.DevicePermiss;
 import com.zhongshu.card.server.core.util.CommonUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -47,7 +48,7 @@ public class CommonService {
                 update.set(key, value);
             }
         });
-        UpdateResult updateResult = mongoTemplate.upsert(query, update, collectionName);
+        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, collectionName);
         return updateResult.getUpsertedId();
     }
 
@@ -60,7 +61,7 @@ public class CommonService {
                 update.set(key, value);
             }
         });
-        UpdateResult updateResult = mongoTemplate.upsert(query, update, collectionName);
+        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, collectionName);
         return updateResult.getUpsertedId();
     }
 
@@ -79,7 +80,7 @@ public class CommonService {
                 update.set(key, value);
             }
         });
-        UpdateResult updateResult = mongoTemplate.upsert(query, update, collectionName);
+        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, collectionName);
         return updateResult.getUpsertedId();
     }
 

+ 8 - 13
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DeviceInfoServiceImpl.java

@@ -2,18 +2,17 @@ package com.zhongshu.card.server.core.service.devices;
 
 import com.github.microservice.components.data.base.util.PageEntityUtil;
 import com.github.microservice.models.device.DeviceInfoSyncParam;
-import com.zhongshu.card.client.model.devices.*;
 import com.github.microservice.net.ResultContent;
 import com.github.microservice.net.ResultMessage;
+import com.zhongshu.card.client.model.devices.*;
 import com.zhongshu.card.client.model.org.OrganizationMiniModel;
 import com.zhongshu.card.client.model.org.UserJoinBusOrgModel;
-import com.zhongshu.card.client.model.school.AreaModel;
 import com.zhongshu.card.client.model.school.AreaSimpleModel;
 import com.zhongshu.card.client.service.school.DeviceInfoService;
 import com.zhongshu.card.client.type.OnLineState;
+import com.zhongshu.card.server.core.dao.devices.DeviceInfoDao;
 import com.zhongshu.card.server.core.dao.org.OrganizationDao;
 import com.zhongshu.card.server.core.dao.school.AreaDao;
-import com.zhongshu.card.server.core.dao.devices.DeviceInfoDao;
 import com.zhongshu.card.server.core.domain.devices.DeviceInfo;
 import com.zhongshu.card.server.core.domain.devices.DevicePermiss;
 import com.zhongshu.card.server.core.domain.org.Organization;
@@ -24,7 +23,6 @@ import com.zhongshu.card.server.core.service.org.OrganizationServiceImpl;
 import com.zhongshu.card.server.core.service.orgManager.OrganizationManagerServiceImpl;
 import com.zhongshu.card.server.core.service.school.AreaServiceImpl;
 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;
@@ -49,22 +47,22 @@ import java.util.stream.Collectors;
 public class DeviceInfoServiceImpl extends SuperService implements DeviceInfoService {
 
     @Autowired
-    DeviceInfoDao deviceInfoDao;
+    private DeviceInfoDao deviceInfoDao;
 
     @Autowired
-    AreaServiceImpl areaService;
+    private AreaServiceImpl areaService;
 
     @Autowired
-    AreaDao areaDao;
+    private AreaDao areaDao;
 
     @Autowired
     private OrganizationServiceImpl organizationServiceImpl;
 
     @Autowired
-    OrganizationDao organizationDao;
+    private OrganizationDao organizationDao;
 
     @Autowired
-    OrganizationManagerServiceImpl organizationManagerService;
+    private OrganizationManagerServiceImpl organizationManagerService;
 
     @Autowired
     private CommonService commonService;
@@ -109,11 +107,9 @@ public class DeviceInfoServiceImpl extends SuperService implements DeviceInfoSer
         HashMap<String, Object> bindMap = new HashMap<>();
         bindMap.put("gateWayId", deviceInfo.getGateWayId());
         commonService.updateData(where, bindMap, DevicePermiss.class.getSimpleName());
-
         return ResultContent.buildSuccess();
     }
 
-
     /**
      * 添加-编辑设备
      *
@@ -320,8 +316,7 @@ public class DeviceInfoServiceImpl extends SuperService implements DeviceInfoSer
             long maxTime = 24 * 60 * 60 * 1000;
             List<DeviceInfo> deviceInfos = new ArrayList<>();
             for (DeviceInfo deviceInfo : list) {
-                if (deviceInfo.getLastOnlineTime() == null
-                        || (System.currentTimeMillis() - deviceInfo.getLastOnlineTime()) > maxTime) {
+                if (deviceInfo.getLastOnlineTime() == null || (System.currentTimeMillis() - deviceInfo.getLastOnlineTime()) > maxTime) {
                     deviceInfo.setOnLineState(OnLineState.OffLine);
                     deviceInfos.add(deviceInfo);
                 }

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

@@ -14,6 +14,7 @@ import com.zhongshu.card.client.type.DataState;
 import com.zhongshu.card.client.type.school.CardState;
 import com.zhongshu.card.server.core.dao.devices.DevicePermissDao;
 import com.zhongshu.card.server.core.dao.org.OrganizationDao;
+import com.zhongshu.card.server.core.dataConfig.CardSystemDefault;
 import com.zhongshu.card.server.core.domain.devices.DevicePermiss;
 import com.zhongshu.card.server.core.domain.org.Organization;
 import com.zhongshu.card.server.core.domain.org.UserAccount;
@@ -299,6 +300,9 @@ public class DevicePermissIotService {
             OrgUserFace orgUserFace = orgUserFaceService.getUserFace(userId, projectOid);
             if (ObjectUtils.isNotEmpty(orgUserFace)) {
                 userPermiss.setFi(orgUserFace.getImg());
+            } else {
+                // 默认头像
+                userPermiss.setFi(CardSystemDefault.defaultPermissFaceUrl);
             }
 
             // 查询用户的卡片

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

@@ -1,6 +1,7 @@
 package com.zhongshu.card.server.core.service.devices;
 
 import com.github.microservice.components.data.base.util.PageEntityUtil;
+import com.github.microservice.core.util.os.SystemUtil;
 import com.github.microservice.net.ResultContent;
 import com.github.microservice.net.ResultMessage;
 import com.google.common.collect.Lists;
@@ -31,6 +32,7 @@ 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.context.event.EventListener;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -39,6 +41,8 @@ import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.stream.Collectors;
 
 /**
@@ -70,16 +74,20 @@ public class DevicePermissService extends SuperService {
     private OrganizationUserDao organizationUserDao;
 
     @Autowired
-    private OrgUserFaceService orgUserFaceService;
+    private DevicePermissEventService devicePermissEventService;
 
     @Autowired
-    private CardInfoServiceImpl cardInfoService;
+    private DevicePermissIotService devicePermissIotService;
 
-    @Autowired
-    private DevicePermissEventService devicePermissEventService;
+    //线程池
+    private ExecutorService executorService = Executors.newFixedThreadPool(SystemUtil.getCpuCoreCount() * 2);
 
     @Autowired
-    private DevicePermissIotService devicePermissIotService;
+    private void init(ApplicationContext applicationContext) {
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            executorService.shutdownNow();
+        }));
+    }
 
     /**
      * 设备绑定用户
@@ -174,30 +182,35 @@ public class DevicePermissService extends SuperService {
     @Async
     @SneakyThrows
     public void syncOrgUserChangeInfo(OrgUserBindUpdateSyncEvent event) {
-        log.info("机构用户信息发生变化 syncOrgUserChangeInfo...");
-        DataOperationType dataOperationType = event.getDataOperationType();
-        List<String> organizationUserIds = event.getOrganizationUserIds();
-        if (dataOperationType != null) {
-            List<OrganizationUser> organizationUsers = organizationUserDao.findByIdIn(organizationUserIds);
-            if (ObjectUtils.isNotEmpty(organizationUsers)) {
-                List<DevicePermiss> list = devicePermissDao.findByOrganizationUserIn(organizationUsers);
-                if (ObjectUtils.isEmpty(list)) {
-                    return;
-                }
-                if (dataOperationType == DataOperationType.Update) {
-                    for (DevicePermiss permiss : list) {
-                        buildOrgUserInfo(permiss, permiss.getOrganizationUser());
+        executorService.execute(() -> {
+            log.info("机构用户信息发生变化 syncOrgUserChangeInfo...");
+            DataOperationType dataOperationType = event.getDataOperationType();
+            List<String> organizationUserIds = event.getOrganizationUserIds();
+            if (dataOperationType != null) {
+                List<OrganizationUser> organizationUsers = organizationUserDao.findByIdIn(organizationUserIds);
+                if (ObjectUtils.isNotEmpty(organizationUsers)) {
+                    List<DevicePermiss> list = devicePermissDao.findByOrganizationUserIn(organizationUsers);
+                    if (ObjectUtils.isEmpty(list)) {
+                        return;
+                    }
+                    String projectOid = organizationUsers.get(0).getProjectOid();
+                    if (dataOperationType == DataOperationType.Update) {
+                        for (DevicePermiss permiss : list) {
+                            buildOrgUserInfo(permiss, permiss.getOrganizationUser());
+                        }
+                        devicePermissDao.saveAll(list);
+                        // 通知权限下发用户信息 编辑
+                        List<String> userIds = organizationUsers.stream().map(OrganizationUser::getUserId).distinct().collect(Collectors.toList());
+                        devicePermissEventService.sendUserInfoChangeEvent(userIds, projectOid);
+                    } else if (dataOperationType == DataOperationType.Delete) {
+                        // 下发移除权限
+                        devicePermissIotService.changeDeviceUser(list, 0);
+                        // 删除
+                        devicePermissDao.deleteAll(list);
                     }
-                    devicePermissDao.saveAll(list);
-                } else if (dataOperationType == DataOperationType.Delete) {
-                    devicePermissDao.deleteAll(list);
                 }
-                // 通知权限下发
-                String projectOid = list.get(0).getProjectOid();
-                List<String> deviceIds = list.stream().map(it -> it.getDeviceId()).collect(Collectors.toUnmodifiableList());
-                devicePermissEventService.sendDeviceChangeEvent(deviceIds, projectOid);
             }
-        }
+        });
     }
 
 

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

@@ -1,18 +1,26 @@
 package com.zhongshu.card.server.core.service.devices;
 
 import cn.hutool.json.JSONUtil;
+import com.github.microservice.components.data.base.util.PageEntityUtil;
+import com.github.microservice.models.gateDoor.gateDoor.GateDoorIotParam;
+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.model.devices.DeviceUseRecordModel;
+import com.zhongshu.card.client.model.devices.DeviceUseRecordSearch;
 import com.zhongshu.card.client.utils.DateUtils;
 import com.zhongshu.card.server.core.dao.devices.DeviceInfoDao;
 import com.zhongshu.card.server.core.dao.devices.DevicePermissDao;
 import com.zhongshu.card.server.core.dao.devices.DeviceUseRecordDao;
+import com.zhongshu.card.server.core.dao.org.OrganizationDao;
 import com.zhongshu.card.server.core.dao.org.UserCountDao;
 import com.zhongshu.card.server.core.dao.school.CardInfoDao;
 import com.zhongshu.card.server.core.domain.devices.DeviceInfo;
 import com.zhongshu.card.server.core.domain.devices.DeviceUseRecords;
+import com.zhongshu.card.server.core.domain.org.Organization;
 import com.zhongshu.card.server.core.domain.org.UserAccount;
 import com.zhongshu.card.server.core.domain.school.CardInfo;
 import com.zhongshu.card.server.core.service.base.SuperService;
@@ -24,8 +32,12 @@ 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.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
+import java.util.Date;
+
 /**
  * @author TRX
  * @date 2024/10/21
@@ -58,25 +70,92 @@ public class DeviceUseRecordService extends SuperService {
     @Autowired
     private DeviceInfoServiceImpl deviceInfoService;
 
+    @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));
+    }
+
     /**
      * 设备使用日志 (物联网来的数据)
      *
      * @param param
      * @return
      */
-    public ResultContent saveDeviceLogs(GateDoorUseParam param) {
+    public ResultContent<DeviceUseRecords> saveDeviceLogs(GateDoorUseParam param) {
         // 返回数据
-        GateDoorUseResult result = new GateDoorUseResult();
         String mqttDataId = param.getMqttDataId();
+        DeviceUseRecords deviceUseRecord = null;
         log.info("saveDeviceUseRecord mqttDataId: {}", mqttDataId);
         if (StringUtils.isNotEmpty(mqttDataId)) {
-            DeviceUseRecords deviceUseRecord = init(mqttDataId);
+            deviceUseRecord = init(mqttDataId);
             if (ObjectUtils.isNotEmpty(deviceUseRecord)) {
                 BeanUtils.copyProperties(param, deviceUseRecord);
                 String deviceId = param.getDeviceId();
                 String cardNo = param.getCardNo();
                 String userId = param.getUserId();
-
                 String projectOid = "";
                 DeviceInfo deviceInfo = null;
                 if (StringUtils.isNotEmpty(deviceId)) {
@@ -100,7 +179,7 @@ public class DeviceUseRecordService extends SuperService {
                 CardInfo cardInfo = null;
                 if (StringUtils.isNotEmpty(cardNo)) {
                     cardInfo = cardInfoDao.findByCode(cardNo);
-                    if (ObjectUtils.isNotEmpty(cardInfo)) {
+                    if (StringUtils.isEmpty(userId) && ObjectUtils.isNotEmpty(cardInfo)) {
                         userId = cardInfo.getUserId();
                     }
                 }
@@ -116,51 +195,23 @@ public class DeviceUseRecordService extends SuperService {
                 }
                 deviceUseRecord.setUserId(userId);
                 deviceUseRecord.setUserAccount(userAccountService.toSimpleModel(userAccount));
-
                 if (StringUtils.isNotEmpty(param.getTime())) {
                     deviceUseRecord.setTimestamp(DateUtils.timeToLong(param.getTime(), DateUtils.FORMAT_LONG));
                 }
                 deviceUseRecord.setProjectOid(projectOid);
-                // 是否是离线的日志(离线的话已经操作了,不能验证数据)
-                Boolean isOffLine = param.getIsOffLine();
-                if (isOffLine == null) {
-                    isOffLine = Boolean.FALSE;
-                }
-                deviceUseRecord.setIsOffLine(isOffLine);
-                if (isOffLine != null && isOffLine) {
-                    Boolean isPassed = param.getIsPassed();
-                    if (isPassed == null) {
-                        isPassed = Boolean.FALSE;
-                    }
-                    // 离线的数据
-                    deviceUseRecord.setIsPassed(isPassed);
-                    if (isPassed) {
-                        deviceUseRecord.setMsg("操作成功");
-                    } else {
-                        deviceUseRecord.setMsg("验证失败");
-                    }
-                } else {
-                    // 在线验证
-                    checkUseDeviceData(deviceUseRecord);
-                }
-
-                // 最后的返回判断
-                if (deviceUseRecord.getIsPassed() != null && deviceUseRecord.getIsPassed()) {
-                    // 成功
-                    result.setSuccess();
-                } else {
-                    // 失败
-                    result.setFailed(deviceUseRecord.getMsg());
+                Organization organization = organizationDao.findTopByOid(projectOid);
+                if (ObjectUtils.isNotEmpty(organization)) {
+                    deviceUseRecord.setProjectName(organization.getName());
                 }
+                deviceUseRecord.setTtl(new Date(System.currentTimeMillis() + ttlTime));
                 deviceUseRecordDao.save(deviceUseRecord);
             } else {
-                result.setFailed("数据已处理");
+                return ResultContent.buildFail("数据初始失败");
             }
         } else {
-            result.setFailed("mqttDataId为空");
+            return ResultContent.buildFail("mqttDataId为空");
         }
-        result.setMqttDataId(mqttDataId);
-        return ResultContent.buildSuccess(JSONUtil.toJsonStr(result));
+        return ResultContent.buildSuccess(deviceUseRecord);
     }
 
     public DeviceUseRecords init(String mqttDataId) {
@@ -248,6 +299,28 @@ public class DeviceUseRecordService extends SuperService {
 //        }
     }
 
+    public ResultContent<Page<DeviceUseRecordModel>> page(DeviceUseRecordSearch param, Pageable pageable) {
+        Page<DeviceUseRecords> page = deviceUseRecordDao.page(pageable, param);
+        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
+    }
+
+    public ResultContent getDetail(String id) {
+        DeviceUseRecords entity = deviceUseRecordDao.findTopById(id);
+        if (ObjectUtils.isEmpty(entity)) {
+            return ResultContent.buildFail(String.format("数据不存在"));
+        }
+        return ResultContent.buildSuccess(toModel(entity));
+    }
+
+    public ResultContent deleteById(String id) {
+        DeviceUseRecords entity = deviceUseRecordDao.findTopById(id);
+        if (ObjectUtils.isEmpty(entity)) {
+            return ResultContent.buildFail(String.format("数据不存在"));
+        }
+        deviceUseRecordDao.delete(entity);
+        return ResultContent.buildSuccess();
+    }
+
     /**
      * 模型转换
      *

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

@@ -7,6 +7,7 @@ import com.github.microservice.auth.client.service.OrganizationUserService;
 import com.github.microservice.auth.client.service.RoleService;
 import com.github.microservice.auth.security.type.AuthType;
 import com.github.microservice.core.util.bean.BeanUtil;
+import com.github.microservice.core.util.os.SystemUtil;
 import com.github.microservice.net.ResultContent;
 import com.zhongshu.card.client.model.base.ProjectOidParam;
 import com.zhongshu.card.client.model.org.*;
@@ -24,6 +25,7 @@ import com.zhongshu.card.server.core.domain.school.DictInfo;
 import com.zhongshu.card.server.core.event.OrgUserBindUpdateSyncEvent;
 import com.zhongshu.card.server.core.model.org.OrgBindUserParam;
 import com.zhongshu.card.server.core.service.base.SuperService;
+import com.zhongshu.card.server.core.service.devices.DevicePermissEventService;
 import com.zhongshu.card.server.core.service.orgManager.OrganizationManagerServiceImpl;
 import com.zhongshu.card.server.core.service.school.DictInfoServiceImpl;
 import com.zhongshu.card.server.core.service.user.DepartmentServiceImpl;
@@ -53,6 +55,10 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -108,6 +114,9 @@ public class OrganizationUserServiceImpl extends SuperService {
     @Autowired
     private OrganizationRelationDao organizationRelationDao;
 
+    @Autowired
+    private DevicePermissEventService devicePermissEventService;
+
     /**
      * 添加编辑用户 添加机构用户 (包括角色 部门 职位等信息)
      * 用户可能不存在
@@ -733,6 +742,36 @@ public class OrganizationUserServiceImpl extends SuperService {
         ExcelUtils.commonExecuteExcel(request, response, execlParam);
     }
 
+    /**
+     * 用户基础信息发送变化
+     *
+     * @param userId
+     */
+    public void changeUserBaseInfo(String userId, String projectOid) {
+        if (StringUtils.isEmpty(userId)) {
+            CompletableFuture.runAsync(() -> {
+                List<String> projectOids = new ArrayList<>();
+                if (StringUtils.isEmpty(projectOid)) {
+                    List<OrganizationUser> list = organizationUserDao.findByUserId(userId);
+                    if (ObjectUtils.isNotEmpty(list)) {
+                        projectOids = list.stream().map(OrganizationUser::getProjectOid).distinct().collect(Collectors.toList());
+                    }
+                } else {
+                    projectOids.add(projectOid);
+                }
+                try {
+                    List<String> userIds = List.of(userId);
+                    for (String _projectOid : projectOids) {
+                        devicePermissEventService.sendUserInfoChangeEvent(userIds, _projectOid);
+                        TimeUnit.SECONDS.sleep(1);
+                    }
+                } catch (Exception e) {
+                    log.error(e.getMessage());
+                }
+            });
+        }
+    }
+
     /**
      * 转换机构用户信息(基本信息 角色  部门)
      *

+ 36 - 7
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/payment/ExpenseFlowServiceImpl.java

@@ -21,13 +21,11 @@ import com.github.microservice.types.OrderState;
 import com.zhongshu.card.client.model.base.SuperSearch;
 import com.zhongshu.card.client.model.operLogs.OperationLogsAddParam;
 import com.zhongshu.card.client.model.org.UserJoinBusOrgModel;
-import com.zhongshu.card.client.model.payment.ExpenseFlowCount;
-import com.zhongshu.card.client.model.payment.ExpenseFlowModel;
-import com.zhongshu.card.client.model.payment.ExpenseFlowSearch;
-import com.zhongshu.card.client.model.payment.ExpenseRefundParam;
+import com.zhongshu.card.client.model.payment.*;
 import com.zhongshu.card.client.model.payment.statistic.BusinessMainStatisticModel;
 import com.zhongshu.card.client.model.payment.statistic.StatisticItem;
 import com.zhongshu.card.client.model.payment.statistic.StatisticSearch;
+import com.zhongshu.card.client.model.school.AreaSimpleModel;
 import com.zhongshu.card.client.service.payment.ExpenseFlowService;
 import com.zhongshu.card.client.type.*;
 import com.zhongshu.card.client.type.school.CardState;
@@ -54,6 +52,7 @@ import com.zhongshu.card.server.core.service.base.SuperService;
 import com.zhongshu.card.server.core.service.org.OrganizationServiceImpl;
 import com.zhongshu.card.server.core.service.pay.BalancePayService;
 import com.zhongshu.card.server.core.service.paySetting.ProjectPaySettingServiceImpl;
+import com.zhongshu.card.server.core.service.school.AreaServiceImpl;
 import com.zhongshu.card.server.core.service.user.OperationLogsService;
 import com.zhongshu.card.server.core.util.*;
 import com.zhongshu.payment.client.model.param.AmountUpdateParam;
@@ -74,6 +73,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -85,6 +85,7 @@ import java.util.stream.Collectors;
 @Slf4j
 @Service
 public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowService {
+
     @Autowired
     ExpenseFlowDao expenseFlowDao;
 
@@ -130,6 +131,9 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
     @Autowired
     private PayCallService payCallService;
 
+    @Autowired
+    private AreaServiceImpl areaService;
+
     /**
      * 创建流水
      *
@@ -290,6 +294,8 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
             return;
         }
         entity.setShopOid(deviceInfo.getBeLongOid());
+        // 设备区域
+        entity.setArea(areaService.toSimpleModel(deviceInfo.getArea()));
 
         // 填充项目信息
         String projectOid = deviceInfo.getProjectOid();
@@ -726,12 +732,12 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
      * @param id
      * @return
      */
-    public ResultContent<ExpenseFlowModel> getDetail(String id) {
+    public ResultContent<ExpenseFlowAreaModel> getDetail(String id) {
         ExpenseFlow entity = expenseFlowDao.findTopById(id);
         if (ObjectUtils.isEmpty(entity)) {
             return ResultContent.buildSuccess(String.format(ResultMessage.DATA_NOT_EXIST, id));
         }
-        ExpenseFlowModel model = toModel(entity);
+        ExpenseFlowAreaModel model = toAreaModel(entity);
         return ResultContent.buildSuccess(model);
     }
 
@@ -775,10 +781,33 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
         ExpenseFlowModel model = new ExpenseFlowModel();
         if (ObjectUtils.isNotEmpty(entity)) {
             BeanUtils.copyProperties(entity, model);
-
             // 卡片信息
+            // 用户信息
+        }
+        return model;
+    }
 
+    /**
+     * 包含区域的model
+     *
+     * @param entity
+     * @return
+     */
+    public ExpenseFlowAreaModel toAreaModel(ExpenseFlow entity) {
+        ExpenseFlowAreaModel model = new ExpenseFlowAreaModel();
+        if (ObjectUtils.isNotEmpty(entity)) {
+            BeanUtils.copyProperties(entity, model);
+            // 卡片信息
             // 用户信息
+            AreaSimpleModel simpleModel = entity.getArea();
+            if (ObjectUtils.isNotEmpty(simpleModel)) {
+                List<AreaSimpleModel> areas = areaService.getParents(simpleModel.getId());
+                if (ObjectUtils.isNotEmpty(areas)) {
+                    Collections.reverse(areas);
+                    List<String> names = areas.stream().map(it -> it.getName()).collect(Collectors.toList());
+                    model.setAreaNames(String.join("/", names));
+                }
+            }
         }
         return model;
     }

+ 9 - 5
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/user/UserAccountServiceImpl.java

@@ -3,8 +3,6 @@ package com.zhongshu.card.server.core.service.user;
 import com.github.microservice.auth.client.content.ResultState;
 import com.github.microservice.auth.client.model.UserAuthModel;
 import com.github.microservice.auth.client.model.UserModel;
-import com.github.microservice.auth.client.service.OrganizationUserService;
-import com.github.microservice.auth.client.service.RoleService;
 import com.github.microservice.auth.client.service.UserService;
 import com.github.microservice.auth.client.type.LoginType;
 import com.github.microservice.components.data.base.util.PageEntityUtil;
@@ -16,19 +14,20 @@ import com.zhongshu.card.client.model.base.UserIdModel;
 import com.zhongshu.card.client.model.org.*;
 import com.zhongshu.card.client.model.org.role.RoleModel;
 import com.zhongshu.card.client.model.school.DictInfoSimpleModel;
-import com.zhongshu.card.client.service.org.OrganizationService;
 import com.zhongshu.card.client.service.org.UserAccountService;
 import com.zhongshu.card.client.type.Sex;
 import com.zhongshu.card.client.type.UserLoginType;
 import com.zhongshu.card.client.type.UserState;
 import com.zhongshu.card.client.type.UserType;
-import com.zhongshu.card.server.core.dao.org.*;
-import com.zhongshu.card.server.core.dao.school.DictInfoDao;
+import com.zhongshu.card.server.core.dao.org.OrganizationDao;
+import com.zhongshu.card.server.core.dao.org.OrganizationUserDao;
+import com.zhongshu.card.server.core.dao.org.UserCountDao;
 import com.zhongshu.card.server.core.dataConfig.CardSystemDefault;
 import com.zhongshu.card.server.core.domain.org.Organization;
 import com.zhongshu.card.server.core.domain.org.OrganizationUser;
 import com.zhongshu.card.server.core.domain.org.UserAccount;
 import com.zhongshu.card.server.core.service.base.SuperService;
+import com.zhongshu.card.server.core.service.devices.DevicePermissEventService;
 import com.zhongshu.card.server.core.service.org.OrganizationServiceImpl;
 import com.zhongshu.card.server.core.service.org.OrganizationUserServiceImpl;
 import com.zhongshu.card.server.core.service.orgManager.OrganizationManagerServiceImpl;
@@ -87,6 +86,9 @@ public class UserAccountServiceImpl extends SuperService implements UserAccountS
     @Autowired
     DictInfoServiceImpl dictInfoService;
 
+    @Autowired
+    private OrganizationUserServiceImpl organizationUserService;
+
     /**
      * 注册基本用户 (没有就注册,有就修改)
      *
@@ -351,6 +353,8 @@ public class UserAccountServiceImpl extends SuperService implements UserAccountS
         BeanUtils.copyProperties(param, account);
         account.setSpellCode(CommonUtil.getPinyin(account.getName()));
         userCountDao.save(account);
+        String projectOid = getCurrentProjectOid();
+        organizationUserService.changeUserBaseInfo(account.getUserId(), projectOid);
         return ResultContent.buildSuccess();
     }