diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
index 1a306ef..18ef0f5 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
@@ -54,6 +54,7 @@
*/
@PostMapping("/{operation}")
@ResponseBody
+// @BussinessLog("消防器材增删改")
public Object operation(@PathVariable(name = "operation") String operateType, @RequestBody FireEquipInfo fireEquipInfo) {
if(OperateTypeEnum.ADD.getOperateType().equals(operateType)){
return fireEquipService.addFireEquipInfo(fireEquipInfo);
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
index 1a306ef..18ef0f5 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
@@ -54,6 +54,7 @@
*/
@PostMapping("/{operation}")
@ResponseBody
+// @BussinessLog("消防器材增删改")
public Object operation(@PathVariable(name = "operation") String operateType, @RequestBody FireEquipInfo fireEquipInfo) {
if(OperateTypeEnum.ADD.getOperateType().equals(operateType)){
return fireEquipService.addFireEquipInfo(fireEquipInfo);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
index a7cf1f8..d86dc30 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
@@ -30,7 +30,6 @@
@RestController
@RequestMapping("/applicationInfo")
public class VisitorApplyController extends ExportController {
- // TODO: 2022/7/23 访客申请增删改同时要增删改海康的预约,修改访客预约v2接口,取消操作使用取消访客预约
@Autowired
private VisitorApplyService visitorApplyService;
/**
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
index 1a306ef..18ef0f5 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
@@ -54,6 +54,7 @@
*/
@PostMapping("/{operation}")
@ResponseBody
+// @BussinessLog("消防器材增删改")
public Object operation(@PathVariable(name = "operation") String operateType, @RequestBody FireEquipInfo fireEquipInfo) {
if(OperateTypeEnum.ADD.getOperateType().equals(operateType)){
return fireEquipService.addFireEquipInfo(fireEquipInfo);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
index a7cf1f8..d86dc30 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
@@ -30,7 +30,6 @@
@RestController
@RequestMapping("/applicationInfo")
public class VisitorApplyController extends ExportController {
- // TODO: 2022/7/23 访客申请增删改同时要增删改海康的预约,修改访客预约v2接口,取消操作使用取消访客预约
@Autowired
private VisitorApplyService visitorApplyService;
/**
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
new file mode 100644
index 0000000..14439eb
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
@@ -0,0 +1,49 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.VisitorRequest;
+import com.casic.missiles.modular.model.VisitInfo;
+import com.casic.missiles.modular.service.VisitService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 访客管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 19:16
+ */
+@Slf4j
+@RestController
+@RequestMapping("/visitInfo")
+public class VisitorController extends ExportController {
+ @Autowired
+ private VisitService visitService;
+
+ /**
+ * 访问记录列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody VisitorRequest visitorRequest) {
+ Page page = PageFactory.defaultPage();
+ List visitorApplies = visitService.visitInfoListPage(page, visitorRequest);
+ page.setRecords(visitorApplies);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 访问记录详情
+ */
+ @PostMapping("/detail")
+ @ResponseBody
+ public Object detail(@RequestBody VisitorRequest visitorRequest) {
+ VisitInfo visitInfo = visitService.visitInfoDetail(visitorRequest.getId());
+ return ResponseData.success(visitInfo);
+ }
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
index 1a306ef..18ef0f5 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
@@ -54,6 +54,7 @@
*/
@PostMapping("/{operation}")
@ResponseBody
+// @BussinessLog("消防器材增删改")
public Object operation(@PathVariable(name = "operation") String operateType, @RequestBody FireEquipInfo fireEquipInfo) {
if(OperateTypeEnum.ADD.getOperateType().equals(operateType)){
return fireEquipService.addFireEquipInfo(fireEquipInfo);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
index a7cf1f8..d86dc30 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
@@ -30,7 +30,6 @@
@RestController
@RequestMapping("/applicationInfo")
public class VisitorApplyController extends ExportController {
- // TODO: 2022/7/23 访客申请增删改同时要增删改海康的预约,修改访客预约v2接口,取消操作使用取消访客预约
@Autowired
private VisitorApplyService visitorApplyService;
/**
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
new file mode 100644
index 0000000..14439eb
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
@@ -0,0 +1,49 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.VisitorRequest;
+import com.casic.missiles.modular.model.VisitInfo;
+import com.casic.missiles.modular.service.VisitService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 访客管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 19:16
+ */
+@Slf4j
+@RestController
+@RequestMapping("/visitInfo")
+public class VisitorController extends ExportController {
+ @Autowired
+ private VisitService visitService;
+
+ /**
+ * 访问记录列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody VisitorRequest visitorRequest) {
+ Page page = PageFactory.defaultPage();
+ List visitorApplies = visitService.visitInfoListPage(page, visitorRequest);
+ page.setRecords(visitorApplies);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 访问记录详情
+ */
+ @PostMapping("/detail")
+ @ResponseBody
+ public Object detail(@RequestBody VisitorRequest visitorRequest) {
+ VisitInfo visitInfo = visitService.visitInfoDetail(visitorRequest.getId());
+ return ResponseData.success(visitInfo);
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
new file mode 100644
index 0000000..4b92489
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
@@ -0,0 +1,171 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.core.application.service.AbstractDictService;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.CategoryLevelMapper;
+import com.casic.missiles.modular.dao.DeviceInfoMapper;
+import com.casic.missiles.modular.dao.FireEquipInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.enums.SecurityEventDict;
+import com.casic.missiles.modular.model.CaseCategoryLevel;
+import com.casic.missiles.modular.model.CaseInfo;
+import com.casic.missiles.modular.redis.RedisUtil;
+import com.casic.missiles.modular.redis.key.CacheKeys;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱驻留页面-前端主动查询相关
+ * @Author: wangpeng
+ * @Date: 2022/7/27 19:46
+ */
+@Slf4j
+@RestController
+@RequestMapping("/cockpit")
+public class CockpitController {
+ @Autowired
+ private RedisUtil redisUtil;
+
+ @Autowired
+ private AbstractDictService dictService;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private CategoryLevelMapper categoryLevelMapper;
+
+ @Autowired
+ private DeviceInfoMapper deviceInfoMapper;
+
+ @Autowired
+ private FireEquipInfoMapper fireEquipInfoMapper;
+
+ /**
+ * 重点区域威胁事件历史统计,计算每个月的各级别事件的数量
+ */
+ @PostMapping("/case/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaEventStatistic(@RequestBody MonthAndLevelGroupDTO monthAndLevelGroupDTO) {
+ Object o = redisUtil.get(CacheKeys.MONTH_STATISTIC_KEY);
+ List list = JSONArray.parseArray(String.valueOf(o), MonthAndLevelGroupDTO.class);
+ if(!CollectionUtils.isEmpty(list)){
+ Map> resultMap = list.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ return ResponseData.success(resultMap);
+ }
+ //查询数据,放入redis
+ List monthAndLevelGroup = caseInfoMapper.selectByLevelAndMonth(monthAndLevelGroupDTO.getYear());
+ Map> resultMap = monthAndLevelGroup.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ //设置过期时间为每月1号0点
+ LocalDateTime midnight = LocalDateTime.now().plusMonths(1).withDayOfMonth(1).withHour(0)
+ .withMinute(0).withSecond(0).withNano(0);
+ long between = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
+ redisUtil.set(CacheKeys.MONTH_STATISTIC_KEY, JSONObject.toJSONString(monthAndLevelGroup), between);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安防事件类别统计
+ */
+ @GetMapping("/case/categoryStatistics")
+ @ResponseBody
+ public Object eventCategoryStatistics() {
+ List categoryLevelGroup = caseInfoMapper.selectByCategoryLevel();
+ categoryLevelGroup.forEach(group -> {
+ CaseCategoryLevel caseCategoryLevel = categoryLevelMapper.getCaseCategoryLevel(group.getCategoryLevelCode());
+ group.setCategoryLevelName(caseCategoryLevel.getName());
+ });
+ return ResponseData.success(categoryLevelGroup);
+ }
+
+ /**
+ * 消防器材类别统计
+ */
+ @GetMapping("/device/fireEquipStatistics")
+ @ResponseBody
+ public Object fireEquipStatistics() {
+ List equipTypeGroup = fireEquipInfoMapper.selectByEquipType();
+ equipTypeGroup.forEach(group -> {
+ String equipTypeName = dictService.getDictNameByCode(SecurityEventDict.EQUIP_TYPE, group.getEquipTypeCode());
+ group.setEquipTypeName(equipTypeName);
+ });
+ return ResponseData.success(equipTypeGroup);
+ }
+
+ /**
+ * 闸机速通门统计-设备状态分组计算数量,devType传闸机字典key
+ * 视频频监控摄像机统计-设备状态分组计算数量,devType传摄像头字典key
+ */
+ @PostMapping("/device/statistics")
+ @ResponseBody
+ public Object GateStatusStatistics(@RequestBody GateStatusGroupDTO gateStatusGroupDTO) {
+ List gateStatusGroup = deviceInfoMapper.selectByType(gateStatusGroupDTO.getDevType());
+ HashMap resultMap = new HashMap<>();
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = gateStatusGroup.stream().collect(Collectors.summarizingInt(GateStatusGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("无该类设备信息");
+ }
+ gateStatusGroup.forEach(group -> {
+ String devStatus = dictService.getDictNameByCode(SecurityEventDict.DEVICE_STATUS, group.getStatus());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ resultMap.put(devStatus, result+"%");
+ });
+ resultMap.put("总", sum);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安全防护分析,设备加所在楼层评分,计算规则:发生安防事件*类别权重*级别权重算分
+ * 优先级3
+ */
+ @PostMapping("/device/securityScore")
+ @ResponseBody
+ public Object SecurityScore(@RequestBody SecurityScoreDTO securityScoreDTO) {
+ //按发生事件的设备所在的area划分计算评分,当天发生的事件
+ String position = securityScoreDTO.getPosition();
+ List caseInfos = caseInfoMapper.selectByPosition(position);
+ //查询各危险级别权重、各类别权重,放入map,避免循环中多次查数据库
+
+ List securityScoreDTOs = new ArrayList<>();
+ caseInfos.forEach(caseInfo -> {
+ SecurityScoreDTO securityScoreDTO1 = new SecurityScoreDTO();
+ securityScoreDTO1.setArea(caseInfo.getArea());
+ // TODO: 2022/8/4 楼层评分计算根据产品定义调整
+// caseInfo.get
+// securityScoreDTO1.setScore();
+ });
+
+ return null;
+ }
+
+ /**
+ * 安防事件时域性频次统计,统计每月安防事件个数
+ */
+ @PostMapping("/device/securityFrequency")
+ @ResponseBody
+ public Object SecurityFrequency(@RequestBody SecurityFrequencyDTO securityFrequencyDTO) {
+ String year = securityFrequencyDTO.getYear();
+ String month = securityFrequencyDTO.getMonth();
+ Integer quantity = caseInfoMapper.selectCountByMonth(year, month);
+ securityFrequencyDTO.setQuantity(quantity);
+ return ResponseData.success(securityFrequencyDTO);
+ }
+
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
index 1a306ef..18ef0f5 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
@@ -54,6 +54,7 @@
*/
@PostMapping("/{operation}")
@ResponseBody
+// @BussinessLog("消防器材增删改")
public Object operation(@PathVariable(name = "operation") String operateType, @RequestBody FireEquipInfo fireEquipInfo) {
if(OperateTypeEnum.ADD.getOperateType().equals(operateType)){
return fireEquipService.addFireEquipInfo(fireEquipInfo);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
index a7cf1f8..d86dc30 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
@@ -30,7 +30,6 @@
@RestController
@RequestMapping("/applicationInfo")
public class VisitorApplyController extends ExportController {
- // TODO: 2022/7/23 访客申请增删改同时要增删改海康的预约,修改访客预约v2接口,取消操作使用取消访客预约
@Autowired
private VisitorApplyService visitorApplyService;
/**
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
new file mode 100644
index 0000000..14439eb
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
@@ -0,0 +1,49 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.VisitorRequest;
+import com.casic.missiles.modular.model.VisitInfo;
+import com.casic.missiles.modular.service.VisitService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 访客管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 19:16
+ */
+@Slf4j
+@RestController
+@RequestMapping("/visitInfo")
+public class VisitorController extends ExportController {
+ @Autowired
+ private VisitService visitService;
+
+ /**
+ * 访问记录列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody VisitorRequest visitorRequest) {
+ Page page = PageFactory.defaultPage();
+ List visitorApplies = visitService.visitInfoListPage(page, visitorRequest);
+ page.setRecords(visitorApplies);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 访问记录详情
+ */
+ @PostMapping("/detail")
+ @ResponseBody
+ public Object detail(@RequestBody VisitorRequest visitorRequest) {
+ VisitInfo visitInfo = visitService.visitInfoDetail(visitorRequest.getId());
+ return ResponseData.success(visitInfo);
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
new file mode 100644
index 0000000..4b92489
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
@@ -0,0 +1,171 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.core.application.service.AbstractDictService;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.CategoryLevelMapper;
+import com.casic.missiles.modular.dao.DeviceInfoMapper;
+import com.casic.missiles.modular.dao.FireEquipInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.enums.SecurityEventDict;
+import com.casic.missiles.modular.model.CaseCategoryLevel;
+import com.casic.missiles.modular.model.CaseInfo;
+import com.casic.missiles.modular.redis.RedisUtil;
+import com.casic.missiles.modular.redis.key.CacheKeys;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱驻留页面-前端主动查询相关
+ * @Author: wangpeng
+ * @Date: 2022/7/27 19:46
+ */
+@Slf4j
+@RestController
+@RequestMapping("/cockpit")
+public class CockpitController {
+ @Autowired
+ private RedisUtil redisUtil;
+
+ @Autowired
+ private AbstractDictService dictService;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private CategoryLevelMapper categoryLevelMapper;
+
+ @Autowired
+ private DeviceInfoMapper deviceInfoMapper;
+
+ @Autowired
+ private FireEquipInfoMapper fireEquipInfoMapper;
+
+ /**
+ * 重点区域威胁事件历史统计,计算每个月的各级别事件的数量
+ */
+ @PostMapping("/case/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaEventStatistic(@RequestBody MonthAndLevelGroupDTO monthAndLevelGroupDTO) {
+ Object o = redisUtil.get(CacheKeys.MONTH_STATISTIC_KEY);
+ List list = JSONArray.parseArray(String.valueOf(o), MonthAndLevelGroupDTO.class);
+ if(!CollectionUtils.isEmpty(list)){
+ Map> resultMap = list.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ return ResponseData.success(resultMap);
+ }
+ //查询数据,放入redis
+ List monthAndLevelGroup = caseInfoMapper.selectByLevelAndMonth(monthAndLevelGroupDTO.getYear());
+ Map> resultMap = monthAndLevelGroup.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ //设置过期时间为每月1号0点
+ LocalDateTime midnight = LocalDateTime.now().plusMonths(1).withDayOfMonth(1).withHour(0)
+ .withMinute(0).withSecond(0).withNano(0);
+ long between = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
+ redisUtil.set(CacheKeys.MONTH_STATISTIC_KEY, JSONObject.toJSONString(monthAndLevelGroup), between);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安防事件类别统计
+ */
+ @GetMapping("/case/categoryStatistics")
+ @ResponseBody
+ public Object eventCategoryStatistics() {
+ List categoryLevelGroup = caseInfoMapper.selectByCategoryLevel();
+ categoryLevelGroup.forEach(group -> {
+ CaseCategoryLevel caseCategoryLevel = categoryLevelMapper.getCaseCategoryLevel(group.getCategoryLevelCode());
+ group.setCategoryLevelName(caseCategoryLevel.getName());
+ });
+ return ResponseData.success(categoryLevelGroup);
+ }
+
+ /**
+ * 消防器材类别统计
+ */
+ @GetMapping("/device/fireEquipStatistics")
+ @ResponseBody
+ public Object fireEquipStatistics() {
+ List equipTypeGroup = fireEquipInfoMapper.selectByEquipType();
+ equipTypeGroup.forEach(group -> {
+ String equipTypeName = dictService.getDictNameByCode(SecurityEventDict.EQUIP_TYPE, group.getEquipTypeCode());
+ group.setEquipTypeName(equipTypeName);
+ });
+ return ResponseData.success(equipTypeGroup);
+ }
+
+ /**
+ * 闸机速通门统计-设备状态分组计算数量,devType传闸机字典key
+ * 视频频监控摄像机统计-设备状态分组计算数量,devType传摄像头字典key
+ */
+ @PostMapping("/device/statistics")
+ @ResponseBody
+ public Object GateStatusStatistics(@RequestBody GateStatusGroupDTO gateStatusGroupDTO) {
+ List gateStatusGroup = deviceInfoMapper.selectByType(gateStatusGroupDTO.getDevType());
+ HashMap resultMap = new HashMap<>();
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = gateStatusGroup.stream().collect(Collectors.summarizingInt(GateStatusGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("无该类设备信息");
+ }
+ gateStatusGroup.forEach(group -> {
+ String devStatus = dictService.getDictNameByCode(SecurityEventDict.DEVICE_STATUS, group.getStatus());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ resultMap.put(devStatus, result+"%");
+ });
+ resultMap.put("总", sum);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安全防护分析,设备加所在楼层评分,计算规则:发生安防事件*类别权重*级别权重算分
+ * 优先级3
+ */
+ @PostMapping("/device/securityScore")
+ @ResponseBody
+ public Object SecurityScore(@RequestBody SecurityScoreDTO securityScoreDTO) {
+ //按发生事件的设备所在的area划分计算评分,当天发生的事件
+ String position = securityScoreDTO.getPosition();
+ List caseInfos = caseInfoMapper.selectByPosition(position);
+ //查询各危险级别权重、各类别权重,放入map,避免循环中多次查数据库
+
+ List securityScoreDTOs = new ArrayList<>();
+ caseInfos.forEach(caseInfo -> {
+ SecurityScoreDTO securityScoreDTO1 = new SecurityScoreDTO();
+ securityScoreDTO1.setArea(caseInfo.getArea());
+ // TODO: 2022/8/4 楼层评分计算根据产品定义调整
+// caseInfo.get
+// securityScoreDTO1.setScore();
+ });
+
+ return null;
+ }
+
+ /**
+ * 安防事件时域性频次统计,统计每月安防事件个数
+ */
+ @PostMapping("/device/securityFrequency")
+ @ResponseBody
+ public Object SecurityFrequency(@RequestBody SecurityFrequencyDTO securityFrequencyDTO) {
+ String year = securityFrequencyDTO.getYear();
+ String month = securityFrequencyDTO.getMonth();
+ Integer quantity = caseInfoMapper.selectCountByMonth(year, month);
+ securityFrequencyDTO.setQuantity(quantity);
+ return ResponseData.success(securityFrequencyDTO);
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
new file mode 100644
index 0000000..ba584ee
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
@@ -0,0 +1,204 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.AttendanceInfoMapper;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.HazardLevelMapper;
+import com.casic.missiles.modular.dao.StaffInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.model.CaseHazardLevel;
+import com.casic.missiles.modular.model.StaffInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱二级页面-物管信息
+ * @Author: wangpeng
+ * @Date: 2022/8/3 15:05
+ */
+@Slf4j
+@RestController
+@RequestMapping("/propertyManage")
+public class PropertyManageController {
+ @Autowired
+ private AttendanceInfoMapper attendanceInfoMapper;
+
+ @Autowired
+ private StaffInfoMapper staffInfoMapper;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private HazardLevelMapper hazardLevelMapper;
+
+ /**
+ * 安防事件时域频次统计,每月的每天安防事件个数
+ * 月维度:展示每个月的每天的数据
+ */
+ @PostMapping("/case/time/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaTimeStatistic(@RequestBody MonthAndDayGroupDTO monthAndDayGroupDTO) {
+ String year = monthAndDayGroupDTO.getYear();
+ String month = monthAndDayGroupDTO.getMonth();
+ List resultList = caseInfoMapper.selectCountByMonthAndDay(year, month);
+ resultList.forEach(result -> {
+ result.setYear(year);
+ result.setMonth(month);
+ });
+ return ResponseData.success(resultList);
+ }
+
+ /**
+ * 安防事件频域频次统计,每年的每月/每周各级别安防事件个数
+ * 年维度:展示平均每个月和每周的数据
+ */
+ @PostMapping("/case/frequency/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaFrequencyStatistic(@RequestBody AvgMonthAndWeekGroupDTO avgMonthAndWeekGroupDTO) {
+ String year = avgMonthAndWeekGroupDTO.getYear();
+ List monthList = caseInfoMapper.selectPreMonthCountByYear(year);
+ Map> collect = monthList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ HashMap strAvgMap = new HashMap<>();
+ for (String key : collect.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ //若年份是本年,则使用个安防级别数量/当前月份数
+ //若不是本年,除数为12
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ monthAndWeekDTO.setMonthQuantity(sum / DateUtil.thisMonth());
+// monthAndWeekDTO.setLevelName();
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ monthAndWeekDTO.setMonthQuantity(sum / 12);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+
+ List weekList = caseInfoMapper.selectPreWeekCountByYear(year);
+ Map> collect1 = weekList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ for (String key : collect1.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }else{
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+ }
+ avgMonthAndWeekGroupDTO.setMap(strAvgMap);
+ return ResponseData.success(avgMonthAndWeekGroupDTO);
+ }
+
+ /**
+ * 员工出勤率,优先级3
+ * 物业/安保人员出勤人数除以物业/安保人员总数,一天有一次记录就算考勤
+ */
+ @PostMapping("/staff/attendanceRatio")
+ @ResponseBody
+ public Object attendanceRatio(@RequestBody AttendanceRatioDTO attendanceRatioDTO) {
+ //员工类型字典key
+ String staffType = attendanceRatioDTO.getStaffType();
+ String dateDimension = attendanceRatioDTO.getDateDimension();
+ List attendanceRatioDTOS = new ArrayList<>();
+ //考勤的人数,按员工类型和单次考勤过滤
+ if("week".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForWeek(staffType);
+ }else if("month".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForMonth(staffType);
+ }else if("year".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForYear(staffType);
+ }
+ if(CollectionUtils.isEmpty(attendanceRatioDTOS)){
+ return ResponseData.error("该查询条件下,无员工出勤数据!");
+ }
+
+ //该类型员工总数
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("staff_type", staffType);
+ Integer sum = staffInfoMapper.selectCount(wrapper);
+ if(sum <= 0){
+ return ResponseData.error("该查询条件下,员工管理中无该类型员工数据!");
+ }
+
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ //计算出勤率
+ attendanceRatioDTOS.forEach(attendanceRatio -> {
+ attendanceRatio.setDateDimension(dateDimension);
+ attendanceRatio.setStaffType(staffType);
+ String ratio = numberFormat.format((float) attendanceRatio.getQuantity() / (float) sum * 100);
+ attendanceRatio.setAttendanceRatio(ratio+"%");
+ });
+ return ResponseData.success(attendanceRatioDTOS);
+ }
+
+ /**
+ * 员工考勤人数变化,功能待定
+ */
+
+ /**
+ * 重点区域安防事态评估,功能待定
+ */
+
+ /**
+ * 重点区域威胁事件类型统计,优先级2
+ */
+ @GetMapping("/case/hazardLevelStatistics")
+ @ResponseBody
+ public Object HazardLevelStatistics() {
+ List hazardLevelGroup = caseInfoMapper.selectByHazardLevel();
+ if(CollectionUtils.isEmpty(hazardLevelGroup)){
+ log.info("重点区域威胁事件类型统计,无安防事件");
+ return ResponseData.error("无安防事件发生!");
+ }
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = hazardLevelGroup.stream().collect(Collectors.summarizingInt(HazardLevelGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("安防事件总数为0");
+ }
+ hazardLevelGroup.forEach(group -> {
+ CaseHazardLevel caseHazardLevel = hazardLevelMapper.getCaseHazardLevel(group.getLevelCode());
+ group.setLevelName(caseHazardLevel.getName());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ group.setLevelRatio(result+"%");
+ });
+ HazardLevelGroupResponse hazardLevelGroupResponse = new HazardLevelGroupResponse();
+ hazardLevelGroupResponse.setHazardLevelGroup(hazardLevelGroup);
+ hazardLevelGroupResponse.setQuantity(sum);
+ return ResponseData.success(hazardLevelGroupResponse);
+ }
+
+ /**
+ * 设备状态计算系数和评判,优先级3,需确认设备恢复时间是否可以获取
+ */
+
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
index 1a306ef..18ef0f5 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
@@ -54,6 +54,7 @@
*/
@PostMapping("/{operation}")
@ResponseBody
+// @BussinessLog("消防器材增删改")
public Object operation(@PathVariable(name = "operation") String operateType, @RequestBody FireEquipInfo fireEquipInfo) {
if(OperateTypeEnum.ADD.getOperateType().equals(operateType)){
return fireEquipService.addFireEquipInfo(fireEquipInfo);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
index a7cf1f8..d86dc30 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
@@ -30,7 +30,6 @@
@RestController
@RequestMapping("/applicationInfo")
public class VisitorApplyController extends ExportController {
- // TODO: 2022/7/23 访客申请增删改同时要增删改海康的预约,修改访客预约v2接口,取消操作使用取消访客预约
@Autowired
private VisitorApplyService visitorApplyService;
/**
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
new file mode 100644
index 0000000..14439eb
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
@@ -0,0 +1,49 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.VisitorRequest;
+import com.casic.missiles.modular.model.VisitInfo;
+import com.casic.missiles.modular.service.VisitService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 访客管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 19:16
+ */
+@Slf4j
+@RestController
+@RequestMapping("/visitInfo")
+public class VisitorController extends ExportController {
+ @Autowired
+ private VisitService visitService;
+
+ /**
+ * 访问记录列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody VisitorRequest visitorRequest) {
+ Page page = PageFactory.defaultPage();
+ List visitorApplies = visitService.visitInfoListPage(page, visitorRequest);
+ page.setRecords(visitorApplies);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 访问记录详情
+ */
+ @PostMapping("/detail")
+ @ResponseBody
+ public Object detail(@RequestBody VisitorRequest visitorRequest) {
+ VisitInfo visitInfo = visitService.visitInfoDetail(visitorRequest.getId());
+ return ResponseData.success(visitInfo);
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
new file mode 100644
index 0000000..4b92489
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
@@ -0,0 +1,171 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.core.application.service.AbstractDictService;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.CategoryLevelMapper;
+import com.casic.missiles.modular.dao.DeviceInfoMapper;
+import com.casic.missiles.modular.dao.FireEquipInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.enums.SecurityEventDict;
+import com.casic.missiles.modular.model.CaseCategoryLevel;
+import com.casic.missiles.modular.model.CaseInfo;
+import com.casic.missiles.modular.redis.RedisUtil;
+import com.casic.missiles.modular.redis.key.CacheKeys;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱驻留页面-前端主动查询相关
+ * @Author: wangpeng
+ * @Date: 2022/7/27 19:46
+ */
+@Slf4j
+@RestController
+@RequestMapping("/cockpit")
+public class CockpitController {
+ @Autowired
+ private RedisUtil redisUtil;
+
+ @Autowired
+ private AbstractDictService dictService;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private CategoryLevelMapper categoryLevelMapper;
+
+ @Autowired
+ private DeviceInfoMapper deviceInfoMapper;
+
+ @Autowired
+ private FireEquipInfoMapper fireEquipInfoMapper;
+
+ /**
+ * 重点区域威胁事件历史统计,计算每个月的各级别事件的数量
+ */
+ @PostMapping("/case/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaEventStatistic(@RequestBody MonthAndLevelGroupDTO monthAndLevelGroupDTO) {
+ Object o = redisUtil.get(CacheKeys.MONTH_STATISTIC_KEY);
+ List list = JSONArray.parseArray(String.valueOf(o), MonthAndLevelGroupDTO.class);
+ if(!CollectionUtils.isEmpty(list)){
+ Map> resultMap = list.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ return ResponseData.success(resultMap);
+ }
+ //查询数据,放入redis
+ List monthAndLevelGroup = caseInfoMapper.selectByLevelAndMonth(monthAndLevelGroupDTO.getYear());
+ Map> resultMap = monthAndLevelGroup.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ //设置过期时间为每月1号0点
+ LocalDateTime midnight = LocalDateTime.now().plusMonths(1).withDayOfMonth(1).withHour(0)
+ .withMinute(0).withSecond(0).withNano(0);
+ long between = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
+ redisUtil.set(CacheKeys.MONTH_STATISTIC_KEY, JSONObject.toJSONString(monthAndLevelGroup), between);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安防事件类别统计
+ */
+ @GetMapping("/case/categoryStatistics")
+ @ResponseBody
+ public Object eventCategoryStatistics() {
+ List categoryLevelGroup = caseInfoMapper.selectByCategoryLevel();
+ categoryLevelGroup.forEach(group -> {
+ CaseCategoryLevel caseCategoryLevel = categoryLevelMapper.getCaseCategoryLevel(group.getCategoryLevelCode());
+ group.setCategoryLevelName(caseCategoryLevel.getName());
+ });
+ return ResponseData.success(categoryLevelGroup);
+ }
+
+ /**
+ * 消防器材类别统计
+ */
+ @GetMapping("/device/fireEquipStatistics")
+ @ResponseBody
+ public Object fireEquipStatistics() {
+ List equipTypeGroup = fireEquipInfoMapper.selectByEquipType();
+ equipTypeGroup.forEach(group -> {
+ String equipTypeName = dictService.getDictNameByCode(SecurityEventDict.EQUIP_TYPE, group.getEquipTypeCode());
+ group.setEquipTypeName(equipTypeName);
+ });
+ return ResponseData.success(equipTypeGroup);
+ }
+
+ /**
+ * 闸机速通门统计-设备状态分组计算数量,devType传闸机字典key
+ * 视频频监控摄像机统计-设备状态分组计算数量,devType传摄像头字典key
+ */
+ @PostMapping("/device/statistics")
+ @ResponseBody
+ public Object GateStatusStatistics(@RequestBody GateStatusGroupDTO gateStatusGroupDTO) {
+ List gateStatusGroup = deviceInfoMapper.selectByType(gateStatusGroupDTO.getDevType());
+ HashMap resultMap = new HashMap<>();
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = gateStatusGroup.stream().collect(Collectors.summarizingInt(GateStatusGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("无该类设备信息");
+ }
+ gateStatusGroup.forEach(group -> {
+ String devStatus = dictService.getDictNameByCode(SecurityEventDict.DEVICE_STATUS, group.getStatus());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ resultMap.put(devStatus, result+"%");
+ });
+ resultMap.put("总", sum);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安全防护分析,设备加所在楼层评分,计算规则:发生安防事件*类别权重*级别权重算分
+ * 优先级3
+ */
+ @PostMapping("/device/securityScore")
+ @ResponseBody
+ public Object SecurityScore(@RequestBody SecurityScoreDTO securityScoreDTO) {
+ //按发生事件的设备所在的area划分计算评分,当天发生的事件
+ String position = securityScoreDTO.getPosition();
+ List caseInfos = caseInfoMapper.selectByPosition(position);
+ //查询各危险级别权重、各类别权重,放入map,避免循环中多次查数据库
+
+ List securityScoreDTOs = new ArrayList<>();
+ caseInfos.forEach(caseInfo -> {
+ SecurityScoreDTO securityScoreDTO1 = new SecurityScoreDTO();
+ securityScoreDTO1.setArea(caseInfo.getArea());
+ // TODO: 2022/8/4 楼层评分计算根据产品定义调整
+// caseInfo.get
+// securityScoreDTO1.setScore();
+ });
+
+ return null;
+ }
+
+ /**
+ * 安防事件时域性频次统计,统计每月安防事件个数
+ */
+ @PostMapping("/device/securityFrequency")
+ @ResponseBody
+ public Object SecurityFrequency(@RequestBody SecurityFrequencyDTO securityFrequencyDTO) {
+ String year = securityFrequencyDTO.getYear();
+ String month = securityFrequencyDTO.getMonth();
+ Integer quantity = caseInfoMapper.selectCountByMonth(year, month);
+ securityFrequencyDTO.setQuantity(quantity);
+ return ResponseData.success(securityFrequencyDTO);
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
new file mode 100644
index 0000000..ba584ee
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
@@ -0,0 +1,204 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.AttendanceInfoMapper;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.HazardLevelMapper;
+import com.casic.missiles.modular.dao.StaffInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.model.CaseHazardLevel;
+import com.casic.missiles.modular.model.StaffInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱二级页面-物管信息
+ * @Author: wangpeng
+ * @Date: 2022/8/3 15:05
+ */
+@Slf4j
+@RestController
+@RequestMapping("/propertyManage")
+public class PropertyManageController {
+ @Autowired
+ private AttendanceInfoMapper attendanceInfoMapper;
+
+ @Autowired
+ private StaffInfoMapper staffInfoMapper;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private HazardLevelMapper hazardLevelMapper;
+
+ /**
+ * 安防事件时域频次统计,每月的每天安防事件个数
+ * 月维度:展示每个月的每天的数据
+ */
+ @PostMapping("/case/time/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaTimeStatistic(@RequestBody MonthAndDayGroupDTO monthAndDayGroupDTO) {
+ String year = monthAndDayGroupDTO.getYear();
+ String month = monthAndDayGroupDTO.getMonth();
+ List resultList = caseInfoMapper.selectCountByMonthAndDay(year, month);
+ resultList.forEach(result -> {
+ result.setYear(year);
+ result.setMonth(month);
+ });
+ return ResponseData.success(resultList);
+ }
+
+ /**
+ * 安防事件频域频次统计,每年的每月/每周各级别安防事件个数
+ * 年维度:展示平均每个月和每周的数据
+ */
+ @PostMapping("/case/frequency/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaFrequencyStatistic(@RequestBody AvgMonthAndWeekGroupDTO avgMonthAndWeekGroupDTO) {
+ String year = avgMonthAndWeekGroupDTO.getYear();
+ List monthList = caseInfoMapper.selectPreMonthCountByYear(year);
+ Map> collect = monthList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ HashMap strAvgMap = new HashMap<>();
+ for (String key : collect.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ //若年份是本年,则使用个安防级别数量/当前月份数
+ //若不是本年,除数为12
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ monthAndWeekDTO.setMonthQuantity(sum / DateUtil.thisMonth());
+// monthAndWeekDTO.setLevelName();
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ monthAndWeekDTO.setMonthQuantity(sum / 12);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+
+ List weekList = caseInfoMapper.selectPreWeekCountByYear(year);
+ Map> collect1 = weekList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ for (String key : collect1.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }else{
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+ }
+ avgMonthAndWeekGroupDTO.setMap(strAvgMap);
+ return ResponseData.success(avgMonthAndWeekGroupDTO);
+ }
+
+ /**
+ * 员工出勤率,优先级3
+ * 物业/安保人员出勤人数除以物业/安保人员总数,一天有一次记录就算考勤
+ */
+ @PostMapping("/staff/attendanceRatio")
+ @ResponseBody
+ public Object attendanceRatio(@RequestBody AttendanceRatioDTO attendanceRatioDTO) {
+ //员工类型字典key
+ String staffType = attendanceRatioDTO.getStaffType();
+ String dateDimension = attendanceRatioDTO.getDateDimension();
+ List attendanceRatioDTOS = new ArrayList<>();
+ //考勤的人数,按员工类型和单次考勤过滤
+ if("week".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForWeek(staffType);
+ }else if("month".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForMonth(staffType);
+ }else if("year".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForYear(staffType);
+ }
+ if(CollectionUtils.isEmpty(attendanceRatioDTOS)){
+ return ResponseData.error("该查询条件下,无员工出勤数据!");
+ }
+
+ //该类型员工总数
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("staff_type", staffType);
+ Integer sum = staffInfoMapper.selectCount(wrapper);
+ if(sum <= 0){
+ return ResponseData.error("该查询条件下,员工管理中无该类型员工数据!");
+ }
+
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ //计算出勤率
+ attendanceRatioDTOS.forEach(attendanceRatio -> {
+ attendanceRatio.setDateDimension(dateDimension);
+ attendanceRatio.setStaffType(staffType);
+ String ratio = numberFormat.format((float) attendanceRatio.getQuantity() / (float) sum * 100);
+ attendanceRatio.setAttendanceRatio(ratio+"%");
+ });
+ return ResponseData.success(attendanceRatioDTOS);
+ }
+
+ /**
+ * 员工考勤人数变化,功能待定
+ */
+
+ /**
+ * 重点区域安防事态评估,功能待定
+ */
+
+ /**
+ * 重点区域威胁事件类型统计,优先级2
+ */
+ @GetMapping("/case/hazardLevelStatistics")
+ @ResponseBody
+ public Object HazardLevelStatistics() {
+ List hazardLevelGroup = caseInfoMapper.selectByHazardLevel();
+ if(CollectionUtils.isEmpty(hazardLevelGroup)){
+ log.info("重点区域威胁事件类型统计,无安防事件");
+ return ResponseData.error("无安防事件发生!");
+ }
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = hazardLevelGroup.stream().collect(Collectors.summarizingInt(HazardLevelGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("安防事件总数为0");
+ }
+ hazardLevelGroup.forEach(group -> {
+ CaseHazardLevel caseHazardLevel = hazardLevelMapper.getCaseHazardLevel(group.getLevelCode());
+ group.setLevelName(caseHazardLevel.getName());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ group.setLevelRatio(result+"%");
+ });
+ HazardLevelGroupResponse hazardLevelGroupResponse = new HazardLevelGroupResponse();
+ hazardLevelGroupResponse.setHazardLevelGroup(hazardLevelGroup);
+ hazardLevelGroupResponse.setQuantity(sum);
+ return ResponseData.success(hazardLevelGroupResponse);
+ }
+
+ /**
+ * 设备状态计算系数和评判,优先级3,需确认设备恢复时间是否可以获取
+ */
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
index 15d0e30..4cad1dd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
@@ -1,20 +1,26 @@
package com.casic.missiles.modular.controller.hik;
-import cn.hutool.core.date.DateTime;
-import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.casic.missiles.model.response.ResponseData;
-import com.casic.missiles.modular.dto.hik.*;
+import com.casic.missiles.modular.dao.HikFaceGroupInfoMapper;
+import com.casic.missiles.modular.dto.hik.EventSubscribeRequest;
+import com.casic.missiles.modular.dto.hik.FaceGroupAdditionRequest;
+import com.casic.missiles.modular.dto.hik.HikRecvEvent;
+import com.casic.missiles.modular.dto.hik.OrgBatchAdd;
import com.casic.missiles.modular.enums.HikUri;
import com.casic.missiles.modular.enums.SecurityEventType;
import com.casic.missiles.modular.model.CaseInfo;
import com.casic.missiles.modular.model.HikFaceGroupInfo;
import com.casic.missiles.modular.service.CaseInfoService;
import com.casic.missiles.modular.service.HikFaceGroupInfoService;
+import com.casic.missiles.modular.service.HikService;
import com.casic.missiles.modular.util.CaseInfoFactoryUtil;
import com.casic.missiles.modular.util.HikUtil;
+import com.casic.missiles.modular.util.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@@ -23,6 +29,7 @@
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* @Description: 海康事件Controller
@@ -43,9 +50,15 @@
@Autowired
private HikFaceGroupInfoService hikFaceGroupInfoService;
+ @Autowired
+ private HikService hikService;
+
@Value("${server.port}")
private int serverPort;
+ @Autowired
+ private HikFaceGroupInfoMapper hikFaceGroupInfoMapper;
+
/**
* 海康事件订阅
*/
@@ -86,34 +99,87 @@
public Object eventRcv(@RequestBody HikRecvEvent hikRecvEvent) {
//1、接收所需事件类型
Long eventType = hikRecvEvent.getEventType();
+ log.info("接收到安防事件类型为:{}", eventType);
CaseInfo caseInfo = caseInfoFactoryUtil.getCaseInfo(eventType);
+ //接收到不关心事件直接返回
+ if(Objects.isNull(caseInfo)){
+ return ResponseData.success();
+ }
//2、不同事件不同处理,caseInfoFactoryUtil已设置好事件基础定义信息
- // 再为事件添加状态(未解决)、设备编码、设备名称、位置、区域、时间
- // TODO: 2022/7/21 异步处理事件
- // TODO: 2022/7/21 海康安装设备后,应该有设备和位置的对应关系表,可维护在设备表中,获取位置和区域信息
- // TODO: 2022/7/21 位置和区域的概念
- // TODO: 2022/7/21 kafka
+ // 再为事件添加状态、设备编码、设备名称、位置、区域、时间
+ // 异步处理事件
+ ThreadPoolUtil.executorService.execute(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ CaseHandle(hikRecvEvent, eventType, caseInfo);
+ }
+ }));
+
+ return null;
+ }
+
+ private void CaseHandle(HikRecvEvent hikRecvEvent, Long eventType, CaseInfo caseInfo) {
JSONArray eventArray = hikRecvEvent.getEventArray();
- ArrayList caseInfos = new ArrayList<>();
+ List caseInfos = new ArrayList<>();
while (eventArray.stream().iterator().hasNext()) {
- // TODO: 2022/7/23 设备过滤,仅将预设置的设备的事件入库,可建立一个设备与事件的表或放入配置中
+ CaseInfo caseInfo1 = new CaseInfo();
+ BeanUtils.copyProperties(caseInfo, caseInfo1);
JSONObject event = (JSONObject) eventArray.stream().iterator().next();
- //ISO8601标准时间格式
- //示例:2018-08-15T 15:53:47.000+08:00
- String happenTimeISO = (String) event.get("happenTime");
- DateTime parse = DateUtil.parse(happenTimeISO);
- String happenTime = DateUtil.formatDateTime(parse);
- caseInfo.setHappenTime(happenTime); //发生时间
- // caseInfo.setStatus(); //事件状态
- // caseInfo.setDeviceCode(); //设备code
- // caseInfo.setDevName(); //设备名
- // caseInfo.setPosition(); //事件位置
- // caseInfo.setAreaName(); //区域
- caseInfos.add(caseInfo);
+ //5种事件进行不同处理
+ if(SecurityEventType.KEY_PERSONNEL_IDENTIFY_EVENT == eventType){
+ //判断所属人脸分组
+ JSONObject data = (JSONObject) event.get("data");
+ JSONObject faceRecognitionResult = (JSONObject) data.get("faceRecognitionResult");
+ JSONArray faceMatchArr = (JSONArray) faceRecognitionResult.get("faceMatch");
+ JSONObject faceMatch = (JSONObject) faceMatchArr.get(0);
+ String faceGroupCode = faceMatch.getString("faceGroupCode");
+ if (StringUtils.isEmpty(faceGroupCode)) {
+ return;
+ }
+ HikFaceGroupInfo blackListGroup = hikFaceGroupInfoMapper.selectByName("blackList");
+ HikFaceGroupInfo propertyPersonnelGroup = hikFaceGroupInfoMapper.selectByName("propertyPersonnel");
+ HikFaceGroupInfo securityPersonnelGroup = hikFaceGroupInfoMapper.selectByName("securityPersonnel");
+ if (faceGroupCode.equals(blackListGroup.getFaceGroupCode())) {
+ //黑名单分组处理
+ caseInfo1 = hikService.blackListHandle(event, caseInfo1);
+ }else if(faceGroupCode.equals(propertyPersonnelGroup.getFaceGroupCode())){
+ //考勤分组处理-物业人员,添加到考勤表
+ hikService.propertyAttendanceHandle(event);
+ }else if(faceGroupCode.equals(securityPersonnelGroup.getFaceGroupCode())){
+ //考勤分组处理-安保人员,添加到考勤表
+ hikService.securityPersonnelHandle(event);
+ }else {
+ return;
+ }
+
+ }else if(SecurityEventType.PERSONNEL_DEMOBILIZED_EVENT == eventType){
+ //离岗事件处理
+ caseInfo1 = hikService.demobilizedHandle(event, caseInfo1);
+ }else if(SecurityEventType.PERSONNEL_GATHER_EVENT == eventType){
+ //人员聚集事件处理
+ caseInfo1 = hikService.personGatherHandle(event, caseInfo1);
+ }else if(SecurityEventType.MONITORING_POINT_OFFLINE == eventType){
+ //监控点离线事件处理
+ caseInfo1 = hikService.monitorPointOfflineHandle(event, caseInfo1);
+ }else if(SecurityEventType.DEVICE_OFFLINE == eventType){
+ //装置离线事件处理
+ caseInfo1 = hikService.deviceOfflineHandle(event, caseInfo1);
+ }else if(SecurityEventType.VISITOR_REGISTER == eventType){
+ //记录访客登记记录,添加到访客记录表
+ hikService.visitorRegisterHandler(event);
+ }else if(SecurityEventType.VISITOR_CHECKOUT == eventType){
+ //记录访客签离记录
+ hikService.visitorCheckOutHandler(event);
+ }
+ if(!Objects.isNull(caseInfo1) && !StringUtils.isEmpty(caseInfo1.getHappenTime())){
+ caseInfos.add(caseInfo1);
+ }
}
//3、安防事件入库
- caseInfoService.addCaseInfoBatch(caseInfos);
- return null;
+ if(!caseInfoService.insertCaseInfoBatch(caseInfos)){
+ log.error("安防事件批量入库异常");
+ }
+ return;
}
/**
@@ -131,9 +197,9 @@
return ResponseData.error("添加人脸分组失败");
}
JSONObject dataJson = (JSONObject) resultJson.get("data");
- String code = (String) dataJson.get("indexCode");
- String name = (String) dataJson.get("name");
- String description = (String) dataJson.get("description");
+ String code = String.valueOf(dataJson.get("indexCode"));
+ String name = String.valueOf(dataJson.get("name"));
+ String description = String.valueOf(dataJson.get("description"));
HikFaceGroupInfo hikFaceGroupInfo = new HikFaceGroupInfo();
hikFaceGroupInfo.setFaceGroupCode(code);
hikFaceGroupInfo.setFaceGroupName(name);
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
index 1a306ef..18ef0f5 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
@@ -54,6 +54,7 @@
*/
@PostMapping("/{operation}")
@ResponseBody
+// @BussinessLog("消防器材增删改")
public Object operation(@PathVariable(name = "operation") String operateType, @RequestBody FireEquipInfo fireEquipInfo) {
if(OperateTypeEnum.ADD.getOperateType().equals(operateType)){
return fireEquipService.addFireEquipInfo(fireEquipInfo);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
index a7cf1f8..d86dc30 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
@@ -30,7 +30,6 @@
@RestController
@RequestMapping("/applicationInfo")
public class VisitorApplyController extends ExportController {
- // TODO: 2022/7/23 访客申请增删改同时要增删改海康的预约,修改访客预约v2接口,取消操作使用取消访客预约
@Autowired
private VisitorApplyService visitorApplyService;
/**
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
new file mode 100644
index 0000000..14439eb
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
@@ -0,0 +1,49 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.VisitorRequest;
+import com.casic.missiles.modular.model.VisitInfo;
+import com.casic.missiles.modular.service.VisitService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 访客管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 19:16
+ */
+@Slf4j
+@RestController
+@RequestMapping("/visitInfo")
+public class VisitorController extends ExportController {
+ @Autowired
+ private VisitService visitService;
+
+ /**
+ * 访问记录列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody VisitorRequest visitorRequest) {
+ Page page = PageFactory.defaultPage();
+ List visitorApplies = visitService.visitInfoListPage(page, visitorRequest);
+ page.setRecords(visitorApplies);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 访问记录详情
+ */
+ @PostMapping("/detail")
+ @ResponseBody
+ public Object detail(@RequestBody VisitorRequest visitorRequest) {
+ VisitInfo visitInfo = visitService.visitInfoDetail(visitorRequest.getId());
+ return ResponseData.success(visitInfo);
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
new file mode 100644
index 0000000..4b92489
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
@@ -0,0 +1,171 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.core.application.service.AbstractDictService;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.CategoryLevelMapper;
+import com.casic.missiles.modular.dao.DeviceInfoMapper;
+import com.casic.missiles.modular.dao.FireEquipInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.enums.SecurityEventDict;
+import com.casic.missiles.modular.model.CaseCategoryLevel;
+import com.casic.missiles.modular.model.CaseInfo;
+import com.casic.missiles.modular.redis.RedisUtil;
+import com.casic.missiles.modular.redis.key.CacheKeys;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱驻留页面-前端主动查询相关
+ * @Author: wangpeng
+ * @Date: 2022/7/27 19:46
+ */
+@Slf4j
+@RestController
+@RequestMapping("/cockpit")
+public class CockpitController {
+ @Autowired
+ private RedisUtil redisUtil;
+
+ @Autowired
+ private AbstractDictService dictService;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private CategoryLevelMapper categoryLevelMapper;
+
+ @Autowired
+ private DeviceInfoMapper deviceInfoMapper;
+
+ @Autowired
+ private FireEquipInfoMapper fireEquipInfoMapper;
+
+ /**
+ * 重点区域威胁事件历史统计,计算每个月的各级别事件的数量
+ */
+ @PostMapping("/case/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaEventStatistic(@RequestBody MonthAndLevelGroupDTO monthAndLevelGroupDTO) {
+ Object o = redisUtil.get(CacheKeys.MONTH_STATISTIC_KEY);
+ List list = JSONArray.parseArray(String.valueOf(o), MonthAndLevelGroupDTO.class);
+ if(!CollectionUtils.isEmpty(list)){
+ Map> resultMap = list.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ return ResponseData.success(resultMap);
+ }
+ //查询数据,放入redis
+ List monthAndLevelGroup = caseInfoMapper.selectByLevelAndMonth(monthAndLevelGroupDTO.getYear());
+ Map> resultMap = monthAndLevelGroup.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ //设置过期时间为每月1号0点
+ LocalDateTime midnight = LocalDateTime.now().plusMonths(1).withDayOfMonth(1).withHour(0)
+ .withMinute(0).withSecond(0).withNano(0);
+ long between = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
+ redisUtil.set(CacheKeys.MONTH_STATISTIC_KEY, JSONObject.toJSONString(monthAndLevelGroup), between);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安防事件类别统计
+ */
+ @GetMapping("/case/categoryStatistics")
+ @ResponseBody
+ public Object eventCategoryStatistics() {
+ List categoryLevelGroup = caseInfoMapper.selectByCategoryLevel();
+ categoryLevelGroup.forEach(group -> {
+ CaseCategoryLevel caseCategoryLevel = categoryLevelMapper.getCaseCategoryLevel(group.getCategoryLevelCode());
+ group.setCategoryLevelName(caseCategoryLevel.getName());
+ });
+ return ResponseData.success(categoryLevelGroup);
+ }
+
+ /**
+ * 消防器材类别统计
+ */
+ @GetMapping("/device/fireEquipStatistics")
+ @ResponseBody
+ public Object fireEquipStatistics() {
+ List equipTypeGroup = fireEquipInfoMapper.selectByEquipType();
+ equipTypeGroup.forEach(group -> {
+ String equipTypeName = dictService.getDictNameByCode(SecurityEventDict.EQUIP_TYPE, group.getEquipTypeCode());
+ group.setEquipTypeName(equipTypeName);
+ });
+ return ResponseData.success(equipTypeGroup);
+ }
+
+ /**
+ * 闸机速通门统计-设备状态分组计算数量,devType传闸机字典key
+ * 视频频监控摄像机统计-设备状态分组计算数量,devType传摄像头字典key
+ */
+ @PostMapping("/device/statistics")
+ @ResponseBody
+ public Object GateStatusStatistics(@RequestBody GateStatusGroupDTO gateStatusGroupDTO) {
+ List gateStatusGroup = deviceInfoMapper.selectByType(gateStatusGroupDTO.getDevType());
+ HashMap resultMap = new HashMap<>();
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = gateStatusGroup.stream().collect(Collectors.summarizingInt(GateStatusGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("无该类设备信息");
+ }
+ gateStatusGroup.forEach(group -> {
+ String devStatus = dictService.getDictNameByCode(SecurityEventDict.DEVICE_STATUS, group.getStatus());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ resultMap.put(devStatus, result+"%");
+ });
+ resultMap.put("总", sum);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安全防护分析,设备加所在楼层评分,计算规则:发生安防事件*类别权重*级别权重算分
+ * 优先级3
+ */
+ @PostMapping("/device/securityScore")
+ @ResponseBody
+ public Object SecurityScore(@RequestBody SecurityScoreDTO securityScoreDTO) {
+ //按发生事件的设备所在的area划分计算评分,当天发生的事件
+ String position = securityScoreDTO.getPosition();
+ List caseInfos = caseInfoMapper.selectByPosition(position);
+ //查询各危险级别权重、各类别权重,放入map,避免循环中多次查数据库
+
+ List securityScoreDTOs = new ArrayList<>();
+ caseInfos.forEach(caseInfo -> {
+ SecurityScoreDTO securityScoreDTO1 = new SecurityScoreDTO();
+ securityScoreDTO1.setArea(caseInfo.getArea());
+ // TODO: 2022/8/4 楼层评分计算根据产品定义调整
+// caseInfo.get
+// securityScoreDTO1.setScore();
+ });
+
+ return null;
+ }
+
+ /**
+ * 安防事件时域性频次统计,统计每月安防事件个数
+ */
+ @PostMapping("/device/securityFrequency")
+ @ResponseBody
+ public Object SecurityFrequency(@RequestBody SecurityFrequencyDTO securityFrequencyDTO) {
+ String year = securityFrequencyDTO.getYear();
+ String month = securityFrequencyDTO.getMonth();
+ Integer quantity = caseInfoMapper.selectCountByMonth(year, month);
+ securityFrequencyDTO.setQuantity(quantity);
+ return ResponseData.success(securityFrequencyDTO);
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
new file mode 100644
index 0000000..ba584ee
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
@@ -0,0 +1,204 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.AttendanceInfoMapper;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.HazardLevelMapper;
+import com.casic.missiles.modular.dao.StaffInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.model.CaseHazardLevel;
+import com.casic.missiles.modular.model.StaffInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱二级页面-物管信息
+ * @Author: wangpeng
+ * @Date: 2022/8/3 15:05
+ */
+@Slf4j
+@RestController
+@RequestMapping("/propertyManage")
+public class PropertyManageController {
+ @Autowired
+ private AttendanceInfoMapper attendanceInfoMapper;
+
+ @Autowired
+ private StaffInfoMapper staffInfoMapper;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private HazardLevelMapper hazardLevelMapper;
+
+ /**
+ * 安防事件时域频次统计,每月的每天安防事件个数
+ * 月维度:展示每个月的每天的数据
+ */
+ @PostMapping("/case/time/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaTimeStatistic(@RequestBody MonthAndDayGroupDTO monthAndDayGroupDTO) {
+ String year = monthAndDayGroupDTO.getYear();
+ String month = monthAndDayGroupDTO.getMonth();
+ List resultList = caseInfoMapper.selectCountByMonthAndDay(year, month);
+ resultList.forEach(result -> {
+ result.setYear(year);
+ result.setMonth(month);
+ });
+ return ResponseData.success(resultList);
+ }
+
+ /**
+ * 安防事件频域频次统计,每年的每月/每周各级别安防事件个数
+ * 年维度:展示平均每个月和每周的数据
+ */
+ @PostMapping("/case/frequency/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaFrequencyStatistic(@RequestBody AvgMonthAndWeekGroupDTO avgMonthAndWeekGroupDTO) {
+ String year = avgMonthAndWeekGroupDTO.getYear();
+ List monthList = caseInfoMapper.selectPreMonthCountByYear(year);
+ Map> collect = monthList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ HashMap strAvgMap = new HashMap<>();
+ for (String key : collect.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ //若年份是本年,则使用个安防级别数量/当前月份数
+ //若不是本年,除数为12
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ monthAndWeekDTO.setMonthQuantity(sum / DateUtil.thisMonth());
+// monthAndWeekDTO.setLevelName();
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ monthAndWeekDTO.setMonthQuantity(sum / 12);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+
+ List weekList = caseInfoMapper.selectPreWeekCountByYear(year);
+ Map> collect1 = weekList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ for (String key : collect1.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }else{
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+ }
+ avgMonthAndWeekGroupDTO.setMap(strAvgMap);
+ return ResponseData.success(avgMonthAndWeekGroupDTO);
+ }
+
+ /**
+ * 员工出勤率,优先级3
+ * 物业/安保人员出勤人数除以物业/安保人员总数,一天有一次记录就算考勤
+ */
+ @PostMapping("/staff/attendanceRatio")
+ @ResponseBody
+ public Object attendanceRatio(@RequestBody AttendanceRatioDTO attendanceRatioDTO) {
+ //员工类型字典key
+ String staffType = attendanceRatioDTO.getStaffType();
+ String dateDimension = attendanceRatioDTO.getDateDimension();
+ List attendanceRatioDTOS = new ArrayList<>();
+ //考勤的人数,按员工类型和单次考勤过滤
+ if("week".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForWeek(staffType);
+ }else if("month".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForMonth(staffType);
+ }else if("year".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForYear(staffType);
+ }
+ if(CollectionUtils.isEmpty(attendanceRatioDTOS)){
+ return ResponseData.error("该查询条件下,无员工出勤数据!");
+ }
+
+ //该类型员工总数
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("staff_type", staffType);
+ Integer sum = staffInfoMapper.selectCount(wrapper);
+ if(sum <= 0){
+ return ResponseData.error("该查询条件下,员工管理中无该类型员工数据!");
+ }
+
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ //计算出勤率
+ attendanceRatioDTOS.forEach(attendanceRatio -> {
+ attendanceRatio.setDateDimension(dateDimension);
+ attendanceRatio.setStaffType(staffType);
+ String ratio = numberFormat.format((float) attendanceRatio.getQuantity() / (float) sum * 100);
+ attendanceRatio.setAttendanceRatio(ratio+"%");
+ });
+ return ResponseData.success(attendanceRatioDTOS);
+ }
+
+ /**
+ * 员工考勤人数变化,功能待定
+ */
+
+ /**
+ * 重点区域安防事态评估,功能待定
+ */
+
+ /**
+ * 重点区域威胁事件类型统计,优先级2
+ */
+ @GetMapping("/case/hazardLevelStatistics")
+ @ResponseBody
+ public Object HazardLevelStatistics() {
+ List hazardLevelGroup = caseInfoMapper.selectByHazardLevel();
+ if(CollectionUtils.isEmpty(hazardLevelGroup)){
+ log.info("重点区域威胁事件类型统计,无安防事件");
+ return ResponseData.error("无安防事件发生!");
+ }
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = hazardLevelGroup.stream().collect(Collectors.summarizingInt(HazardLevelGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("安防事件总数为0");
+ }
+ hazardLevelGroup.forEach(group -> {
+ CaseHazardLevel caseHazardLevel = hazardLevelMapper.getCaseHazardLevel(group.getLevelCode());
+ group.setLevelName(caseHazardLevel.getName());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ group.setLevelRatio(result+"%");
+ });
+ HazardLevelGroupResponse hazardLevelGroupResponse = new HazardLevelGroupResponse();
+ hazardLevelGroupResponse.setHazardLevelGroup(hazardLevelGroup);
+ hazardLevelGroupResponse.setQuantity(sum);
+ return ResponseData.success(hazardLevelGroupResponse);
+ }
+
+ /**
+ * 设备状态计算系数和评判,优先级3,需确认设备恢复时间是否可以获取
+ */
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
index 15d0e30..4cad1dd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
@@ -1,20 +1,26 @@
package com.casic.missiles.modular.controller.hik;
-import cn.hutool.core.date.DateTime;
-import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.casic.missiles.model.response.ResponseData;
-import com.casic.missiles.modular.dto.hik.*;
+import com.casic.missiles.modular.dao.HikFaceGroupInfoMapper;
+import com.casic.missiles.modular.dto.hik.EventSubscribeRequest;
+import com.casic.missiles.modular.dto.hik.FaceGroupAdditionRequest;
+import com.casic.missiles.modular.dto.hik.HikRecvEvent;
+import com.casic.missiles.modular.dto.hik.OrgBatchAdd;
import com.casic.missiles.modular.enums.HikUri;
import com.casic.missiles.modular.enums.SecurityEventType;
import com.casic.missiles.modular.model.CaseInfo;
import com.casic.missiles.modular.model.HikFaceGroupInfo;
import com.casic.missiles.modular.service.CaseInfoService;
import com.casic.missiles.modular.service.HikFaceGroupInfoService;
+import com.casic.missiles.modular.service.HikService;
import com.casic.missiles.modular.util.CaseInfoFactoryUtil;
import com.casic.missiles.modular.util.HikUtil;
+import com.casic.missiles.modular.util.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@@ -23,6 +29,7 @@
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* @Description: 海康事件Controller
@@ -43,9 +50,15 @@
@Autowired
private HikFaceGroupInfoService hikFaceGroupInfoService;
+ @Autowired
+ private HikService hikService;
+
@Value("${server.port}")
private int serverPort;
+ @Autowired
+ private HikFaceGroupInfoMapper hikFaceGroupInfoMapper;
+
/**
* 海康事件订阅
*/
@@ -86,34 +99,87 @@
public Object eventRcv(@RequestBody HikRecvEvent hikRecvEvent) {
//1、接收所需事件类型
Long eventType = hikRecvEvent.getEventType();
+ log.info("接收到安防事件类型为:{}", eventType);
CaseInfo caseInfo = caseInfoFactoryUtil.getCaseInfo(eventType);
+ //接收到不关心事件直接返回
+ if(Objects.isNull(caseInfo)){
+ return ResponseData.success();
+ }
//2、不同事件不同处理,caseInfoFactoryUtil已设置好事件基础定义信息
- // 再为事件添加状态(未解决)、设备编码、设备名称、位置、区域、时间
- // TODO: 2022/7/21 异步处理事件
- // TODO: 2022/7/21 海康安装设备后,应该有设备和位置的对应关系表,可维护在设备表中,获取位置和区域信息
- // TODO: 2022/7/21 位置和区域的概念
- // TODO: 2022/7/21 kafka
+ // 再为事件添加状态、设备编码、设备名称、位置、区域、时间
+ // 异步处理事件
+ ThreadPoolUtil.executorService.execute(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ CaseHandle(hikRecvEvent, eventType, caseInfo);
+ }
+ }));
+
+ return null;
+ }
+
+ private void CaseHandle(HikRecvEvent hikRecvEvent, Long eventType, CaseInfo caseInfo) {
JSONArray eventArray = hikRecvEvent.getEventArray();
- ArrayList caseInfos = new ArrayList<>();
+ List caseInfos = new ArrayList<>();
while (eventArray.stream().iterator().hasNext()) {
- // TODO: 2022/7/23 设备过滤,仅将预设置的设备的事件入库,可建立一个设备与事件的表或放入配置中
+ CaseInfo caseInfo1 = new CaseInfo();
+ BeanUtils.copyProperties(caseInfo, caseInfo1);
JSONObject event = (JSONObject) eventArray.stream().iterator().next();
- //ISO8601标准时间格式
- //示例:2018-08-15T 15:53:47.000+08:00
- String happenTimeISO = (String) event.get("happenTime");
- DateTime parse = DateUtil.parse(happenTimeISO);
- String happenTime = DateUtil.formatDateTime(parse);
- caseInfo.setHappenTime(happenTime); //发生时间
- // caseInfo.setStatus(); //事件状态
- // caseInfo.setDeviceCode(); //设备code
- // caseInfo.setDevName(); //设备名
- // caseInfo.setPosition(); //事件位置
- // caseInfo.setAreaName(); //区域
- caseInfos.add(caseInfo);
+ //5种事件进行不同处理
+ if(SecurityEventType.KEY_PERSONNEL_IDENTIFY_EVENT == eventType){
+ //判断所属人脸分组
+ JSONObject data = (JSONObject) event.get("data");
+ JSONObject faceRecognitionResult = (JSONObject) data.get("faceRecognitionResult");
+ JSONArray faceMatchArr = (JSONArray) faceRecognitionResult.get("faceMatch");
+ JSONObject faceMatch = (JSONObject) faceMatchArr.get(0);
+ String faceGroupCode = faceMatch.getString("faceGroupCode");
+ if (StringUtils.isEmpty(faceGroupCode)) {
+ return;
+ }
+ HikFaceGroupInfo blackListGroup = hikFaceGroupInfoMapper.selectByName("blackList");
+ HikFaceGroupInfo propertyPersonnelGroup = hikFaceGroupInfoMapper.selectByName("propertyPersonnel");
+ HikFaceGroupInfo securityPersonnelGroup = hikFaceGroupInfoMapper.selectByName("securityPersonnel");
+ if (faceGroupCode.equals(blackListGroup.getFaceGroupCode())) {
+ //黑名单分组处理
+ caseInfo1 = hikService.blackListHandle(event, caseInfo1);
+ }else if(faceGroupCode.equals(propertyPersonnelGroup.getFaceGroupCode())){
+ //考勤分组处理-物业人员,添加到考勤表
+ hikService.propertyAttendanceHandle(event);
+ }else if(faceGroupCode.equals(securityPersonnelGroup.getFaceGroupCode())){
+ //考勤分组处理-安保人员,添加到考勤表
+ hikService.securityPersonnelHandle(event);
+ }else {
+ return;
+ }
+
+ }else if(SecurityEventType.PERSONNEL_DEMOBILIZED_EVENT == eventType){
+ //离岗事件处理
+ caseInfo1 = hikService.demobilizedHandle(event, caseInfo1);
+ }else if(SecurityEventType.PERSONNEL_GATHER_EVENT == eventType){
+ //人员聚集事件处理
+ caseInfo1 = hikService.personGatherHandle(event, caseInfo1);
+ }else if(SecurityEventType.MONITORING_POINT_OFFLINE == eventType){
+ //监控点离线事件处理
+ caseInfo1 = hikService.monitorPointOfflineHandle(event, caseInfo1);
+ }else if(SecurityEventType.DEVICE_OFFLINE == eventType){
+ //装置离线事件处理
+ caseInfo1 = hikService.deviceOfflineHandle(event, caseInfo1);
+ }else if(SecurityEventType.VISITOR_REGISTER == eventType){
+ //记录访客登记记录,添加到访客记录表
+ hikService.visitorRegisterHandler(event);
+ }else if(SecurityEventType.VISITOR_CHECKOUT == eventType){
+ //记录访客签离记录
+ hikService.visitorCheckOutHandler(event);
+ }
+ if(!Objects.isNull(caseInfo1) && !StringUtils.isEmpty(caseInfo1.getHappenTime())){
+ caseInfos.add(caseInfo1);
+ }
}
//3、安防事件入库
- caseInfoService.addCaseInfoBatch(caseInfos);
- return null;
+ if(!caseInfoService.insertCaseInfoBatch(caseInfos)){
+ log.error("安防事件批量入库异常");
+ }
+ return;
}
/**
@@ -131,9 +197,9 @@
return ResponseData.error("添加人脸分组失败");
}
JSONObject dataJson = (JSONObject) resultJson.get("data");
- String code = (String) dataJson.get("indexCode");
- String name = (String) dataJson.get("name");
- String description = (String) dataJson.get("description");
+ String code = String.valueOf(dataJson.get("indexCode"));
+ String name = String.valueOf(dataJson.get("name"));
+ String description = String.valueOf(dataJson.get("description"));
HikFaceGroupInfo hikFaceGroupInfo = new HikFaceGroupInfo();
hikFaceGroupInfo.setFaceGroupCode(code);
hikFaceGroupInfo.setFaceGroupName(name);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/dao/AttendanceInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/dao/AttendanceInfoMapper.java
new file mode 100644
index 0000000..f9e793e
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/dao/AttendanceInfoMapper.java
@@ -0,0 +1,29 @@
+package com.casic.missiles.modular.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.dto.statistics.AttendanceRatioDTO;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:53
+ */
+@Mapper
+public interface AttendanceInfoMapper extends BaseMapper {
+ List getAttendanceInfoListPage(@Param("page") Page page, StaffInfoRequest attendanceInfoRequest);
+
+ AttendanceInfo selectByCodeAndDate(@Param("staffCode") String staffCode);
+
+ List getCountByTypeAndDateForWeek(@Param("staffType")String staffType);
+
+ List getCountByTypeAndDateForMonth(@Param("staffType")String staffType);
+
+ List getCountByTypeAndDateForYear(@Param("staffType")String staffType);
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
index 1a306ef..18ef0f5 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
@@ -54,6 +54,7 @@
*/
@PostMapping("/{operation}")
@ResponseBody
+// @BussinessLog("消防器材增删改")
public Object operation(@PathVariable(name = "operation") String operateType, @RequestBody FireEquipInfo fireEquipInfo) {
if(OperateTypeEnum.ADD.getOperateType().equals(operateType)){
return fireEquipService.addFireEquipInfo(fireEquipInfo);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
index a7cf1f8..d86dc30 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
@@ -30,7 +30,6 @@
@RestController
@RequestMapping("/applicationInfo")
public class VisitorApplyController extends ExportController {
- // TODO: 2022/7/23 访客申请增删改同时要增删改海康的预约,修改访客预约v2接口,取消操作使用取消访客预约
@Autowired
private VisitorApplyService visitorApplyService;
/**
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
new file mode 100644
index 0000000..14439eb
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
@@ -0,0 +1,49 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.VisitorRequest;
+import com.casic.missiles.modular.model.VisitInfo;
+import com.casic.missiles.modular.service.VisitService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 访客管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 19:16
+ */
+@Slf4j
+@RestController
+@RequestMapping("/visitInfo")
+public class VisitorController extends ExportController {
+ @Autowired
+ private VisitService visitService;
+
+ /**
+ * 访问记录列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody VisitorRequest visitorRequest) {
+ Page page = PageFactory.defaultPage();
+ List visitorApplies = visitService.visitInfoListPage(page, visitorRequest);
+ page.setRecords(visitorApplies);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 访问记录详情
+ */
+ @PostMapping("/detail")
+ @ResponseBody
+ public Object detail(@RequestBody VisitorRequest visitorRequest) {
+ VisitInfo visitInfo = visitService.visitInfoDetail(visitorRequest.getId());
+ return ResponseData.success(visitInfo);
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
new file mode 100644
index 0000000..4b92489
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
@@ -0,0 +1,171 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.core.application.service.AbstractDictService;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.CategoryLevelMapper;
+import com.casic.missiles.modular.dao.DeviceInfoMapper;
+import com.casic.missiles.modular.dao.FireEquipInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.enums.SecurityEventDict;
+import com.casic.missiles.modular.model.CaseCategoryLevel;
+import com.casic.missiles.modular.model.CaseInfo;
+import com.casic.missiles.modular.redis.RedisUtil;
+import com.casic.missiles.modular.redis.key.CacheKeys;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱驻留页面-前端主动查询相关
+ * @Author: wangpeng
+ * @Date: 2022/7/27 19:46
+ */
+@Slf4j
+@RestController
+@RequestMapping("/cockpit")
+public class CockpitController {
+ @Autowired
+ private RedisUtil redisUtil;
+
+ @Autowired
+ private AbstractDictService dictService;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private CategoryLevelMapper categoryLevelMapper;
+
+ @Autowired
+ private DeviceInfoMapper deviceInfoMapper;
+
+ @Autowired
+ private FireEquipInfoMapper fireEquipInfoMapper;
+
+ /**
+ * 重点区域威胁事件历史统计,计算每个月的各级别事件的数量
+ */
+ @PostMapping("/case/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaEventStatistic(@RequestBody MonthAndLevelGroupDTO monthAndLevelGroupDTO) {
+ Object o = redisUtil.get(CacheKeys.MONTH_STATISTIC_KEY);
+ List list = JSONArray.parseArray(String.valueOf(o), MonthAndLevelGroupDTO.class);
+ if(!CollectionUtils.isEmpty(list)){
+ Map> resultMap = list.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ return ResponseData.success(resultMap);
+ }
+ //查询数据,放入redis
+ List monthAndLevelGroup = caseInfoMapper.selectByLevelAndMonth(monthAndLevelGroupDTO.getYear());
+ Map> resultMap = monthAndLevelGroup.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ //设置过期时间为每月1号0点
+ LocalDateTime midnight = LocalDateTime.now().plusMonths(1).withDayOfMonth(1).withHour(0)
+ .withMinute(0).withSecond(0).withNano(0);
+ long between = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
+ redisUtil.set(CacheKeys.MONTH_STATISTIC_KEY, JSONObject.toJSONString(monthAndLevelGroup), between);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安防事件类别统计
+ */
+ @GetMapping("/case/categoryStatistics")
+ @ResponseBody
+ public Object eventCategoryStatistics() {
+ List categoryLevelGroup = caseInfoMapper.selectByCategoryLevel();
+ categoryLevelGroup.forEach(group -> {
+ CaseCategoryLevel caseCategoryLevel = categoryLevelMapper.getCaseCategoryLevel(group.getCategoryLevelCode());
+ group.setCategoryLevelName(caseCategoryLevel.getName());
+ });
+ return ResponseData.success(categoryLevelGroup);
+ }
+
+ /**
+ * 消防器材类别统计
+ */
+ @GetMapping("/device/fireEquipStatistics")
+ @ResponseBody
+ public Object fireEquipStatistics() {
+ List equipTypeGroup = fireEquipInfoMapper.selectByEquipType();
+ equipTypeGroup.forEach(group -> {
+ String equipTypeName = dictService.getDictNameByCode(SecurityEventDict.EQUIP_TYPE, group.getEquipTypeCode());
+ group.setEquipTypeName(equipTypeName);
+ });
+ return ResponseData.success(equipTypeGroup);
+ }
+
+ /**
+ * 闸机速通门统计-设备状态分组计算数量,devType传闸机字典key
+ * 视频频监控摄像机统计-设备状态分组计算数量,devType传摄像头字典key
+ */
+ @PostMapping("/device/statistics")
+ @ResponseBody
+ public Object GateStatusStatistics(@RequestBody GateStatusGroupDTO gateStatusGroupDTO) {
+ List gateStatusGroup = deviceInfoMapper.selectByType(gateStatusGroupDTO.getDevType());
+ HashMap resultMap = new HashMap<>();
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = gateStatusGroup.stream().collect(Collectors.summarizingInt(GateStatusGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("无该类设备信息");
+ }
+ gateStatusGroup.forEach(group -> {
+ String devStatus = dictService.getDictNameByCode(SecurityEventDict.DEVICE_STATUS, group.getStatus());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ resultMap.put(devStatus, result+"%");
+ });
+ resultMap.put("总", sum);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安全防护分析,设备加所在楼层评分,计算规则:发生安防事件*类别权重*级别权重算分
+ * 优先级3
+ */
+ @PostMapping("/device/securityScore")
+ @ResponseBody
+ public Object SecurityScore(@RequestBody SecurityScoreDTO securityScoreDTO) {
+ //按发生事件的设备所在的area划分计算评分,当天发生的事件
+ String position = securityScoreDTO.getPosition();
+ List caseInfos = caseInfoMapper.selectByPosition(position);
+ //查询各危险级别权重、各类别权重,放入map,避免循环中多次查数据库
+
+ List securityScoreDTOs = new ArrayList<>();
+ caseInfos.forEach(caseInfo -> {
+ SecurityScoreDTO securityScoreDTO1 = new SecurityScoreDTO();
+ securityScoreDTO1.setArea(caseInfo.getArea());
+ // TODO: 2022/8/4 楼层评分计算根据产品定义调整
+// caseInfo.get
+// securityScoreDTO1.setScore();
+ });
+
+ return null;
+ }
+
+ /**
+ * 安防事件时域性频次统计,统计每月安防事件个数
+ */
+ @PostMapping("/device/securityFrequency")
+ @ResponseBody
+ public Object SecurityFrequency(@RequestBody SecurityFrequencyDTO securityFrequencyDTO) {
+ String year = securityFrequencyDTO.getYear();
+ String month = securityFrequencyDTO.getMonth();
+ Integer quantity = caseInfoMapper.selectCountByMonth(year, month);
+ securityFrequencyDTO.setQuantity(quantity);
+ return ResponseData.success(securityFrequencyDTO);
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
new file mode 100644
index 0000000..ba584ee
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
@@ -0,0 +1,204 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.AttendanceInfoMapper;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.HazardLevelMapper;
+import com.casic.missiles.modular.dao.StaffInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.model.CaseHazardLevel;
+import com.casic.missiles.modular.model.StaffInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱二级页面-物管信息
+ * @Author: wangpeng
+ * @Date: 2022/8/3 15:05
+ */
+@Slf4j
+@RestController
+@RequestMapping("/propertyManage")
+public class PropertyManageController {
+ @Autowired
+ private AttendanceInfoMapper attendanceInfoMapper;
+
+ @Autowired
+ private StaffInfoMapper staffInfoMapper;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private HazardLevelMapper hazardLevelMapper;
+
+ /**
+ * 安防事件时域频次统计,每月的每天安防事件个数
+ * 月维度:展示每个月的每天的数据
+ */
+ @PostMapping("/case/time/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaTimeStatistic(@RequestBody MonthAndDayGroupDTO monthAndDayGroupDTO) {
+ String year = monthAndDayGroupDTO.getYear();
+ String month = monthAndDayGroupDTO.getMonth();
+ List resultList = caseInfoMapper.selectCountByMonthAndDay(year, month);
+ resultList.forEach(result -> {
+ result.setYear(year);
+ result.setMonth(month);
+ });
+ return ResponseData.success(resultList);
+ }
+
+ /**
+ * 安防事件频域频次统计,每年的每月/每周各级别安防事件个数
+ * 年维度:展示平均每个月和每周的数据
+ */
+ @PostMapping("/case/frequency/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaFrequencyStatistic(@RequestBody AvgMonthAndWeekGroupDTO avgMonthAndWeekGroupDTO) {
+ String year = avgMonthAndWeekGroupDTO.getYear();
+ List monthList = caseInfoMapper.selectPreMonthCountByYear(year);
+ Map> collect = monthList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ HashMap strAvgMap = new HashMap<>();
+ for (String key : collect.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ //若年份是本年,则使用个安防级别数量/当前月份数
+ //若不是本年,除数为12
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ monthAndWeekDTO.setMonthQuantity(sum / DateUtil.thisMonth());
+// monthAndWeekDTO.setLevelName();
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ monthAndWeekDTO.setMonthQuantity(sum / 12);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+
+ List weekList = caseInfoMapper.selectPreWeekCountByYear(year);
+ Map> collect1 = weekList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ for (String key : collect1.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }else{
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+ }
+ avgMonthAndWeekGroupDTO.setMap(strAvgMap);
+ return ResponseData.success(avgMonthAndWeekGroupDTO);
+ }
+
+ /**
+ * 员工出勤率,优先级3
+ * 物业/安保人员出勤人数除以物业/安保人员总数,一天有一次记录就算考勤
+ */
+ @PostMapping("/staff/attendanceRatio")
+ @ResponseBody
+ public Object attendanceRatio(@RequestBody AttendanceRatioDTO attendanceRatioDTO) {
+ //员工类型字典key
+ String staffType = attendanceRatioDTO.getStaffType();
+ String dateDimension = attendanceRatioDTO.getDateDimension();
+ List attendanceRatioDTOS = new ArrayList<>();
+ //考勤的人数,按员工类型和单次考勤过滤
+ if("week".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForWeek(staffType);
+ }else if("month".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForMonth(staffType);
+ }else if("year".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForYear(staffType);
+ }
+ if(CollectionUtils.isEmpty(attendanceRatioDTOS)){
+ return ResponseData.error("该查询条件下,无员工出勤数据!");
+ }
+
+ //该类型员工总数
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("staff_type", staffType);
+ Integer sum = staffInfoMapper.selectCount(wrapper);
+ if(sum <= 0){
+ return ResponseData.error("该查询条件下,员工管理中无该类型员工数据!");
+ }
+
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ //计算出勤率
+ attendanceRatioDTOS.forEach(attendanceRatio -> {
+ attendanceRatio.setDateDimension(dateDimension);
+ attendanceRatio.setStaffType(staffType);
+ String ratio = numberFormat.format((float) attendanceRatio.getQuantity() / (float) sum * 100);
+ attendanceRatio.setAttendanceRatio(ratio+"%");
+ });
+ return ResponseData.success(attendanceRatioDTOS);
+ }
+
+ /**
+ * 员工考勤人数变化,功能待定
+ */
+
+ /**
+ * 重点区域安防事态评估,功能待定
+ */
+
+ /**
+ * 重点区域威胁事件类型统计,优先级2
+ */
+ @GetMapping("/case/hazardLevelStatistics")
+ @ResponseBody
+ public Object HazardLevelStatistics() {
+ List hazardLevelGroup = caseInfoMapper.selectByHazardLevel();
+ if(CollectionUtils.isEmpty(hazardLevelGroup)){
+ log.info("重点区域威胁事件类型统计,无安防事件");
+ return ResponseData.error("无安防事件发生!");
+ }
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = hazardLevelGroup.stream().collect(Collectors.summarizingInt(HazardLevelGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("安防事件总数为0");
+ }
+ hazardLevelGroup.forEach(group -> {
+ CaseHazardLevel caseHazardLevel = hazardLevelMapper.getCaseHazardLevel(group.getLevelCode());
+ group.setLevelName(caseHazardLevel.getName());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ group.setLevelRatio(result+"%");
+ });
+ HazardLevelGroupResponse hazardLevelGroupResponse = new HazardLevelGroupResponse();
+ hazardLevelGroupResponse.setHazardLevelGroup(hazardLevelGroup);
+ hazardLevelGroupResponse.setQuantity(sum);
+ return ResponseData.success(hazardLevelGroupResponse);
+ }
+
+ /**
+ * 设备状态计算系数和评判,优先级3,需确认设备恢复时间是否可以获取
+ */
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
index 15d0e30..4cad1dd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
@@ -1,20 +1,26 @@
package com.casic.missiles.modular.controller.hik;
-import cn.hutool.core.date.DateTime;
-import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.casic.missiles.model.response.ResponseData;
-import com.casic.missiles.modular.dto.hik.*;
+import com.casic.missiles.modular.dao.HikFaceGroupInfoMapper;
+import com.casic.missiles.modular.dto.hik.EventSubscribeRequest;
+import com.casic.missiles.modular.dto.hik.FaceGroupAdditionRequest;
+import com.casic.missiles.modular.dto.hik.HikRecvEvent;
+import com.casic.missiles.modular.dto.hik.OrgBatchAdd;
import com.casic.missiles.modular.enums.HikUri;
import com.casic.missiles.modular.enums.SecurityEventType;
import com.casic.missiles.modular.model.CaseInfo;
import com.casic.missiles.modular.model.HikFaceGroupInfo;
import com.casic.missiles.modular.service.CaseInfoService;
import com.casic.missiles.modular.service.HikFaceGroupInfoService;
+import com.casic.missiles.modular.service.HikService;
import com.casic.missiles.modular.util.CaseInfoFactoryUtil;
import com.casic.missiles.modular.util.HikUtil;
+import com.casic.missiles.modular.util.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@@ -23,6 +29,7 @@
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* @Description: 海康事件Controller
@@ -43,9 +50,15 @@
@Autowired
private HikFaceGroupInfoService hikFaceGroupInfoService;
+ @Autowired
+ private HikService hikService;
+
@Value("${server.port}")
private int serverPort;
+ @Autowired
+ private HikFaceGroupInfoMapper hikFaceGroupInfoMapper;
+
/**
* 海康事件订阅
*/
@@ -86,34 +99,87 @@
public Object eventRcv(@RequestBody HikRecvEvent hikRecvEvent) {
//1、接收所需事件类型
Long eventType = hikRecvEvent.getEventType();
+ log.info("接收到安防事件类型为:{}", eventType);
CaseInfo caseInfo = caseInfoFactoryUtil.getCaseInfo(eventType);
+ //接收到不关心事件直接返回
+ if(Objects.isNull(caseInfo)){
+ return ResponseData.success();
+ }
//2、不同事件不同处理,caseInfoFactoryUtil已设置好事件基础定义信息
- // 再为事件添加状态(未解决)、设备编码、设备名称、位置、区域、时间
- // TODO: 2022/7/21 异步处理事件
- // TODO: 2022/7/21 海康安装设备后,应该有设备和位置的对应关系表,可维护在设备表中,获取位置和区域信息
- // TODO: 2022/7/21 位置和区域的概念
- // TODO: 2022/7/21 kafka
+ // 再为事件添加状态、设备编码、设备名称、位置、区域、时间
+ // 异步处理事件
+ ThreadPoolUtil.executorService.execute(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ CaseHandle(hikRecvEvent, eventType, caseInfo);
+ }
+ }));
+
+ return null;
+ }
+
+ private void CaseHandle(HikRecvEvent hikRecvEvent, Long eventType, CaseInfo caseInfo) {
JSONArray eventArray = hikRecvEvent.getEventArray();
- ArrayList caseInfos = new ArrayList<>();
+ List caseInfos = new ArrayList<>();
while (eventArray.stream().iterator().hasNext()) {
- // TODO: 2022/7/23 设备过滤,仅将预设置的设备的事件入库,可建立一个设备与事件的表或放入配置中
+ CaseInfo caseInfo1 = new CaseInfo();
+ BeanUtils.copyProperties(caseInfo, caseInfo1);
JSONObject event = (JSONObject) eventArray.stream().iterator().next();
- //ISO8601标准时间格式
- //示例:2018-08-15T 15:53:47.000+08:00
- String happenTimeISO = (String) event.get("happenTime");
- DateTime parse = DateUtil.parse(happenTimeISO);
- String happenTime = DateUtil.formatDateTime(parse);
- caseInfo.setHappenTime(happenTime); //发生时间
- // caseInfo.setStatus(); //事件状态
- // caseInfo.setDeviceCode(); //设备code
- // caseInfo.setDevName(); //设备名
- // caseInfo.setPosition(); //事件位置
- // caseInfo.setAreaName(); //区域
- caseInfos.add(caseInfo);
+ //5种事件进行不同处理
+ if(SecurityEventType.KEY_PERSONNEL_IDENTIFY_EVENT == eventType){
+ //判断所属人脸分组
+ JSONObject data = (JSONObject) event.get("data");
+ JSONObject faceRecognitionResult = (JSONObject) data.get("faceRecognitionResult");
+ JSONArray faceMatchArr = (JSONArray) faceRecognitionResult.get("faceMatch");
+ JSONObject faceMatch = (JSONObject) faceMatchArr.get(0);
+ String faceGroupCode = faceMatch.getString("faceGroupCode");
+ if (StringUtils.isEmpty(faceGroupCode)) {
+ return;
+ }
+ HikFaceGroupInfo blackListGroup = hikFaceGroupInfoMapper.selectByName("blackList");
+ HikFaceGroupInfo propertyPersonnelGroup = hikFaceGroupInfoMapper.selectByName("propertyPersonnel");
+ HikFaceGroupInfo securityPersonnelGroup = hikFaceGroupInfoMapper.selectByName("securityPersonnel");
+ if (faceGroupCode.equals(blackListGroup.getFaceGroupCode())) {
+ //黑名单分组处理
+ caseInfo1 = hikService.blackListHandle(event, caseInfo1);
+ }else if(faceGroupCode.equals(propertyPersonnelGroup.getFaceGroupCode())){
+ //考勤分组处理-物业人员,添加到考勤表
+ hikService.propertyAttendanceHandle(event);
+ }else if(faceGroupCode.equals(securityPersonnelGroup.getFaceGroupCode())){
+ //考勤分组处理-安保人员,添加到考勤表
+ hikService.securityPersonnelHandle(event);
+ }else {
+ return;
+ }
+
+ }else if(SecurityEventType.PERSONNEL_DEMOBILIZED_EVENT == eventType){
+ //离岗事件处理
+ caseInfo1 = hikService.demobilizedHandle(event, caseInfo1);
+ }else if(SecurityEventType.PERSONNEL_GATHER_EVENT == eventType){
+ //人员聚集事件处理
+ caseInfo1 = hikService.personGatherHandle(event, caseInfo1);
+ }else if(SecurityEventType.MONITORING_POINT_OFFLINE == eventType){
+ //监控点离线事件处理
+ caseInfo1 = hikService.monitorPointOfflineHandle(event, caseInfo1);
+ }else if(SecurityEventType.DEVICE_OFFLINE == eventType){
+ //装置离线事件处理
+ caseInfo1 = hikService.deviceOfflineHandle(event, caseInfo1);
+ }else if(SecurityEventType.VISITOR_REGISTER == eventType){
+ //记录访客登记记录,添加到访客记录表
+ hikService.visitorRegisterHandler(event);
+ }else if(SecurityEventType.VISITOR_CHECKOUT == eventType){
+ //记录访客签离记录
+ hikService.visitorCheckOutHandler(event);
+ }
+ if(!Objects.isNull(caseInfo1) && !StringUtils.isEmpty(caseInfo1.getHappenTime())){
+ caseInfos.add(caseInfo1);
+ }
}
//3、安防事件入库
- caseInfoService.addCaseInfoBatch(caseInfos);
- return null;
+ if(!caseInfoService.insertCaseInfoBatch(caseInfos)){
+ log.error("安防事件批量入库异常");
+ }
+ return;
}
/**
@@ -131,9 +197,9 @@
return ResponseData.error("添加人脸分组失败");
}
JSONObject dataJson = (JSONObject) resultJson.get("data");
- String code = (String) dataJson.get("indexCode");
- String name = (String) dataJson.get("name");
- String description = (String) dataJson.get("description");
+ String code = String.valueOf(dataJson.get("indexCode"));
+ String name = String.valueOf(dataJson.get("name"));
+ String description = String.valueOf(dataJson.get("description"));
HikFaceGroupInfo hikFaceGroupInfo = new HikFaceGroupInfo();
hikFaceGroupInfo.setFaceGroupCode(code);
hikFaceGroupInfo.setFaceGroupName(name);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/dao/AttendanceInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/dao/AttendanceInfoMapper.java
new file mode 100644
index 0000000..f9e793e
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/dao/AttendanceInfoMapper.java
@@ -0,0 +1,29 @@
+package com.casic.missiles.modular.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.dto.statistics.AttendanceRatioDTO;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:53
+ */
+@Mapper
+public interface AttendanceInfoMapper extends BaseMapper {
+ List getAttendanceInfoListPage(@Param("page") Page page, StaffInfoRequest attendanceInfoRequest);
+
+ AttendanceInfo selectByCodeAndDate(@Param("staffCode") String staffCode);
+
+ List getCountByTypeAndDateForWeek(@Param("staffType")String staffType);
+
+ List getCountByTypeAndDateForMonth(@Param("staffType")String staffType);
+
+ List getCountByTypeAndDateForYear(@Param("staffType")String staffType);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/dao/CaseInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/dao/CaseInfoMapper.java
index aa6795d..8b9e67c 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/dao/CaseInfoMapper.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/dao/CaseInfoMapper.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.modular.dto.CaseInfoRequest;
+import com.casic.missiles.modular.dto.statistics.*;
import com.casic.missiles.modular.model.CaseInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -20,4 +21,20 @@
List getCaseInfoListPage(@Param("page") Page page, CaseInfoRequest caseInfoRequest);
int updateStatusById(CaseInfoRequest caseInfoRequest);
+
+ List selectByLevelAndMonth(@Param("year") String year);
+
+ List selectByCategoryLevel();
+
+ List selectByHazardLevel();
+
+ List selectByPosition(@Param("position") String position);
+
+ Integer selectCountByMonth(@Param("year") String year, @Param("month") String month);
+
+ List selectCountByMonthAndDay(@Param("year") String year, @Param("month") String month);
+
+ List selectPreMonthCountByYear(@Param("year") String year);
+
+ List selectPreWeekCountByYear(@Param("year") String year);
}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 67a92aa..70883f0 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -66,6 +66,10 @@
casic-export-support
${extension.version}
+
+ org.springframework.data
+ spring-data-redis
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
new file mode 100644
index 0000000..4a73087
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/aspect/FrontLogAspect.java
@@ -0,0 +1,78 @@
+package com.casic.missiles.modular.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.model.response.ResponseData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * @Description: Controller层统一日志
+ * @Author: wangpeng
+ * @Date: 2022/8/4 9:03
+ */
+@Aspect
+@Component
+@Slf4j
+@Order(Integer.MIN_VALUE)
+public class FrontLogAspect {
+ @Pointcut("execution(* com.casic.missiles.modular.controller..*.*(..))")
+ public void point() {
+ }
+
+ @Around("point()")
+ public Object aroundCheck(ProceedingJoinPoint joinPoint) throws Throwable {
+// String requestId = UUID.randomUUID().toString().replace("-", "");
+// MDC.put("requestId", requestId);
+ long start = System.currentTimeMillis();
+ Object result;
+ String methodName = joinPoint.getSignature().getName();
+ Class> classTarget = joinPoint.getTarget().getClass();
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ try {
+ String args;
+ if ("GET".equals(request.getMethod())) {
+ args = request.getQueryString();
+ } else {
+ Object[] param = joinPoint.getArgs();
+ if (param != null && param.length > 0) {
+ args = JSON.toJSONString(param[0]);
+ } else {
+ args = "";
+ }
+ }
+ log.info("ThreadID:{},MethodName:{},RequestURI:{},Param:{},url:{}",
+ Thread.currentThread().getId(),
+ classTarget.getName() + "." + methodName, request.getRequestURI(), JSONObject.toJSONString(args), request.getRequestURI());
+ result = joinPoint.proceed();
+ long duration = System.currentTimeMillis() - start;
+ log.info("ThreadID:{},MethodName:{},Response:{},TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, JSONObject.toJSONString(result), duration + "ms", request.getRequestURI());
+
+ return result;
+ } catch (Throwable e) {
+ //添加异常抛出 主要是用于全局异常捕获处理
+ if (e instanceof ConstraintViolationException) {
+ throw e;
+ }
+ long duration = System.currentTimeMillis() - start;
+ result = ResponseData.error("系统异常");
+ log.error("ThreadID:{},MethodName:{},Exception:{},Response:{}, TimeCost:{},url:{}",
+ Thread.currentThread().getId(), classTarget.getName() + "." + methodName, ExceptionUtils.getStackTrace(e), result, duration + "ms", request.getRequestURI());
+ return result;
+ }
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
new file mode 100644
index 0000000..1958fae
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/async/ScheduleConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.async;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * @Description: 各定时任务异步执行
+ * @Author: wangpeng
+ * @Date: 2022/8/5 9:46
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
new file mode 100644
index 0000000..60f1d6b
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/AccessGroupConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/8/2 15:52
+ */
+@Data
+@Component
+@ConfigurationProperties("accessgroup")
+public class AccessGroupConfig {
+ private HashMap> configMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
new file mode 100644
index 0000000..f9c7354
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/config/CaseConfig.java
@@ -0,0 +1,20 @@
+package com.casic.missiles.modular.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @Description: 事件与设备关系配置
+ * @Author: wangpeng
+ * @Date: 2022/7/28 11:32
+ */
+@Data
+@Component
+@ConfigurationProperties("case")
+public class CaseConfig {
+ private HashMap> devMap;
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
new file mode 100644
index 0000000..bf8c58c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/AttendanceController.java
@@ -0,0 +1,39 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import com.casic.missiles.modular.service.AttendanceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 考勤管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:26
+ */
+@Slf4j
+@RestController
+@RequestMapping("/attendanceInfo")
+public class AttendanceController extends ExportController {
+ @Autowired
+ private AttendanceService attendanceService;
+
+ /**
+ * 考勤列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody StaffInfoRequest staffInfoRequest) {
+ Page page = PageFactory.defaultPage();
+ List attendanceInfos = attendanceService.attendanceInfoListPage(page, staffInfoRequest);
+ page.setRecords(attendanceInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
index bd2b575..0e4fbfc 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DeviceController.java
@@ -206,7 +206,6 @@
@PostMapping("/gateGroup/statusControl")
@ResponseBody
public Object gateStatusControl(@RequestBody GateGroupDTO gateGroupDTO) {
- // TODO: 2022/7/27 海康门禁点反控需要门禁点唯一标识,需到现场导出海康一份再录入咱们平台使用(与设备编号关联上)
// TODO: 2022/7/27 门禁状态字典要与海康的状态相同
//0: 常开
//1: 门闭
@@ -219,10 +218,12 @@
log.info("闸机通道状态控制:不存在分组的闸机编号,request:{}", gateGroupDTO);
return ResponseData.error("不存在分组下的闸机编号");
}
+ //根据闸机编号列表获取门禁点唯一标识列表
+ List indexCodes = deviceInfoService.selectIndexCodesByCodes(deviceCodes);
//海康门禁点反控
DoorControlRequest doorControlRequest = new DoorControlRequest();
//需根据设备编号获取到对应的门禁点唯一标识
-// doorControlRequest.setDoorIndexCodes();
+ doorControlRequest.setDoorIndexCodes(indexCodes);
doorControlRequest.setControlType(Integer.valueOf(gateGroupDTO.getStatus()));
String body = JSONObject.toJSONString(deviceCodes);
String resultStr = HikUtil.hikApi(HikUri.DOOR_CONTROL, body);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
index 1a306ef..18ef0f5 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/FireEquipController.java
@@ -54,6 +54,7 @@
*/
@PostMapping("/{operation}")
@ResponseBody
+// @BussinessLog("消防器材增删改")
public Object operation(@PathVariable(name = "operation") String operateType, @RequestBody FireEquipInfo fireEquipInfo) {
if(OperateTypeEnum.ADD.getOperateType().equals(operateType)){
return fireEquipService.addFireEquipInfo(fireEquipInfo);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
index a7cf1f8..d86dc30 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorApplyController.java
@@ -30,7 +30,6 @@
@RestController
@RequestMapping("/applicationInfo")
public class VisitorApplyController extends ExportController {
- // TODO: 2022/7/23 访客申请增删改同时要增删改海康的预约,修改访客预约v2接口,取消操作使用取消访客预约
@Autowired
private VisitorApplyService visitorApplyService;
/**
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
new file mode 100644
index 0000000..14439eb
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/VisitorController.java
@@ -0,0 +1,49 @@
+package com.casic.missiles.modular.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.ExportController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dto.VisitorRequest;
+import com.casic.missiles.modular.model.VisitInfo;
+import com.casic.missiles.modular.service.VisitService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @Description: 访客管理Controller
+ * @Author: wangpeng
+ * @Date: 2022/7/28 19:16
+ */
+@Slf4j
+@RestController
+@RequestMapping("/visitInfo")
+public class VisitorController extends ExportController {
+ @Autowired
+ private VisitService visitService;
+
+ /**
+ * 访问记录列表(分页)
+ */
+ @PostMapping("/listPage")
+ @ResponseBody
+ public Object listPage(@RequestBody VisitorRequest visitorRequest) {
+ Page page = PageFactory.defaultPage();
+ List visitorApplies = visitService.visitInfoListPage(page, visitorRequest);
+ page.setRecords(visitorApplies);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 访问记录详情
+ */
+ @PostMapping("/detail")
+ @ResponseBody
+ public Object detail(@RequestBody VisitorRequest visitorRequest) {
+ VisitInfo visitInfo = visitService.visitInfoDetail(visitorRequest.getId());
+ return ResponseData.success(visitInfo);
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
new file mode 100644
index 0000000..4b92489
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/CockpitController.java
@@ -0,0 +1,171 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.casic.missiles.core.application.service.AbstractDictService;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.CategoryLevelMapper;
+import com.casic.missiles.modular.dao.DeviceInfoMapper;
+import com.casic.missiles.modular.dao.FireEquipInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.enums.SecurityEventDict;
+import com.casic.missiles.modular.model.CaseCategoryLevel;
+import com.casic.missiles.modular.model.CaseInfo;
+import com.casic.missiles.modular.redis.RedisUtil;
+import com.casic.missiles.modular.redis.key.CacheKeys;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱驻留页面-前端主动查询相关
+ * @Author: wangpeng
+ * @Date: 2022/7/27 19:46
+ */
+@Slf4j
+@RestController
+@RequestMapping("/cockpit")
+public class CockpitController {
+ @Autowired
+ private RedisUtil redisUtil;
+
+ @Autowired
+ private AbstractDictService dictService;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private CategoryLevelMapper categoryLevelMapper;
+
+ @Autowired
+ private DeviceInfoMapper deviceInfoMapper;
+
+ @Autowired
+ private FireEquipInfoMapper fireEquipInfoMapper;
+
+ /**
+ * 重点区域威胁事件历史统计,计算每个月的各级别事件的数量
+ */
+ @PostMapping("/case/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaEventStatistic(@RequestBody MonthAndLevelGroupDTO monthAndLevelGroupDTO) {
+ Object o = redisUtil.get(CacheKeys.MONTH_STATISTIC_KEY);
+ List list = JSONArray.parseArray(String.valueOf(o), MonthAndLevelGroupDTO.class);
+ if(!CollectionUtils.isEmpty(list)){
+ Map> resultMap = list.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ return ResponseData.success(resultMap);
+ }
+ //查询数据,放入redis
+ List monthAndLevelGroup = caseInfoMapper.selectByLevelAndMonth(monthAndLevelGroupDTO.getYear());
+ Map> resultMap = monthAndLevelGroup.stream().collect(Collectors.groupingBy(MonthAndLevelGroupDTO::getMonth));
+ //设置过期时间为每月1号0点
+ LocalDateTime midnight = LocalDateTime.now().plusMonths(1).withDayOfMonth(1).withHour(0)
+ .withMinute(0).withSecond(0).withNano(0);
+ long between = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
+ redisUtil.set(CacheKeys.MONTH_STATISTIC_KEY, JSONObject.toJSONString(monthAndLevelGroup), between);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安防事件类别统计
+ */
+ @GetMapping("/case/categoryStatistics")
+ @ResponseBody
+ public Object eventCategoryStatistics() {
+ List categoryLevelGroup = caseInfoMapper.selectByCategoryLevel();
+ categoryLevelGroup.forEach(group -> {
+ CaseCategoryLevel caseCategoryLevel = categoryLevelMapper.getCaseCategoryLevel(group.getCategoryLevelCode());
+ group.setCategoryLevelName(caseCategoryLevel.getName());
+ });
+ return ResponseData.success(categoryLevelGroup);
+ }
+
+ /**
+ * 消防器材类别统计
+ */
+ @GetMapping("/device/fireEquipStatistics")
+ @ResponseBody
+ public Object fireEquipStatistics() {
+ List equipTypeGroup = fireEquipInfoMapper.selectByEquipType();
+ equipTypeGroup.forEach(group -> {
+ String equipTypeName = dictService.getDictNameByCode(SecurityEventDict.EQUIP_TYPE, group.getEquipTypeCode());
+ group.setEquipTypeName(equipTypeName);
+ });
+ return ResponseData.success(equipTypeGroup);
+ }
+
+ /**
+ * 闸机速通门统计-设备状态分组计算数量,devType传闸机字典key
+ * 视频频监控摄像机统计-设备状态分组计算数量,devType传摄像头字典key
+ */
+ @PostMapping("/device/statistics")
+ @ResponseBody
+ public Object GateStatusStatistics(@RequestBody GateStatusGroupDTO gateStatusGroupDTO) {
+ List gateStatusGroup = deviceInfoMapper.selectByType(gateStatusGroupDTO.getDevType());
+ HashMap resultMap = new HashMap<>();
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = gateStatusGroup.stream().collect(Collectors.summarizingInt(GateStatusGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("无该类设备信息");
+ }
+ gateStatusGroup.forEach(group -> {
+ String devStatus = dictService.getDictNameByCode(SecurityEventDict.DEVICE_STATUS, group.getStatus());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ resultMap.put(devStatus, result+"%");
+ });
+ resultMap.put("总", sum);
+ return ResponseData.success(resultMap);
+ }
+
+ /**
+ * 安全防护分析,设备加所在楼层评分,计算规则:发生安防事件*类别权重*级别权重算分
+ * 优先级3
+ */
+ @PostMapping("/device/securityScore")
+ @ResponseBody
+ public Object SecurityScore(@RequestBody SecurityScoreDTO securityScoreDTO) {
+ //按发生事件的设备所在的area划分计算评分,当天发生的事件
+ String position = securityScoreDTO.getPosition();
+ List caseInfos = caseInfoMapper.selectByPosition(position);
+ //查询各危险级别权重、各类别权重,放入map,避免循环中多次查数据库
+
+ List securityScoreDTOs = new ArrayList<>();
+ caseInfos.forEach(caseInfo -> {
+ SecurityScoreDTO securityScoreDTO1 = new SecurityScoreDTO();
+ securityScoreDTO1.setArea(caseInfo.getArea());
+ // TODO: 2022/8/4 楼层评分计算根据产品定义调整
+// caseInfo.get
+// securityScoreDTO1.setScore();
+ });
+
+ return null;
+ }
+
+ /**
+ * 安防事件时域性频次统计,统计每月安防事件个数
+ */
+ @PostMapping("/device/securityFrequency")
+ @ResponseBody
+ public Object SecurityFrequency(@RequestBody SecurityFrequencyDTO securityFrequencyDTO) {
+ String year = securityFrequencyDTO.getYear();
+ String month = securityFrequencyDTO.getMonth();
+ Integer quantity = caseInfoMapper.selectCountByMonth(year, month);
+ securityFrequencyDTO.setQuantity(quantity);
+ return ResponseData.success(securityFrequencyDTO);
+ }
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
new file mode 100644
index 0000000..ba584ee
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/cockpit/PropertyManageController.java
@@ -0,0 +1,204 @@
+package com.casic.missiles.modular.controller.cockpit;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.dao.AttendanceInfoMapper;
+import com.casic.missiles.modular.dao.CaseInfoMapper;
+import com.casic.missiles.modular.dao.HazardLevelMapper;
+import com.casic.missiles.modular.dao.StaffInfoMapper;
+import com.casic.missiles.modular.dto.statistics.*;
+import com.casic.missiles.modular.model.CaseHazardLevel;
+import com.casic.missiles.modular.model.StaffInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.NumberFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 驾驶舱二级页面-物管信息
+ * @Author: wangpeng
+ * @Date: 2022/8/3 15:05
+ */
+@Slf4j
+@RestController
+@RequestMapping("/propertyManage")
+public class PropertyManageController {
+ @Autowired
+ private AttendanceInfoMapper attendanceInfoMapper;
+
+ @Autowired
+ private StaffInfoMapper staffInfoMapper;
+
+ @Autowired
+ private CaseInfoMapper caseInfoMapper;
+
+ @Autowired
+ private HazardLevelMapper hazardLevelMapper;
+
+ /**
+ * 安防事件时域频次统计,每月的每天安防事件个数
+ * 月维度:展示每个月的每天的数据
+ */
+ @PostMapping("/case/time/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaTimeStatistic(@RequestBody MonthAndDayGroupDTO monthAndDayGroupDTO) {
+ String year = monthAndDayGroupDTO.getYear();
+ String month = monthAndDayGroupDTO.getMonth();
+ List resultList = caseInfoMapper.selectCountByMonthAndDay(year, month);
+ resultList.forEach(result -> {
+ result.setYear(year);
+ result.setMonth(month);
+ });
+ return ResponseData.success(resultList);
+ }
+
+ /**
+ * 安防事件频域频次统计,每年的每月/每周各级别安防事件个数
+ * 年维度:展示平均每个月和每周的数据
+ */
+ @PostMapping("/case/frequency/keyAreaStatistic")
+ @ResponseBody
+ public Object keyAreaFrequencyStatistic(@RequestBody AvgMonthAndWeekGroupDTO avgMonthAndWeekGroupDTO) {
+ String year = avgMonthAndWeekGroupDTO.getYear();
+ List monthList = caseInfoMapper.selectPreMonthCountByYear(year);
+ Map> collect = monthList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ HashMap strAvgMap = new HashMap<>();
+ for (String key : collect.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ //若年份是本年,则使用个安防级别数量/当前月份数
+ //若不是本年,除数为12
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ monthAndWeekDTO.setMonthQuantity(sum / DateUtil.thisMonth());
+// monthAndWeekDTO.setLevelName();
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ monthAndWeekDTO.setMonthQuantity(sum / 12);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+
+ List weekList = caseInfoMapper.selectPreWeekCountByYear(year);
+ Map> collect1 = weekList.stream().collect(Collectors.groupingBy(PreMonthOrWeekCaseDTO::getHazardLevelCode));
+ for (String key : collect1.keySet()) {
+ List preMonthOrWeekCaseDTOS = collect.get(key);
+ int sum = preMonthOrWeekCaseDTOS.stream().mapToInt(PreMonthOrWeekCaseDTO::getQuantity).sum();
+ if(year.equals(String.valueOf(DateUtil.thisYear()))){
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / DateUtil.thisWeekOfYear());
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }else{
+ if(!Objects.isNull(strAvgMap.get(key))){
+ MonthAndWeekDTO monthAndWeekDTO = strAvgMap.get(key);
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }else{
+ MonthAndWeekDTO monthAndWeekDTO = new MonthAndWeekDTO();
+ monthAndWeekDTO.setWeekQuantity(sum / 52);
+ strAvgMap.put(key, monthAndWeekDTO);
+ }
+ }
+ }
+ avgMonthAndWeekGroupDTO.setMap(strAvgMap);
+ return ResponseData.success(avgMonthAndWeekGroupDTO);
+ }
+
+ /**
+ * 员工出勤率,优先级3
+ * 物业/安保人员出勤人数除以物业/安保人员总数,一天有一次记录就算考勤
+ */
+ @PostMapping("/staff/attendanceRatio")
+ @ResponseBody
+ public Object attendanceRatio(@RequestBody AttendanceRatioDTO attendanceRatioDTO) {
+ //员工类型字典key
+ String staffType = attendanceRatioDTO.getStaffType();
+ String dateDimension = attendanceRatioDTO.getDateDimension();
+ List attendanceRatioDTOS = new ArrayList<>();
+ //考勤的人数,按员工类型和单次考勤过滤
+ if("week".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForWeek(staffType);
+ }else if("month".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForMonth(staffType);
+ }else if("year".equals(dateDimension)){
+ attendanceRatioDTOS = attendanceInfoMapper.getCountByTypeAndDateForYear(staffType);
+ }
+ if(CollectionUtils.isEmpty(attendanceRatioDTOS)){
+ return ResponseData.error("该查询条件下,无员工出勤数据!");
+ }
+
+ //该类型员工总数
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("staff_type", staffType);
+ Integer sum = staffInfoMapper.selectCount(wrapper);
+ if(sum <= 0){
+ return ResponseData.error("该查询条件下,员工管理中无该类型员工数据!");
+ }
+
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ //计算出勤率
+ attendanceRatioDTOS.forEach(attendanceRatio -> {
+ attendanceRatio.setDateDimension(dateDimension);
+ attendanceRatio.setStaffType(staffType);
+ String ratio = numberFormat.format((float) attendanceRatio.getQuantity() / (float) sum * 100);
+ attendanceRatio.setAttendanceRatio(ratio+"%");
+ });
+ return ResponseData.success(attendanceRatioDTOS);
+ }
+
+ /**
+ * 员工考勤人数变化,功能待定
+ */
+
+ /**
+ * 重点区域安防事态评估,功能待定
+ */
+
+ /**
+ * 重点区域威胁事件类型统计,优先级2
+ */
+ @GetMapping("/case/hazardLevelStatistics")
+ @ResponseBody
+ public Object HazardLevelStatistics() {
+ List hazardLevelGroup = caseInfoMapper.selectByHazardLevel();
+ if(CollectionUtils.isEmpty(hazardLevelGroup)){
+ log.info("重点区域威胁事件类型统计,无安防事件");
+ return ResponseData.error("无安防事件发生!");
+ }
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ // 设置精确到小数点后2位
+ numberFormat.setMaximumFractionDigits(2);
+ long sum = hazardLevelGroup.stream().collect(Collectors.summarizingInt(HazardLevelGroupDTO::getQuantity)).getSum();
+ if(sum <= 0){
+ return ResponseData.error("安防事件总数为0");
+ }
+ hazardLevelGroup.forEach(group -> {
+ CaseHazardLevel caseHazardLevel = hazardLevelMapper.getCaseHazardLevel(group.getLevelCode());
+ group.setLevelName(caseHazardLevel.getName());
+ String result = numberFormat.format((float) group.getQuantity() / (float) sum * 100);
+ group.setLevelRatio(result+"%");
+ });
+ HazardLevelGroupResponse hazardLevelGroupResponse = new HazardLevelGroupResponse();
+ hazardLevelGroupResponse.setHazardLevelGroup(hazardLevelGroup);
+ hazardLevelGroupResponse.setQuantity(sum);
+ return ResponseData.success(hazardLevelGroupResponse);
+ }
+
+ /**
+ * 设备状态计算系数和评判,优先级3,需确认设备恢复时间是否可以获取
+ */
+
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
index 15d0e30..4cad1dd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/hik/HikController.java
@@ -1,20 +1,26 @@
package com.casic.missiles.modular.controller.hik;
-import cn.hutool.core.date.DateTime;
-import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.casic.missiles.model.response.ResponseData;
-import com.casic.missiles.modular.dto.hik.*;
+import com.casic.missiles.modular.dao.HikFaceGroupInfoMapper;
+import com.casic.missiles.modular.dto.hik.EventSubscribeRequest;
+import com.casic.missiles.modular.dto.hik.FaceGroupAdditionRequest;
+import com.casic.missiles.modular.dto.hik.HikRecvEvent;
+import com.casic.missiles.modular.dto.hik.OrgBatchAdd;
import com.casic.missiles.modular.enums.HikUri;
import com.casic.missiles.modular.enums.SecurityEventType;
import com.casic.missiles.modular.model.CaseInfo;
import com.casic.missiles.modular.model.HikFaceGroupInfo;
import com.casic.missiles.modular.service.CaseInfoService;
import com.casic.missiles.modular.service.HikFaceGroupInfoService;
+import com.casic.missiles.modular.service.HikService;
import com.casic.missiles.modular.util.CaseInfoFactoryUtil;
import com.casic.missiles.modular.util.HikUtil;
+import com.casic.missiles.modular.util.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@@ -23,6 +29,7 @@
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* @Description: 海康事件Controller
@@ -43,9 +50,15 @@
@Autowired
private HikFaceGroupInfoService hikFaceGroupInfoService;
+ @Autowired
+ private HikService hikService;
+
@Value("${server.port}")
private int serverPort;
+ @Autowired
+ private HikFaceGroupInfoMapper hikFaceGroupInfoMapper;
+
/**
* 海康事件订阅
*/
@@ -86,34 +99,87 @@
public Object eventRcv(@RequestBody HikRecvEvent hikRecvEvent) {
//1、接收所需事件类型
Long eventType = hikRecvEvent.getEventType();
+ log.info("接收到安防事件类型为:{}", eventType);
CaseInfo caseInfo = caseInfoFactoryUtil.getCaseInfo(eventType);
+ //接收到不关心事件直接返回
+ if(Objects.isNull(caseInfo)){
+ return ResponseData.success();
+ }
//2、不同事件不同处理,caseInfoFactoryUtil已设置好事件基础定义信息
- // 再为事件添加状态(未解决)、设备编码、设备名称、位置、区域、时间
- // TODO: 2022/7/21 异步处理事件
- // TODO: 2022/7/21 海康安装设备后,应该有设备和位置的对应关系表,可维护在设备表中,获取位置和区域信息
- // TODO: 2022/7/21 位置和区域的概念
- // TODO: 2022/7/21 kafka
+ // 再为事件添加状态、设备编码、设备名称、位置、区域、时间
+ // 异步处理事件
+ ThreadPoolUtil.executorService.execute(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ CaseHandle(hikRecvEvent, eventType, caseInfo);
+ }
+ }));
+
+ return null;
+ }
+
+ private void CaseHandle(HikRecvEvent hikRecvEvent, Long eventType, CaseInfo caseInfo) {
JSONArray eventArray = hikRecvEvent.getEventArray();
- ArrayList caseInfos = new ArrayList<>();
+ List caseInfos = new ArrayList<>();
while (eventArray.stream().iterator().hasNext()) {
- // TODO: 2022/7/23 设备过滤,仅将预设置的设备的事件入库,可建立一个设备与事件的表或放入配置中
+ CaseInfo caseInfo1 = new CaseInfo();
+ BeanUtils.copyProperties(caseInfo, caseInfo1);
JSONObject event = (JSONObject) eventArray.stream().iterator().next();
- //ISO8601标准时间格式
- //示例:2018-08-15T 15:53:47.000+08:00
- String happenTimeISO = (String) event.get("happenTime");
- DateTime parse = DateUtil.parse(happenTimeISO);
- String happenTime = DateUtil.formatDateTime(parse);
- caseInfo.setHappenTime(happenTime); //发生时间
- // caseInfo.setStatus(); //事件状态
- // caseInfo.setDeviceCode(); //设备code
- // caseInfo.setDevName(); //设备名
- // caseInfo.setPosition(); //事件位置
- // caseInfo.setAreaName(); //区域
- caseInfos.add(caseInfo);
+ //5种事件进行不同处理
+ if(SecurityEventType.KEY_PERSONNEL_IDENTIFY_EVENT == eventType){
+ //判断所属人脸分组
+ JSONObject data = (JSONObject) event.get("data");
+ JSONObject faceRecognitionResult = (JSONObject) data.get("faceRecognitionResult");
+ JSONArray faceMatchArr = (JSONArray) faceRecognitionResult.get("faceMatch");
+ JSONObject faceMatch = (JSONObject) faceMatchArr.get(0);
+ String faceGroupCode = faceMatch.getString("faceGroupCode");
+ if (StringUtils.isEmpty(faceGroupCode)) {
+ return;
+ }
+ HikFaceGroupInfo blackListGroup = hikFaceGroupInfoMapper.selectByName("blackList");
+ HikFaceGroupInfo propertyPersonnelGroup = hikFaceGroupInfoMapper.selectByName("propertyPersonnel");
+ HikFaceGroupInfo securityPersonnelGroup = hikFaceGroupInfoMapper.selectByName("securityPersonnel");
+ if (faceGroupCode.equals(blackListGroup.getFaceGroupCode())) {
+ //黑名单分组处理
+ caseInfo1 = hikService.blackListHandle(event, caseInfo1);
+ }else if(faceGroupCode.equals(propertyPersonnelGroup.getFaceGroupCode())){
+ //考勤分组处理-物业人员,添加到考勤表
+ hikService.propertyAttendanceHandle(event);
+ }else if(faceGroupCode.equals(securityPersonnelGroup.getFaceGroupCode())){
+ //考勤分组处理-安保人员,添加到考勤表
+ hikService.securityPersonnelHandle(event);
+ }else {
+ return;
+ }
+
+ }else if(SecurityEventType.PERSONNEL_DEMOBILIZED_EVENT == eventType){
+ //离岗事件处理
+ caseInfo1 = hikService.demobilizedHandle(event, caseInfo1);
+ }else if(SecurityEventType.PERSONNEL_GATHER_EVENT == eventType){
+ //人员聚集事件处理
+ caseInfo1 = hikService.personGatherHandle(event, caseInfo1);
+ }else if(SecurityEventType.MONITORING_POINT_OFFLINE == eventType){
+ //监控点离线事件处理
+ caseInfo1 = hikService.monitorPointOfflineHandle(event, caseInfo1);
+ }else if(SecurityEventType.DEVICE_OFFLINE == eventType){
+ //装置离线事件处理
+ caseInfo1 = hikService.deviceOfflineHandle(event, caseInfo1);
+ }else if(SecurityEventType.VISITOR_REGISTER == eventType){
+ //记录访客登记记录,添加到访客记录表
+ hikService.visitorRegisterHandler(event);
+ }else if(SecurityEventType.VISITOR_CHECKOUT == eventType){
+ //记录访客签离记录
+ hikService.visitorCheckOutHandler(event);
+ }
+ if(!Objects.isNull(caseInfo1) && !StringUtils.isEmpty(caseInfo1.getHappenTime())){
+ caseInfos.add(caseInfo1);
+ }
}
//3、安防事件入库
- caseInfoService.addCaseInfoBatch(caseInfos);
- return null;
+ if(!caseInfoService.insertCaseInfoBatch(caseInfos)){
+ log.error("安防事件批量入库异常");
+ }
+ return;
}
/**
@@ -131,9 +197,9 @@
return ResponseData.error("添加人脸分组失败");
}
JSONObject dataJson = (JSONObject) resultJson.get("data");
- String code = (String) dataJson.get("indexCode");
- String name = (String) dataJson.get("name");
- String description = (String) dataJson.get("description");
+ String code = String.valueOf(dataJson.get("indexCode"));
+ String name = String.valueOf(dataJson.get("name"));
+ String description = String.valueOf(dataJson.get("description"));
HikFaceGroupInfo hikFaceGroupInfo = new HikFaceGroupInfo();
hikFaceGroupInfo.setFaceGroupCode(code);
hikFaceGroupInfo.setFaceGroupName(name);
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/dao/AttendanceInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/dao/AttendanceInfoMapper.java
new file mode 100644
index 0000000..f9e793e
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/dao/AttendanceInfoMapper.java
@@ -0,0 +1,29 @@
+package com.casic.missiles.modular.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.dto.StaffInfoRequest;
+import com.casic.missiles.modular.dto.statistics.AttendanceRatioDTO;
+import com.casic.missiles.modular.model.AttendanceInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author: wangpeng
+ * @Date: 2022/7/28 16:53
+ */
+@Mapper
+public interface AttendanceInfoMapper extends BaseMapper {
+ List getAttendanceInfoListPage(@Param("page") Page page, StaffInfoRequest attendanceInfoRequest);
+
+ AttendanceInfo selectByCodeAndDate(@Param("staffCode") String staffCode);
+
+ List getCountByTypeAndDateForWeek(@Param("staffType")String staffType);
+
+ List getCountByTypeAndDateForMonth(@Param("staffType")String staffType);
+
+ List getCountByTypeAndDateForYear(@Param("staffType")String staffType);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/dao/CaseInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/dao/CaseInfoMapper.java
index aa6795d..8b9e67c 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/dao/CaseInfoMapper.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/dao/CaseInfoMapper.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.modular.dto.CaseInfoRequest;
+import com.casic.missiles.modular.dto.statistics.*;
import com.casic.missiles.modular.model.CaseInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -20,4 +21,20 @@
List getCaseInfoListPage(@Param("page") Page