王鑫刚 hace 2 meses
padre
commit
d1451e0ea7
Se han modificado 100 ficheros con 2383 adiciones y 391 borrados
  1. 29 2
      yqk-common/pom.xml
  2. 45 0
      yqk-common/src/main/java/com/yx/face/boot/RabbitMqConstants.java
  3. 52 0
      yqk-common/src/main/java/com/yx/face/boot/core/Constants.java
  4. 24 0
      yqk-common/src/main/java/com/yx/face/boot/easyexcel/CollectCustomMerge.java
  5. 143 0
      yqk-common/src/main/java/com/yx/face/boot/easyexcel/CustomMergeStrategy.java
  6. 39 0
      yqk-common/src/main/java/com/yx/face/boot/mybatis/LanguageDriverUpdateIn.java
  7. 35 0
      yqk-common/src/main/java/com/yx/face/boot/mybatis/MyMetaObjectHandler.java
  8. 30 0
      yqk-common/src/main/java/com/yx/face/boot/mybatis/MybatisConfig.java
  9. 39 0
      yqk-common/src/main/java/com/yx/face/boot/uitls/AddressUtil.java
  10. 39 0
      yqk-common/src/main/java/com/yx/face/boot/uitls/Chinese2PinyinUtil.java
  11. 6 0
      yqk-common/src/main/java/com/yx/face/model/entity/DownFaceNew.java
  12. 6 1
      yqk-common/src/main/java/com/yx/face/model/entity/FaceDevice.java
  13. 65 0
      yqk-common/src/main/java/com/yx/face/model/entity/StatAge.java
  14. 92 0
      yqk-common/src/main/java/com/yx/face/model/entity/StatData.java
  15. 91 0
      yqk-common/src/main/java/com/yx/face/model/entity/StatDataItem.java
  16. 66 0
      yqk-common/src/main/java/com/yx/face/model/entity/StatPeople.java
  17. 65 0
      yqk-common/src/main/java/com/yx/face/model/entity/StatSex.java
  18. 65 0
      yqk-common/src/main/java/com/yx/face/model/entity/StatSource.java
  19. 4 1
      yqk-common/src/main/java/com/yx/face/model/entity/UserInfo.java
  20. 10 1
      yqk-common/src/main/java/com/yx/face/model/entity/UserVisitorListDetail.java
  21. 3 0
      yqk-common/src/main/java/com/yx/face/model/entity/Visitee.java
  22. 58 0
      yqk-common/src/main/java/com/yx/face/model/entity/issue/IssueDevice.java
  23. 85 0
      yqk-common/src/main/java/com/yx/face/model/entity/issue/IssueDeviceItem.java
  24. 52 0
      yqk-common/src/main/java/com/yx/face/model/entity/issue/IssueDeviceUser.java
  25. 2 1
      yqk-common/src/main/java/com/yx/face/model/enums/FaceDeviceTypeEnum.java
  26. 39 0
      yqk-common/src/main/java/com/yx/face/model/enums/StatAgeTypeEnum.java
  27. 36 0
      yqk-common/src/main/java/com/yx/face/model/enums/StatDataStatusEnum.java
  28. 44 0
      yqk-common/src/main/java/com/yx/face/model/enums/issue/IssueStatusEnum.java
  29. 47 0
      yqk-common/src/main/java/com/yx/face/model/enums/issue/IssueTypeEnum.java
  30. 25 0
      yqk-common/src/main/java/com/yx/face/model/enums/issue/IssueUserTypeEnum.java
  31. 0 71
      yqk-job/src/main/java/com/yx/face/boot/core/Constants.java
  32. 5 0
      yqk-job/src/main/java/com/yx/face/boot/rabbitConfig/config/ProducerConsumerConfig.java
  33. 0 3
      yqk-job/src/main/java/com/yx/face/dao/ExamUserWhitelistDao.java
  34. 1 1
      yqk-job/src/main/java/com/yx/face/dao/FaceRequestLogDao.java
  35. 1 1
      yqk-job/src/main/java/com/yx/face/dao/HealthCodeDao.java
  36. 1 1
      yqk-job/src/main/java/com/yx/face/dao/RoleAuthDao.java
  37. 1 1
      yqk-job/src/main/java/com/yx/face/dao/RoleDao.java
  38. 17 0
      yqk-job/src/main/java/com/yx/face/dao/StatAgeDao.java
  39. 15 0
      yqk-job/src/main/java/com/yx/face/dao/StatDataDao.java
  40. 16 0
      yqk-job/src/main/java/com/yx/face/dao/StatDataItemDao.java
  41. 16 0
      yqk-job/src/main/java/com/yx/face/dao/StatPeopleDao.java
  42. 16 0
      yqk-job/src/main/java/com/yx/face/dao/StatSexDao.java
  43. 16 0
      yqk-job/src/main/java/com/yx/face/dao/StatSourceDao.java
  44. 0 3
      yqk-job/src/main/java/com/yx/face/dao/UserControlEarlyWarningListDao.java
  45. 0 5
      yqk-job/src/main/java/com/yx/face/dao/UserControlEarlyWarningListLogDao.java
  46. 1 1
      yqk-job/src/main/java/com/yx/face/dao/UserFaceRecordsDao.java
  47. 0 2
      yqk-job/src/main/java/com/yx/face/dao/UserVisitorListDetailDao.java
  48. 0 1
      yqk-job/src/main/java/com/yx/face/dao/UserWhitelistDao.java
  49. 0 1
      yqk-job/src/main/java/com/yx/face/dao/WarningLogDao.java
  50. 30 0
      yqk-job/src/main/java/com/yx/face/model/dto/UserVisitorListDetailHealth.java
  51. 5 1
      yqk-job/src/main/java/com/yx/face/model/dto/UserVisitorListDetailInfo.java
  52. 0 2
      yqk-job/src/main/java/com/yx/face/model/dto/UserVisitorListDetailVisitor.java
  53. 32 0
      yqk-job/src/main/java/com/yx/face/model/mq/StatDataMq.java
  54. 3 0
      yqk-job/src/main/java/com/yx/face/model/vo/AdminVO.java
  55. 0 1
      yqk-job/src/main/java/com/yx/face/server/DingTalkServer.java
  56. 0 3
      yqk-job/src/main/java/com/yx/face/service/UserControlEarlyWarningListService.java
  57. 0 1
      yqk-job/src/main/java/com/yx/face/service/UserVisitorListDetailService.java
  58. 1 6
      yqk-job/src/main/java/com/yx/face/service/dataFix/impl/DataFixServiceImpl.java
  59. 0 1
      yqk-job/src/main/java/com/yx/face/service/impl/AdminServiceImpl.java
  60. 0 1
      yqk-job/src/main/java/com/yx/face/service/impl/AdminTagServiceImpl.java
  61. 1 6
      yqk-job/src/main/java/com/yx/face/service/impl/FaceServiceImpl.java
  62. 4 10
      yqk-job/src/main/java/com/yx/face/service/impl/FaceTBServiceImpl.java
  63. 1 2
      yqk-job/src/main/java/com/yx/face/service/impl/InOutStatisticsServiceImpl.java
  64. 0 1
      yqk-job/src/main/java/com/yx/face/service/impl/UserBlackListServiceImpl.java
  65. 1 6
      yqk-job/src/main/java/com/yx/face/service/impl/UserControlEarlyWarningListServiceImpl.java
  66. 0 1
      yqk-job/src/main/java/com/yx/face/service/impl/UserVisitorListDetailServiceImpl.java
  67. 0 1
      yqk-job/src/main/java/com/yx/face/service/job/FaceServiceTask.java
  68. 0 1
      yqk-job/src/main/java/com/yx/face/service/job/FkjDeviceTask.java
  69. 0 7
      yqk-job/src/main/java/com/yx/face/service/job/FkjQrcodeTask.java
  70. 0 2
      yqk-job/src/main/java/com/yx/face/service/job/InOutStatisticsTask.java
  71. 1 5
      yqk-job/src/main/java/com/yx/face/service/job/SpiIotUserWhitelistTask.java
  72. 71 0
      yqk-job/src/main/java/com/yx/face/service/job/StatDataTask.java
  73. 52 25
      yqk-job/src/main/java/com/yx/face/service/job/TbFaceTestTask.java
  74. 0 2
      yqk-job/src/main/java/com/yx/face/service/job/UserCattleTask.java
  75. 0 51
      yqk-job/src/main/java/com/yx/face/service/job/UserInfoJob.java
  76. 4 0
      yqk-job/src/main/java/com/yx/face/service/job/ZeroTask.java
  77. 0 1
      yqk-job/src/main/java/com/yx/face/service/job/fiveMinute/VisitorClearTask.java
  78. 0 1
      yqk-job/src/main/java/com/yx/face/service/job/zeroTask/AdminDataShowTask.java
  79. 0 4
      yqk-job/src/main/java/com/yx/face/service/job/zeroTask/ClearFaceLogTask.java
  80. 49 0
      yqk-job/src/main/java/com/yx/face/service/job/zeroTask/ClearStatTask.java
  81. 0 4
      yqk-job/src/main/java/com/yx/face/service/job/zeroTask/ClearVisitorDataTask.java
  82. 0 1
      yqk-job/src/main/java/com/yx/face/service/job/zeroTask/UserInfoTask.java
  83. 301 0
      yqk-job/src/main/java/com/yx/face/service/mq/StatServer.java
  84. 7 5
      yqk-job/src/main/resources/application-prod.yml
  85. 4 2
      yqk-job/src/main/resources/application-test.yml
  86. 3 0
      yqk-linkage/src/main/java/com/yixin/ms/model/vo/HealtCodeUserVO.java
  87. 1 0
      yqk-linkage/src/main/java/com/yixin/ms/service/impl/HealthCodeServiceImpl.java
  88. 1 1
      yqk-linkage/src/main/resources/application.yml
  89. 5 0
      yqk-master/pom.xml
  90. 112 0
      yqk-master/src/main/java/com/yx/face/boot/config/WebsocketConfig.java
  91. 79 0
      yqk-master/src/main/java/com/yx/face/boot/consumer/HhfaceIssueConsumer.java
  92. 0 59
      yqk-master/src/main/java/com/yx/face/boot/core/Constants.java
  93. 43 31
      yqk-master/src/main/java/com/yx/face/boot/rabbitConfig/config/ProducerConsumerConfig.java
  94. 40 2
      yqk-master/src/main/java/com/yx/face/boot/rabbitConfig/config/SnQuenueConfig.java
  95. 0 34
      yqk-master/src/main/java/com/yx/face/boot/rabbitConfig/listener/PutFaceQueueListener.java
  96. 11 1
      yqk-master/src/main/java/com/yx/face/boot/uitls/RedisUtil.java
  97. 14 1
      yqk-master/src/main/java/com/yx/face/constant/RabbitMqConstants.java
  98. 1 1
      yqk-master/src/main/java/com/yx/face/controller/TBFaceController.java
  99. 4 5
      yqk-master/src/main/java/com/yx/face/controller/UploadController.java
  100. 60 5
      yqk-master/src/main/java/com/yx/face/controller/admin/AdminDataShowController.java

+ 29 - 2
yqk-common/pom.xml

@@ -83,7 +83,12 @@
                     <artifactId>mybatis-spring-boot-starter</artifactId>
                     <groupId>org.mybatis.spring.boot</groupId>
                 </exclusion>
+                <exclusion>
+                    <artifactId>jsqlparser</artifactId>
+                    <groupId>com.github.jsqlparser</groupId>
+                </exclusion>
             </exclusions>
+
         </dependency>
 
         <dependency>
@@ -152,7 +157,7 @@
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
-            <version>5.7.0</version>
+            <version>5.8.11</version>
         </dependency>
         <dependency>
             <groupId>com.squareup.okhttp3</groupId>
@@ -268,7 +273,29 @@
             <groupId>org.aspectj</groupId>
             <artifactId>aspectjweaver</artifactId>
         </dependency>
+        <!-- 数据库相关 https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.2</version>
+        </dependency>
 
-
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-extension</artifactId>
+            <version>3.5.2</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/com.belerweb/pinyin4j -->
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>2.5.1</version>
+        </dependency>
+        <!--========================【EXCEL相关依赖】===============================-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>2.2.8</version>
+        </dependency>
     </dependencies>
 </project>

+ 45 - 0
yqk-common/src/main/java/com/yx/face/boot/RabbitMqConstants.java

@@ -0,0 +1,45 @@
+package com.yx.face.boot;
+
+/**
+ * @author shisl
+ * @package com.yx.face.constant
+ * @class RabbitMqConstants
+ * @date 2023/4/20 上午9:22
+ * @description
+ */
+public interface RabbitMqConstants {
+
+    /**
+     * iot设备用户同步
+     */
+    String IOT_USER_QUEUE_NAME = "iotUserQueue";
+    String IOT_MESSAGE_TYPE_addSingleUser2iot = "addSingleUser2Iot";
+    String IOT_MESSAGE_TYPE_delUserFromIot = "delUserFromIot";
+    String IOT_MESSAGE_TYPE_batchAddUser2Iot = "batchAddUser2Iot";
+    String IOT_MESSAGE_TYPE_delBySn = "delBySn";
+
+    /**
+     * 用户信息 推送到政务网
+     */
+    String USER_INFO_QUEUE_NAME = "userInfoQueue";
+    String USER_MESSAGE_TYPE_ADD = "addUser";
+    String USER_MESSAGE_TYPE_UPDATE = "updateUser";
+    String USER_MESSAGE_TYPE_DEL = "delUser";
+
+
+    /**
+     * 人员数据下发和删除mq
+     */
+    String GENERAL_USER_QUEUE_NAME = "generalUserQueue";
+    String GENERAL_MESSAGE_TYPE_addSingleUser2Device = "addSingleUser2Device";
+    String GENERAL_MESSAGE_TYPE_batchAddUser2Device = "batchAddUser2Device";
+    String GENERA_MESSAGE_TYPE_delUserFromDevice = "delUserFromDevice";
+    String GENERAL_MESSAGE_TYPE_delUserBySn = "delBySn";
+    String GENERAL_MESSAGE_TYPE_issueCancel = "issueCancel";
+    /**
+     * 人员数据下发和删除mq回调
+     */
+    String GENERAL_USER_CALLBACK_QUEUE_NAME = "generalUserCallbackQueue";
+
+
+}

+ 52 - 0
yqk-common/src/main/java/com/yx/face/boot/core/Constants.java

@@ -52,4 +52,56 @@ public class Constants {
     public static final String IN_OUT_WARNING = "IN_OUT_WARNING:";
     /*访客机加密key值*/
     public static final String FKJ_KEY = "a2f0e24913f378add01b9f36546a2edb";
+
+    public static final Integer DEVICE_DELAY = 5000;//设备缓存延迟时间 单位(毫秒)
+    public static final String DEVICE_EXCHANGE = "sn.delay.exchange";
+    public static final String DEVICE_CACHE_QUQUE = "snCacheQueue";
+    /**--- websocket消息相关 ---**/
+    /**
+     * 消息来源 <br />
+     * TQ:塘栖<br />
+     * TQSERVER:塘栖服务端<br />
+     * HHFACE:HHFACE客户端
+     */
+    public static final String SOURCE_TQ = "TQ";
+    public static final String SOURCE_TQSERVER = "TQSERVER";
+    public static final String SOURCE_HHFACE = "HHFACE";
+    /**
+     * 业务操作类型:<br />
+     * ISSUE_ALL: 全量下发 <br />
+     * ISSUE_INCREMENT:增量下发<br />
+     * FACE_DELETED:人脸删除<br />
+     * FACE_DELETED_ALL:全量删除
+     * ISSUE_CALLBACK:人员下发回调<br />
+     * FACE_DELETED_CALLBACK:人员删除毁掉<br />
+     * ISSUE_NOT_FETCH:设备端抓去未下发人员信息
+     */
+    public static final String OP_ISSUE_ALL = "ISSUE_ALL";
+    public static final String OP_ISSUE_INCREMENT = "ISSUE_INCREMENT";
+    public static final String OP_FACE_DELETED = "FACE_DELETED";
+    public static final String OP_FACE_DELETED_ALL = "FACE_DELETED_ALL";
+    public static final String OP_ISSUE_CANCEL = "ISSUE_CANCEL";
+
+    public static final String STAT_ALL_NUM = "STAT::ALL::NUM::";//进出人次
+    public static final String STAT_IN_NUM = "STAT::IN::NUM::";//进场人数
+
+    /**
+     * iot设备用户同步
+     */
+    public static final String IOT_USER_QUEUE_NAME = "iotUserQueue";
+    public static final String IOT_MESSAGE_TYPE_addSingleUser2iot = "addSingleUser2Iot";
+    public static final String IOT_MESSAGE_TYPE_delUserFromIot = "delUserFromIot";
+    public static final String IOT_MESSAGE_TYPE_batchAddUser2Iot = "batchAddUser2Iot";
+    public static final String IOT_MESSAGE_TYPE_delBySn = "delBySn";
+    /**
+     * 用户信息
+     */
+    public static final String USER_INFO_QUEUE_NAME = "userInfoQueue";
+    public static final String USER_MESSAGE_TYPE_ADD = "addUser";
+    public static final String USER_MESSAGE_TYPE_UPDATE = "updateUser";
+    public static final String USER_MESSAGE_TYPE_DEL = "delUser";
+    /*
+     * 数据统计
+     * */
+    public static final String STAT_DATA_QUEUE_NAME = "statDataQueue";//队列名 STAT::ALL::NUM::adminId::yyyy-MM-dd
 }

+ 24 - 0
yqk-common/src/main/java/com/yx/face/boot/easyexcel/CollectCustomMerge.java

@@ -0,0 +1,24 @@
+package com.yx.face.boot.easyexcel;
+
+import java.lang.annotation.*;
+
+/**
+ * 自定义注解,用于判断是否需要合并以及合并的主键
+ * 标记哪些属性需要合并,哪个是主键
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface CollectCustomMerge {
+
+    /**
+     * 是否需要合并单元格
+     */
+    boolean needMerge() default false;
+
+    /**
+     * 是否是主键,即该字段相同的行合并
+     */
+    boolean isPk() default false;
+}
+

+ 143 - 0
yqk-common/src/main/java/com/yx/face/boot/easyexcel/CustomMergeStrategy.java

@@ -0,0 +1,143 @@
+package com.yx.face.boot.easyexcel;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.write.handler.RowWriteHandler;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: lkz
+ * @Title: CustomMergeStrategy
+ * @Description: 自定义单元格合并策略类CustomMergeStrategy,当Excel中两列主键相同时,合并被标记需要合并的列
+ * @Date: 2023/7/5 9:16
+ */
+public class CustomMergeStrategy implements RowWriteHandler {
+    /**
+     * 主键下标
+     */
+    private Integer pkIndex;
+
+    /**
+     * 需要合并的列的下标集合
+     */
+    private List<Integer> needMergeColumnIndex = new ArrayList<>();
+
+    /**
+     * DTO数据类型
+     */
+    private Class<?> elementType;
+
+    public CustomMergeStrategy(Class<?> elementType) {
+        this.elementType = elementType;
+    }
+
+    @Override
+    public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer rowIndex, Integer relativeRowIndex, Boolean isHead) {
+
+    }
+
+    @Override
+    public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {
+
+    }
+
+    @Override
+    public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {
+        // 如果是标题,则直接返回
+        if (isHead) {
+            return;
+        }
+
+        // 获取当前sheet
+        Sheet sheet = writeSheetHolder.getSheet();
+
+        // 获取标题行
+        Row titleRow = sheet.getRow(0);
+
+        if (null == pkIndex) {
+            this.lazyInit(writeSheetHolder);
+        }
+
+        // 判断是否需要和上一行进行合并
+        // 不能和标题合并,只能数据行之间合并
+        if (row.getRowNum() <= 1) {
+            return;
+        }
+        // 获取上一行数据
+        Row lastRow = sheet.getRow(row.getRowNum() - 1);
+        // 将本行和上一行是同一类型的数据(通过主键字段进行判断),则需要合并
+        if (lastRow.getCell(pkIndex).getStringCellValue().equalsIgnoreCase(row.getCell(pkIndex).getStringCellValue())) {
+            for (Integer needMerIndex : needMergeColumnIndex) {
+                CellRangeAddress cellRangeAddress = new CellRangeAddress(row.getRowNum() - 1, row.getRowNum(),
+                        needMerIndex, needMerIndex);
+                sheet.addMergedRegionUnsafe(cellRangeAddress);
+            }
+        }
+    }
+
+    /**
+     * 初始化主键下标和需要合并字段的下标
+     */
+    private void lazyInit(WriteSheetHolder writeSheetHolder) {
+
+        // 获取当前sheet
+        Sheet sheet = writeSheetHolder.getSheet();
+
+        // 获取标题行
+        Row titleRow = sheet.getRow(0);
+        // 获取DTO的类型
+        Class<?> eleType = this.elementType;
+
+        // 获取DTO所有的属性
+        Field[] fields = eleType.getDeclaredFields();
+
+        // 遍历所有的字段,因为是基于DTO的字段来构建excel,所以字段数 >= excel的列数
+        for (Field theField : fields) {
+            // 获取@ExcelProperty注解,用于获取该字段对应在excel中的列的下标
+            ExcelProperty easyExcelAnno = theField.getAnnotation(ExcelProperty.class);
+            // 为空,则表示该字段不需要导入到excel,直接处理下一个字段
+            if (null == easyExcelAnno) {
+                continue;
+            }
+            // 获取自定义的注解,用于合并单元格
+            CollectCustomMerge collectCustomMerge = theField.getAnnotation(CollectCustomMerge.class);
+
+            // 没有@CustomMerge注解的默认不合并
+            if (null == collectCustomMerge) {
+                continue;
+            }
+
+            for (int index = 0; index < fields.length; index++) {
+                Cell theCell = titleRow.getCell(index);
+                // 当配置为不需要导出时,返回的为null,这里作一下判断,防止NPE
+                if (null == theCell) {
+                    continue;
+                }
+                // 将字段和excel的表头匹配上
+                if (easyExcelAnno.value()[0].equalsIgnoreCase(theCell.getStringCellValue())) {
+                    if (collectCustomMerge.isPk()) {
+                        pkIndex = index;
+                    }
+
+                    if (collectCustomMerge.needMerge()) {
+                        needMergeColumnIndex.add(index);
+                    }
+                }
+            }
+        }
+
+        // 没有指定主键,则异常
+        if (null == this.pkIndex) {
+            throw new IllegalStateException("使用@CustomMerge注解必须指定主键");
+        }
+
+    }
+}

+ 39 - 0
yqk-common/src/main/java/com/yx/face/boot/mybatis/LanguageDriverUpdateIn.java

@@ -0,0 +1,39 @@
+package com.yx.face.boot.mybatis;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.mapping.SqlSource;
+import org.apache.ibatis.scripting.LanguageDriver;
+import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
+import org.apache.ibatis.session.Configuration;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Slf4j
+/**
+ * @author shisl
+ * @package com.yx.face.boot.mybatis
+ * @class LanguageDriverUpdateIn
+ * @date 2024/10/23 下午5:12
+ * @description 构造update in 动态sql更新
+ */
+public class LanguageDriverUpdateIn extends XMLLanguageDriver implements LanguageDriver {
+
+    private final Pattern pattern = Pattern.compile("\\(#\\{(\\w+)\\}\\)");
+
+    @Override
+    public SqlSource createSqlSource(
+            Configuration configuration, String script, Class<?> parameterType) {
+        Matcher matcher = pattern.matcher(script);
+        if (matcher.find()) {
+            script =
+                    matcher.replaceAll(
+                            "(<foreach collection=\"$1\" item=\"__item\" separator=\",\" >#{__item}</foreach>)");
+        }
+        script = "<script>" + script + "</script>";
+        SqlSource source = super.createSqlSource(configuration, script, parameterType);
+        log.info("sql=>{}", script);
+        return source;
+    }
+}

+ 35 - 0
yqk-common/src/main/java/com/yx/face/boot/mybatis/MyMetaObjectHandler.java

@@ -0,0 +1,35 @@
+package com.yx.face.boot.mybatis;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/**
+ * @author shisl
+ * @package cn.hh.party.building.app.config
+ * @class MyMetaObjectHandler
+ * @date 2022/12/22 下午2:55
+ * @description mybatis-plus数据插入监听器,可自动插入默认值
+ * 将需要此功能的属性加上注解 @TableField(fill = FieldFill.INSERT/INSERT_UPDATE)
+ */
+@Component
+public class MyMetaObjectHandler implements MetaObjectHandler {
+
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        // 执行插入操作时执行该逻辑
+        // 实体类属性名称和要自动填充的值
+        this.setFieldValByName("createTime", new Date(), metaObject);
+        this.setFieldValByName("updateTime", new Date(), metaObject);
+        // 设置逻辑删除字段为0
+        this.setFieldValByName("isDeleted", Boolean.FALSE, metaObject);
+        this.setFieldValByName("version", 1, metaObject);    }
+
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        // 执行更新操作时执行该逻辑
+        this.setFieldValByName("updateTime", new Date(), metaObject);
+    }
+}

+ 30 - 0
yqk-common/src/main/java/com/yx/face/boot/mybatis/MybatisConfig.java

@@ -0,0 +1,30 @@
+package com.yx.face.boot.mybatis;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author shisl
+ * @package cn.hh.party.building.app.config
+ * @class MybatisConfig
+ * @date 2022/12/22 下午2:59
+ * @description
+ */
+@Configuration
+public class MybatisConfig {
+
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
+        // 配置乐观锁插件
+        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
+        // 配置分页插件
+        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+        return mybatisPlusInterceptor;
+    }
+
+}

+ 39 - 0
yqk-common/src/main/java/com/yx/face/boot/uitls/AddressUtil.java

@@ -0,0 +1,39 @@
+package com.yx.face.boot.uitls;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+@Component
+@Slf4j
+public class AddressUtil {
+
+    @Value("${server.port}")
+    private String serverPort;
+    @Value("${server.servlet.web.prefix}")
+    private String webPrefix;
+    @Value("${web.address}")
+    private String webAddress;
+
+    public static String address;
+
+    @PostConstruct
+    public void setAddress() throws UnknownHostException {
+        if(StrUtil.isNotBlank(webAddress)){
+            AddressUtil.address = webAddress;
+        }else {
+            StringBuilder stringBuilder = new StringBuilder();
+            stringBuilder.append("http://").append(InetAddress.getLocalHost().getHostAddress()).append(":").append(webPrefix).append("/");
+            AddressUtil.address = stringBuilder.toString();
+        }
+        log.info("初始化webAddress:{}",address);
+    }
+
+
+
+}

+ 39 - 0
yqk-common/src/main/java/com/yx/face/boot/uitls/Chinese2PinyinUtil.java

@@ -0,0 +1,39 @@
+package com.yx.face.boot.uitls;
+
+import lombok.extern.slf4j.Slf4j;
+import net.sourceforge.pinyin4j.PinyinHelper;
+
+/**
+ * @author shisl
+ * @package com.yx.face.boot.uitls
+ * @class Chinese2PinyinUtil
+ * @date 2024/8/26 下午5:25
+ * @description
+ */
+@Slf4j
+public class Chinese2PinyinUtil {
+
+    public static String getPinyinFirstLetter(String chinese) {
+        if (Preconditions.isBlank(chinese)) {
+            return null;
+        }
+
+        StringBuilder pinyin = new StringBuilder();
+        // 将中文字符串转换为拼音数组
+        for (char ch : chinese.toCharArray()) {
+            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(ch);
+
+            // 如果字符是中文,则获取其拼音的首字母
+            if (pinyinArray != null && pinyinArray.length > 0) {
+                pinyin.append(pinyinArray[0].charAt(0));
+            } else {
+                // 非中文字符直接拼接
+                pinyin.append(ch);
+            }
+        }
+        return pinyin.toString();
+    }
+
+    ;
+
+}

+ 6 - 0
yqk-common/src/main/java/com/yx/face/model/entity/DownFaceNew.java

@@ -51,4 +51,10 @@ public class DownFaceNew {
     @ApiModelProperty(value = "人员类型 通行证人脸:1 | 常客:2 | 访客:3")
     private Integer userType;
 
+    @ApiModelProperty(value = "人脸特征值")
+    private String facialFeature;
+
+    @ApiModelProperty(value = "所属账号id")
+    private Integer adminId;
+
 }

+ 6 - 1
yqk-common/src/main/java/com/yx/face/model/entity/FaceDevice.java

@@ -34,7 +34,7 @@ public class FaceDevice {
     private String sn;
 
     /**
-     * 名称or标签
+     * 名称or标签 地点
      */
 
 
@@ -173,5 +173,10 @@ public class FaceDevice {
 
     @Column(name = "report_time")
     private Date reportTime;
+
+    @ApiModelProperty(value = "设备类型")
+    @Column(name = "dev_type")
+    private String devType;
+
 }
 

+ 65 - 0
yqk-common/src/main/java/com/yx/face/model/entity/StatAge.java

@@ -0,0 +1,65 @@
+package com.yx.face.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.io.Serializable;
+import java.time.LocalDate;
+
+/**
+ * <p>
+ * 统计-人员年龄分布情况
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("stat_age")
+public class StatAge implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    /**
+     * 账号
+     */
+    @TableField("admin_id")
+    private Integer adminId;
+
+    /**
+     * 统计日期
+     */
+    @TableField("stat_date")
+    private LocalDate statDate;
+
+    /**
+     * 统计人员年龄分布情况
+     */
+    @TableField("age_type")
+    private Integer ageType;
+
+    /**
+     * 人数
+     */
+    @TableField("stat_num")
+    private Integer statNum;
+
+}

+ 92 - 0
yqk-common/src/main/java/com/yx/face/model/entity/StatData.java

@@ -0,0 +1,92 @@
+package com.yx.face.model.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 统计-人员进出统计数据
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("stat_data")
+public class StatData implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    /**
+     * 账号
+     */
+    @TableField("admin_id")
+    private Integer adminId;
+
+    /**
+     * 姓名
+     */
+    @TableField("name")
+    private String name;
+
+    /**
+     * 手机号
+     */
+    @TableField("phone")
+    private String phone;
+
+    /**
+     * 身份证号
+     */
+    @TableField("id_number")
+    private String idNumber;
+
+    /**
+     * 物理卡号
+     */
+    @TableField("card_id_ex")
+    private String cardIdEx;
+
+    /**
+     * 状态 1-在场 2-离场 3-其他
+     */
+    @TableField("status")
+    private Integer status;
+
+    /**
+     * 人员类别 1-员工 2-访客 3-其他
+     */
+    @TableField("people_type")
+    private Integer peopleType;
+
+    /**
+     * 停留时长
+     */
+    @TableField("between_time")
+    private String betweenTime;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "create_time",fill = FieldFill.INSERT)
+    private Date createTime;
+
+}

+ 91 - 0
yqk-common/src/main/java/com/yx/face/model/entity/StatDataItem.java

@@ -0,0 +1,91 @@
+package com.yx.face.model.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.io.Serializable;
+import java.util.Date;
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("stat_data_item")
+public class StatDataItem implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    /**
+     * 统计-人员进出统计数据主键
+     */
+    @TableField("stat_data_id")
+    private Long statDataId;
+
+    /**
+     * 账号
+     */
+    @TableField("admin_id")
+    private Integer adminId;
+
+    /**
+     * 设备编号
+     */
+    @TableField("sn")
+    private String sn;
+
+    /**
+     * 设备地点
+     */
+    @TableField("sn_name")
+    private String snName;
+
+    /**
+     * 通行类型 1-进 2-出
+     */
+    @TableField("pass")
+    private Integer pass;
+
+    /**
+     * 通行时间
+     */
+    @TableField("pass_time")
+    private Date passTime;
+
+    /**
+     * 照片
+     */
+    @TableField("photo")
+    private String photo;
+
+    /**
+     * 是否正常 0-异常 1-正常
+     */
+    @TableField("status")
+    private Boolean status;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "create_time",fill = FieldFill.INSERT)
+    private Date createTime;
+
+}

+ 66 - 0
yqk-common/src/main/java/com/yx/face/model/entity/StatPeople.java

@@ -0,0 +1,66 @@
+package com.yx.face.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+/**
+ * <p>
+ * 统计-各时段在场人数情况
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("stat_people")
+public class StatPeople implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    /**
+     * 账号
+     */
+    @TableField("admin_id")
+    private Integer adminId;
+
+    /**
+     * 统计日期
+     */
+    @TableField("stat_date")
+    private LocalDate statDate;
+
+    /**
+     * 统计时间
+     */
+    @TableField("stat_time")
+    private LocalTime statTime;
+
+    /**
+     * 在场人数
+     */
+    @TableField("stat_num")
+    private Integer statNum;
+
+}

+ 65 - 0
yqk-common/src/main/java/com/yx/face/model/entity/StatSex.java

@@ -0,0 +1,65 @@
+package com.yx.face.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.io.Serializable;
+import java.time.LocalDate;
+
+/**
+ * <p>
+ * 统计-人员性别分布情况
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("stat_sex")
+public class StatSex implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    /**
+     * 账号
+     */
+    @TableField("admin_id")
+    private Integer adminId;
+
+    /**
+     * 统计日期
+     */
+    @TableField("stat_date")
+    private LocalDate statDate;
+
+    /**
+     * 统计人员性别分布情况 1 : 男 , 0 : 女
+     */
+    @TableField("sex_type")
+    private Integer sexType;
+
+    /**
+     * 人数
+     */
+    @TableField("stat_num")
+    private Integer statNum;
+
+}

+ 65 - 0
yqk-common/src/main/java/com/yx/face/model/entity/StatSource.java

@@ -0,0 +1,65 @@
+package com.yx.face.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.io.Serializable;
+import java.time.LocalDate;
+
+/**
+ * <p>
+ * 统计-人员来源地分布情况
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("stat_source")
+public class StatSource implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    /**
+     * 账号
+     */
+    @TableField("admin_id")
+    private Integer adminId;
+
+    /**
+     * 统计日期
+     */
+    @TableField("stat_date")
+    private LocalDate statDate;
+
+    /**
+     * 统计人员来源地
+     */
+    @TableField("stat_source_code")
+    private String statSourceCode;
+
+    /**
+     * 在场人数
+     */
+    @TableField("stat_num")
+    private Integer statNum;
+
+}

+ 4 - 1
yqk-common/src/main/java/com/yx/face/model/entity/UserInfo.java

@@ -87,7 +87,7 @@ public class UserInfo {
     private String zfbUserId;
     /**
      * 性别 通过身份证解析或护照OCR获取
-     *  1985-09-03
+     * 1985-09-03
      */
     @Column(name = "gender_str")
     private String genderStr;
@@ -99,6 +99,9 @@ public class UserInfo {
     @ApiModelProperty(value = "护照照片")
     private String hztx;
 
+    @ApiModelProperty(value = "人脸特征值")
+    private String facialFeature;
+
 
 }
 

+ 10 - 1
yqk-common/src/main/java/com/yx/face/model/entity/UserVisitorListDetail.java

@@ -1,8 +1,11 @@
 package com.yx.face.model.entity;
 
+import com.yx.face.boot.handle.IntegerTypeHandler;
 import com.yx.face.model.vo.ContextVO;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import lombok.experimental.Accessors;
+import tk.mybatis.mapper.annotation.ColumnType;
 
 import javax.persistence.*;
 import java.io.Serializable;
@@ -11,6 +14,7 @@ import java.util.List;
 
 
 @Data
+@Accessors(chain = true)
 @Table(name = "user_visitor_list_detail")
 public class UserVisitorListDetail implements Serializable {
     @Id
@@ -235,7 +239,7 @@ public class UserVisitorListDetail implements Serializable {
      * 用于排序的时间差
      */
     @Transient
-    private long sortTimeSub ;
+    private long sortTimeSub;
 
     @ApiModelProperty("楼层")
     private Integer floor;
@@ -245,4 +249,9 @@ public class UserVisitorListDetail implements Serializable {
     private String ladderQrCode;
     @ApiModelProperty("登记地点")
     private String registerAddress;
+
+    @ApiModelProperty("通行区域区域列表")
+    @ColumnType(typeHandler = IntegerTypeHandler.class, column = "zone_pass_json")
+    private List<Integer> zoneDevicePassIdList;
+
 }

+ 3 - 0
yqk-common/src/main/java/com/yx/face/model/entity/Visitee.java

@@ -55,6 +55,9 @@ public class Visitee implements Serializable {
     @ApiModelProperty(value = "绑定区域 [1,2,3] 全部是null")
     private String zoneIds;
 
+    @ApiModelProperty(value = "拼音首字母")
+    private String pinyinFirstLetter;
+
     @Transient
     @ApiModelProperty(value = "账户名称")
     private String username;

+ 58 - 0
yqk-common/src/main/java/com/yx/face/model/entity/issue/IssueDevice.java

@@ -0,0 +1,58 @@
+package com.yx.face.model.entity.issue;
+
+import com.yx.face.model.entity.Base;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.persistence.Column;
+import javax.persistence.Table;
+
+/**
+ * @author shisl
+ * @package com.yx.face.model.entity.issue
+ * @class IssueDevice
+ * @date 2024/4/15 下午2:13
+ * @description 下发设备列表
+ */
+@Data
+@Accessors(chain = true)
+@Table(name = "issue_device")
+public class IssueDevice extends Base {
+
+    @ApiModelProperty(value = "任务编号")
+    @Column(name = "trace_id")
+    private String traceId;
+
+    @ApiModelProperty(value = "设备sn")
+    @Column(name = "device_sn")
+    private String deviceSn;
+
+    @ApiModelProperty(value = "所属账号id")
+    @Column(name = "admin_id")
+    private Integer adminId;
+    @ApiModelProperty(value = "所属账号名称")
+    @Column(name = "admin_user_name")
+    private String adminUserName;
+
+    @ApiModelProperty(value = "下发人员数量")
+    @Column(name = "issue_face_count")
+    private Integer issueFaceCount;
+    @ApiModelProperty(value = "已下发人员数量")
+    @Column(name = "had_issue_face_count")
+    private Integer hadIssueFaceCount;
+
+    @ApiModelProperty(value = "下发类型 IssueTypeEnum")
+    @Column(name = "issue_type")
+    private String issueType;
+
+    @ApiModelProperty(value = "下发状态 IssueStatusEnum")
+    @Column(name = "issue_status")
+    private String issueStatus;
+
+    @ApiModelProperty(value = "备注")
+    @Column(name = "remarks")
+    private String remarks;
+
+
+}

+ 85 - 0
yqk-common/src/main/java/com/yx/face/model/entity/issue/IssueDeviceItem.java

@@ -0,0 +1,85 @@
+package com.yx.face.model.entity.issue;
+
+import com.yx.face.model.entity.Base;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.persistence.Column;
+import javax.persistence.Table;
+import java.util.Date;
+
+/**
+ * @author shisl
+ * @package com.yx.face.model.entity.issue
+ * @class IssueDevice
+ * @date 2024/4/15 下午2:13
+ * @description 下发到设备的人脸信息明细
+ */
+@Data
+@Accessors(chain = true)
+@Table(name = "issue_device_item")
+public class IssueDeviceItem extends Base {
+
+    @ApiModelProperty(value = "issue_Device表id")
+    @Column(name = "issue_device_id")
+    private Long issueDeviceId;
+
+    @ApiModelProperty(value = "user_info表id")
+    @Column(name = "user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "adminId+userId+sn DigestUtil.md5Hex ")
+    @Column(name = "org_id")
+    private String orgId;
+
+    @ApiModelProperty(value = "姓名")
+    @Column(name = "user_name")
+    private String userName;
+
+    @ApiModelProperty(value = "手机号")
+    @Column(name = "phone")
+    private String phone;
+
+    @ApiModelProperty(value = "身份证号")
+    @Column(name = "id_number")
+    private String idNumber;
+
+    @ApiModelProperty(value = "物理卡号")
+    @Column(name = "card_id_ex")
+    private String cardIdEx;
+
+    @ApiModelProperty(value = "照片")
+    @Column(name = "photo")
+    private String photo;
+
+    @ApiModelProperty(value = "人脸特征值")
+    @Column(name = "facial_feature")
+    private String facialFeature;
+
+    @ApiModelProperty(value = "人员类型 员工/访客")
+    @Column(name = "user_type")
+    private Integer userType;
+
+    @ApiModelProperty(value = "有效期开始时间")
+    @Column(name = "start_time")
+    private Date startTime;
+
+    @ApiModelProperty(value = "有效期结束时间")
+    @Column(name = "end_time")
+    private Date endTime;
+
+    @ApiModelProperty(value = "下发时间")
+    @Column(name = "issue_time")
+    private Date issueTime;
+
+    @ApiModelProperty(value = "下发状态 下发中  processing/成功 success/失败 failed  IssueStatusEnum")
+    @Column(name = "issue_status")
+    private String issueStatus;
+
+    @ApiModelProperty(value = "备注")
+    @Column(name = "remarks")
+    private String remarks;
+
+
+}

+ 52 - 0
yqk-common/src/main/java/com/yx/face/model/entity/issue/IssueDeviceUser.java

@@ -0,0 +1,52 @@
+package com.yx.face.model.entity.issue;
+
+import com.yx.face.boot.handle.IntegerTypeHandler;
+import com.yx.face.model.entity.Base;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import tk.mybatis.mapper.annotation.ColumnType;
+
+import javax.persistence.Column;
+import javax.persistence.Table;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author shisl
+ * @package com.yx.face.model.entity.issue
+ * @class IssueDeviceUser
+ * @date 2024/4/17 下午6:43
+ * @description
+ */
+@Data
+@Accessors(chain = true)
+@Table(name = "issue_device_user")
+public class IssueDeviceUser extends Base {
+
+    @ApiModelProperty(value = "设备sn")
+    @Column(name = "device_sn")
+    private String deviceSn;
+
+    @ApiModelProperty(value = "设备人员数量")
+    @Column(name = "user_count")
+    private Integer userCount;
+
+    @ApiModelProperty(value = "ip地址")
+    @Column(name = "internet_ip")
+    private String internetIp;
+
+    @ApiModelProperty(value = "HHFACE版本号")
+    @Column(name = "hh_face_Version")
+    private String HhFaceVersion;
+
+    @ApiModelProperty("用户集合ids  [1,2,3,4,5,6]")
+    @ColumnType(typeHandler = IntegerTypeHandler.class, column = "user_ids")
+    private List<Integer> userIds;
+
+    @ApiModelProperty(value = "最后一次tracking心跳时间")
+    @Column(name = "last_tracking_time")
+    private Date lastTrackingTime;
+
+
+}

+ 2 - 1
yqk-common/src/main/java/com/yx/face/model/enums/FaceDeviceTypeEnum.java

@@ -19,7 +19,8 @@ public enum FaceDeviceTypeEnum {
     FKJ(4, "FKJ", "访客机"),
     ZFB(5, "TB", "支付宝人脸终端"),
     SMART_LOCK(6, "SL", "智能门锁"),
-    BLUETOOTH_SMART_LOCK(7, "BSL", "蓝牙智能门锁");
+    BLUETOOTH_SMART_LOCK(7, "BSL", "蓝牙智能门锁"),
+    HHFACE(8, "HHFACE", "HHFACE应用");
 
     private Integer type;
 

+ 39 - 0
yqk-common/src/main/java/com/yx/face/model/enums/StatAgeTypeEnum.java

@@ -0,0 +1,39 @@
+package com.yx.face.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * @description:
+ * @ClassName PassEnum
+ * @Author WXG
+ * @Date 2023/12/5 17:10
+ */
+@AllArgsConstructor
+@Getter
+public enum StatAgeTypeEnum {
+
+    AGE_20(1, "20岁以下"),
+    AGE_35(2, "20-35岁"),
+    AGE_50(3, "36-50岁"),
+    AGE_65(4, "51-65岁"),
+    AGE_OTHER(5, "65岁以上"),
+    ;
+
+    private Integer code;
+    private String desc;
+
+    public static StatAgeTypeEnum getEnumByCode(Integer code){
+        if(Objects.isNull(code)){
+            return null;
+        }
+        for (StatAgeTypeEnum passEnum : values()){
+            if(passEnum.code.equals(code)){
+                return passEnum;
+            }
+        }
+        return null;
+    }
+}

+ 36 - 0
yqk-common/src/main/java/com/yx/face/model/enums/StatDataStatusEnum.java

@@ -0,0 +1,36 @@
+package com.yx.face.model.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * @description:
+ * @ClassName PassEnum
+ * @Author WXG
+ * @Date 2023/12/5 17:10
+ */
+@AllArgsConstructor
+@Getter
+public enum StatDataStatusEnum {
+
+    IN(1, "进"),
+    OUT(2, "出"),
+    ;
+
+    private Integer code;
+    private String desc;
+
+    public static StatDataStatusEnum getEnumByCode(Integer code){
+        if(Objects.isNull(code)){
+            return null;
+        }
+        for (StatDataStatusEnum passEnum : values()){
+            if(passEnum.code.equals(code)){
+                return passEnum;
+            }
+        }
+        return null;
+    }
+}

+ 44 - 0
yqk-common/src/main/java/com/yx/face/model/enums/issue/IssueStatusEnum.java

@@ -0,0 +1,44 @@
+package com.yx.face.model.enums.issue;
+
+import com.yx.face.boot.uitls.Preconditions;
+import lombok.Getter;
+
+/**
+ * @author shisl
+ * @package com.yx.face.model.enums.issue
+ * @class IssueStatusEnum
+ * @date 2024/4/15 下午2:27
+ * @description 下发状态 等待中 pending/下发中 processing/中断 interruption/成功 success/失败 failed/已取消 cancel
+ */
+@Getter
+public enum IssueStatusEnum {
+
+    PENDING("pending", "等待中"),
+    PROCESSING("processing", "下发中"),
+    INTERRUPTION("interruption", "中断"),
+    SUCCESS("success", "成功"),
+    FAILED("failed", "失败"),
+    CANCEL("cancel", "已取消"),
+    ;
+
+    private String code;
+    private String desc;
+
+    IssueStatusEnum(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public static IssueStatusEnum getByCode(String code) {
+        if (Preconditions.isBlank(code)) {
+            return null;
+        }
+        for (IssueStatusEnum item : IssueStatusEnum.values()) {
+            if (item.getCode().equals(code)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+}

+ 47 - 0
yqk-common/src/main/java/com/yx/face/model/enums/issue/IssueTypeEnum.java

@@ -0,0 +1,47 @@
+package com.yx.face.model.enums.issue;
+
+import com.yx.face.boot.core.Constants;
+import com.yx.face.boot.uitls.Preconditions;
+import lombok.Getter;
+
+/**
+ * @author shisl
+ * @package com.yx.face.model.enums.issue
+ * @class IssuedTypeEnum
+ * @date 2024/4/15 下午2:23
+ * @description 下发类型 全量下发issue_all/增量下发issue_increment
+ */
+@Getter
+public enum IssueTypeEnum {
+
+    ISSUE_ALL("all", "全量下发", Constants.OP_ISSUE_ALL),
+    ISSUE_INCREMENT("increment", "增量下发", Constants.OP_ISSUE_INCREMENT),
+    FACE_DELETED("face_delete", "删除", Constants.OP_FACE_DELETED),
+    FACE_DELETED_ALL("face_delete_all", "全量删除", Constants.OP_FACE_DELETED_ALL),
+    ISSUE_CANCEL("cancel", "取消下发", Constants.OP_ISSUE_CANCEL)
+    ;
+
+    private String code;
+    private String desc;
+    private String opCode;
+
+    IssueTypeEnum(String code, String desc, String opCode) {
+        this.code = code;
+        this.desc = desc;
+        this.opCode = opCode;
+    }
+
+    public static IssueTypeEnum getByCode(String code) {
+        if (Preconditions.isBlank(code)) {
+            return null;
+        }
+        for (IssueTypeEnum item : IssueTypeEnum.values()) {
+            if (item.getCode().equals(code)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+
+}

+ 25 - 0
yqk-common/src/main/java/com/yx/face/model/enums/issue/IssueUserTypeEnum.java

@@ -0,0 +1,25 @@
+package com.yx.face.model.enums.issue;
+
+import lombok.Getter;
+
+/**
+ * @author shisl
+ * @package com.yx.face.model.enums.issue
+ * @class IssueUserTypeEnum
+ * @date 2024/4/15 下午2:44
+ * @description 下发人员类型 常客 whitelist/访客 visitor
+ */
+@Getter
+public enum IssueUserTypeEnum {
+
+    WHITELIST("whitelist", "常客"),
+    VISITOR("visitor", "访客"),;
+
+    private String code;
+    private String desc;
+
+    IssueUserTypeEnum(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+}

+ 0 - 71
yqk-job/src/main/java/com/yx/face/boot/core/Constants.java

@@ -1,71 +0,0 @@
-package com.yx.face.boot.core;
-
-/**
- * @description: Constants <br>
- * @date: 2021/3/29 17:08 <br>
- * @author: PWB <br>
- */
-public class Constants {
-
-    public static final String UPLOAD_PATH = "file/image/upload/";
-    public static final String UPLOAD_IMAGE = "file/upload/images/";
-    public static final String UPLOAD_IMAGE_NEW = "file/upload/imagesnew/";
-    public static final String UPLOAD_EXCEL = "file/upload/excel/";
-    public static final String UPLOAD_PHOTO = "file/upload/photo/";
-    public static final String UPLOAD_VIDEO = "file/upload/videos/";
-    public static final String UPLOAD_DOCUMENT = "file/upload/document/";
-    public static final String UPLOAD_OTHER = "file/upload/other";
-    public static final String SYSTEM_FILE = "file/system/";
-    public static final String SALT = "YcYp65l;uq234pwb;iIjHg872S-ajfL.khp636**YX2021";
-    public static final String SALT_PRE = "SU2ti983*238--=833##383yuu";
-
-
-    //无锡苏康码加密秘钥key
-    public static final String SUPER_APP_KEY = "super_app_key";
-    //无锡苏康码 url
-    public static final String SKM_API_URL = "skm_aip_url";
-    //无锡苏康码
-    public static final String SUPER_SIGN = "super_sign";
-
-    public static final String TB_API_URL = "tb_aip_url";
-
-    public static final String TURN_ON_OR_STOP = "turn_on_or_stop";
-
-    //微信相关参数:登录地址
-    public static final String WX_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
-    //微信相关参数:AccessToken获取地址
-    public static final String WX_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
-    //微信相关参数:订阅消息请求地址
-    public static final String WX_MESSAGE_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={0}";
-
-
-    //背景审核复议结果通知
-    public static final String WX_MS_TEMPLATE_4955 = "JPSs7hM4vBwwQXfShKWNEM3C_qyZFqBnBbfHJHWwfCQ";
-
-
-    //申请通行证结果通知
-    public static final String WX_MS_TEMPLATE_592 = "mh0qTV5SrTkXUHpg7AwC9VHSLhq8QzNQqI7VoQrwC4U";
-
-
-    /**
-     * iot设备用户同步
-     */
-    public static final String IOT_USER_QUEUE_NAME = "iotUserQueue";
-    public static final String IOT_MESSAGE_TYPE_addSingleUser2iot = "addSingleUser2Iot";
-    public static final String IOT_MESSAGE_TYPE_delUserFromIot = "delUserFromIot";
-    public static final String IOT_MESSAGE_TYPE_batchAddUser2Iot = "batchAddUser2Iot";
-    public static final String IOT_MESSAGE_TYPE_delBySn = "delBySn";
-
-    /*进出记录统计时默认key值前缀*/
-    public static final String IN_OUT_STATISTICS = "IN_OUT_STATISTICS:";
-
-    /**
-     * 用户信息
-     */
-    public static final String USER_INFO_QUEUE_NAME = "userInfoQueue";
-    public static final String USER_MESSAGE_TYPE_ADD = "addUser";
-    public static final String USER_MESSAGE_TYPE_UPDATE = "updateUser";
-    public static final String USER_MESSAGE_TYPE_DEL = "delUser";
-    /*进出记录预警前缀key 全部应该是key+admin:+idNumber*/
-    public static final String IN_OUT_WARNING = "IN_OUT_WARNING:";
-}

+ 5 - 0
yqk-job/src/main/java/com/yx/face/boot/rabbitConfig/config/ProducerConsumerConfig.java

@@ -26,5 +26,10 @@ public class ProducerConsumerConfig {
         Queue queue = new Queue(Constants.USER_INFO_QUEUE_NAME);
         return queue;
     }
+    @Bean
+    public Queue statDataQueue() {
+        Queue queue = new Queue(Constants.STAT_DATA_QUEUE_NAME);
+        return queue;
+    }
 
 }

+ 0 - 3
yqk-job/src/main/java/com/yx/face/dao/ExamUserWhitelistDao.java

@@ -4,9 +4,6 @@ import com.yx.face.model.entity.ExamUserWhitelist;
 import org.apache.ibatis.annotations.Param;
 import tk.mybatis.mapper.common.BaseMapper;
 
-import java.util.List;
-import java.util.Map;
-
 /**
  * <p>
  * 考试用户白名单 Mapper 接口

+ 1 - 1
yqk-job/src/main/java/com/yx/face/dao/FaceRequestLogDao.java

@@ -1,7 +1,7 @@
 package com.yx.face.dao;
 
-import com.yx.face.model.entity.FaceRequestLog;
 import com.yx.face.boot.component.tk.TKMapper;
+import com.yx.face.model.entity.FaceRequestLog;
 
 /**
  * @description: 天波人脸服务请求日志表(FaceRequestLog)表数据库访问层 <br>

+ 1 - 1
yqk-job/src/main/java/com/yx/face/dao/HealthCodeDao.java

@@ -1,7 +1,7 @@
 package com.yx.face.dao;
 
-import com.yx.face.model.entity.HealthCode;
 import com.yx.face.boot.component.tk.TKMapper;
+import com.yx.face.model.entity.HealthCode;
 
 /**
  * @description: (HealthCode)表数据库访问层 <br>

+ 1 - 1
yqk-job/src/main/java/com/yx/face/dao/RoleAuthDao.java

@@ -1,7 +1,7 @@
 package com.yx.face.dao;
 
-import com.yx.face.model.entity.RoleAuth;
 import com.yx.face.boot.component.tk.TKMapper;
+import com.yx.face.model.entity.RoleAuth;
 
 /**
  * @description: 权限表(RoleAuth)表数据库访问层 <br>

+ 1 - 1
yqk-job/src/main/java/com/yx/face/dao/RoleDao.java

@@ -1,7 +1,7 @@
 package com.yx.face.dao;
 
-import com.yx.face.model.entity.Role;
 import com.yx.face.boot.component.tk.TKMapper;
+import com.yx.face.model.entity.Role;
 
 /**
  * @description: 角色表(Role)表数据库访问层 <br>

+ 17 - 0
yqk-job/src/main/java/com/yx/face/dao/StatAgeDao.java

@@ -0,0 +1,17 @@
+package com.yx.face.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yx.face.model.entity.StatAge;
+
+
+/**
+ * <p>
+ * 统计-人员年龄分布情况 Mapper 接口
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+public interface StatAgeDao extends BaseMapper<StatAge> {
+
+}

+ 15 - 0
yqk-job/src/main/java/com/yx/face/dao/StatDataDao.java

@@ -0,0 +1,15 @@
+package com.yx.face.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yx.face.model.entity.StatData;
+/**
+ * <p>
+ * 统计-人员进出统计数据 Mapper 接口
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+public interface StatDataDao extends BaseMapper<StatData> {
+
+}

+ 16 - 0
yqk-job/src/main/java/com/yx/face/dao/StatDataItemDao.java

@@ -0,0 +1,16 @@
+package com.yx.face.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yx.face.model.entity.StatDataItem;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+public interface StatDataItemDao extends BaseMapper<StatDataItem> {
+
+}

+ 16 - 0
yqk-job/src/main/java/com/yx/face/dao/StatPeopleDao.java

@@ -0,0 +1,16 @@
+package com.yx.face.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yx.face.model.entity.StatPeople;
+
+/**
+ * <p>
+ * 统计-各时段在场人数情况 Mapper 接口
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+public interface StatPeopleDao extends BaseMapper<StatPeople> {
+
+}

+ 16 - 0
yqk-job/src/main/java/com/yx/face/dao/StatSexDao.java

@@ -0,0 +1,16 @@
+package com.yx.face.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yx.face.model.entity.StatSex;
+
+/**
+ * <p>
+ * 统计-人员性别分布情况 Mapper 接口
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+public interface StatSexDao extends BaseMapper<StatSex> {
+
+}

+ 16 - 0
yqk-job/src/main/java/com/yx/face/dao/StatSourceDao.java

@@ -0,0 +1,16 @@
+package com.yx.face.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yx.face.model.entity.StatSource;
+
+/**
+ * <p>
+ * 统计-人员来源地分布情况 Mapper 接口
+ * </p>
+ *
+ * @author wxg
+ * @since 2024-08-13
+ */
+public interface StatSourceDao extends BaseMapper<StatSource> {
+
+}

+ 0 - 3
yqk-job/src/main/java/com/yx/face/dao/UserControlEarlyWarningListDao.java

@@ -5,9 +5,6 @@ import com.yx.face.model.entity.UserControlEarlyWarningList;
 import com.yx.face.model.vo.AdminAndUserEarlyWarningVO;
 import org.apache.ibatis.annotations.Param;
 
-import java.util.List;
-import java.util.Map;
-
 /**
  * <p>
  * 预警人员 Mapper 接口

+ 0 - 5
yqk-job/src/main/java/com/yx/face/dao/UserControlEarlyWarningListLogDao.java

@@ -1,12 +1,7 @@
 package com.yx.face.dao;
 
 import com.yx.face.boot.component.tk.TKMapper;
-import com.yx.face.model.entity.Admin;
 import com.yx.face.model.entity.UserControlEarlyWarningListLog;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.HashMap;
-import java.util.List;
 
 /**
  * <p>

+ 1 - 1
yqk-job/src/main/java/com/yx/face/dao/UserFaceRecordsDao.java

@@ -1,7 +1,7 @@
 package com.yx.face.dao;
 
-import com.yx.face.model.entity.UserFaceRecords;
 import com.yx.face.boot.component.tk.TKMapper;
+import com.yx.face.model.entity.UserFaceRecords;
 
 /**
  * @description: 用户人脸记录表(UserFaceRecords)表数据库访问层 <br>

+ 0 - 2
yqk-job/src/main/java/com/yx/face/dao/UserVisitorListDetailDao.java

@@ -1,12 +1,10 @@
 package com.yx.face.dao;
 
 import com.yx.face.boot.component.tk.TKMapper;
-
 import com.yx.face.model.entity.UserVisitorListDetail;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
-import java.util.Map;
 
 public interface UserVisitorListDetailDao extends TKMapper<UserVisitorListDetail> {
 

+ 0 - 1
yqk-job/src/main/java/com/yx/face/dao/UserWhitelistDao.java

@@ -1,7 +1,6 @@
 package com.yx.face.dao;
 
 import com.yx.face.boot.component.tk.TKMapper;
-import com.yx.face.model.entity.UserVisitorListDetail;
 import com.yx.face.model.entity.UserWhitelist;
 import com.yx.face.model.entity.UserWhitelistDetail;
 import com.yx.face.model.vo.UserWhitelistVO;

+ 0 - 1
yqk-job/src/main/java/com/yx/face/dao/WarningLogDao.java

@@ -1,7 +1,6 @@
 package com.yx.face.dao;
 
 import com.yx.face.boot.component.tk.TKMapper;
-import com.yx.face.model.entity.AdminInoutWarnConfig;
 import com.yx.face.model.entity.WarningLog;
 import org.springframework.stereotype.Repository;
 

+ 30 - 0
yqk-job/src/main/java/com/yx/face/model/dto/UserVisitorListDetailHealth.java

@@ -0,0 +1,30 @@
+package com.yx.face.model.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+@Data
+public class UserVisitorListDetailHealth implements Serializable {
+
+    @ApiModelProperty("健康码")
+    private String jkm;
+    @ApiModelProperty("健康码图片")
+    private String jkmPhoto;
+    @ApiModelProperty("核酸")
+    private String hs;
+    @ApiModelProperty("核酸检测时间")
+    private String hsCheckTime;
+    @ApiModelProperty("核酸结果时间")
+    private String hsResultTime;
+    @ApiModelProperty("核酸图片")
+    private String hsPhoto;
+    @ApiModelProperty("行程信息1 代表没有去过高风险地区 2 代表去过高风险地区 3 代表用户没有行程记录")
+    private String xc;
+    @ApiModelProperty("行程码图片")
+    private String xcPhoto;
+    @ApiModelProperty("获取行程码的手机号")
+    private String xcPhone;
+}

+ 5 - 1
yqk-job/src/main/java/com/yx/face/model/dto/UserVisitorListDetailInfo.java

@@ -1,6 +1,5 @@
 package com.yx.face.model.dto;
 
-
 import com.yx.face.model.vo.ContextVO;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -8,9 +7,11 @@ import lombok.Data;
 import java.io.Serializable;
 import java.util.List;
 
+
 @Data
 public class UserVisitorListDetailInfo implements Serializable {
 
+
     @ApiModelProperty(value = "访客机信息是否回显 1-回显 2-不回显")
     private Integer visitorStatus = 2;
 
@@ -20,6 +21,9 @@ public class UserVisitorListDetailInfo implements Serializable {
     @ApiModelProperty("三码 1-健康码 2-核酸 3-行程码")
     private List<String> threeCodeList;
 
+    @ApiModelProperty(value = "健康码信息")
+    private UserVisitorListDetailHealth userVisitorListDetailHealth;
+
     @ApiModelProperty(value = "自定义信息是否回显 1-回显 2-不回显")
     private Integer contentStatus = 2;
 

+ 0 - 2
yqk-job/src/main/java/com/yx/face/model/dto/UserVisitorListDetailVisitor.java

@@ -1,6 +1,5 @@
 package com.yx.face.model.dto;
 
-
 import com.yx.face.model.vo.ContextVO;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -214,4 +213,3 @@ public class UserVisitorListDetailVisitor implements Serializable {
     @ApiModelProperty("获取行程码的手机号")
     private String xcPhone;
 }
-

+ 32 - 0
yqk-job/src/main/java/com/yx/face/model/mq/StatDataMq.java

@@ -0,0 +1,32 @@
+package com.yx.face.model.mq;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class StatDataMq implements Serializable {
+    /*账号*/
+    private Integer adminId;
+    /*姓名 */
+    private String name;
+    /*手机号*/
+    private String phone;
+    /**身份证号*/
+    private String idNumber;
+    /*物理卡号*/
+    private String cardIdEx;
+    /*人员类别 1-员工 2-访客 3-其他*/
+    private Integer peopleType;
+    /*设备编号*/
+    private String sn;
+    /*设备地点*/
+    private String snName;
+    /*通行类型 1-进 2-出*/
+    private Integer pass;
+    /*通行时间*/
+    private Date passTime;
+    /*照片*/
+    private String photo;
+}

+ 3 - 0
yqk-job/src/main/java/com/yx/face/model/vo/AdminVO.java

@@ -149,5 +149,8 @@ public class AdminVO {
     @ApiModelProperty(value = "是否开启进出预警 false-不开启 true-开启")
     private Boolean isOpenInoutWarning;
 
+    @ApiModelProperty(value = "是否开启进出记录统计 false-不开启 true-开启")
+    private Boolean openInOutStatistics;
+
 }
 

+ 0 - 1
yqk-job/src/main/java/com/yx/face/server/DingTalkServer.java

@@ -13,7 +13,6 @@ import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
 import com.taobao.api.ApiException;
 import com.yx.face.server.dto.DingTalkRecordUpload;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
 

+ 0 - 3
yqk-job/src/main/java/com/yx/face/service/UserControlEarlyWarningListService.java

@@ -1,8 +1,5 @@
 package com.yx.face.service;
 
-import com.github.pagehelper.PageInfo;
-import java.util.List;
-
 /**
  * <p>
  * 预警人员 服务类

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/UserVisitorListDetailService.java

@@ -1,7 +1,6 @@
 package com.yx.face.service;
 
 
-import com.yx.face.model.entity.Admin;
 import com.yx.face.model.entity.FaceLog;
 import com.yx.face.model.vo.AdminVO;
 

+ 1 - 6
yqk-job/src/main/java/com/yx/face/service/dataFix/impl/DataFixServiceImpl.java

@@ -2,13 +2,11 @@ package com.yx.face.service.dataFix.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.http.HttpUtil;
-import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.yx.face.boot.restful.CommonException;
 import com.yx.face.boot.restful.RestResponse;
 import com.yx.face.boot.restful.RestResult;
 import com.yx.face.boot.uitls.Base64Util;
-import com.yx.face.boot.uitls.FileUtils;
 import com.yx.face.boot.uitls.Sm4Util;
 import com.yx.face.dao.FaceDeviceDao;
 import com.yx.face.dao.FaceLogDao;
@@ -17,10 +15,7 @@ import com.yx.face.model.dto.FaceLogDataPushDto;
 import com.yx.face.model.dto.UserVisitorListDetailInfo;
 import com.yx.face.model.dto.UserVisitorListDetailVisitor;
 import com.yx.face.model.dto.dataFix.ClockWayPushVO;
-import com.yx.face.model.entity.FaceDevice;
-import com.yx.face.model.entity.FaceLog;
-import com.yx.face.model.entity.FkjHeartTracking;
-import com.yx.face.model.entity.UserWhitelist;
+import com.yx.face.model.entity.*;
 import com.yx.face.model.vo.AdminVO;
 import com.yx.face.service.AdminService;
 import com.yx.face.service.FaceService;

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/impl/AdminServiceImpl.java

@@ -8,7 +8,6 @@ import com.yx.face.model.entity.Admin;
 import com.yx.face.model.vo.AdminVO;
 import com.yx.face.model.vo.ContextVO;
 import com.yx.face.service.AdminService;
-
 import org.springframework.stereotype.Service;
 import tk.mybatis.mapper.entity.Example;
 import tk.mybatis.mapper.weekend.WeekendSqls;

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/impl/AdminTagServiceImpl.java

@@ -2,7 +2,6 @@ package com.yx.face.service.impl;
 
 
 import com.yx.face.service.AdminTagService;
-
 import org.springframework.stereotype.Service;
 
 

+ 1 - 6
yqk-job/src/main/java/com/yx/face/service/impl/FaceServiceImpl.java

@@ -6,14 +6,9 @@ import com.yx.face.dao.UserVisitorListDao;
 import com.yx.face.dao.UserWhitelistDao;
 import com.yx.face.model.dto.UserVisitorListDetailInfo;
 import com.yx.face.model.dto.UserVisitorListDetailVisitor;
-import com.yx.face.model.entity.UserVisitorList;
-import com.yx.face.model.entity.UserVisitorListDetail;
-import com.yx.face.model.entity.UserWhitelist;
-import com.yx.face.model.entity.UserWhitelistDetail;
+import com.yx.face.model.entity.*;
 import com.yx.face.service.FaceService;
-
 import lombok.extern.slf4j.Slf4j;
-
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 

+ 4 - 10
yqk-job/src/main/java/com/yx/face/service/impl/FaceTBServiceImpl.java

@@ -4,25 +4,19 @@ package com.yx.face.service.impl;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.yx.face.boot.uitls.DateUtils;
-import com.yx.face.boot.uitls.RedisUtil;
-import com.yx.face.dao.*;
+import com.yx.face.dao.FaceDeviceDao;
+import com.yx.face.dao.FacePassDao;
+import com.yx.face.dao.FaceRequestLogDao;
+import com.yx.face.dao.FaceTaskDao;
 import com.yx.face.model.entity.DownFaceNew;
 import com.yx.face.model.entity.FacePass;
 import com.yx.face.model.entity.FaceRequestLog;
 import com.yx.face.model.entity.FaceTask;
-import com.yx.face.model.enums.FaceDeviceTypeEnum;
 import com.yx.face.model.vo.FaceDeviceLessVO;
-import com.yx.face.service.AdminService;
 import com.yx.face.service.FaceTBService;
-
-import com.yx.face.service.UserControlEarlyWarningListService;
-import com.yx.face.service.UserWhitelistService;
-import com.yx.face.service.feign.TBDeviceFaceService;
 import lombok.extern.slf4j.Slf4j;
-
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;

+ 1 - 2
yqk-job/src/main/java/com/yx/face/service/impl/InOutStatisticsServiceImpl.java

@@ -2,18 +2,17 @@ package com.yx.face.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
 import com.yx.face.boot.core.Constants;
 import com.yx.face.boot.uitls.RedisUtil;
 import com.yx.face.dao.InOutStatisticsDao;
 import com.yx.face.model.entity.InOutStatistics;
-import com.yx.face.model.enums.RedisCacheKey;
 import com.yx.face.model.redis.InOutStatisticsBean;
 import com.yx.face.service.InOutStatisticsService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
 import java.util.Date;
 import java.util.List;
 

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/impl/UserBlackListServiceImpl.java

@@ -3,7 +3,6 @@ package com.yx.face.service.impl;
 
 import com.yx.face.service.UserBlackListService;
 import lombok.extern.slf4j.Slf4j;
-
 import org.springframework.stereotype.Service;
 
 

+ 1 - 6
yqk-job/src/main/java/com/yx/face/service/impl/UserControlEarlyWarningListServiceImpl.java

@@ -1,22 +1,17 @@
 package com.yx.face.service.impl;
 
-import com.github.pagehelper.PageHelper;
-import com.github.pagehelper.PageInfo;
 import com.yx.face.dao.UserControlEarlyWarningListDao;
 import com.yx.face.dao.UserControlEarlyWarningListLogDao;
-import com.yx.face.model.entity.UserControlEarlyWarningList;
 import com.yx.face.model.entity.UserControlEarlyWarningListLog;
-
 import com.yx.face.model.vo.AdminAndUserEarlyWarningVO;
 import com.yx.face.service.AdminService;
 import com.yx.face.service.UserControlEarlyWarningListService;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.*;
+import java.util.Date;
 
 /**
  * <p>

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/impl/UserVisitorListDetailServiceImpl.java

@@ -3,7 +3,6 @@ package com.yx.face.service.impl;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.date.DateUtil;
-import com.yx.face.boot.uitls.DateUtils;
 import com.yx.face.dao.AdminDao;
 import com.yx.face.dao.FaceDeviceDao;
 import com.yx.face.dao.UserVisitorListDetailDao;

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/job/FaceServiceTask.java

@@ -1,6 +1,5 @@
 package com.yx.face.service.job;
 
-import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.yx.face.dao.*;

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/job/FkjDeviceTask.java

@@ -5,7 +5,6 @@ import com.yx.face.dao.FaceDeviceDao;
 import com.yx.face.dao.FkjHeartTrackingDao;
 import com.yx.face.model.entity.FaceDevice;
 import com.yx.face.model.entity.FkjHeartTracking;
-import com.yx.face.model.entity.SpiIotUserWhitelist;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.EnableAsync;

+ 0 - 7
yqk-job/src/main/java/com/yx/face/service/job/FkjQrcodeTask.java

@@ -1,11 +1,6 @@
 package com.yx.face.service.job;
 
-import com.yx.face.boot.uitls.DateUtils;
-import com.yx.face.dao.FaceDeviceDao;
-import com.yx.face.dao.FkjHeartTrackingDao;
 import com.yx.face.dao.FkjQrcodeDao;
-import com.yx.face.model.entity.FaceDevice;
-import com.yx.face.model.entity.FkjHeartTracking;
 import com.yx.face.model.entity.FkjQrcode;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Configuration;
@@ -17,8 +12,6 @@ import tk.mybatis.mapper.weekend.WeekendSqls;
 
 import javax.annotation.Resource;
 import java.util.Date;
-import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * @author shisl

+ 0 - 2
yqk-job/src/main/java/com/yx/face/service/job/InOutStatisticsTask.java

@@ -7,8 +7,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
-import javax.annotation.PostConstruct;
-
 @Slf4j
 @Component
 @AllArgsConstructor(onConstructor_ = @Autowired)

+ 1 - 5
yqk-job/src/main/java/com/yx/face/service/job/SpiIotUserWhitelistTask.java

@@ -19,11 +19,7 @@ import tk.mybatis.mapper.entity.Example;
 import tk.mybatis.mapper.weekend.WeekendSqls;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Component

+ 71 - 0
yqk-job/src/main/java/com/yx/face/service/job/StatDataTask.java

@@ -0,0 +1,71 @@
+package com.yx.face.service.job;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.yx.face.dao.AdminDao;
+import com.yx.face.dao.StatDataDao;
+import com.yx.face.dao.StatPeopleDao;
+import com.yx.face.model.entity.Admin;
+import com.yx.face.model.entity.StatData;
+import com.yx.face.model.entity.StatPeople;
+import com.yx.face.model.enums.AdminPlaceTypeEnum;
+import com.yx.face.model.enums.AdminTypeEnum;
+import com.yx.face.model.enums.StatDataStatusEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.util.List;
+
+/**
+ * 批量删除用户库用户
+ */
+@Configuration
+@EnableScheduling
+@EnableAsync
+@Slf4j
+public class StatDataTask {
+
+    @Resource
+    private AdminDao adminDao;
+    @Resource
+    private StatPeopleDao statPeopleDao;
+    @Resource
+    private StatDataDao statDataDao;
+
+    /**
+     * 每个小时的0/15/30/45执行
+     */
+    @Scheduled(cron = "0 0,15,30,45 * * * ? ", zone = "Asia/Shanghai")
+    public void statData() {
+        log.info("--->开始执行数据统计");
+        LocalDate now = LocalDate.now();
+        LocalTime nowTime = LocalTime.now();
+        Admin admin = new Admin();
+        admin.setOpenInOutStatistics(true);
+        admin.setType(AdminTypeEnum.DISTRICT.getCode());
+        admin.setPlaceType(AdminPlaceTypeEnum.COMMON_PLACE.getCode());
+        List<Admin> adminList = adminDao.select(admin);
+        for (Admin item : adminList) {
+            Long count = statDataDao.selectCount(
+                    Wrappers.<StatData>query()
+                            .select("DISTINCT id_number")
+                            .lambda()
+                            .eq(StatData::getAdminId, item.getId())
+                            .eq(StatData::getStatus, StatDataStatusEnum.IN.getCode())
+            );
+            StatPeople statPeople = new StatPeople();
+            statPeople.setAdminId(item.getId());
+            statPeople.setStatDate(now);
+            statPeople.setStatTime(nowTime);
+            statPeople.setStatNum(Math.toIntExact(count));
+            statPeopleDao.insert(statPeople);
+        }
+        log.info("--->完成执行数据统计");
+    }
+
+}

+ 52 - 25
yqk-job/src/main/java/com/yx/face/service/job/TbFaceTestTask.java

@@ -11,15 +11,15 @@ import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.Maps;
-import com.yx.face.FaceServerJobApplication;
 import com.yx.face.boot.core.Constants;
+import com.yx.face.boot.uitls.AddressUtil;
 import com.yx.face.boot.uitls.FileUtils;
-import com.yx.face.boot.uitls.IPUtils;
 import com.yx.face.boot.uitls.RedisUtil;
-import com.yx.face.boot.uitls.WebAddressUtil;
 import com.yx.face.dao.*;
 import com.yx.face.model.entity.*;
 import com.yx.face.model.enums.PassEnum;
+import com.yx.face.model.enums.UserRightNoEnum;
+import com.yx.face.model.mq.StatDataMq;
 import com.yx.face.model.vo.AdminVO;
 import com.yx.face.model.vo.ContextVO;
 import com.yx.face.model.vo.WhiteVisitorCertificationVO;
@@ -27,6 +27,7 @@ import com.yx.face.service.*;
 import com.yx.face.service.impl.AsyncTriggerRetryImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.aop.interceptor.AsyncExecutionAspectSupport;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -74,6 +75,8 @@ public class TbFaceTestTask {
     private UserVisitorListService userVisitorListService;
     @Resource
     private FaceLogDetailDao faceLogDetailDao;
+    @Resource
+    private ShortTermFaceLogDetailDao shortTermFaceLogDetailDao;
     @Autowired
     private UserVisitorListDetailService userVisitorListDetailService;
     @Resource
@@ -81,10 +84,22 @@ public class TbFaceTestTask {
     @Resource
     private AdminInoutWarnConfigDao adminInoutWarnConfigDao;
     @Autowired
+    private RestTemplate restTemplate;
+    @Autowired
     private RedisUtil redisUtil;
     @Resource
     private WarningLogDao warningLogDao;
+   
+
+//    //推送进出记录到公安网地址
+//    @Value("${push.faceLogUrl}")
+//    private String pushFaceLogUrl;
+
+    @Autowired
+    private RabbitTemplate rabbitTemplate;
 
+    /*    @Resource
+        private ShortTermFaceLogDao shortTermFaceLogDao;*/
     @RabbitListener(queues = "faceLogQueue")
     public void toClearUserInfo(Map<String, Object> dto) {
         log.info("----------开始------进出记录存入-------------");
@@ -271,7 +286,8 @@ public class TbFaceTestTask {
 //                photo = buildImage(photo, sn + pin);
                 String pathString = now.getTime() + String.valueOf((int) (Math.random() * 10000)) + ".jpg";
                 String filePath = FileUtils.getDirectory(Constants.UPLOAD_IMAGE_NEW) + "/";
-                photo = IPUtils.getLocalAddress(WebAddressUtil.address) + FileUtils.transformBase64Image(photo, filePath, pathString);
+                photo = AddressUtil.address + FileUtils.transformBase64Image(photo, filePath, pathString);
+
             }
             if (verifytype != 0) {
                 userId = Long.valueOf(pin);
@@ -356,30 +372,13 @@ public class TbFaceTestTask {
                 if (admin.getFaceLogHoldDays() != null && admin.getFaceLogHoldDays().intValue() != 0) {
                     faceLogDao.insertSelective(faceLog);
                 }
+                //进出数据统计
+                this.statData(admin,faceLog,whiteVisitorCertificationVO);
+
                 /*无效的数据不用进行数据的处理只做存储*/
                 if(!status){
                     return;
                 }
-
-                //推送数据到公安网
-//                pushFaceLog2Gongan(faceLog);
-
-                //短期通行记录
-//                shortTermFaceLogDao.insertSelective(BeanUtil.copyProperties(faceLog, ShortTermFaceLog.class));
-//                List<UserWhitelist> userWhitelists = userMap.get(cardid);
-//                if(CollectionUtil.isEmpty(userWhitelists)){
-//                    faceLogDao.insertSelective(faceLog);
-//                    //短期通行记录
-//                    shortTermFaceLogDao.insertSelective(BeanUtil.copyProperties(faceLog, ShortTermFaceLog.class));
-//                }else{
-//                    //深拷贝对象
-//                    List<FaceLog> faceLogs = userWhitelists.stream().map(v -> JSON.parseObject(JSON.toJSONString(faceLog), FaceLog.class).setAdminId(v.getAdminId())).collect(Collectors.toList());
-//                    faceLogDao.insertList(faceLogs);
-//                    //短期通行记录
-//                    for (FaceLog faceLog1 : faceLogs) {
-//                        shortTermFaceLogDao.insertSelective(BeanUtil.copyProperties(faceLog1, ShortTermFaceLog.class));
-//                    }
-//                }
                 //进出预警
                 this.adminInoutWarnConfig(faceLog, admin, whiteVisitorCertificationVO);
                 /*楼宇场景下-访客入场通知*/
@@ -430,6 +429,35 @@ public class TbFaceTestTask {
         log.info("----------完成------进出记录存入-------------");
     }
 
+    private void statData(AdminVO admin, FaceLog faceLog, WhiteVisitorCertificationVO whiteVisitorCertificationVO) {
+        if(!admin.getOpenInOutStatistics()){//没有开启数据统计
+            return;
+        }
+
+        StatDataMq mq = new StatDataMq();
+        mq.setAdminId(faceLog.getAdminId());
+        mq.setName(faceLog.getName());
+        mq.setPhone(faceLog.getPhone());
+        mq.setIdNumber(faceLog.getCardid());
+        mq.setCardIdEx(faceLog.getCardidex());
+        int peopleType;
+        if (UserRightNoEnum.REGULAR.getCode().equals(faceLog.getRightno())){//普通人员
+            peopleType = 1;
+        }else if (UserRightNoEnum.VISITORS.getCode().equals(faceLog.getRightno())){//访客
+            peopleType = 2;
+        }else{//其他
+            peopleType = 3;
+        }
+        mq.setPeopleType(peopleType);
+        mq.setSn(faceLog.getDeviceSn());
+        mq.setSnName(whiteVisitorCertificationVO.getName());
+        mq.setPass(faceLog.getOutType());
+        mq.setPassTime(DateUtil.parse(faceLog.getFaceTime()));
+        mq.setPhoto(faceLog.getPhoto());
+        //推到mq中消费
+        rabbitTemplate.convertAndSend(Constants.STAT_DATA_QUEUE_NAME, mq);
+    }
+
     private void adminInoutWarnConfig(FaceLog faceLog, AdminVO admin, WhiteVisitorCertificationVO vo) {
         if (!admin.getIsOpenInoutWarning()) {
             return;
@@ -455,7 +483,6 @@ public class TbFaceTestTask {
         synchronized (this) {
             redisUtil.lSet(key, faceTime, times);
             List<Date> dateList = redisUtil.lGet(key, 0, -1, Date.class);
-            dateList = CollUtil.isEmpty(dateList) ? new ArrayList<>() : dateList;
             effectiveDateList = dateList.stream().filter(p -> DateUtil.compare(p, dateTime) >= 0).collect(Collectors.toList());
             if (dateList.size() != effectiveDateList.size()) {
                 redisUtil.del(key);

+ 0 - 2
yqk-job/src/main/java/com/yx/face/service/job/UserCattleTask.java

@@ -2,7 +2,6 @@ package com.yx.face.service.job;
 
 import com.yx.face.dao.FaceLogDao;
 import com.yx.face.dao.UserCattleDao;
-import com.yx.face.dao.UserInfoDao;
 import com.yx.face.model.entity.FaceLog;
 import com.yx.face.model.entity.UserCattle;
 import lombok.extern.slf4j.Slf4j;
@@ -13,7 +12,6 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import java.text.SimpleDateFormat;
 import java.util.*;

+ 0 - 51
yqk-job/src/main/java/com/yx/face/service/job/UserInfoJob.java

@@ -1,51 +0,0 @@
-package com.yx.face.service.job;
-
-import com.alibaba.fastjson.JSONObject;
-import com.yx.face.boot.core.Constants;
-import com.yx.face.dao.UserInfoDao;
-import com.yx.face.model.dto.UserInfoDto;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.amqp.rabbit.annotation.RabbitListener;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-
-import javax.annotation.Resource;
-import java.util.Arrays;
-
-@Component
-@Slf4j
-public class UserInfoJob {
-    @RabbitListener(queues = Constants.USER_INFO_QUEUE_NAME)
-    public synchronized void userInfoSync(String message) {
-        log.info("----------开始用户注册信息同步-------------");
-//        JSONObject obj = JSONObject.parseObject(message);
-//        String bizType = obj.get("bizType").toString();
-//        if (Constants.USER_MESSAGE_TYPE_ADD.equals(bizType)) { //添加用户注册信息
-//            UserInfoDto dto = JSONObject.parseObject(obj.get("data").toString(), UserInfoDto.class);
-//            try {
-//                restTemplate.postForObject(userInfoAddUrl, Arrays.asList(dto), String.class);
-//            } catch (Exception e) {
-//                log.error("推送添加用户注册数据到公安网失败");
-//            }
-//        } else if (Constants.USER_MESSAGE_TYPE_UPDATE.equals(bizType)) {//修改用户注册信息
-//            UserInfoDto dto = JSONObject.parseObject(obj.get("data").toString(), UserInfoDto.class);
-//            try {
-//                restTemplate.postForObject(userInfoUpdateUrl, Arrays.asList(dto), String.class);
-//            } catch (Exception e) {
-//                log.error("推送更新用户注册数据到公安网失败");
-//            }
-//        } else if (Constants.USER_MESSAGE_TYPE_DEL.equals(bizType)) {//删除用户注册信息
-//            UserInfoDto dto = JSONObject.parseObject(obj.get("data").toString(), UserInfoDto.class);
-//            try {
-//                restTemplate.postForObject(userInfoDelUrl, Arrays.asList(dto), String.class);
-//            } catch (Exception e) {
-//                log.error("推送删除用户注册数据到公安网失败");
-//            }
-//        }
-        log.info("----------完成用户注册信息同步-------------");
-    }
-
-
-}

+ 4 - 0
yqk-job/src/main/java/com/yx/face/service/job/ZeroTask.java

@@ -32,6 +32,8 @@ public class ZeroTask {
     private ClearVisitorDataTask clearVisitorDataTask;
     @Resource
     private ClearFaceLogTask clearFaceLogTask;
+    @Resource
+    private ClearStatTask clearStatTask;
 
     //测试
     //@Scheduled(cron = "0 1/1 * * * ?", zone = "Asia/Shanghai")
@@ -49,5 +51,7 @@ public class ZeroTask {
         userInfoTask.toClearUserInfo();
         /*清除FaceLog数据*/
         clearFaceLogTask.toClearFaceLog();
+        /*清楚7天前的统计数据*/
+        clearStatTask.clearTask();
     }
 }

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/job/fiveMinute/VisitorClearTask.java

@@ -11,7 +11,6 @@ import com.yx.face.dao.UserVisitorListDao;
 import com.yx.face.model.entity.Admin;
 import com.yx.face.model.entity.UserVisitorList;
 import com.yx.face.model.po.VisitorClearPo;
-import jdk.nashorn.internal.ir.annotations.Reference;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.Async;

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/job/zeroTask/AdminDataShowTask.java

@@ -10,7 +10,6 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.scheduling.annotation.Scheduled;
 
 import javax.annotation.Resource;
 import java.util.List;

+ 0 - 4
yqk-job/src/main/java/com/yx/face/service/job/zeroTask/ClearFaceLogTask.java

@@ -7,17 +7,13 @@ import com.alibaba.fastjson.JSONObject;
 import com.yx.face.dao.AdminDao;
 import com.yx.face.dao.FaceLogDao;
 import com.yx.face.dao.FaceLogDetailDao;
-import com.yx.face.dao.ShortTermFaceLogDao;
-import com.yx.face.dao.ShortTermFaceLogDetailDao;
 import com.yx.face.model.entity.Admin;
-import com.yx.face.model.entity.FaceTask;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;

+ 49 - 0
yqk-job/src/main/java/com/yx/face/service/job/zeroTask/ClearStatTask.java

@@ -0,0 +1,49 @@
+package com.yx.face.service.job.zeroTask;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.yx.face.dao.*;
+import com.yx.face.model.entity.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import java.time.LocalDate;
+
+/**
+ * @description:
+ * @ClassName ClearVisitorDataTask
+ * @Author WXG
+ * @Date 2022/12/12 9:19
+ */
+@Configuration      //1.主要用于标记配置类,兼备Component的效果。
+@EnableScheduling   // 2.开启定时任务
+@EnableAsync
+@Slf4j
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class ClearStatTask {
+    private final StatAgeDao statAgeDao;
+    private final StatDataDao statDataDao;
+    private final StatDataItemDao statDataItemDao;
+    private final StatPeopleDao statPeopleDao;
+    private final StatSexDao statSexDao;
+    private final StatSourceDao statSourceDao;
+    @Async
+    public void clearTask() {
+        log.info("----------开始------清除统计数据-------------");
+        LocalDate now = LocalDate.now();
+        LocalDate localDate = now.minusDays(7);
+
+        statAgeDao.delete(Wrappers.<StatAge>lambdaQuery().lt(StatAge::getStatDate,localDate));
+        statDataDao.delete(Wrappers.<StatData>lambdaQuery().lt(StatData::getCreateTime,localDate));
+        statDataItemDao.delete(Wrappers.<StatDataItem>lambdaQuery().lt(StatDataItem::getCreateTime,localDate));
+        statPeopleDao.delete(Wrappers.<StatPeople>lambdaQuery().lt(StatPeople::getStatDate,localDate));
+        statSexDao.delete(Wrappers.<StatSex>lambdaQuery().lt(StatSex::getStatDate,localDate));
+        statSourceDao.delete(Wrappers.<StatSource>lambdaQuery().lt(StatSource::getStatDate,localDate));
+
+        log.info("----------完成------清除统计数据-------------");
+    }
+}

+ 0 - 4
yqk-job/src/main/java/com/yx/face/service/job/zeroTask/ClearVisitorDataTask.java

@@ -1,8 +1,6 @@
 package com.yx.face.service.job.zeroTask;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.date.DatePattern;
-import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import com.yx.face.dao.AdminDao;
 import com.yx.face.dao.FaceDeviceDao;
@@ -17,10 +15,8 @@ import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import tk.mybatis.mapper.entity.Example;
-import tk.mybatis.mapper.weekend.Weekend;
 import tk.mybatis.mapper.weekend.WeekendSqls;
 
-import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import java.util.Date;
 import java.util.List;

+ 0 - 1
yqk-job/src/main/java/com/yx/face/service/job/zeroTask/UserInfoTask.java

@@ -6,7 +6,6 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.scheduling.annotation.Scheduled;
 
 import javax.annotation.Resource;
 

+ 301 - 0
yqk-job/src/main/java/com/yx/face/service/mq/StatServer.java

@@ -0,0 +1,301 @@
+package com.yx.face.service.mq;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.IdcardUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.yx.face.boot.core.Constants;
+import com.yx.face.boot.uitls.RedisUtil;
+import com.yx.face.dao.*;
+import com.yx.face.model.entity.*;
+import com.yx.face.model.enums.PassEnum;
+import com.yx.face.model.enums.StatAgeTypeEnum;
+import com.yx.face.model.enums.StatDataStatusEnum;
+import com.yx.face.model.mq.StatDataMq;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Component
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@Slf4j
+public class StatServer {
+    private final StatAgeDao statAgeDao;
+    private final StatDataDao statDataDao;
+    private final StatDataItemDao statDataItemDao;
+    private final StatPeopleDao statPeopleDao;
+    private final StatSexDao statSexDao;
+    private final StatSourceDao statSourceDao;
+    private final RedisUtil redisUtil;
+
+    private static List<Integer> list;
+
+    static {
+        list = new ArrayList<>(10);
+        for (int i = 0; i < 10; i++) {
+            list.add(i);
+        }
+    }
+
+    @RabbitListener(queues = Constants.STAT_DATA_QUEUE_NAME)
+    public void statDataQueue(StatDataMq mq) {
+        try {
+            method(mq);
+        }catch (Exception e){
+            log.error("消费报错",e);
+        }
+    }
+
+    private void method(StatDataMq mq) {
+        Integer adminId = mq.getAdminId();
+        int lock = adminId % 10;
+        synchronized (list.get(lock)) {
+            if (DateUtil.compare(mq.getPassTime(), DateUtil.beginOfDay(new Date())) < 0) {
+                return;
+            }
+            //TODO 处理统计数据
+            log.info("处理统计数据:{}", mq);
+
+            String today = DateUtil.formatDate(mq.getPassTime());
+            String key = Constants.STAT_ALL_NUM + adminId + "::" + today;
+            this.keyIncr(key);//进出人次
+
+            if (mq.getPass() == null || mq.getPass() == 0) {//通用的设备进出不统计
+                return;
+            }
+            if (!IdcardUtil.isValidCard(mq.getIdNumber())) {//只统计有身份证的
+                return;
+            }
+
+            PassEnum passEnum = PassEnum.getEnumByCode(mq.getPass());
+            if (passEnum == null) return;
+            switch (passEnum) {
+                case IN:
+                    this.inStat(mq);
+                    break;
+                case OUT:
+                    this.outStat(mq);
+                    break;
+            }
+        }
+    }
+
+    private void outStat(StatDataMq mq) {
+        LocalDateTime dateTime1 = mq.getPassTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+        List<StatData> statDataList = statDataDao.selectList(
+                Wrappers.<StatData>lambdaQuery()
+                        .eq(StatData::getAdminId, mq.getAdminId())
+                        .eq(StatData::getIdNumber, mq.getIdNumber())
+                        .eq(StatData::getStatus, StatDataStatusEnum.IN.getCode())
+                        .orderByDesc(StatData::getId)
+        );
+        if (CollUtil.isNotEmpty(statDataList)) {
+            for (StatData statData : statDataList) {
+                StatDataItem statDataItem = statDataItemDao.selectOne(
+                        Wrappers.<StatDataItem>lambdaQuery()
+                                .eq(StatDataItem::getStatDataId, statData.getId())
+                                .orderByDesc(StatDataItem::getPassTime)
+                                .last("limit 1")
+                );
+                LocalDateTime dateTime2 = statDataItem.getPassTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+                Duration duration = Duration.between(dateTime1, dateTime2);
+                // 获取相差的小时
+                long hours = Math.abs(duration.toHours());
+                // 获取相差的分钟
+                long minutes = Math.abs(duration.toMinutes() % 60);
+                // 获取相差的秒
+                long seconds = Math.abs(duration.getSeconds() % 60);
+                statData.setBetweenTime(String.format("%02d",hours) + ":" + String.format("%02d",minutes) + ":" + String.format("%02d",seconds));
+                statData.setStatus(StatDataStatusEnum.OUT.getCode());
+                statDataDao.updateById(statData);
+                StatDataItem item = BeanUtil.copyProperties(mq, StatDataItem.class);
+                item.setStatDataId(statData.getId());
+                item.setStatus(true);
+                statDataItemDao.insert(item);
+            }
+        }else {
+            StatData statData = statDataDao.selectOne(
+                    Wrappers.<StatData>lambdaQuery()
+                            .eq(StatData::getAdminId, mq.getAdminId())
+                            .eq(StatData::getIdNumber, mq.getIdNumber())
+                            .eq(StatData::getStatus, StatDataStatusEnum.OUT.getCode())
+                            .between(StatData::getCreateTime, DateUtil.formatDateTime(DateUtil.beginOfDay(mq.getPassTime())), DateUtil.formatDateTime(DateUtil.endOfDay(mq.getPassTime())))
+                            .orderByDesc(StatData::getId)
+                            .last("limit 1")
+            );
+            if(ObjectUtil.isNull(statData)){
+                statData = BeanUtil.copyProperties(mq, StatData.class);
+                statData.setStatus(StatDataStatusEnum.OUT.getCode());
+                statDataDao.insert(statData);
+                StatDataItem item = BeanUtil.copyProperties(mq, StatDataItem.class);
+                item.setStatDataId(statData.getId());
+                item.setStatus(false);
+                statDataItemDao.insert(item);
+            }else {
+                StatDataItem item = BeanUtil.copyProperties(mq, StatDataItem.class);
+                item.setStatDataId(statData.getId());
+                item.setStatus(false);
+                statDataItemDao.insert(item);
+                StatDataItem statDataItem = new StatDataItem();
+                statDataItem.setStatus(false);
+                statDataItemDao.update(statDataItem, Wrappers.<StatDataItem>lambdaUpdate()
+                        .eq(StatDataItem::getStatDataId, statData.getId())
+                        .eq(StatDataItem::getPass,StatDataStatusEnum.OUT.getCode())
+                );
+            }
+        }
+
+    }
+
+    private void inStat(StatDataMq mq) {
+        //查询当天
+        StatData statData = statDataDao.selectOne(
+                Wrappers.<StatData>lambdaQuery()
+                        .eq(StatData::getAdminId, mq.getAdminId())
+                        .eq(StatData::getIdNumber, mq.getIdNumber())
+                        .eq(StatData::getStatus, StatDataStatusEnum.IN.getCode())
+                        .between(StatData::getCreateTime, DateUtil.formatDateTime(DateUtil.beginOfDay(mq.getPassTime())), DateUtil.formatDateTime(DateUtil.endOfDay(mq.getPassTime())))
+                        .orderByDesc(StatData::getId)
+                        .last("limit 1")
+        );
+        if (ObjectUtil.isNull(statData)) {
+            statData = BeanUtil.copyProperties(mq, StatData.class);
+            statData.setStatus(StatDataStatusEnum.IN.getCode());
+            statDataDao.insert(statData);
+            StatDataItem item = BeanUtil.copyProperties(mq, StatDataItem.class);
+            item.setStatDataId(statData.getId());
+            item.setStatus(true);
+            statDataItemDao.insert(item);
+            //数据统计
+            this.stat(mq);
+        } else {
+            StatDataItem item = BeanUtil.copyProperties(mq, StatDataItem.class);
+            item.setStatDataId(statData.getId());
+            item.setStatus(false);
+            statDataItemDao.insert(item);
+            StatDataItem statDataItem = new StatDataItem();
+            statDataItem.setStatus(false);
+            statDataItemDao.update(statDataItem, Wrappers.<StatDataItem>lambdaUpdate()
+                    .eq(StatDataItem::getStatDataId, statData.getId())
+                    .eq(StatDataItem::getPass,StatDataStatusEnum.IN.getCode()));
+        }
+
+
+    }
+
+    private void stat(StatDataMq mq) {
+        LocalDate localDate = mq.getPassTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+        //1.进场人数
+        String key = Constants.STAT_IN_NUM + mq.getAdminId() + "::" + DateUtil.formatDate(mq.getPassTime());
+        this.keyIncr(key);
+        //2.人员年龄
+        int age = IdcardUtil.getAgeByIdCard(mq.getIdNumber());
+        int ageType = this.getAgeType(age);
+        StatAge statAge = statAgeDao.selectOne(
+                Wrappers.<StatAge>lambdaQuery()
+                        .eq(StatAge::getAdminId, mq.getAdminId())
+                        .eq(StatAge::getStatDate, localDate)
+                        .eq(StatAge::getAgeType, ageType)
+        );
+        if (ObjectUtil.isNull(statAge)) {
+            statAge = new StatAge();
+            statAge.setAdminId(mq.getAdminId());
+            statAge.setStatDate(localDate);
+            statAge.setAgeType(ageType);
+            statAge.setStatNum(1);
+            statAgeDao.insert(statAge);
+        } else {
+            statAge.setStatNum(statAge.getStatNum() + 1);
+            statAgeDao.updateById(statAge);
+        }
+        //3.人员性别
+        int sexType = IdcardUtil.getGenderByIdCard(mq.getIdNumber());
+        StatSex statSex = statSexDao.selectOne(
+                Wrappers.<StatSex>lambdaQuery()
+                        .eq(StatSex::getAdminId, mq.getAdminId())
+                        .eq(StatSex::getStatDate, localDate)
+                        .eq(StatSex::getSexType, sexType)
+        );
+        if (ObjectUtil.isNull(statSex)) {
+            statSex = new StatSex();
+            statSex.setAdminId(mq.getAdminId());
+            statSex.setStatDate(localDate);
+            statSex.setSexType(sexType);
+            statSex.setStatNum(1);
+            statSexDao.insert(statSex);
+        } else {
+            statSex.setStatNum(statSex.getStatNum() + 1);
+            statSexDao.updateById(statSex);
+        }
+        //4.人员来源地
+        String statSourceCode = IdcardUtil.getProvinceCodeByIdCard(mq.getIdNumber());
+        StatSource statSource = statSourceDao.selectOne(
+                Wrappers.<StatSource>lambdaQuery()
+                        .eq(StatSource::getAdminId, mq.getAdminId())
+                        .eq(StatSource::getStatDate, localDate)
+                        .eq(StatSource::getStatSourceCode, statSourceCode)
+        );
+        if (ObjectUtil.isNull(statSource)) {
+            statSource = new StatSource();
+            statSource.setAdminId(mq.getAdminId());
+            statSource.setStatDate(localDate);
+            statSource.setStatSourceCode(statSourceCode+"00");//因为我们area_code表中,省级账号有四位 3300
+            statSource.setStatNum(1);
+            statSourceDao.insert(statSource);
+        } else {
+            statSource.setStatNum(statSource.getStatNum() + 1);
+            statSourceDao.updateById(statSource);
+        }
+    }
+
+    private int getAgeType(int age) {
+        if (age < 20) {
+            return StatAgeTypeEnum.AGE_20.getCode();
+        } else if (age <= 35) {
+            return StatAgeTypeEnum.AGE_35.getCode();
+        } else if (age <= 50) {
+            return StatAgeTypeEnum.AGE_50.getCode();
+        } else if (age <= 65) {
+            return StatAgeTypeEnum.AGE_65.getCode();
+        } else {
+            return StatAgeTypeEnum.AGE_OTHER.getCode();
+        }
+    }
+
+    public void keyIncr(String key) {
+        long incr = redisUtil.incr(key, 1);
+        if (incr == 1) {
+            redisUtil.expire(key, 86400L * 8);
+        }
+    }
+
+    public static void main(String[] args) {
+        DateTime date = DateUtil.date();
+        DateTime dateTime = DateUtil.offsetDay(date, 1);
+        System.out.println(DateUtil.between(date, dateTime, DateUnit.SECOND));
+        LocalDateTime dateTime1 = LocalDateTime.now();
+        LocalDateTime dateTime2 = dateTime1.plusHours(1).plusMinutes(2).plusSeconds(5);
+        Duration duration = Duration.between(dateTime2, dateTime1);
+        // 获取相差的小时
+        long hours = Math.abs(duration.toHours());
+        // 获取相差的分钟
+        long minutes = Math.abs(duration.toMinutes() % 60);
+        // 获取相差的秒
+        long seconds = Math.abs(duration.getSeconds() % 60);
+        System.out.println(hours + ":" + minutes + ":" + String.format("%02d",seconds));
+    }
+}

+ 7 - 5
yqk-job/src/main/resources/application-prod.yml

@@ -4,6 +4,8 @@ server:
     context-path: /yx-fyzd-job
     session:
       persistent: false
+    web:
+      prefix: 9100/yx-fyzd
   tomcat:
     accept-count: 150
     uri-encoding: UTF-8
@@ -19,7 +21,7 @@ spring:
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://127.0.0.1:3306/yqk_fyzd?characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
     username: root
-    password: 123456
+    password: nqj##361
     type: com.alibaba.druid.pool.DruidDataSource
     # druid参数调优(可选)
     initialSize: 5
@@ -44,10 +46,10 @@ spring:
         login-username: admin
         login-password: Nqj##117521
   rabbitmq:
-    host: 172.168.1.31
+    host: 127.0.0.1
     port: 5672
-    username: hanghui
-    password: nqj##361
+    username: guest
+    password: guest
     listener:
       simple:
         #        acknowledge-mode: manual #设置确认模式手工确认
@@ -125,7 +127,7 @@ knife4j:
 ##``````````````````````````````````` 上传文件 配置``````````````````````````````````````````````````````````````###
 file.upload.path: file/
 file.upload.path.relative: /file/**
-web.address: http://192.168.1.198:9100/yx-fyzd/
+web.address:
 ##---------------------------------------健康码是否开启白名单地址------------------------------------------------------##
 tb.jkm.device.white.list.url: http://192.168.1.5:1831/Hanghui/deviceWhiteList
 ##``````````````````````````````````` 人脸服务 配置``````````````````````````````````````````````````````````````###

+ 4 - 2
yqk-job/src/main/resources/application-test.yml

@@ -4,6 +4,8 @@ server:
     context-path: /yx-fyzd-job
     session:
       persistent: false
+    web:
+      prefix: 9100/yx-fyzd
   tomcat:
     accept-count: 150
     uri-encoding: UTF-8
@@ -17,9 +19,9 @@ spring:
     time-zone: GMT+8
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://127.0.0.1:3306/yqk_fyzd?characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://218.108.80.158:55557/yqk_fyzd?characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
     username: root
-    password: 123456
+    password: Nqj##117521
     type: com.alibaba.druid.pool.DruidDataSource
     # druid参数调优(可选)
     initialSize: 5

+ 3 - 0
yqk-linkage/src/main/java/com/yixin/ms/model/vo/HealtCodeUserVO.java

@@ -226,5 +226,8 @@ public class HealtCodeUserVO {
 
     @ApiModelProperty("用户姓名")
     private String name;
+
+    @ApiModelProperty(value = "卡号")
+    private String cardIdEx;
 }
 

+ 1 - 0
yqk-linkage/src/main/java/com/yixin/ms/service/impl/HealthCodeServiceImpl.java

@@ -202,6 +202,7 @@ public class HealthCodeServiceImpl implements HealthCodeService {
 
     public static HealtCodeUserVO initHealthUserVo(ShortTermDTO shortTermDTO,PlaceInfoVO placeInfoVO) {
         HealtCodeUserVO userVO = new HealtCodeUserVO();
+        userVO.setCardIdEx(shortTermDTO.getCardIdEx());
         userVO.setIsOpen(0);
         userVO.setOpenVoiceMsg("请通行");
         userVO.setOpenMsg("请通行");

+ 1 - 1
yqk-linkage/src/main/resources/application.yml

@@ -1,3 +1,3 @@
 spring:
   profiles:
-    active: prod
+    active: test

+ 5 - 0
yqk-master/pom.xml

@@ -15,6 +15,11 @@
             <artifactId>yqk-common</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.java-websocket</groupId>
+            <artifactId>Java-WebSocket</artifactId>
+            <version>1.5.6</version>
+        </dependency>
     </dependencies>
     <build>
         <finalName>yx-fyzd</finalName>

+ 112 - 0
yqk-master/src/main/java/com/yx/face/boot/config/WebsocketConfig.java

@@ -0,0 +1,112 @@
+package com.yx.face.boot.config;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yx.face.boot.core.Constants;
+import com.yx.face.model.dto.issue.WebsocketMsgReq;
+import com.yx.face.service.issue.IssueDeviceService;
+import lombok.extern.slf4j.Slf4j;
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.drafts.Draft_6455;
+import org.java_websocket.handshake.ServerHandshake;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.net.URI;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.Executor;
+
+/**
+ * @author shisl
+ * @package com.yx.face.boot.config
+ * @class WebsocketConfig
+ * @date 2024/4/7 下午4:00
+ * @description
+ */
+@Slf4j
+@Configuration
+@Component
+public class WebsocketConfig {
+
+    @Resource
+    private Executor executor;
+
+    @Resource
+    private IssueDeviceService issueDeviceService;
+
+    @Value("${websocket.wsSwitch}")
+    private Boolean wsSwitch;
+
+    @Bean(name = "otaWebSocketClient")
+    public WebSocketClient webSocketClient(@Value("${websocket.uri}") String websocketUri,
+                                           @Value("${websocket.token}") String websocketToken) {
+        try {
+
+            WebSocketClient webSocketClient = new WebSocketClient(new URI(String.format(websocketUri, websocketToken, Constants.SOURCE_TQSERVER)), new Draft_6455(), null, 60000) {
+                //连接服务端时触发
+                @Override
+                public void onOpen(ServerHandshake handshakedata) {
+                    log.info("websocket客户端和服务器连接成功");
+                }
+
+                //收到服务端消息时触发
+                @Override
+                public void onMessage(String message) {
+                    //TODO。。。处理业务逻辑
+                    handleBiz(message);
+                }
+
+                //和服务端断开连接时触发
+                @Override
+                public void onClose(int code, String reason, boolean remote) {
+                    log.info("websocket客户端退出连接");
+                }
+
+                //连接异常时触发
+                @Override
+                public void onError(Exception ex) {
+                    ex.printStackTrace();
+                    log.info("websocket客户端和服务器连接发生错误={}", ex.getMessage());
+                }
+            };
+
+            webSocketClient.connect();
+            Timer t = new Timer();
+            t.scheduleAtFixedRate(new TimerTask() {
+                @Override
+                public void run() {
+                    log.info("进入定时器");
+                    if (webSocketClient.isClosed()) {
+                        log.error("断线重连");
+                        webSocketClient.reconnect();
+                    }
+                }
+            }, 1000, 5000);
+            return webSocketClient;
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("--->websocket连接异常");
+        }
+        return null;
+    }
+
+    /**
+     * 处理设备消息
+     *
+     * @param message
+     */
+    private void handleBiz(String message) {
+
+        if (!wsSwitch) {
+            log.info("---->关闭ws开关");
+            return;
+        }
+        WebsocketMsgReq msgReq = JSONObject.parseObject(message, WebsocketMsgReq.class);
+        log.info("--->msgReq:{}", JSONObject.toJSONString(msgReq));
+        issueDeviceService.handleCallback(msgReq);
+    }
+
+}

+ 79 - 0
yqk-master/src/main/java/com/yx/face/boot/consumer/HhfaceIssueConsumer.java

@@ -0,0 +1,79 @@
+package com.yx.face.boot.consumer;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yx.face.constant.RabbitMqConstants;
+import com.yx.face.model.dto.hhface.AddSnIssuedMsg;
+import com.yx.face.model.dto.hhface.DelFaceBySnMsg;
+import com.yx.face.model.dto.hhface.DeleteBySnMsg;
+import com.yx.face.model.dto.hhface.DownUserMsg;
+import com.yx.face.model.dto.issue.WebsocketMsgReq;
+import com.yx.face.service.FaceTBService;
+import com.yx.face.service.impl.AsyncTriggerRetryImpl;
+import com.yx.face.service.issue.IssueDeviceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * @author shisl
+ * @package com.yx.face.boot.rabbitConfig.listener
+ * @class HhfaceIssueConsumer
+ * @date 2024/9/10 下午3:46
+ * @description
+ */
+@Slf4j
+@Component
+public class HhfaceIssueConsumer {
+
+    @Resource
+    private FaceTBService faceTBService;
+
+    @Resource
+    private AsyncTriggerRetryImpl asyncTriggerRetryImpl;
+
+    @Resource
+    private IssueDeviceService issueDeviceService;
+
+    @RabbitListener(queues = RabbitMqConstants.GENERAL_USER_QUEUE_NAME)
+    public synchronized void generalUserQueue(String message) {
+        try {
+            JSONObject obj = JSONObject.parseObject(message);
+            String bizType = obj.get("bizType").toString();
+            if (RabbitMqConstants.GENERAL_MESSAGE_TYPE_addSingleUser2Device.equals(bizType)) {
+                DownUserMsg dto = JSONObject.parseObject(obj.get("data").toString(), DownUserMsg.class);
+                log.info("----->消费单个用户下发消息:{}", JSONObject.toJSONString(dto.getDownFace()));
+                faceTBService.downUser(dto.getDownFace(), dto.getTaskInfo());
+
+            } else if (RabbitMqConstants.GENERAL_MESSAGE_TYPE_batchAddUser2Device.equals(bizType)) {
+                AddSnIssuedMsg dto = JSONObject.parseObject(obj.get("data").toString(), AddSnIssuedMsg.class);
+                log.info("----->消费批量用户下发消息:{}", JSONObject.toJSONString(dto));
+                asyncTriggerRetryImpl.addSnIssued(dto.getFaceDevice(), dto.getAdminVO(), dto.getTaskInfo(), dto.getIssueType());
+
+            } else if (RabbitMqConstants.GENERA_MESSAGE_TYPE_delUserFromDevice.equals(bizType)) {
+                DelFaceBySnMsg dto = JSONObject.parseObject(obj.get("data").toString(), DelFaceBySnMsg.class);
+                log.info("----->消费指定用户删除消息:{}", JSONObject.toJSONString(dto));
+                faceTBService.delFaceBySn(dto.getSn(), dto.getUserIds(), dto.getTaskInfo());
+
+            } else if (RabbitMqConstants.GENERAL_MESSAGE_TYPE_delUserBySn.equals(bizType)) {
+                DeleteBySnMsg dto = JSONObject.parseObject(obj.get("data").toString(), DeleteBySnMsg.class);
+                log.info("----->消费清空设备用户消息:{}", JSONObject.toJSONString(dto));
+                faceTBService.deleteBySn(dto.getSn(), dto.getTaskInfo());
+            }
+        } catch (Exception e) {
+            log.error("消费下发消息失败的数据体:{}", message);
+            log.error("消费下发消息失败:", e);
+        }
+
+    }
+
+    @RabbitListener(queues = RabbitMqConstants.GENERAL_USER_CALLBACK_QUEUE_NAME)
+    public synchronized void generalUserCallbackQueue(String message) {
+        WebsocketMsgReq msgReq = JSONObject.parseObject(message, WebsocketMsgReq.class);
+        log.info("----->消费HHFACE回调消息:{}", message);
+        issueDeviceService.handleCallback(msgReq);
+    }
+
+
+}

+ 0 - 59
yqk-master/src/main/java/com/yx/face/boot/core/Constants.java

@@ -1,59 +0,0 @@
-package com.yx.face.boot.core;
-
-/**
- * @description: Constants <br>
- * @date: 2021/3/29 17:08 <br>
- * @author: PWB <br>
- */
-public class Constants {
-
-    public static final String UPLOAD_PATH = "file/image/upload/";
-    public static final String UPLOAD_IMAGE = "file/upload/images/";
-    public static final String UPLOAD_IMAGE_NEW = "file/upload/imagesnew/";
-    public static final String UPLOAD_EXCEL = "file/upload/excel/";
-    public static final String UPLOAD_PHOTO = "file/upload/photo/";
-    public static final String UPLOAD_VIDEO = "file/upload/videos/";
-    public static final String UPLOAD_DOCUMENT = "file/upload/document/";
-    public static final String UPLOAD_OTHER = "file/upload/other";
-    public static final String SYSTEM_FILE = "file/system/";
-    public static final String SALT = "YcYp65l;uq234pwb;iIjHg872S-ajfL.khp636**YX2021";
-    public static final String SALT_PRE = "SU2ti983*238--=833##383yuu";
-
-
-    //无锡苏康码加密秘钥key
-    public static final String SUPER_APP_KEY = "super_app_key";
-    //无锡苏康码 url
-    public static final String SKM_API_URL = "skm_aip_url";
-    //无锡苏康码
-    public static final String SUPER_SIGN = "super_sign";
-
-    public static final String TB_API_URL = "tb_aip_url";
-
-    public static final String TURN_ON_OR_STOP = "turn_on_or_stop";
-
-    //微信相关参数:登录地址
-    public static final String WX_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
-    //微信相关参数:AccessToken获取地址
-    public static final String WX_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
-    //微信相关参数:订阅消息请求地址
-    public static final String WX_MESSAGE_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={0}";
-
-
-    //背景审核复议结果通知
-    public static final String WX_MS_TEMPLATE_4955 = "JPSs7hM4vBwwQXfShKWNEM3C_qyZFqBnBbfHJHWwfCQ";
-
-
-    //申请通行证结果通知
-    public static final String WX_MS_TEMPLATE_592 = "mh0qTV5SrTkXUHpg7AwC9VHSLhq8QzNQqI7VoQrwC4U";
-
-    /*进出记录统计时默认key值前缀*/
-    public static final String IN_OUT_STATISTICS = "IN_OUT_STATISTICS:";
-    /*进出记录预警前缀key 全部应该是key+admin:+idNumber*/
-    public static final String IN_OUT_WARNING = "IN_OUT_WARNING:";
-    /*访客机加密key值*/
-    public static final String FKJ_KEY = "a2f0e24913f378add01b9f36546a2edb";
-
-    public static final Integer DEVICE_DELAY = 5000;//设备缓存延迟时间 单位(毫秒)
-    public static final String DEVICE_EXCHANGE = "sn.delay.exchange";
-    public static final String DEVICE_CACHE_QUQUE = "snCacheQueue";
-}

+ 43 - 31
yqk-master/src/main/java/com/yx/face/boot/rabbitConfig/config/ProducerConsumerConfig.java

@@ -8,36 +8,48 @@ import org.springframework.context.annotation.Configuration;
 //生产者消费者模式的配置,包括一个队列和两个对应的消费者
 @Configuration
 public class ProducerConsumerConfig {
-	
-	@Bean
-	public Queue myQueue() {
-		Queue queue=new Queue("myqueue");
-		return queue;
-	}
-
-
-	@Bean
-	public Queue PutFaceQueue() {
-		Queue queue=new Queue("putFaceQueue");
-		return queue;
-	}
-
-	@Bean
-	public Queue faceLogQueue() {
-		Queue queue=new Queue("faceLogQueue");
-		return queue;
-	}
-
-	@Bean
-	public Queue iotUserQueue() {
-		Queue queue=new Queue(RabbitMqConstants.IOT_USER_QUEUE_NAME);
-		return queue;
-	}
-
-	@Bean
-	public Queue userInfoQueue() {
-		Queue queue=new Queue(RabbitMqConstants.USER_INFO_QUEUE_NAME);
-		return queue;
-	}
+
+    @Bean
+    public Queue myQueue() {
+        Queue queue = new Queue("myqueue");
+        return queue;
+    }
+
+
+    @Bean
+    public Queue PutFaceQueue() {
+        Queue queue = new Queue("putFaceQueue");
+        return queue;
+    }
+
+    @Bean
+    public Queue faceLogQueue() {
+        Queue queue = new Queue("faceLogQueue");
+        return queue;
+    }
+
+    @Bean
+    public Queue iotUserQueue() {
+        Queue queue = new Queue(RabbitMqConstants.IOT_USER_QUEUE_NAME);
+        return queue;
+    }
+
+    @Bean
+    public Queue userInfoQueue() {
+        Queue queue = new Queue(RabbitMqConstants.USER_INFO_QUEUE_NAME);
+        return queue;
+    }
+
+    @Bean
+    public Queue generalUserQueue() {
+        Queue queue = new Queue(RabbitMqConstants.GENERAL_USER_QUEUE_NAME);
+        return queue;
+    }
+
+    @Bean
+    public Queue generalCallbackUserQueue() {
+        Queue queue = new Queue(RabbitMqConstants.GENERAL_USER_CALLBACK_QUEUE_NAME);
+        return queue;
+    }
 
 }

+ 40 - 2
yqk-master/src/main/java/com/yx/face/boot/rabbitConfig/config/SnQuenueConfig.java

@@ -1,6 +1,5 @@
 package com.yx.face.boot.rabbitConfig.config;
 
-import com.yx.face.boot.core.Constants;
 import org.springframework.amqp.core.*;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
@@ -18,13 +17,52 @@ import java.util.Map;
 @Configuration
 public class SnQuenueConfig {
 
+    public static final String QUEUE_NAME = "snCacheQueueDelay";
     @Bean
     public Queue demoQueue() {
+
         Map<String,Object> arguments=new HashMap<>(3);
         //设置TTL 单位是ms
         arguments.put("x-message-ttl",5000);
-        return QueueBuilder.durable(Constants.DEVICE_CACHE_QUQUE).withArguments(arguments).build();
+        return QueueBuilder.durable(QUEUE_NAME).withArguments(arguments).build();
+    }
+
+    //创建交换机
+    @Bean(name = "topi-exchange")
+    public TopicExchange getExchange(){
+        return new TopicExchange("topi-exchange", true, false);
+    }
+    //创建队列
+    @Bean(name = "topi-queue")
+    public Queue getQueue(){
+        Map<String, Object> args = new HashMap<>();
+        args.put("x-message-ttl",1000*3600*6); // 定义过期时间
+        args.put("x-dead-letter-exchange", "dead-exchange"); // 与交换机产生关联
+        args.put("x-dead-letter-routing-key","*.dead.*"); // 路由规则
+        return new Queue("topi-queue", true, false, false,args);
+    }
+    //绑定队列
+    @Bean
+    public Binding topiBinding(@Qualifier("topi-exchange") TopicExchange topicExchange, @Qualifier("topi-queue") Queue queue){
+        return BindingBuilder.bind(queue).to(topicExchange).with("*.topi.*");
     }
 
+    //创建死信MQ
+    //创建交换机
+    @Bean(name = "dead-exchange")
+    public TopicExchange deadExchange(){
+        return new TopicExchange("dead-exchange", true, false);
+    }
+    //创建队列
+    @Bean(name = "dead-queue")
+    public Queue deadQueue(){
+        return new Queue("dead-queue", true, false, false);
+    }
+
+    //绑定队列
+    @Bean
+    public Binding deadBinding(@Qualifier("dead-exchange") TopicExchange topicExchange, @Qualifier("dead-queue") Queue queue){
+        return BindingBuilder.bind(queue).to(topicExchange).with("*.dead.*");
+    }
 
 }

+ 0 - 34
yqk-master/src/main/java/com/yx/face/boot/rabbitConfig/listener/PutFaceQueueListener.java

@@ -1,34 +0,0 @@
-package com.yx.face.boot.rabbitConfig.listener;
-
-
-import com.alibaba.fastjson.JSONObject;
-import com.yx.face.boot.rabbitConfig.po.Mail;
-import com.yx.face.boot.rabbitConfig.po.PutFaceQueueVo;
-import com.yx.face.service.UserInfoService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.amqp.rabbit.annotation.RabbitListener;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Component;
-
-import java.util.Objects;
-
-
-@Component
-@Slf4j
-public class PutFaceQueueListener {
-
-	@Autowired
-	private UserInfoService userInfoService;
-
-//	@RabbitListener(queues = "putFaceQueue")
-//	public void displayMail(Mail mail) throws Exception {
-//		log.info("进入消费{}",mail);
-//		if (Objects.isNull(mail)) {
-//			return;
-//		}
-//		PutFaceQueueVo faceQueueVo = JSONObject.parseObject(mail.getData(),PutFaceQueueVo.class);
-//		log.info("转成实体数据{}",faceQueueVo);
-//		userInfoService.downFaceByTask(faceQueueVo.getUserInfo(),faceQueueVo.getStartTime(),faceQueueVo.getEndTime(),faceQueueVo.getType(), faceQueueVo.getTaskId(), faceQueueVo.getByPhoneAndId(), faceQueueVo.getUserVisitorList());
-//	}
-}

+ 11 - 1
yqk-master/src/main/java/com/yx/face/boot/uitls/RedisUtil.java

@@ -1,6 +1,7 @@
 package com.yx.face.boot.uitls;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
@@ -81,7 +82,16 @@ public class RedisUtil {
     public Object get(String key) {
         return key == null ? null : redisTemplate.opsForValue().get(key);
     }
-
+    public <T> T get(String key, Class<T> tClass) {
+        if(key == null){
+            return null;
+        }
+        Object o = redisTemplate.opsForValue().get(key);
+        if(ObjectUtil.isEmpty(o)){
+            return null;
+        }
+        return (T)o;
+    }
     /**
      * 普通缓存放入
      *

+ 14 - 1
yqk-master/src/main/java/com/yx/face/constant/RabbitMqConstants.java

@@ -8,7 +8,6 @@ package com.yx.face.constant;
  * @description
  */
 public interface RabbitMqConstants {
-
     /**
      * iot设备用户同步
      */
@@ -27,4 +26,18 @@ public interface RabbitMqConstants {
     String USER_MESSAGE_TYPE_DEL = "delUser";
 
 
+    /**
+     * 人员数据下发和删除mq
+     */
+    String GENERAL_USER_QUEUE_NAME = "generalUserQueue";
+    String GENERAL_MESSAGE_TYPE_addSingleUser2Device = "addSingleUser2Device";
+    String GENERAL_MESSAGE_TYPE_batchAddUser2Device = "batchAddUser2Device";
+    String GENERA_MESSAGE_TYPE_delUserFromDevice = "delUserFromDevice";
+    String GENERAL_MESSAGE_TYPE_delUserBySn = "delBySn";
+    String GENERAL_MESSAGE_TYPE_issueCancel = "issueCancel";
+    /**
+     * 人员数据下发和删除mq回调
+     */
+    String GENERAL_USER_CALLBACK_QUEUE_NAME = "generalUserCallbackQueue";
+
 }

+ 1 - 1
yqk-master/src/main/java/com/yx/face/controller/TBFaceController.java

@@ -98,7 +98,7 @@ public class TBFaceController {
         try {
             return faceTBService.eventRecords(getParam(request));
         } catch (Exception e) {
-            log.info("推送刷脸刷卡记录 异常={}", e.getMessage());
+            log.info("推送刷脸刷卡记录 异常", e);
         }
         Map<String, Object> result = Maps.newHashMapWithExpectedSize(1);
         result.put("errCode", "00");

+ 4 - 5
yqk-master/src/main/java/com/yx/face/controller/UploadController.java

@@ -15,11 +15,10 @@ import com.yx.face.boot.core.BaseController;
 import com.yx.face.boot.core.Constants;
 import com.yx.face.boot.restful.RestResponse;
 import com.yx.face.boot.restful.RestResult;
+import com.yx.face.boot.uitls.AddressUtil;
 import com.yx.face.boot.uitls.ClassUtil;
 import com.yx.face.boot.uitls.FileUtils;
-import com.yx.face.boot.uitls.WebAddressUtil;
 import com.yx.face.dao.SystemConfigDao;
-import com.yx.face.dao.SystemNoticeDao;
 import com.yx.face.service.FaceService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -53,7 +52,7 @@ public class UploadController extends BaseController {
     private final FaceService faceService;
     private final SystemConfigDao systemConfigDao;
 
-
+   
 
     //上传图片
     @ApiOperation(value = "单图片上传接口", notes = "单图片上传接口")
@@ -69,7 +68,7 @@ public class UploadController extends BaseController {
     public RestResult<String> pictureLocal(@RequestParam MultipartFile file) throws IOException {
         String filePath = FileUtils.getDirectory(Constants.UPLOAD_IMAGE_NEW);
         filePath = FileUtils.saveByCopy(filePath, file);
-        filePath = WebAddressUtil.address.concat(filePath);
+        filePath = AddressUtil.address.concat(filePath);
         return RestResponse.ok(filePath);
     }
 
@@ -78,7 +77,7 @@ public class UploadController extends BaseController {
     public RestResult<String> uploadVideo(@RequestParam MultipartFile file) throws IOException, ServletException {
         String filePath = FileUtils.getDirectory(Constants.UPLOAD_VIDEO);
         String rootFilePath = FileUtils.saveByCopy(filePath, file);
-        rootFilePath = WebAddressUtil.address.concat(rootFilePath);
+        rootFilePath = AddressUtil.address.concat(rootFilePath);
         return RestResponse.ok(rootFilePath);
     }
 

+ 60 - 5
yqk-master/src/main/java/com/yx/face/controller/admin/AdminDataShowController.java

@@ -1,18 +1,28 @@
 package com.yx.face.controller.admin;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.yx.face.boot.restful.RestDTO;
 import com.yx.face.boot.restful.RestResponse;
 import com.yx.face.boot.restful.RestResult;
-import com.yx.face.model.vo.AdminDataVO;
+import com.yx.face.model.dto.AdminDataDTO;
 import com.yx.face.model.vo.AdminDeviceVO;
+import com.yx.face.model.vo.stat.*;
 import com.yx.face.service.AdminDataShowService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 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 javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.util.List;
+
 /**
  * @description:
  * @ClassName AdminDataShow
@@ -23,18 +33,63 @@ import org.springframework.web.bind.annotation.RestController;
 @Api(tags = "B 数据大屏显示")
 @RestController
 @RequestMapping("admin/dataShow")
+@Validated
 public class AdminDataShowController {
 
     private final AdminDataShowService adminDataShowService;
 
     @ApiOperation("获取设备数量")
     @PostMapping("getDeviceNumber")
+    @ApiOperationSupport(order = 10)
     public RestResult<AdminDeviceVO> getDeviceNumber() {
         return RestResponse.ok(adminDataShowService.getDeviceNumber());
     }
-    @ApiOperation("获取通行信息")
-    @PostMapping("getAdminData")
-    public RestResult<AdminDataVO> getAdminData() {
-        return RestResponse.ok(adminDataShowService.getGloablePassData());
+//    @ApiOperation("获取通行信息")
+//    @PostMapping("getAdminData")
+//    public RestResult<AdminDataVO> getAdminData() {
+//        return RestResponse.ok(adminDataShowService.getGloablePassData());
+//    }
+
+    @ApiOperation("人员通行情况")
+    @PostMapping("stat/pass")
+    @ApiOperationSupport(order = 20)
+    public RestResult<StatPassVO> statPass(@RequestBody @Valid AdminDataDTO dto) {
+        return RestResponse.ok(adminDataShowService.statPass(dto));
+    }
+    @ApiOperation("人员年龄分布情况")
+    @PostMapping("stat/age")
+    @ApiOperationSupport(order = 30)
+    public RestResult<StatAgeVO> statAge(@RequestBody @Valid AdminDataDTO dto) {
+        return RestResponse.ok(adminDataShowService.statAge(dto));
+    }
+    @ApiOperation("人员性别分布情况")
+    @PostMapping("stat/sex")
+    @ApiOperationSupport(order = 40)
+    public RestResult<StatSexVO> statSex(@RequestBody @Valid AdminDataDTO dto) {
+        return RestResponse.ok(adminDataShowService.statSex(dto));
+    }
+    @ApiOperation("各时段在场人数情况")
+    @PostMapping("stat/people")
+    @ApiOperationSupport(order = 50)
+    public RestResult<StatPeopleVO> statPeople(@RequestBody @Valid AdminDataDTO dto) {
+        return RestResponse.ok(adminDataShowService.statPeople(dto));
+    }
+    @ApiOperation("人员来源地分布情况")
+    @PostMapping("stat/source")
+    @ApiOperationSupport(order = 60)
+    public RestResult<List<StatSourceVO>> statSource(@RequestBody @Valid AdminDataDTO dto) {
+        return RestResponse.ok(adminDataShowService.statSource(dto));
+    }
+    @ApiOperation("人员进出统计数据")
+    @PostMapping("stat/pageList")
+    @ApiOperationSupport(order = 70)
+    public RestResult<IPage<StatDataVO>> pageList(@RequestBody RestDTO<StatDataSearch> dto) {
+        return RestResponse.ok(adminDataShowService.pageList(dto));
+    }
+    @ApiOperation(value = "人员进出统计数据-导出",notes = "最多导出最前面的5万条数据")
+    @PostMapping("stat/excelOut")
+    @ApiOperationSupport(order = 80)
+    public void excelOut(@RequestBody StatDataSearch dto, HttpServletResponse response) {
+        adminDataShowService.excelOut(dto,response);
     }
 }

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio