Browse Source

Merge branch 'v2.2.0' of http://39.106.8.246:3003/apm/energy-alarm-service into v2.2.0

lixing 3 years ago
parent
commit
e5fc8b749d
77 changed files with 5625 additions and 1 deletions
  1. 27 0
      src/main/java/com/persagy/apm/dmpalarm/client/PhysicalWorldClient.java
  2. 34 0
      src/main/java/com/persagy/apm/dmpalarm/client/PhysicalWorldFallBackFactory.java
  3. 44 0
      src/main/java/com/persagy/apm/dmpalarm/config/DmpMessageAspect.java
  4. 84 0
      src/main/java/com/persagy/apm/dmpalarm/config/DmpParameterStorage.java
  5. 34 0
      src/main/java/com/persagy/apm/dmpalarm/config/GlobalExceptionHandler.java
  6. 76 0
      src/main/java/com/persagy/apm/dmpalarm/config/MybatisJsonHandler.java
  7. 44 0
      src/main/java/com/persagy/apm/dmpalarm/config/MybatisPlusTableNameConfig.java
  8. 68 0
      src/main/java/com/persagy/apm/dmpalarm/config/QueryAspect.java
  9. 123 0
      src/main/java/com/persagy/apm/dmpalarm/config/RequestLogAspect.java
  10. 60 0
      src/main/java/com/persagy/apm/dmpalarm/config/RequestParamCheckAspect.java
  11. 74 0
      src/main/java/com/persagy/apm/dmpalarm/config/TableNameAspect.java
  12. 58 0
      src/main/java/com/persagy/apm/dmpalarm/config/WebConfig.java
  13. 59 0
      src/main/java/com/persagy/apm/dmpalarm/controller/AlarmCommentController.java
  14. 109 0
      src/main/java/com/persagy/apm/dmpalarm/controller/AlarmConfigController.java
  15. 48 0
      src/main/java/com/persagy/apm/dmpalarm/controller/AlarmItemController.java
  16. 43 0
      src/main/java/com/persagy/apm/dmpalarm/controller/AlarmLogController.java
  17. 54 0
      src/main/java/com/persagy/apm/dmpalarm/controller/AlarmRecordController.java
  18. 52 0
      src/main/java/com/persagy/apm/dmpalarm/controller/AlarmTargetController.java
  19. 176 0
      src/main/java/com/persagy/apm/dmpalarm/criteria/CriteriaUtils.java
  20. 97 0
      src/main/java/com/persagy/apm/dmpalarm/criteria/JsonCriteria.java
  21. 15 0
      src/main/java/com/persagy/apm/dmpalarm/dao/AlarmCommentMapper.java
  22. 15 0
      src/main/java/com/persagy/apm/dmpalarm/dao/AlarmConfigMapper.java
  23. 15 0
      src/main/java/com/persagy/apm/dmpalarm/dao/AlarmItemMapper.java
  24. 15 0
      src/main/java/com/persagy/apm/dmpalarm/dao/AlarmLogMapper.java
  25. 16 0
      src/main/java/com/persagy/apm/dmpalarm/dao/AlarmRecordMapper.java
  26. 15 0
      src/main/java/com/persagy/apm/dmpalarm/dao/AlarmTargetMapper.java
  27. 12 0
      src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmListType.java
  28. 14 0
      src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmLogType.java
  29. 35 0
      src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmMessageType.java
  30. 13 0
      src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmRecordWithColumns.java
  31. 26 0
      src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmState.java
  32. 28 0
      src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmTreatState.java
  33. 41 0
      src/main/java/com/persagy/apm/dmpalarm/jms/ConsumeMessageThreadPool.java
  34. 127 0
      src/main/java/com/persagy/apm/dmpalarm/jms/JmsConfig.java
  35. 14 0
      src/main/java/com/persagy/apm/dmpalarm/jms/MessageExecutor.java
  36. 99 0
      src/main/java/com/persagy/apm/dmpalarm/jms/MessageProcesser.java
  37. 87 0
      src/main/java/com/persagy/apm/dmpalarm/jms/RabbitmqConfig.java
  38. 66 0
      src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmConfigBatchCreateExecutor.java
  39. 35 0
      src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmItemCreateExecutor.java
  40. 44 0
      src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmItemUpdateExecutor.java
  41. 39 0
      src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmTargetCreateExecutor.java
  42. 40 0
      src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmTargetDeleteExecutor.java
  43. 40 0
      src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmTargetUpdateExecutor.java
  44. 42 0
      src/main/java/com/persagy/apm/dmpalarm/jms/executor/InstanceObjectDeleteExecutor.java
  45. 229 0
      src/main/java/com/persagy/apm/dmpalarm/json/JacksonMapper.java
  46. 58 0
      src/main/java/com/persagy/apm/dmpalarm/model/AlarmComment.java
  47. 120 0
      src/main/java/com/persagy/apm/dmpalarm/model/AlarmConfig.java
  48. 81 0
      src/main/java/com/persagy/apm/dmpalarm/model/AlarmItem.java
  49. 47 0
      src/main/java/com/persagy/apm/dmpalarm/model/AlarmLog.java
  50. 104 0
      src/main/java/com/persagy/apm/dmpalarm/model/AlarmRecord.java
  51. 76 0
      src/main/java/com/persagy/apm/dmpalarm/model/AlarmTarget.java
  52. 49 0
      src/main/java/com/persagy/apm/dmpalarm/model/DmpMessage.java
  53. 19 0
      src/main/java/com/persagy/apm/dmpalarm/service/IAlarmCommentService.java
  54. 42 0
      src/main/java/com/persagy/apm/dmpalarm/service/IAlarmConfigService.java
  55. 30 0
      src/main/java/com/persagy/apm/dmpalarm/service/IAlarmItemService.java
  56. 27 0
      src/main/java/com/persagy/apm/dmpalarm/service/IAlarmLogService.java
  57. 24 0
      src/main/java/com/persagy/apm/dmpalarm/service/IAlarmRecordService.java
  58. 37 0
      src/main/java/com/persagy/apm/dmpalarm/service/IAlarmTargetService.java
  59. 11 0
      src/main/java/com/persagy/apm/dmpalarm/service/IPhysicalWorldService.java
  60. 67 0
      src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmCommentServiceImpl.java
  61. 835 0
      src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmConfigServiceImpl.java
  62. 205 0
      src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmItemServiceImpl.java
  63. 119 0
      src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmLogServiceImpl.java
  64. 325 0
      src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmRecordServiceImpl.java
  65. 336 0
      src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmTargetServiceImpl.java
  66. 47 0
      src/main/java/com/persagy/apm/dmpalarm/service/impl/BaseServiceImpl.java
  67. 82 0
      src/main/java/com/persagy/apm/dmpalarm/service/impl/PhysicalWorldServiceImpl.java
  68. 101 0
      src/main/java/com/persagy/apm/dmpalarm/utils/CheckRequiredParam.java
  69. 17 0
      src/main/java/com/persagy/apm/dmpalarm/utils/DatePatternStyle.java
  70. 33 0
      src/main/java/com/persagy/apm/dmpalarm/utils/MD5Utils.java
  71. 32 0
      src/main/java/com/persagy/apm/dmpalarm/utils/SpringUtils.java
  72. 44 0
      src/main/java/com/persagy/apm/dmpalarm/utils/UtilsTools.java
  73. 72 0
      src/main/java/com/persagy/apm/dmpalarm/web/BaseResponse.java
  74. 28 0
      src/main/java/com/persagy/apm/dmpalarm/web/ListResponse.java
  75. 42 0
      src/main/java/com/persagy/apm/dmpalarm/web/MapResponse.java
  76. 28 0
      src/main/java/com/persagy/apm/dmpalarm/web/PagedResponse.java
  77. 1 1
      src/main/resources/db/init/data.sql

+ 27 - 0
src/main/java/com/persagy/apm/dmpalarm/client/PhysicalWorldClient.java

@@ -0,0 +1,27 @@
+package com.persagy.apm.dmpalarm.client;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+/**
+ * @description: 对接物理世界接口
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/10/20 5:04 下午
+ * @version: V1.0
+ **/
+@FeignClient(name = "dmp-rwd", fallbackFactory = PhysicalWorldFallBackFactory.class)
+public interface PhysicalWorldClient {
+
+    @PostMapping("rwd/instance/object/query")
+    public PagedResponse<ObjectNode> queryObj(
+            @RequestParam("projectId") String projectId,
+            @RequestParam("groupCode") String groupCode,
+            @RequestBody JsonCriteria criteria);
+}

+ 34 - 0
src/main/java/com/persagy/apm/dmpalarm/client/PhysicalWorldFallBackFactory.java

@@ -0,0 +1,34 @@
+package com.persagy.apm.dmpalarm.client;
+
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import feign.hystrix.FallbackFactory;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @description:
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/10/26 2:04 下午
+ * @version: V1.0
+ **/
+@Slf4j
+@Component
+public class PhysicalWorldFallBackFactory implements FallbackFactory<PhysicalWorldClient> {
+
+    @Override
+    public PhysicalWorldClient create(Throwable cause) {
+        return new PhysicalWorldClient() {
+            @Override
+            public PagedResponse<ObjectNode> queryObj(String projectId, String groupCode, JsonCriteria criteria) {
+                log.error("物理世界接口请求失败,url: {}, projectId: {}, requestBody: {}", "/instance/object/query", projectId, criteria);
+
+                return null;
+            }
+        };
+    }
+}

+ 44 - 0
src/main/java/com/persagy/apm/dmpalarm/config/DmpMessageAspect.java

@@ -0,0 +1,44 @@
+package com.persagy.apm.dmpalarm.config;
+
+import java.util.List;
+
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.persagy.apm.dmpalarm.jms.MessageProcesser;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+
+/**
+ * @author: yaoll
+ * @date: 2020-10-22
+ * @verison: 1.0
+ */
+@Aspect
+@Component
+public class DmpMessageAspect {
+	@Autowired
+	private MessageProcesser messageProcesser;
+
+	@Pointcut("execution(public * com.persagy.apm.*.controller.*.*(..))")
+	public void controllerPoint() {
+	}
+
+	@AfterReturning(returning = "ret", pointcut = "controllerPoint()")
+	public void doAfterReturning(Object ret) {
+		if (ret != null) {
+			if (ret instanceof BaseResponse) {
+				BaseResponse<?> resp = (BaseResponse<?>) ret;
+				List<DmpMessage> messageList = resp.getMessageList();
+				if (messageList != null && messageList.size() > 0) {
+					for (DmpMessage message : messageList) {
+						messageProcesser.convertAndSend(message);
+					}
+				}
+			}
+		}
+	}
+}

+ 84 - 0
src/main/java/com/persagy/apm/dmpalarm/config/DmpParameterStorage.java

@@ -0,0 +1,84 @@
+package com.persagy.apm.dmpalarm.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-22
+ * @verison: 1.0
+ */
+public class DmpParameterStorage extends HandlerInterceptorAdapter {
+
+	private static final ThreadLocal<ParameterData> storage = new ThreadLocal<>();
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+		ParameterData data = new ParameterData();
+		data.groupCode = request.getParameter("groupCode");
+		data.schemaId = request.getParameter("schemaId");
+		data.projectId = request.getParameter("projectId");
+		data.appId = request.getParameter("appId");
+		data.userId = request.getParameter("userId");
+
+		storage.set(data);
+		return true;
+	}
+
+	@Override
+	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+		storage.remove();
+	}
+
+	@Override
+	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+		storage.remove();
+	}
+
+	@Setter
+	@Getter
+	public static class ParameterData {
+		private String groupCode;
+		private String schemaId;
+		private String projectId;
+		private String appId;
+		private String userId;
+	}
+
+	public static void set(ParameterData data) {
+		storage.set(data);
+	}
+
+	public static void clear(){
+		storage.remove();
+	}
+
+	public static String getGroupCode() {
+		return storage.get().groupCode;
+	}
+	public static String setGroupCode(String groupCode) {
+		return storage.get().groupCode=groupCode;
+	}
+
+	public static String getSchemaId() {
+		return storage.get().schemaId;
+	}
+
+	public static String getProjectId() {
+		return storage.get().projectId;
+	}
+
+	public static String getAppId() {
+		return storage.get().appId;
+	}
+
+	public static String getUserId() {
+		return storage.get().userId;
+	}
+
+}

+ 34 - 0
src/main/java/com/persagy/apm/dmpalarm/config/GlobalExceptionHandler.java

@@ -0,0 +1,34 @@
+package com.persagy.apm.dmpalarm.config;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import com.persagy.apm.dmpalarm.web.MapResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @description: 全局异常处理
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/12/4 11:00 上午
+ * @version: V1.0
+ **/
+@RestControllerAdvice
+@Slf4j
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class GlobalExceptionHandler {
+    @ExceptionHandler(value = Exception.class)
+    MapResponse handleException(Exception e, HttpServletRequest request, HttpServletResponse response) {
+        log.error(e.getMessage(),e);
+        MapResponse resp = new MapResponse();
+        resp.setResult("fail");
+        resp.setMessage(e.getMessage());
+        return resp;
+    }
+}

+ 76 - 0
src/main/java/com/persagy/apm/dmpalarm/config/MybatisJsonHandler.java

@@ -0,0 +1,76 @@
+package com.persagy.apm.dmpalarm.config;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import com.alibaba.fastjson.JSONObject;
+
+@MappedTypes(JSONObject.class)
+@MappedJdbcTypes(JdbcType.VARCHAR)
+public class MybatisJsonHandler extends BaseTypeHandler<JSONObject> {
+
+	/**
+	 * 设置非空参数
+	 *
+	 * @param ps
+	 * @param i
+	 * @param parameter
+	 * @param jdbcType
+	 * @throws SQLException
+	 */
+	@Override
+	public void setNonNullParameter(PreparedStatement ps, int i, JSONObject parameter, JdbcType jdbcType)
+			throws SQLException {
+		ps.setString(i, String.valueOf(parameter.toJSONString()));
+	}
+
+	/**
+	 * 根据列名,获取可以为空的结果
+	 *
+	 * @param rs
+	 * @param columnName
+	 * @return
+	 * @throws SQLException
+	 */
+	@Override
+	public JSONObject getNullableResult(ResultSet rs, String columnName) throws SQLException {
+		String sqlJson = rs.getString(columnName);
+		if (null != sqlJson) {
+			return JSONObject.parseObject(sqlJson);
+		}
+		return null;
+	}
+
+	/**
+	 * 根据列索引,获取可以为空的结果
+	 *
+	 * @param rs
+	 * @param columnIndex
+	 * @return
+	 * @throws SQLException
+	 */
+	@Override
+	public JSONObject getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+		String sqlJson = rs.getString(columnIndex);
+		if (null != sqlJson) {
+			return JSONObject.parseObject(sqlJson);
+		}
+		return null;
+	}
+
+	@Override
+	public JSONObject getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+		String sqlJson = cs.getString(columnIndex);
+		if (null != sqlJson) {
+			return JSONObject.parseObject(sqlJson);
+		}
+		return null;
+	}
+}

+ 44 - 0
src/main/java/com/persagy/apm/dmpalarm/config/MybatisPlusTableNameConfig.java

@@ -0,0 +1,44 @@
+package com.persagy.apm.dmpalarm.config;
+
+import java.util.Collections;
+import java.util.HashMap;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.baomidou.mybatisplus.extension.parsers.DynamicTableNameParser;
+import com.baomidou.mybatisplus.extension.parsers.ITableNameHandler;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.persagy.apm.dmpalarm.utils.UtilsTools;
+import com.persagy.common.utils.StringUtil;
+
+/**
+ * 动态表名
+ */
+@Configuration
+public class MybatisPlusTableNameConfig {
+
+	@SuppressWarnings("serial")
+	@Bean
+	public PaginationInterceptor paginationInterceptor() {
+		PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
+		DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
+		dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>(2) {
+			{
+				put("alarm_record", (metaObject, sql, tableName) -> {
+					System.err.println("tableName " + tableName);
+					System.err.println("sql " + sql);
+					System.err.println("metaObject " + metaObject);
+					String myTableName = UtilsTools.myTableNameSuffix.get();
+					if (StringUtil.isNotBlank(myTableName)) {
+						tableName = tableName + "_" + myTableName;
+					}
+					return tableName;
+				});
+			}
+		});
+		paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
+		return paginationInterceptor;
+	}
+
+}

+ 68 - 0
src/main/java/com/persagy/apm/dmpalarm/config/QueryAspect.java

@@ -0,0 +1,68 @@
+package com.persagy.apm.dmpalarm.config;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.StringUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+
+/**
+ * @description: 查询切面
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/12/3 9:42 上午
+ * @version: V1.0
+ */
+@Aspect
+@Component
+public class QueryAspect {
+	@Pointcut("execution(public * com.persagy.apm.dmpalarm.service.*.query(..))")
+	public void queryPoint() {
+	}
+
+	/**
+	 * @description: 在查询条件中增加根据项目id和集团编码
+	 * @param: joinPoint
+	 * @return: void
+	 * @exception:
+	 * @author: lixing
+	 * @company: Persagy Technology Co.,Ltd
+	 * @since: 2020/12/3 9:56 上午
+	 * @version: V1.0
+	 */
+	@Before("queryPoint()")
+	public void doBefore(JoinPoint joinPoint) {
+		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+		HttpServletRequest request = attributes.getRequest();
+
+		Object[] args = joinPoint.getArgs();
+		for (Object arg : args) {
+			if (arg instanceof JsonCriteria) {
+				JsonCriteria criteria = (JsonCriteria) arg;
+				/* 查询接口中,参数为0代表查询所有;报警条目查询例外,0代表查询通用*/
+				// 查询参数中不包含groupCode,且param中groupCode不等于0,将groupCode放入查询条件
+				if (StringUtils.isEmpty(criteria.getCriteria().getString("groupCode")) &&
+						!"0".equals(request.getParameter("groupCode"))) {
+					criteria.getCriteria().put("groupCode", request.getParameter("groupCode"));
+				}
+				// 查询参数中不包含projectId,且param中projectId不等于0,将projectId放入查询条件
+				if (StringUtils.isEmpty(criteria.getCriteria().getString("projectId")) &&
+						!"0".equals(request.getParameter("projectId"))) {
+					criteria.getCriteria().put("projectId", request.getParameter("projectId"));
+				}
+				// 查询参数中不包含appId,且param中appId不等于0,将appId放入查询条件
+				if (StringUtils.isEmpty(criteria.getCriteria().getString("appId")) &&
+						!"0".equals(request.getParameter("appId"))) {
+					criteria.getCriteria().put("appId", request.getParameter("appId"));
+				}
+			}
+		}
+	}
+}

+ 123 - 0
src/main/java/com/persagy/apm/dmpalarm/config/RequestLogAspect.java

@@ -0,0 +1,123 @@
+package com.persagy.apm.dmpalarm.config;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-22
+ * @verison: 1.0
+ */
+@Slf4j
+@Aspect
+@Component
+public class RequestLogAspect {
+
+	private static final ThreadLocal<LogData> dataStorage = new ThreadLocal<>();
+
+	private static final AtomicInteger flag = new AtomicInteger(10000000);
+
+
+	@Pointcut("execution(public * com.persagy.apm.dmpalarm.controller.*.*(..))")
+	public void controllerPoint() {
+	}
+
+	@Before("controllerPoint()")
+	public void doBefore(JoinPoint joinPoint) {
+		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+		HttpServletRequest request = attributes.getRequest();
+		LogData data = initFlag(request);
+		dataStorage.set(data);
+		log.info("{} REQUEST URL      : {} {}", data.intFlag, data.method, data.url);
+		log.info("{} REQUEST ARGS     : {}", data.intFlag, JacksonMapper.toSimpleJson(prepare(joinPoint)));
+	}
+
+	public static List<Object> prepare(JoinPoint joinPoint) {
+		Object[] args = joinPoint.getArgs();
+		List<Object> list = new LinkedList<>();
+		if (args != null && args.length > 0) {
+			for (Object arg : args) {
+				if (arg instanceof ServletRequest) {
+					continue;
+				}
+				if (arg instanceof ServletResponse) {
+					continue;
+				}
+				if (arg instanceof MultipartFile) {
+					continue;
+				}
+				list.add(arg);
+			}
+		}
+		return list;
+	}
+
+	@AfterReturning(returning = "ret", pointcut = "controllerPoint()")
+	public void doAfterReturning(Object ret) {
+
+		LogData data = dataStorage.get();
+		if (ret != null) {
+			if (ret instanceof BaseResponse) {
+				log.info("{} REQUEST DURATION : {} {} {}", data.intFlag, System.currentTimeMillis() - data.timestamp, ((BaseResponse<?>) ret).getResult(), data.url);
+			} else {
+				log.info("{} REQUEST DURATION : {} {} {}", data.intFlag, System.currentTimeMillis() - data.timestamp, ret.getClass().getName(), data.url);
+			}
+		} else {
+			log.info("{} REQUEST DURATION : {} {} {}", data.intFlag, System.currentTimeMillis() - data.timestamp, "null", data.url);
+		}
+		dataStorage.remove();
+	}
+
+	@AfterThrowing(throwing = "ex", pointcut = "controllerPoint()")
+	public void doAfterThrowing(Throwable ex) {
+		LogData data = dataStorage.get();
+		log.error("{} REQUEST EXCEPTION: {} {} {}", data.intFlag, System.currentTimeMillis() - data.timestamp, data.url, ex.getMessage());
+		dataStorage.remove();
+	}
+
+	private static LogData initFlag(HttpServletRequest request) {
+		LogData data = new LogData();
+		data.timestamp = System.currentTimeMillis();
+		data.method = request.getMethod();
+
+		String requestURI = request.getRequestURI();
+		String queryString = request.getQueryString();
+		data.url = requestURI + (queryString == null ? "" : "?" + queryString);
+
+		int result = flag.addAndGet(1);
+		if (result >= 99999999) {
+			flag.set(10000000);
+		}
+		data.intFlag = result;
+		dataStorage.set(data);
+		return data;
+	}
+
+	private static class LogData {
+		Integer intFlag;
+		Long timestamp;
+		String url;
+		String method;
+	}
+}

+ 60 - 0
src/main/java/com/persagy/apm/dmpalarm/config/RequestParamCheckAspect.java

@@ -0,0 +1,60 @@
+package com.persagy.apm.dmpalarm.config;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.StringUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+
+/**
+ * @description: 查询切面
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/12/3 9:42 上午
+ * @version: V1.0
+ */
+@Aspect
+@Component
+public class RequestParamCheckAspect {
+
+	private static final String errorInfo = "request url中参数[%s]不能为空";
+	@Pointcut("execution(public * com.persagy.apm.dmpalarm.controller.*.*(..))")
+	public void point() {
+	}
+
+	/**
+	 * @description: 校验参数中的必填项
+	 * @param: joinPoint
+	 * @return: void
+	 * @exception:
+	 * @author: lixing
+	 * @company: Persagy Technology Co.,Ltd
+	 * @since: 2020/12/3 9:56 上午
+	 * @version: V1.0
+	 */
+	@Before("point()")
+	public void doBefore(JoinPoint joinPoint) throws Exception{
+		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+		HttpServletRequest request = attributes.getRequest();
+		String projectId = request.getParameter("projectId");
+		String groupCode = request.getParameter("groupCode");
+		String userId = request.getParameter("userId");
+
+		if (StringUtils.isEmpty(projectId)) {
+			throw new RuntimeException(String.format(errorInfo, "projectId"));
+		}
+		if (StringUtils.isEmpty(groupCode)) {
+			throw new RuntimeException(String.format(errorInfo, "groupCode"));
+		}
+		if (StringUtils.isEmpty(userId)) {
+			throw new RuntimeException(String.format(errorInfo, "userId"));
+		}
+	}
+
+}

+ 74 - 0
src/main/java/com/persagy/apm/dmpalarm/config/TableNameAspect.java

@@ -0,0 +1,74 @@
+package com.persagy.apm.dmpalarm.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+
+import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.segments.NormalSegmentList;
+import com.persagy.apm.dmpalarm.model.AlarmRecord;
+
+@Aspect
+@Component
+public class TableNameAspect {
+	@Pointcut("execution( * com.baomidou.mybatisplus.core.mapper.BaseMapper.*(..)) || "
+			+ " execution( * com.persagy.apm.dmpalarm.service.impl.BaseServiceImpl.*(..))")
+	public void point() {
+		System.out.println(12345);
+	}
+
+	@Before("point()")
+	public void doBefore(JoinPoint joinPoint) {
+		for (Object args : joinPoint.getArgs()) {
+			if(args instanceof QueryWrapper) {
+			   QueryWrapper<?> queryWrapper = (QueryWrapper<?>)args;
+			  NormalSegmentList normal = queryWrapper.getExpression().getNormal();
+			  System.out.println(normal.get(2));
+			  Map<String,String> map=new HashMap<>();
+			  int i=1;
+			  String key="";
+			  for (ISqlSegment iSqlSegment : normal) {
+				  if(i==1) {
+					  key=iSqlSegment.getSqlSegment();
+					  map.put(iSqlSegment.getSqlSegment(), null);
+				  }
+				  if(i==3) {
+					  iSqlSegment.getSqlSegment();
+					  map.put(key, iSqlSegment.getSqlSegment());
+					  i=-1;
+				  }	  
+				  i++;
+				
+			}
+			  System.out.println(map);
+//			  Map<String,String> map=new HashMap<>();
+//			  String[] strs="and#<#>#!=#like#in#not#null#no".split("#");
+//			  String  sqlSegment = normal.getSqlSegment().toUpperCase().replace("AND", "");
+//			  for (int i = 0; i < strs.length; i++) {
+//				  sqlSegment=sqlSegment.replace(strs[i].toUpperCase(), "");
+//			 }
+//			  sqlSegment= sqlSegment.replace("(", "").replace(")", "").trim();
+//			  String[] sqlSegments = sqlSegment.split(" ");
+//			  for (String string : sqlSegments) {
+//				System.out.println(string.trim());
+		
+			  
+			   Map<String, Object> nap = queryWrapper.getParamNameValuePairs();
+				String start=(String) queryWrapper.getParamNameValuePairs().get(AlarmRecord.PROP_EFFECT_START_TIME);
+				String end=(String) queryWrapper.getParamNameValuePairs().get(AlarmRecord.PROP_EFFECT_END_TIME);
+					  System.out.println(start);
+					  System.out.println(end);
+					  
+			}else if(args instanceof AlarmRecord) {
+				System.out.println(args);
+			}
+		}
+		
+	}
+}

+ 58 - 0
src/main/java/com/persagy/apm/dmpalarm/config/WebConfig.java

@@ -0,0 +1,58 @@
+package com.persagy.apm.dmpalarm.config;
+
+import org.springframework.amqp.core.AcknowledgeMode;
+import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
+import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
+import org.springframework.amqp.support.converter.MessageConverter;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-22
+ * @verison: 1.0
+ */
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+	@Bean
+	public DmpParameterStorage dmpParameterStorage() {
+		return new DmpParameterStorage();
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		// 设置拦截的路径、不拦截的路径、优先级等等
+		registry.addInterceptor(dmpParameterStorage()).addPathPatterns("/**");
+	}
+
+	@Bean
+	public HttpMessageConverters customConverters() {
+		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
+		converter.setObjectMapper(JacksonMapper.nonEmptyMapper);
+		return new HttpMessageConverters(converter);
+	}
+	// JMS 使用
+	@Bean
+	public MessageConverter customMessageConvert() {
+		return new Jackson2JsonMessageConverter();
+	}
+
+	@Bean
+	public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
+		SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
+		factory.setConnectionFactory(connectionFactory);
+		factory.setMessageConverter(new Jackson2JsonMessageConverter());
+		factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
+		return factory;
+	}
+
+}

+ 59 - 0
src/main/java/com/persagy/apm/dmpalarm/controller/AlarmCommentController.java

@@ -0,0 +1,59 @@
+package com.persagy.apm.dmpalarm.controller;
+
+import javax.annotation.Resource;
+
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.jms.MessageProcesser;
+import com.persagy.apm.dmpalarm.model.AlarmComment;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmCommentService;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import io.swagger.annotations.Api;
+
+/**
+ * 报警批注控制层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:43:56
+ */
+@Api(tags = "报警批注")
+@Validated
+@RestController("dmpAlarmComment")
+@RequestMapping("/alarm/comment")
+public class AlarmCommentController {
+    @Resource(name = "dmpAlarmCommentService")
+    private IAlarmCommentService alarmCommentService;
+    @Resource
+    private MessageProcesser messageProcesser;
+
+    @PostMapping("/query")
+    public PagedResponse<AlarmComment> query(@RequestBody JsonCriteria criteria) {
+        return alarmCommentService.query(criteria);
+    }
+
+    @PostMapping("/create")
+    public MapResponse create(@RequestBody AlarmComment param) {
+        return alarmCommentService.create(param);
+    }
+
+    @PostMapping("/sendMessage")
+    public MapResponse update(@RequestBody AlarmComment param) {
+        for (int i = 0; i < 2000; i++) {
+            DmpMessage dmpMessage = new DmpMessage();
+            dmpMessage.setMid(String.valueOf(i));
+            dmpMessage.setType("sleep");
+            messageProcesser.convertAndSend(dmpMessage);
+        }
+        return new MapResponse();
+    }
+
+}
+

+ 109 - 0
src/main/java/com/persagy/apm/dmpalarm/controller/AlarmConfigController.java

@@ -0,0 +1,109 @@
+package com.persagy.apm.dmpalarm.controller;
+
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmConfig;
+import com.persagy.apm.dmpalarm.service.IAlarmConfigService;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import io.swagger.annotations.Api;
+
+/**
+ * 报警定义控制层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:43:56
+ */
+@Api(tags = "报警定义")
+@Validated
+@RestController("dmpAlarmConfig")
+@RequestMapping("/alarm/config")
+public class AlarmConfigController {
+    @Resource(name="dmpAlarmConfigService")
+    private IAlarmConfigService alarmConfigService;
+
+    @PostMapping("/query")
+    public PagedResponse<AlarmConfig> query(@RequestBody JsonCriteria criteria) {
+        return alarmConfigService.query(criteria);
+    }
+
+    @PostMapping("/create")
+    public MapResponse create(@RequestBody AlarmConfig alarmConfig) {
+        return alarmConfigService.create(alarmConfig);
+    }
+
+    /**
+     * @description: 批量创建报警定义
+     * @param: param
+     * @return: com.persagy.common.web.MapResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/22 2:37 下午
+     * @version: V1.0
+     */
+    @PostMapping("/batch_create")
+    public MapResponse batchCreate(@RequestBody AlarmConfig alarmConfig) {
+        List<AlarmConfig> configModels = alarmConfig.getAlarmConfigs();
+        if (configModels == null) {
+            MapResponse response = new MapResponse();
+            response.setFail("请传入要创建的报警定义!");
+            return response;
+        }
+        return alarmConfigService.batchCreate(configModels);
+    }
+
+    @PostMapping("/update")
+    public MapResponse update(@RequestBody AlarmConfig param) {
+        return alarmConfigService.update(param);
+    }
+
+    /**
+     * @description: 批量更新报警定义
+     * @param: param
+     * @return: com.persagy.common.web.MapResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/22 2:37 下午
+     * @version: V1.0
+     */
+    @PostMapping("/batch_update")
+    public MapResponse batchUpdate(@RequestBody AlarmConfig alarmConfig) {
+        List<AlarmConfig> configModels = alarmConfig.getAlarmConfigs();
+        if (configModels == null) {
+            MapResponse response = new MapResponse();
+            response.setFail("请传入要修改的报警定义!");
+            return response;
+        }
+        return alarmConfigService.batchUpdate(configModels);
+    }
+
+    @PostMapping("/delete")
+    public MapResponse delete(@RequestBody AlarmConfig alarmConfig) {
+        return alarmConfigService.delete(alarmConfig);
+    }
+
+    @PostMapping("/batch_delete")
+    public MapResponse batchDelete(@RequestBody AlarmConfig alarmConfig) {
+        return alarmConfigService.batchDelete(alarmConfig);
+    }
+
+
+    @PostMapping("/init")
+    public MapResponse init(@RequestBody AlarmConfig alarmConfig) {
+        return alarmConfigService.init(alarmConfig);
+    }
+
+}
+

+ 48 - 0
src/main/java/com/persagy/apm/dmpalarm/controller/AlarmItemController.java

@@ -0,0 +1,48 @@
+package com.persagy.apm.dmpalarm.controller;
+
+import javax.annotation.Resource;
+
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmItem;
+import com.persagy.apm.dmpalarm.service.IAlarmItemService;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import io.swagger.annotations.Api;
+
+/**
+ * 报警条目控制层
+ * @author lixing
+ * @version V1.0 2021-12-09 10:43:56
+ */
+@Api(tags = "报警条目") 
+@Validated
+@RestController("dmpAlarmItem")
+@RequestMapping("/alarm/item")
+public class AlarmItemController {
+    @Resource(name="dmpAlarmItemService")
+    private IAlarmItemService alarmItemService;
+
+
+    @PostMapping("/query")
+    public PagedResponse<AlarmItem> query(@RequestBody JsonCriteria criteria) {
+        return alarmItemService.query(criteria);
+    }
+
+    @PostMapping("/create")
+    public MapResponse create(@RequestBody AlarmItem param){
+        return alarmItemService.create(param);
+    }
+
+    @PostMapping("/update")
+    public MapResponse update(@RequestBody AlarmItem param){
+        return alarmItemService.update(param);
+    }
+}
+

+ 43 - 0
src/main/java/com/persagy/apm/dmpalarm/controller/AlarmLogController.java

@@ -0,0 +1,43 @@
+package com.persagy.apm.dmpalarm.controller;
+
+import javax.annotation.Resource;
+
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmLog;
+import com.persagy.apm.dmpalarm.service.IAlarmLogService;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import io.swagger.annotations.Api;
+
+/**
+ * 报警日志控制层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:43:56
+ */
+@Api(tags = "报警日志")
+@Validated
+@RestController("dmpAlarmLog")
+@RequestMapping("/alarm/log")
+public class AlarmLogController {
+    @Resource
+    private IAlarmLogService alarmLogService;
+
+    @PostMapping("/query")
+    public PagedResponse<AlarmLog> query(@RequestBody JsonCriteria criteria) {
+        return alarmLogService.query(criteria);
+    }
+
+    @PostMapping("/create")
+    public MapResponse create(@RequestBody AlarmLog param) {
+        return alarmLogService.create(param);
+    }
+}
+

+ 54 - 0
src/main/java/com/persagy/apm/dmpalarm/controller/AlarmRecordController.java

@@ -0,0 +1,54 @@
+package com.persagy.apm.dmpalarm.controller;
+
+import javax.annotation.Resource;
+
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmRecord;
+import com.persagy.apm.dmpalarm.service.IAlarmRecordService;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import io.swagger.annotations.Api;
+
+/**
+ * 报警记录控制层
+ * 
+ * @author lixing
+ * @version V1.0 2021-12-09 10:43:56
+ */
+@Api(tags = "报警记录")
+@Validated
+@RestController("dmpAlarmRecord")
+@RequestMapping("/alarm/record")
+public class AlarmRecordController {
+
+	@Resource(name="dmpAlarmRecordService")
+	private IAlarmRecordService alarmRecordService;
+
+	@PostMapping("/query")
+	public PagedResponse<AlarmRecord> query(@RequestBody JsonCriteria criteria) {
+		return alarmRecordService.query(criteria);
+	}
+
+	@PostMapping("/create")
+	public MapResponse create(@RequestBody AlarmRecord alarmRecord) {
+		return alarmRecordService.create(alarmRecord);
+	}
+
+	@PostMapping("/update")
+	public MapResponse update(@RequestBody AlarmRecord alarmRecord) {
+		return alarmRecordService.update(alarmRecord);
+	}
+
+	@PostMapping("/batch_update")
+	public MapResponse batchUpdate(@RequestBody AlarmRecord alarmRecord) {
+		return alarmRecordService.batchUpdate(alarmRecord);
+	}
+
+}

+ 52 - 0
src/main/java/com/persagy/apm/dmpalarm/controller/AlarmTargetController.java

@@ -0,0 +1,52 @@
+package com.persagy.apm.dmpalarm.controller;
+
+import javax.annotation.Resource;
+
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmTarget;
+import com.persagy.apm.dmpalarm.service.IAlarmTargetService;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import io.swagger.annotations.Api;
+
+/**
+ * 报警匹配条件控制层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:43:56
+ */
+@Api(tags = "报警匹配条件")
+@Validated
+@RestController("dmpAlarmTarget")
+@RequestMapping("/alarm/target")
+public class AlarmTargetController {
+    @Resource
+    private IAlarmTargetService alarmTargetService;
+
+    @PostMapping("/query")
+    public PagedResponse<AlarmTarget> query(@RequestBody JsonCriteria criteria) {
+        return alarmTargetService.query(criteria);
+    }
+    @PostMapping("/create")
+    public MapResponse create(@RequestBody AlarmTarget param) {
+        return alarmTargetService.create(param);
+    }
+
+    @PostMapping("/update")
+    public MapResponse update(@RequestBody AlarmTarget param) {
+        return alarmTargetService.update(param);
+    }
+
+    @PostMapping("/delete")
+    public MapResponse delete(@RequestBody AlarmTarget param) {
+        return alarmTargetService.delete(param);
+    }
+}
+

+ 176 - 0
src/main/java/com/persagy/apm/dmpalarm/criteria/CriteriaUtils.java

@@ -0,0 +1,176 @@
+package com.persagy.apm.dmpalarm.criteria;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.springframework.stereotype.Component;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria.Order;
+import com.persagy.apm.dmpalarm.utils.UtilsTools;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import cn.hutool.core.date.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class CriteriaUtils {
+
+	/**
+	 * 批量拼接报警条件
+	 * 
+	 * @param <T>
+	 * 
+	 */
+	@SuppressWarnings("unchecked")
+	public <T> QueryWrapper<T> handleAlarmConditions(JsonCriteria jsonCriteria, Class<T> classes) {
+		T t = null;
+		try {
+			t = classes.newInstance();
+		} catch (InstantiationException | IllegalAccessException e1) {
+			log.error(e1.getMessage(), e1);
+		}
+		try {
+			QueryWrapper<T> queryWrapper = new QueryWrapper<>(t);
+			JSONObject criteriaJson = jsonCriteria.getCriteria();
+			Field[] fields = classes.getDeclaredFields();
+			for (Field field : fields) {
+				String fieldName = field.getName();
+				Type type = field.getGenericType();
+				Object columnValue = criteriaJson.get(fieldName);
+				if (columnValue == null) {
+					continue;
+				}
+				if (columnValue instanceof List) {
+					List<Object> valueList = (List<Object>) columnValue;
+					queryWrapper.in(UtilsTools.humpToLine(fieldName), valueList);
+				} else if (columnValue instanceof Map) {
+					Map<String, Object> columMap = (Map<String, Object>) columnValue;
+					for (Entry<String, Object> columEntry : columMap.entrySet()) {
+						Object value = columEntry.getValue();
+						switch (columEntry.getKey()) {
+						case "$ne":
+							if (value instanceof List) {
+								List<Object> valueList = (List<Object>) columnValue;
+								queryWrapper.notIn(UtilsTools.humpToLine(fieldName), typeConversion(valueList, type.getTypeName()));
+							} else {
+								queryWrapper.ne(UtilsTools.humpToLine(fieldName), typeConversion(value, type.getTypeName()));
+							}
+							break;
+						case "$gt":
+							queryWrapper.gt(UtilsTools.humpToLine(fieldName), typeConversion(value, type.getTypeName()));
+							break;
+						case "$gte":
+							queryWrapper.ge(UtilsTools.humpToLine(fieldName), typeConversion(value, type.getTypeName()));
+							break;
+						case "$lt":
+							queryWrapper.lt(UtilsTools.humpToLine(fieldName), typeConversion(value, type.getTypeName()));
+							break;
+						case "$lte":
+							queryWrapper.le(UtilsTools.humpToLine(fieldName), typeConversion(value, type.getTypeName()));
+							break;
+						case "$in":
+							if (value instanceof List) {
+								List<Object> valueList = (List<Object>) columnValue;
+								queryWrapper.in(UtilsTools.humpToLine(fieldName), typeConversion(valueList, type.getTypeName()));
+							} else {
+								queryWrapper.eq(UtilsTools.humpToLine(fieldName), typeConversion(value, type.getTypeName()));
+							}
+							break;
+						case "$like":
+							queryWrapper.like(UtilsTools.humpToLine(fieldName), typeConversion(value, type.getTypeName()));
+							break;
+						case "$notlike":
+							queryWrapper.notLike(UtilsTools.humpToLine(fieldName), typeConversion(value, type.getTypeName()));
+							break;
+						case "$null":
+							Boolean b = (Boolean) value;
+							if (b) {
+								queryWrapper.isNull(UtilsTools.humpToLine(fieldName));
+							} else {
+								queryWrapper.isNotNull(UtilsTools.humpToLine(fieldName));
+							}
+							break;
+						}
+					}
+				} else {
+					queryWrapper.eq(UtilsTools.humpToLine(fieldName), typeConversion(columnValue,  type.getTypeName()));
+				}
+
+			}
+			for (Order order : jsonCriteria.getOrders()) {
+				if (order.isAsc()) {
+					queryWrapper.orderByAsc(UtilsTools.humpToLine(order.getColumn()));
+				} else {
+					queryWrapper.orderByDesc(UtilsTools.humpToLine(order.getColumn()));
+				}
+			}
+			return queryWrapper;
+		} catch (Exception e) {
+			log.error("CriteriaUtils handleAlarmConditions error ", e);
+		}
+		return new QueryWrapper<T>(t);
+	}
+
+	public <T> PagedResponse<T> getPagedResponse(JsonCriteria criteria , Class<T> classes , QueryWrapper<T> queryWrapper , BaseMapper<T> baseMapper){
+		PagedResponse<T> pagedResponse = new PagedResponse<>();
+		if (criteria.isOnlyCount()) {
+			Integer count = baseMapper.selectCount(queryWrapper);
+			pagedResponse.setCount(count.longValue());
+		} else {
+			Page<T> page = baseMapper.selectPage(new Page<>(criteria.getPage(), criteria.getSize()), queryWrapper);
+			pagedResponse.setCount(page.getTotal());
+			pagedResponse.setData(page.getRecords());
+		}
+		return pagedResponse;
+	}
+
+	/**
+	 * 类型转换
+	 * 
+	 * @param obj
+	 * @return
+	 */
+	private Object typeConversion(Object obj, String typeName) {
+		Object resultObj = null;
+		if (Date.class.getName().equals(typeName) || Timestamp.class.getName().equals(typeName)) {
+			resultObj = DateUtil.parse(obj.toString());
+		} else if (Integer.class.getName().equals(typeName)) {
+			resultObj = Integer.valueOf(obj.toString());
+		} else if (Long.class.getName().equals(typeName)) {
+			resultObj = Long.valueOf(obj.toString());
+		} else if (Double.class.getName().equals(typeName)) {
+			resultObj = Double.valueOf(obj.toString());
+		} else if (Float.class.getName().equals(typeName)) {
+			resultObj = Float.valueOf(obj.toString());
+		} else if (Short.class.getName().equals(typeName)) {
+			resultObj = Short.valueOf(obj.toString());
+		} else {
+			resultObj = obj.toString();
+		}
+		return resultObj;
+	}
+	/**
+	 * 批量类型转换
+	 *
+	 * @return
+	 */
+	private Collection<?> typeConversion(Collection<?> coll, String typeName) {
+		List<Object> resultList = new ArrayList<>();
+		for (Object object : coll) {
+			resultList.add(this.typeConversion(object, typeName));
+		}
+		return resultList;
+	}
+}

+ 97 - 0
src/main/java/com/persagy/apm/dmpalarm/criteria/JsonCriteria.java

@@ -0,0 +1,97 @@
+package com.persagy.apm.dmpalarm.criteria;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.alibaba.fastjson.JSONObject;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-04
+ * @verison: 1.0
+ *
+ *           <pre>
+ * {
+ *     "page": 1,
+ *     "size": 10,
+ *     "onlyCount": false,
+ *     "criteria": {
+ *         "name": "zhangsan",
+ *         "name": [ "zhangsan", "lisi" ],
+ *         "age": {
+ *             "$gt": 18,
+ *             "$lt": 35
+ *         },
+ *         "gender": {
+ *             "$null": false
+ *         }
+ *     },
+ *     "orders": [
+ *            {
+ *     		 	"column": "name",
+ *     		 	"asc": false
+ *            }
+ *     ],
+ *     "withColumns": [
+ *     		"name", "age"
+ *     ]
+ * }
+ *           </pre>
+ */
+public class JsonCriteria {
+
+	@Getter
+	@Setter
+	private Integer page =1;
+
+	@Getter
+	@Setter
+	private Integer size=10;
+
+	/**
+	 * 是否只统计数量
+	 */
+	@Getter
+	@Setter
+	private boolean onlyCount = false;
+
+	@Getter
+	@Setter
+	private boolean withoutCount = false;
+
+	@Getter
+	@Setter
+	private JSONObject criteria = new JSONObject();
+
+	@Getter
+	@Setter
+	private List<Order> orders = new ArrayList<>();
+
+	@Getter
+	@Setter
+	private Set<String> withColumns = new HashSet<>();
+
+	@Data
+	public static class Order {
+		private String column;
+		private boolean asc = true;
+
+		public Order() {
+		}
+
+		public Order(String column) {
+			this.column = column;
+		}
+
+		public Order(String column, boolean asc) {
+			this.column = column;
+			this.asc = asc;
+		}
+	}
+}

+ 15 - 0
src/main/java/com/persagy/apm/dmpalarm/dao/AlarmCommentMapper.java

@@ -0,0 +1,15 @@
+package com.persagy.apm.dmpalarm.dao;
+
+import com.persagy.apm.dmpalarm.model.AlarmComment;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 报警批注(AlarmComment)dao层
+ * @author lixing
+ * @version V1.0 2021-12-09 10:46:43
+ */
+@Mapper
+public interface AlarmCommentMapper extends BaseMapper<AlarmComment>{
+
+}

+ 15 - 0
src/main/java/com/persagy/apm/dmpalarm/dao/AlarmConfigMapper.java

@@ -0,0 +1,15 @@
+package com.persagy.apm.dmpalarm.dao;
+
+import com.persagy.apm.dmpalarm.model.AlarmConfig;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 报警定义(AlarmConfig)dao层
+ * @author lixing
+ * @version V1.0 2021-12-09 10:46:43
+ */
+@Mapper
+public interface AlarmConfigMapper extends BaseMapper<AlarmConfig>{
+
+}

+ 15 - 0
src/main/java/com/persagy/apm/dmpalarm/dao/AlarmItemMapper.java

@@ -0,0 +1,15 @@
+package com.persagy.apm.dmpalarm.dao;
+
+import com.persagy.apm.dmpalarm.model.AlarmItem;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 报警条目(AlarmItem)dao层
+ * @author lixing
+ * @version V1.0 2021-12-09 10:46:43
+ */
+@Mapper
+public interface AlarmItemMapper extends BaseMapper<AlarmItem>{
+
+}

+ 15 - 0
src/main/java/com/persagy/apm/dmpalarm/dao/AlarmLogMapper.java

@@ -0,0 +1,15 @@
+package com.persagy.apm.dmpalarm.dao;
+
+import com.persagy.apm.dmpalarm.model.AlarmLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 报警日志(AlarmLog)dao层
+ * @author lixing
+ * @version V1.0 2021-12-09 10:46:43
+ */
+@Mapper
+public interface AlarmLogMapper extends BaseMapper<AlarmLog>{
+
+}

+ 16 - 0
src/main/java/com/persagy/apm/dmpalarm/dao/AlarmRecordMapper.java

@@ -0,0 +1,16 @@
+package com.persagy.apm.dmpalarm.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.persagy.apm.dmpalarm.model.AlarmRecord;
+
+/**
+ * 报警记录(AlarmRecord)dao层
+ * @author lixing
+ * @version V1.0 2021-12-09 10:46:43
+ */
+@Mapper
+public interface AlarmRecordMapper extends BaseMapper<AlarmRecord>{
+
+}

+ 15 - 0
src/main/java/com/persagy/apm/dmpalarm/dao/AlarmTargetMapper.java

@@ -0,0 +1,15 @@
+package com.persagy.apm.dmpalarm.dao;
+
+import com.persagy.apm.dmpalarm.model.AlarmTarget;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 报警匹配条件(AlarmTarget)dao层
+ * @author lixing
+ * @version V1.0 2021-12-09 10:46:43
+ */
+@Mapper
+public interface AlarmTargetMapper extends BaseMapper<AlarmTarget>{
+
+}

+ 12 - 0
src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmListType.java

@@ -0,0 +1,12 @@
+package com.persagy.apm.dmpalarm.enumeration;
+
+/**
+ * 报警记录列表类型
+ *
+ * @author lixing
+ * @version V1.0 2021/11/17 9:08 下午
+ */
+public enum EnumAlarmListType {
+    CURRENT,
+    HISTORY;
+}

+ 14 - 0
src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmLogType.java

@@ -0,0 +1,14 @@
+package com.persagy.apm.dmpalarm.enumeration;
+
+/**
+ * @description:
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/10/19 2:07 下午
+ * @version: V1.0
+ **/
+public enum EnumAlarmLogType {
+    ALARMSTATE,
+    TREATMODE,
+    TREATSTATE
+}

+ 35 - 0
src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmMessageType.java

@@ -0,0 +1,35 @@
+package com.persagy.apm.dmpalarm.enumeration;
+
+import lombok.Getter;
+
+/**
+ * @description: 报警消息类型
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/10/22 8:08 下午
+ * @version: V1.0
+ **/
+public enum EnumAlarmMessageType {
+    ALARM_CONFIGS_CHANGE("alarm_configs_change", "报警定义变动"),
+    ALARM_TARGET_UPDATE("alarmTargetUpdate", "报警匹配条件更新"),
+    ALARM_TARGET_CREATE("alarmTargetCreate", "新增报警匹配条件"),
+    ALARM_TARGET_DELETE("alarmTargetDelete", "删除报警匹配条件"),
+    ALARM_ITEM_CREATE("alarmItemCreate", "新增报警条目"),
+    ALARM_ITEM_UPDATE("alarmItemUpdate", "报警条目更新"),
+    ALARM_ITEM_DELETE("alarmItemDelete", "删除报警条目"),
+    ALARM_RECORD_CREATE("alarmRecordCreate", "新增报警"),
+    ALARM_RECORD_UPDATE("alarmRecordUpdate", "报警更新"),
+    ALARM_CONFIG_BATCH_CREATE("alarmConfigBatchCreate", "报警定义批量创建"),
+    ALARM_CONFIG_BATCH_DELETE("alarmConfigBatchDelete", "报警定义批量删除"),
+    INSTANCE_OBJ_DELETE("instanceObjectDelete", "设备删除");
+
+    @Getter
+    private String value;
+    @Getter
+    private String desc;
+
+    EnumAlarmMessageType(String value, String desc) {
+        this.value = value;
+        this.desc = desc;
+    }
+}

+ 13 - 0
src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmRecordWithColumns.java

@@ -0,0 +1,13 @@
+package com.persagy.apm.dmpalarm.enumeration;
+
+/**
+ * @description:
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/12/8 4:44 下午
+ * @version: V1.0
+ */
+public enum EnumAlarmRecordWithColumns {
+    ignoreTime,
+    treatEndTime
+}

+ 26 - 0
src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmState.java

@@ -0,0 +1,26 @@
+package com.persagy.apm.dmpalarm.enumeration;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 报警状态
+ *
+ * @author lixing
+ * @version V1.0 2021/11/17 9:08 下午
+ */
+@AllArgsConstructor
+public enum EnumAlarmState {
+    UN_HANDLE(1, "未恢复"),
+    END(2, "已恢复"),
+    EXPIRE(3, "已过期");
+
+    @Setter
+    @Getter
+    private Integer type;
+
+    @Setter
+    @Getter
+    private String desc;
+}

+ 28 - 0
src/main/java/com/persagy/apm/dmpalarm/enumeration/EnumAlarmTreatState.java

@@ -0,0 +1,28 @@
+package com.persagy.apm.dmpalarm.enumeration;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 报警处理状态
+ *
+ * @author lixing
+ * @version V1.0 2021/11/17 9:08 下午
+ */
+@AllArgsConstructor
+public enum EnumAlarmTreatState {
+    UN_HANDLE(1, "未处理"),
+    HANDLING(2, "处理中"),
+    DONE(3, "处理完成"),
+    // 用于兼容子系统业务,后期会移除该状态
+    IGNORE(4, "已忽略");
+
+    @Setter
+    @Getter
+    private Integer type;
+
+    @Setter
+    @Getter
+    private String desc;
+}

+ 41 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/ConsumeMessageThreadPool.java

@@ -0,0 +1,41 @@
+package com.persagy.apm.dmpalarm.jms;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+
+import cn.hutool.core.thread.ExecutorBuilder;
+
+/**
+ * 消费消息线程池
+ *
+ * @author lixing
+ * @version V1.0 2021/5/12 2:53 下午
+ **/
+@Component
+public class ConsumeMessageThreadPool {
+    private final ExecutorService es;
+
+    @Autowired
+    private MessageProcesser messageProcesser;
+
+    public ConsumeMessageThreadPool() {
+        es = ExecutorBuilder.create()
+                .setCorePoolSize(5)
+                .setMaxPoolSize(10)
+                .setWorkQueue(new LinkedBlockingQueue<>(10))
+                .setHandler(new ThreadPoolExecutor.CallerRunsPolicy())
+                .build();
+    }
+
+    public void consumeMessage(DmpMessage message) throws Exception {
+        es.execute(() -> {
+            messageProcesser.listen(message);
+        });
+    }
+}

+ 127 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/JmsConfig.java

@@ -0,0 +1,127 @@
+package com.persagy.apm.dmpalarm.jms;
+
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.*;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * @author: yaoll
+ * @date: 2020-10-22
+ * @verison: 1.0
+ */
+@Slf4j
+@Deprecated
+//@Configuration
+public class JmsConfig {
+    @Autowired
+    ConsumeMessageThreadPool consumeMessageThreadPool;
+
+    @Value("${persagy.dmp.exchange}")
+    private String exchange;
+
+    @Value("${persagy.dmp.alarm.routingKey}")
+    private String dmpAlarmRoutingKey;
+
+    /**
+     * 报警定义路由键
+     */
+    @Value("${persagy.dmp.alarm.config.routingKey}")
+    private String dmpAlarmConfigRoutingKey;
+
+    @Value("${alarm.obj.routingKey}")
+    private String alarmObjRoutingKey;
+
+    @Value("${persagy.dmp.rwd.routingKey}")
+    private String rwdRoutingKey;
+
+    @Value("${persagy.dmp.alarm.queue}")
+    private String alarmQueue;
+
+//    @Value("${persagy.dmp.alarm.rwd.queue}")
+//    private String alarmRwdQueue;
+//
+//    @Bean
+//    public Queue alarmRwdQueue() {
+//        return new Queue(alarmRwdQueue, true);
+//    }
+//
+//    @Bean
+//    public Binding alarmRwdBinding() {
+//        return BindingBuilder.bind(alarmRwdQueue()).to(exchange()).with(rwdRoutingKey);
+//    }
+
+    /**
+     * 报警对象队列
+     */
+    private final String alarmObjQueue = "alarm-obj-queue";
+
+    @Autowired
+    private MessageProcesser messageProcesser;
+
+//    @Bean
+    public TopicExchange exchange() {
+        return new TopicExchange(exchange);
+    }
+
+  //  @Bean
+    public Queue alarmQueue() {
+        return new Queue(alarmQueue, true);
+    }
+
+    @Bean
+    public Binding alarmBinding() {
+        return BindingBuilder.bind(alarmQueue()).to(exchange()).with(dmpAlarmRoutingKey);
+    }
+
+  //  @Bean
+    public Queue alarmObjQueue() {
+        return new Queue(alarmObjQueue, true);
+    }
+
+    @Bean
+    public Binding alarmObjBinding() {
+        return BindingBuilder.bind(alarmObjQueue()).to(exchange()).with(alarmObjRoutingKey);
+    }
+
+    @RabbitListener(queues = {alarmObjQueue})    //监听器监听指定的Queue
+    public void process(String message, Channel channel, Message msg) throws Exception{
+        // 手动确认消息已消费
+        try {
+            log.info("============================== Receive:" + message);
+            DmpMessage dmpMessage = JacksonMapper.toObject(message, DmpMessage.class);
+            if (dmpMessage != null) {
+                messageProcesser.listen(dmpMessage);
+            }
+
+            channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
+        } catch (Exception e) {
+            Boolean isRedeliveredFail = msg.getMessageProperties().getRedelivered();
+            // true表示消息已经重复处理失败
+            if (isRedeliveredFail) {
+                // 拒绝消息,requeue=false 表示不再重新入队,如果配置了死信队列则进入死信队列
+                log.error("重复消费消息失败,message: {}", message);
+                channel.basicReject(msg.getMessageProperties().getDeliveryTag(), false);
+            } else {
+                // 如果是第一次失败则再次放入队列
+                // requeue为是否重新回到队列,true重新入队
+                channel.basicNack(msg.getMessageProperties().getDeliveryTag(), false, true);
+            }
+        }
+    }
+
+//    @RabbitListener(queues ="${persagy.dmp.alarm.rwd.queue}")    //监听器监听指定的Queue
+//    public void processRwdMsg(DmpMessage message, Channel channel, Message msg) {
+//        consumeMessageThreadPool.consumeMessage(message, channel, msg);
+//    }
+
+//    @RabbitListener(queues = "${persagy.dmp.alarm.queue}")    //监听器监听指定的Queue
+//    public void processAlarmMsg(DmpMessage message, Channel channel, Message msg) {
+//        consumeMessageThreadPool.consumeMessage(message, channel, msg);
+//    }
+}

+ 14 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/MessageExecutor.java

@@ -0,0 +1,14 @@
+package com.persagy.apm.dmpalarm.jms;
+
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+
+/**
+ * @author: yaoll
+ * @date: 2020-10-22
+ * @verison: 1.0
+ */
+public interface MessageExecutor {
+
+	void execute(DmpMessage message) throws Exception;
+
+}

+ 99 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/MessageProcesser.java

@@ -0,0 +1,99 @@
+package com.persagy.apm.dmpalarm.jms;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import com.persagy.apm.dmpalarm.config.DmpParameterStorage;
+import com.persagy.apm.dmpalarm.enumeration.EnumAlarmMessageType;
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.utils.SpringUtils;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author: yaoll
+ * @date: 2020-10-22
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class MessageProcesser {
+
+	@Value("${persagy.dmp.exchange}")
+	private String exchange;
+
+	@Value("${persagy.dmp.alarm.routingKey}")
+	private String dmpAlarmRoutingKey;
+
+	/**
+	 * 报警定义的routingKey
+	 */
+	private static final String alarmConfigRoutingKey = "alarm-config-routing-key";
+
+	@Autowired
+	private RabbitTemplate rabbitTemplate;
+
+	public void convertAndSend(DmpMessage message) {
+		log.info("向rabbitMQ发送消息,message:" + JacksonMapper.toSimpleJson(message));
+		// 如果是报警定义的变化,通过报警定义的routingKey发送,否则用报警公用的routingKey发送
+		if (EnumAlarmMessageType.ALARM_CONFIGS_CHANGE.getValue().equals(message.getType())) {
+			rabbitTemplate.convertAndSend(exchange, alarmConfigRoutingKey, message);
+		} else {
+			rabbitTemplate.convertAndSend(exchange, dmpAlarmRoutingKey, message);
+		}
+	}
+
+	private static final Set<String> beanNames = new HashSet<>();
+
+	static {
+//		beanNames.add(EnumAlarmMessageType.ALARM_TARGET_CREATE.getValue());
+//		beanNames.add(EnumAlarmMessageType.ALARM_TARGET_UPDATE.getValue());
+//		beanNames.add(EnumAlarmMessageType.ALARM_ITEM_UPDATE.getValue());
+//		beanNames.add(EnumAlarmMessageType.INSTANCE_OBJ_DELETE.getValue());
+//		beanNames.add(EnumAlarmMessageType.ALARM_TARGET_DELETE.getValue());
+		beanNames.add(EnumAlarmMessageType.ALARM_CONFIG_BATCH_CREATE.getValue());
+//		beanNames.add(EnumAlarmMessageType.ALARM_CONFIG_BATCH_DELETE.getValue());
+	}
+
+	public void listen(DmpMessage message) {
+		String type = message.getType();
+		if (!beanNames.contains(type)) {
+			return;
+		}
+
+		String executorName = type + "Executor";
+
+		MessageExecutor executor = null;
+		try {
+			executor = SpringUtils.getBean(executorName, MessageExecutor.class);
+		} catch (Exception e) {
+			log.error(e.getMessage());
+		}
+		if (executor == null) {
+			log.error("bean for [" + executorName + "] not exists");
+		}
+
+		try {
+			DmpParameterStorage.ParameterData data = new DmpParameterStorage.ParameterData();
+			data.setGroupCode(message.getGroupCode());
+			data.setProjectId(message.getProjectId());
+			data.setAppId(message.getAppId());
+
+			DmpParameterStorage.set(data);
+
+			executor.execute(message);
+
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			DmpParameterStorage.clear();
+		}
+	}
+
+}

+ 87 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/RabbitmqConfig.java

@@ -0,0 +1,87 @@
+package com.persagy.apm.dmpalarm.jms;
+
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.*;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * rabbitmq配置
+ *
+ * @author lixing
+ * @version V1.0 2021/10/11 7:32 下午
+ */
+@Slf4j
+@Configuration
+public class RabbitmqConfig {
+    @Autowired
+    ConsumeMessageThreadPool consumeMessageThreadPool;
+
+    /**
+     * 报警交换机
+     */
+    private final String exchange = "exchange-dmp";
+
+    /**
+     * 报警定义路由键
+     */
+    private final String dmpAlarmConfigRoutingKey = "alarm-config-routing-key";
+
+    /**
+     * 报警对象队列
+     */
+    private final String alarmConfigQueue = "alarm-config-queue1";
+
+    @Bean
+    public TopicExchange exchange() {
+        return new TopicExchange(exchange);
+    }
+
+    @Bean
+    public Queue alarmConfigQueue() {
+        return new Queue(alarmConfigQueue, true);
+    }
+
+    @Bean
+    public Binding alarmObjBinding() {
+        return BindingBuilder.bind(alarmConfigQueue()).to(exchange()).with(dmpAlarmConfigRoutingKey);
+    }
+
+    /**
+     * 监听消息
+     *
+     * @param message DmpMessage(中台报警消息对象)
+     * @param channel channel对象,用于反馈消息消费结果
+     * @param msg rabbitmq消息对象
+     * @author lixing
+     * @version V1.0 2021/10/11 7:40 下午
+     */
+    @RabbitListener(queues = {alarmConfigQueue})
+    public void process(DmpMessage message, Channel channel, Message msg) throws Exception{
+        // 手动确认消息已消费
+        try {
+            log.info("============================== Receive:" + message);
+            if (message != null) {
+                consumeMessageThreadPool.consumeMessage(message);
+            }
+
+            channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
+        } catch (Exception e) {
+            Boolean isRedeliveredFail = msg.getMessageProperties().getRedelivered();
+            // true表示消息已经重复处理失败
+            if (isRedeliveredFail) {
+                // 拒绝消息,requeue=false 表示不再重新入队,如果配置了死信队列则进入死信队列
+                log.error("重复消费消息失败,message: {}", message);
+                channel.basicReject(msg.getMessageProperties().getDeliveryTag(), false);
+            } else {
+                // 如果是第一次失败则再次放入队列
+                // requeue为是否重新回到队列,true重新入队
+                channel.basicNack(msg.getMessageProperties().getDeliveryTag(), false, true);
+            }
+        }
+    }
+}

+ 66 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmConfigBatchCreateExecutor.java

@@ -0,0 +1,66 @@
+package com.persagy.apm.dmpalarm.jms.executor;
+
+import com.alibaba.fastjson.JSON;
+import com.persagy.apm.dmpalarm.config.DmpParameterStorage;
+import com.persagy.apm.dmpalarm.jms.MessageExecutor;
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.AlarmConfig;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmConfigService;
+import com.persagy.apm.dmpalarm.utils.CheckRequiredParam;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 批量创建报警定义
+ *
+ * @author lixing
+ * @version V1.0 2021/10/11 8:00 下午
+ */
+@Slf4j
+@Component
+public class AlarmConfigBatchCreateExecutor implements MessageExecutor {
+    @Autowired
+    private IAlarmConfigService alarmConfigService;
+
+    @Override
+    public void execute(DmpMessage message) throws Exception {
+        /* 验证消息是否符合要求 */
+        CheckRequiredParam.check(message, "exts");
+
+        Map<String, Object> exts = message.getExts();
+        String key = "alarmConfigs";
+        Object obj = exts.get(key);
+        List<AlarmConfig> configModels = new ArrayList<>();
+        if (obj instanceof ArrayList<?>) {
+            for (Object o : (List<?>) obj) {
+                AlarmConfig alarmConfigModel = JacksonMapper.toObject(
+                        JSON.toJSONString(o), AlarmConfig.class);
+                configModels.add(alarmConfigModel);
+            }
+        }
+        if (CollectionUtils.isEmpty(configModels)) {
+            return;
+        }
+        /* 设置通用请求参数 */
+        DmpParameterStorage.ParameterData data = new DmpParameterStorage.ParameterData();
+        data.setAppId(message.getAppId());
+        data.setGroupCode(message.getGroupCode());
+        data.setProjectId(message.getProjectId());
+        data.setUserId(message.getUserId());
+        DmpParameterStorage.set(data);
+
+        MapResponse response = alarmConfigService.batchCreate(configModels);
+        if (BaseResponse.FAIL.equals(response.getResult())) {
+            log.error("消费AlarmConfigBatchCreate消息异常,{}", response.getMessage());
+        }
+    }
+}

+ 35 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmItemCreateExecutor.java

@@ -0,0 +1,35 @@
+package com.persagy.apm.dmpalarm.jms.executor;
+
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import com.persagy.apm.dmpalarm.jms.MessageExecutor;
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author: lixing
+ * @date: 2020-10-23
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class AlarmItemCreateExecutor implements MessageExecutor {
+
+
+	@Override
+	public void execute(DmpMessage message) {
+		log.info("AlarmItemCreate : {}", JacksonMapper.toSimpleJson(message));
+
+		/* 验证消息是否符合要求 */
+		String itemCode = message.getStr1();
+
+		if (StringUtils.isEmpty(itemCode)) {
+			log.error("AlarmItemUpdate消息中缺少itemCode信息");
+		}
+
+		// 消费消息,当前没有消费消息的场景,预留此接口
+	}
+}

+ 44 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmItemUpdateExecutor.java

@@ -0,0 +1,44 @@
+package com.persagy.apm.dmpalarm.jms.executor;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import com.persagy.apm.dmpalarm.jms.MessageExecutor;
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmConfigService;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author: lixing
+ * @date: 2020-10-23
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class AlarmItemUpdateExecutor implements MessageExecutor {
+	@Resource(name="dmpAlarmConfigService")
+	private IAlarmConfigService alarmConfigService;
+
+	@Override
+	public void execute(DmpMessage message) {
+		log.info("AlarmItemUpdate : {}", JacksonMapper.toSimpleJson(message));
+
+		/* 验证消息是否符合要求 */
+		String itemCode = message.getStr1();
+
+		if (StringUtils.isEmpty(itemCode)) {
+			log.error("AlarmItemUpdate消息中缺少itemCode信息");
+		}
+
+		MapResponse response = alarmConfigService.batchUpdateWhenItemUpdate(itemCode, message.getProjectId(), message.getGroupCode());
+		if (BaseResponse.FAIL.equals(response.getResult())) {
+			log.error("消费AlarmItemUpdate消息异常,{}", response.getMessage());
+		}
+	}
+}

+ 39 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmTargetCreateExecutor.java

@@ -0,0 +1,39 @@
+package com.persagy.apm.dmpalarm.jms.executor;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Component;
+
+import com.persagy.apm.dmpalarm.jms.MessageExecutor;
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmConfigService;
+import com.persagy.apm.dmpalarm.utils.CheckRequiredParam;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author: lixing
+ * @date: 2020-10-23
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class AlarmTargetCreateExecutor implements MessageExecutor {
+	@Resource(name="dmpAlarmConfigService")
+    private IAlarmConfigService alarmConfigService;
+
+    @Override
+    public void execute(DmpMessage message) {
+        log.info("AlarmTargetCreate : {}", JacksonMapper.toSimpleJson(message));
+
+        /* 验证消息是否符合要求 */
+        CheckRequiredParam.check(message, "targetId", "projectId", "groupCode");
+        MapResponse response = alarmConfigService.batchUpdateWhenTargetUpdate(message.getTargetId(), message.getProjectId(), message.getGroupCode(), message.getAppId());
+        if (BaseResponse.FAIL.equals(response.getResult())) {
+            log.error("消费AlarmTargetCreate消息异常,{}", response.getMessage());
+        }
+    }
+}

+ 40 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmTargetDeleteExecutor.java

@@ -0,0 +1,40 @@
+package com.persagy.apm.dmpalarm.jms.executor;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Component;
+
+import com.persagy.apm.dmpalarm.jms.MessageExecutor;
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmConfigService;
+import com.persagy.apm.dmpalarm.utils.CheckRequiredParam;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author: lixing
+ * @date: 2020-10-23
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class AlarmTargetDeleteExecutor implements MessageExecutor {
+	@Resource(name="dmpAlarmConfigService")
+	private IAlarmConfigService alarmConfigService;
+
+	@Override
+	public void execute(DmpMessage message) {
+		log.info("AlarmTargetDelete : {}", JacksonMapper.toSimpleJson(message));
+
+		/* 验证消息是否符合要求 */
+		CheckRequiredParam.check(message, "targetId", "projectId", "groupCode");
+
+		MapResponse response = alarmConfigService.batchDeleteWhenTargetDelete(message.getTargetId(), message.getProjectId(), message.getGroupCode());
+		if (BaseResponse.FAIL.equals(response.getResult())) {
+			log.error("消费AlarmTargetDelete消息异常,{}", response.getMessage());
+		}
+	}
+}

+ 40 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/executor/AlarmTargetUpdateExecutor.java

@@ -0,0 +1,40 @@
+package com.persagy.apm.dmpalarm.jms.executor;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Component;
+
+import com.persagy.apm.dmpalarm.jms.MessageExecutor;
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmConfigService;
+import com.persagy.apm.dmpalarm.utils.CheckRequiredParam;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author: lixing
+ * @date: 2020-10-23
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class AlarmTargetUpdateExecutor implements MessageExecutor {
+	@Resource(name="dmpAlarmConfigService")
+    private IAlarmConfigService alarmConfigService;
+
+    @Override
+    public void execute(DmpMessage message) {
+        log.info("AlarmTargetUpdate : {}", JacksonMapper.toSimpleJson(message));
+
+        /* 验证消息是否符合要求 */
+        CheckRequiredParam.check(message, "targetId", "projectId", "groupCode");
+
+        MapResponse response = alarmConfigService.batchUpdateWhenTargetUpdate(message.getTargetId(), message.getProjectId(), message.getGroupCode(), message.getAppId());
+        if (BaseResponse.FAIL.equals(response.getResult())) {
+            log.error("消费AlarmTargetUpdate消息异常,{}", response.getMessage());
+        }
+    }
+}

+ 42 - 0
src/main/java/com/persagy/apm/dmpalarm/jms/executor/InstanceObjectDeleteExecutor.java

@@ -0,0 +1,42 @@
+package com.persagy.apm.dmpalarm.jms.executor;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Component;
+
+import com.persagy.apm.dmpalarm.jms.MessageExecutor;
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmConfigService;
+import com.persagy.apm.dmpalarm.utils.CheckRequiredParam;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @description: 对象类删除
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/12/10 10:53 上午
+ * @version: V1.0
+ */
+@Slf4j
+@Component
+public class InstanceObjectDeleteExecutor implements MessageExecutor {
+	@Resource(name="dmpAlarmConfigService")
+	private IAlarmConfigService alarmConfigService;
+
+	@Override
+	public void execute(DmpMessage message) {
+		log.info("InstanceObjDelete : {}", JacksonMapper.toSimpleJson(message));
+
+		/* 验证消息是否符合要求 */
+		CheckRequiredParam.check(message, "targetId", "projectId");
+
+		MapResponse response = alarmConfigService.deleteOnRemoveObj(message.getTargetId(), message.getProjectId());
+		if (BaseResponse.FAIL.equals(response.getResult())) {
+			log.error("消费InstanceObjDelete消息异常,{}", response.getMessage());
+		}
+	}
+}

+ 229 - 0
src/main/java/com/persagy/apm/dmpalarm/json/JacksonMapper.java

@@ -0,0 +1,229 @@
+package com.persagy.apm.dmpalarm.json;
+
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeType;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-04
+ * @verison: 1.0
+ */
+public class JacksonMapper {
+
+	private static Logger logger = LoggerFactory.getLogger(JacksonMapper.class);
+
+	public static final ObjectMapper nonEmptyMapper;
+	public static final ObjectMapper nonDefaultMapper;
+	public static final ObjectMapper nonEmptyFormatMapper;
+
+	static {
+		nonEmptyMapper = new ObjectMapper();
+		nonEmptyMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+		nonEmptyMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+		nonEmptyMapper.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
+
+		nonDefaultMapper = new ObjectMapper();
+		nonDefaultMapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
+		nonDefaultMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+		nonDefaultMapper.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
+
+		nonEmptyFormatMapper = new ObjectMapper();
+		nonEmptyFormatMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+		nonEmptyFormatMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+		nonEmptyFormatMapper.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
+		nonEmptyFormatMapper.enable(SerializationFeature.INDENT_OUTPUT);
+	}
+
+	private static boolean isEmpty(final CharSequence cs) {
+		return cs == null || cs.length() == 0;
+	}
+
+	public static <T> T toObject(String jsonString, Class<T> clazz) {
+		if (!isEmpty(jsonString)) {
+			try {
+				return nonEmptyMapper.readValue(jsonString, clazz);
+			} catch (IOException e) {
+				logger.warn("parse json string to {} error: {}", clazz.getName(), jsonString, e);
+			}
+		}
+		return null;
+	}
+
+	public static <T> T toObject(String jsonString, TypeReference<T> typeRef) {
+		if (!isEmpty(jsonString)) {
+			try {
+				return nonEmptyMapper.readValue(jsonString, typeRef);
+			} catch (IOException e) {
+				logger.warn("parse json string to {} error: {}", typeRef.toString(), jsonString, e);
+			}
+		}
+		return null;
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <T> T toObject(String jsonString, JavaType javaType) {
+		if (!isEmpty(jsonString)) {
+			try {
+				return (T) nonEmptyMapper.readValue(jsonString, javaType);
+			} catch (IOException e) {
+				logger.warn("parse json string to {} error: {}", javaType.toString(), jsonString, e);
+			}
+		}
+		return null;
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <T> T toObject(String jsonString, Class<?> cla, Class<?>... clb) {
+		if (!isEmpty(jsonString)) {
+			try {
+				JavaType javaType = nonEmptyMapper.getTypeFactory().constructParametricType(cla, clb);
+				return (T) nonEmptyMapper.readValue(jsonString, javaType);
+			} catch (IOException e) {
+				logger.warn("parse json string to {} error: {}", cla.getName(), jsonString, e);
+			}
+		}
+		return null;
+	}
+
+	public static JavaType constructParametricType(Class<?> parametrized, Class<?>... parameterClasses) {
+		return nonEmptyMapper.getTypeFactory().constructParametricType(parametrized, parameterClasses);
+	}
+
+	public static JavaType constructParametricType(Class<?> rawType, JavaType... parameterTypes) {
+		return nonEmptyMapper.getTypeFactory().constructParametricType(rawType, parameterTypes);
+	}
+
+	public static String toSimpleJson(Object object) {
+		try {
+			return nonEmptyMapper.writeValueAsString(object);
+		} catch (JsonProcessingException e) {
+			logger.error("write to json string error:" + object, e);
+		}
+		return null;
+	}
+
+	public static String toFormatJson(Object object) {
+		try {
+			return nonEmptyFormatMapper.writeValueAsString(object);
+		} catch (JsonProcessingException e) {
+			logger.error("write to json string error:" + object, e);
+		}
+		return null;
+	}
+
+	public static final String getString(ObjectNode obj, String key) {
+		return getString(obj, key, null);
+	}
+
+	public static final String getString(ObjectNode obj, String key, String defaultValue) {
+		if (obj == null) {
+			return defaultValue;
+		}
+		if (!obj.has(key)) {
+			return defaultValue;
+		}
+		return obj.get(key).asText();
+	}
+
+	public static final Integer getInteger(ObjectNode obj, String key) {
+		return getInteger(obj, key, null);
+	}
+
+	public static final Integer getInteger(ObjectNode obj, String key, Integer defaultValue) {
+		if (obj == null) {
+			return defaultValue;
+		}
+		if (!obj.has(key)) {
+			return defaultValue;
+		}
+		JsonNode jsonNode = obj.get(key);
+
+		return Integer.valueOf(jsonNode.asText());
+	}
+
+	public static final Double getDouble(ObjectNode obj, String key) {
+		return getDouble(obj, key, null);
+	}
+
+	public static final Double getDouble(ObjectNode obj, String key, Double defaultValue) {
+		if (obj == null) {
+			return defaultValue;
+		}
+		if (!obj.has(key)) {
+			return defaultValue;
+		}
+		return Double.valueOf(obj.get(key).asText());
+	}
+
+	public static final Boolean getBoolean(ObjectNode obj, String key) {
+		return getBoolean(obj, key, null);
+	}
+
+	public static final Boolean getBoolean(ObjectNode obj, String key, Boolean defaultValue) {
+		if (obj == null) {
+			return defaultValue;
+		}
+		if (!obj.has(key)) {
+			return defaultValue;
+		}
+		return Boolean.valueOf(obj.get(key).toString());
+	}
+
+	public static final ObjectNode getObject(ObjectNode obj, String key) {
+		return getObject(obj, key, null);
+	}
+
+	public static final ObjectNode getObject(ObjectNode obj, String key, ObjectNode defaultValue) {
+		if (obj == null) {
+			return defaultValue;
+		}
+		if (!obj.has(key)) {
+			return defaultValue;
+		}
+		JsonNode jsonNode = obj.get(key);
+		JsonNodeType nodeType = jsonNode.getNodeType();
+		if (nodeType == JsonNodeType.STRING) {
+			return toObject(jsonNode.asText(), ObjectNode.class);
+		} else if (nodeType == JsonNodeType.OBJECT) {
+			return (ObjectNode) jsonNode;
+		}
+		return defaultValue;
+	}
+
+
+	public static final ArrayNode getArray(ObjectNode obj, String key) {
+		return getArray(obj, key, null);
+	}
+
+	public static final ArrayNode getArray(ObjectNode obj, String key, ArrayNode defaultValue) {
+		if (obj == null) {
+			return defaultValue;
+		}
+		if (!obj.has(key)) {
+			return defaultValue;
+		}
+		JsonNode jsonNode = obj.get(key);
+		JsonNodeType nodeType = jsonNode.getNodeType();
+		if (nodeType == JsonNodeType.STRING) {
+			return toObject(jsonNode.asText(), ArrayNode.class);
+		} else if (nodeType == JsonNodeType.ARRAY) {
+			return (ArrayNode) jsonNode;
+		}
+		return defaultValue;
+	}
+
+}

+ 58 - 0
src/main/java/com/persagy/apm/dmpalarm/model/AlarmComment.java

@@ -0,0 +1,58 @@
+package com.persagy.apm.dmpalarm.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 报警批注(AlarmComment)实体类
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:53
+ */
+@Data
+@ApiModel(description = "报警批注")
+public class AlarmComment implements Serializable {
+    private static final long serialVersionUID = -25604656657950729L;
+
+    private String id;
+
+    @ApiModelProperty("报警记录id")
+    private String recordId;
+    
+    @ApiModelProperty("批注内容")
+    private String content;
+    
+    @ApiModelProperty("创建人")
+    private String createUser;
+    
+    @ApiModelProperty("项目id")
+    private String projectId;
+    
+    @ApiModelProperty("集团编码")
+    private String groupCode;
+    
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+    
+    @ApiModelProperty("更新时间")
+    private Date updateTime;
+    
+    @ApiModelProperty("更新人")
+    private String updateUser;
+
+    private int valid;
+    
+
+    public static String PROP_RECORD_ID = "record_id";
+    public static String PROP_CONTENT = "content";
+    public static String PROP_CREATE_USER = "create_user";
+    public static String PROP_PROJECT_ID = "project_id";
+    public static String PROP_GROUP_CODE = "group_code";
+    public static String PROP_CREATE_TIME = "create_time";
+    public static String PROP_UPDATE_TIME = "update_time";
+    public static String PROP_UPDATE_USER = "update_user";
+
+}

+ 120 - 0
src/main/java/com/persagy/apm/dmpalarm/model/AlarmConfig.java

@@ -0,0 +1,120 @@
+package com.persagy.apm.dmpalarm.model;
+
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import com.persagy.apm.common.model.entity.AuditableEntity;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 报警定义(AlarmConfig)实体类
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:53
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(description = "报警定义")
+public class AlarmConfig extends AuditableEntity<AlarmConfig> implements Serializable {
+    private static final long serialVersionUID = -50363859666957294L;
+
+    @ApiModelProperty("对象id")
+    private String objId;
+    
+    @ApiModelProperty("对象类型编码")
+    private String classCode;
+    
+    @ApiModelProperty("项目id")
+    private String projectId;
+    
+    @ApiModelProperty("集团编码")
+    private String groupCode;
+    
+    @ApiModelProperty("报警条目编码")
+    private String itemCode;
+    
+    @ApiModelProperty("报警匹配条件id")
+    private String targetId;
+    
+    @ApiModelProperty("报警分类")
+    private String category;
+    
+    @ApiModelProperty("严重程度")
+    private String level;
+    
+    @ApiModelProperty("备注")
+    private String remark;
+    
+    @ApiModelProperty("触发条件")
+    private JSONObject condition;
+    
+    @ApiModelProperty("屏蔽状态 1-open、0- 屏蔽")
+    private Integer open;
+    
+    @ApiModelProperty("是否重点关注")
+    private Integer concern;
+    
+    @ApiModelProperty("是否自定义")
+    private Integer userDefined;
+    
+    @ApiModelProperty("创建用户")
+    private String createUser;
+    
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+    
+    @ApiModelProperty("更新用户")
+    private String updateUser;
+    
+    @ApiModelProperty("更新时间")
+    private Date updateTime;
+
+    private List<AlarmConfig> alarmConfigs;
+
+    /**
+     * @description: <p>报警定义唯一标识; 当报警条目和报警匹配条件变化时会重新生成报警定义,
+     * 因此在与其他系统进行通讯时,一般不使用报警定义的id作为其唯一标识,而是使用itemCode + objID作为其唯一标识</p>
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/26 11:25 上午
+     * @version: V1.0
+     */
+    @Data
+    public class AlarmConfigUnique {
+        private String itemCode;
+        private String objId;
+        private String targetId;
+
+        AlarmConfigUnique(String itemCode, String objId, String targetId) {
+            this.itemCode = itemCode;
+            this.objId = objId;
+            this.targetId = targetId;
+        }
+    }
+
+    public AlarmConfigUnique getAlarmConfigUnique() {
+        return new AlarmConfigUnique(this.itemCode, this.objId, this.targetId);
+    }
+
+    public static String PROP_OBJ_ID = "obj_id";
+    public static String PROP_CLASS_CODE = "class_code";
+    public static String PROP_PROJECT_ID = "project_id";
+    public static String PROP_GROUP_CODE = "group_code";
+    public static String PROP_ITEM_CODE = "item_code";
+    public static String PROP_TARGET_ID = "target_id";
+    public static String PROP_CATEGORY = "category";
+    public static String PROP_LEVEL = "level";
+    public static String PROP_REMARK = "remark";
+    public static String PROP_CONDITION = "condition";
+    public static String PROP_OPEN = "open";
+    public static String PROP_CONCERN = "concern";
+    public static String PROP_USER_DEFINED = "user_defined";
+    public static String PROP_CREATE_USER = "create_user";
+    public static String PROP_CREATE_TIME = "create_time";
+    public static String PROP_UPDATE_USER = "update_user";
+    public static String PROP_UPDATE_TIME = "update_time";
+
+}

+ 81 - 0
src/main/java/com/persagy/apm/dmpalarm/model/AlarmItem.java

@@ -0,0 +1,81 @@
+package com.persagy.apm.dmpalarm.model;
+
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import com.persagy.apm.common.model.entity.AuditableEntity;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 报警条目(AlarmItem)实体类
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:49
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(description = "报警条目")
+public class AlarmItem extends AuditableEntity<AlarmItem> implements Serializable {
+    private static final long serialVersionUID = 683658832546296259L;
+
+    @ApiModelProperty("报警条目编码")
+    private String code;
+    
+    @ApiModelProperty("报警条目名称")
+    private String name;
+    
+    @ApiModelProperty("报警分类")
+    private String category;
+    
+    @ApiModelProperty("严重程度")
+    private String level;
+    
+    @ApiModelProperty("备注")
+    private String remark;
+    
+    @ApiModelProperty("触发条件")
+    private JSONObject condition;
+    
+    @ApiModelProperty("处理算法")
+    private String dealFun;
+    
+    @ApiModelProperty("创建用户")
+    private String createUser;
+    
+    @ApiModelProperty("项目id,0代表通用")
+    private String projectId;
+    
+    @ApiModelProperty("集团编码,0代表通用")
+    private String groupCode;
+    
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+    
+    @ApiModelProperty("更新用户")
+    private String updateUser;
+    
+    @ApiModelProperty("更新时间")
+    private Date updateTime;
+    
+    @ApiModelProperty("应用id")
+    private String appId;
+    
+
+    public static String PROP_CODE = "code";
+    public static String PROP_NAME = "name";
+    public static String PROP_CATEGORY = "category";
+    public static String PROP_LEVEL = "level";
+    public static String PROP_REMARK = "remark";
+    public static String PROP_CONDITION = "condition";
+    public static String PROP_DEAL_FUN = "deal_fun";
+    public static String PROP_CREATE_USER = "create_user";
+    public static String PROP_PROJECT_ID = "project_id";
+    public static String PROP_GROUP_CODE = "group_code";
+    public static String PROP_CREATE_TIME = "create_time";
+    public static String PROP_UPDATE_USER = "update_user";
+    public static String PROP_UPDATE_TIME = "update_time";
+    public static String PROP_APP_ID = "app_id";
+
+}

+ 47 - 0
src/main/java/com/persagy/apm/dmpalarm/model/AlarmLog.java

@@ -0,0 +1,47 @@
+package com.persagy.apm.dmpalarm.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.alibaba.fastjson.JSONObject;
+import com.persagy.apm.dmpalarm.enumeration.EnumAlarmLogType;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+/**
+ * 报警日志(AlarmLog)实体类
+ * 
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:53
+ */
+@Data
+@ApiModel(description = "报警日志")
+public class AlarmLog implements Serializable {
+	private static final long serialVersionUID = 618980609835731542L;
+
+	private String id;
+	private String recordId;
+	private EnumAlarmLogType type;
+	private Integer nature;
+	private Integer before;
+	private Integer after;
+	private JSONObject remark;
+	private Date createTime;
+	private String projectId;
+	private String groupCode;
+	private String createUser;
+
+	public static String PROP_RECORD_ID = "record_id";
+	public static String PROP_TYPE = "type";
+	public static String PROP_NATURE = "nature";
+	public static String PROP_BEFORE = "before";
+	public static String PROP_AFTER = "after";
+	public static String PROP_REMARK = "remark";
+	public static String PROP_PROJECT_ID = "project_id";
+	public static String PROP_GROUP_CODE = "group_code";
+	public static String PROP_CREATE_TIME = "create_time";
+	public static String PROP_UPDATE_TIME = "update_time";
+	public static String PROP_CREATE_USER = "create_user";
+
+}

+ 104 - 0
src/main/java/com/persagy/apm/dmpalarm/model/AlarmRecord.java

@@ -0,0 +1,104 @@
+package com.persagy.apm.dmpalarm.model;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
+
+import lombok.Data;
+
+@Data
+public class AlarmRecord implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private String id;
+	private String itemCode;
+	private String projectId;
+	private String objId;
+	private String classCode;
+	private String level;
+	private String remark;
+	private String name;
+	private String category;
+	private Integer concern;
+	private Integer state;
+	private Date effectStartTime;
+	private Date effectEndTime;
+	/**
+	 * 报警性质
+	 */
+	private Integer nature;
+	/**
+	 * 处理方式
+	 */
+	private Integer treatMode;
+	/**
+	 * 处理状态
+	 */
+	private Integer treatState;
+	private String createUser;
+	@TableField("`condition`")
+	private JSONObject condition;
+	private JSONObject triggerInfo;
+	private Date triggerTime;
+	private JSONObject endInfo;
+	private Date endTime;
+	private Date createTime;
+	private String updateUser;
+	private Date updateTime;
+	private Integer valid;
+	private String groupCode;
+	private String orderId;
+	private String orderState;
+	private JSONObject supplement;
+
+	/**
+	 * 忽略报警时间
+	 */
+	@TableField(exist = false)
+	private Date ignoreTime;
+	/**
+	 * 报警处理完成时间
+	 */
+
+	@TableField(exist = false)
+	private Date treatEndTime;
+	private String targetId;
+	@TableField(exist = false)
+	private List<AlarmRecord> alarmRecordModels;
+	public static String PROP_ITEM_CODE = "item_code";
+	public static String PROP_PROJECT_ID = "project_id";
+	public static String PROP_OBJ_ID = "obj_id";
+	public static String PROP_CLASS_CODE = "class_code";
+	public static String PROP_LEVEL = "level";
+	public static String PROP_REMARK = "remark";
+	public static String PROP_CREATE_USER = "create_user";
+	public static String PROP_CREATE_TIME = "create_time";
+	public static String PROP_UPDATE_USER = "update_user";
+	public static String PROP_UPDATE_TIME = "update_time";
+	public static String PROP_NAME = "name";
+	public static String PROP_CATEGORY = "category";
+	public static String PROP_CONCERN = "concern";
+	public static String PROP_STATE = "state";
+	public static String PROP_EFFECT_START_TIME = "effect_start_time";
+	public static String PROP_EFFECT_END_TIME = "effect_end_time";
+	public static String PROP_NATURE = "nature";
+	public static String PROP_TREAT_MODE = "treat_mode";
+	public static String PROP_TREAT_STATE = "treat_state";
+	public static String PROP_GROUP_CODE = "group_code";
+	public static String PROP_CONDITION = "condition";
+	public static String PROP_TRIGGER_INFO = "trigger_info";
+	public static String PROP_END_INFO = "end_info";
+	public static String PROP_TRIGGER_TIME = "trigger_time";
+	public static String PROP_END_TIME = "end_time";
+	public static String PROP_ORDER_ID = "order_id";
+	public static String PROP_ORDER_STATE = "order_state";
+	public static String PROP_SUPPLEMENT = "supplement";
+	public static String PROP_TARGET_ID = "target_id";
+
+}

+ 76 - 0
src/main/java/com/persagy/apm/dmpalarm/model/AlarmTarget.java

@@ -0,0 +1,76 @@
+package com.persagy.apm.dmpalarm.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.alibaba.fastjson.JSONObject;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 报警匹配条件(AlarmTarget)实体类
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:53
+ */
+@Data
+@ApiModel(description = "报警匹配条件")
+public class AlarmTarget implements Serializable {
+    private static final long serialVersionUID = 584249238241159229L;
+    @ApiModelProperty("主键")
+    private String id;
+
+    @ApiModelProperty("报警条目id")
+    private String itemCode;
+    
+    @ApiModelProperty("对象类型")
+    private String classCode;
+    
+    @ApiModelProperty("触发条件")
+    private JSONObject condition;
+    
+    @ApiModelProperty("报警等级")
+    private String level;
+    
+    @ApiModelProperty("是否重点关注")
+    private Integer concern;
+    
+    @ApiModelProperty("屏蔽状态(0:不屏蔽,1:屏蔽)")
+    private Integer open;
+    
+    @ApiModelProperty("创建用户")
+    private String createUser;
+    
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+    
+    @ApiModelProperty("更新用户")
+    private String updateUser;
+    
+    @ApiModelProperty("更新时间")
+    private Date updateTime;
+    
+    @ApiModelProperty("项目id")
+    private String projectId;
+    
+    @ApiModelProperty("集团编码")
+    private String groupCode;
+
+    private Integer valid;
+    
+
+    public static String PROP_ITEM_CODE = "item_code";
+    public static String PROP_CLASS_CODE = "class_code";
+    public static String PROP_CONDITION = "condition";
+    public static String PROP_LEVEL = "level";
+    public static String PROP_CONCERN = "concern";
+    public static String PROP_OPEN = "open";
+    public static String PROP_CREATE_USER = "create_user";
+    public static String PROP_CREATE_TIME = "create_time";
+    public static String PROP_UPDATE_USER = "update_user";
+    public static String PROP_UPDATE_TIME = "update_time";
+    public static String PROP_PROJECT_ID = "project_id";
+    public static String PROP_GROUP_CODE = "group_code";
+
+}

+ 49 - 0
src/main/java/com/persagy/apm/dmpalarm/model/DmpMessage.java

@@ -0,0 +1,49 @@
+package com.persagy.apm.dmpalarm.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author: yaoll
+ * @date: 2020-10-22
+ * @verison: 1.0
+ */
+
+@Getter
+@Setter
+public class DmpMessage {
+
+	private String mid;
+	private String type;
+	private String groupCode;
+	private String projectId;
+	private String targetId;
+	private Integer int1;
+	private Integer int2;
+	private String str1;
+	private String str2;
+	private String sendTime;
+	private String expireTime;
+	private String appId;
+	private String userId;
+	private Map<String, Object> exts;
+
+	public DmpMessage() {
+	}
+
+	public DmpMessage(String type, String targetId) {
+		this.type = type;
+		this.targetId = targetId;
+	}
+
+	public DmpMessage add(String key, Object value) {
+		if (exts == null) {
+			this.exts = new HashMap<>();
+		}
+		this.exts.put(key, value);
+		return this;
+	}
+}

+ 19 - 0
src/main/java/com/persagy/apm/dmpalarm/service/IAlarmCommentService.java

@@ -0,0 +1,19 @@
+package com.persagy.apm.dmpalarm.service;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmComment;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+/**
+ * 报警批注(AlarmComment) service接口
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+public interface IAlarmCommentService  {
+
+    public PagedResponse<AlarmComment> query(JsonCriteria criteria);
+
+    public MapResponse create(AlarmComment param);
+}

+ 42 - 0
src/main/java/com/persagy/apm/dmpalarm/service/IAlarmConfigService.java

@@ -0,0 +1,42 @@
+package com.persagy.apm.dmpalarm.service;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmConfig;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import java.util.List;
+
+/**
+ * 报警定义(AlarmConfig) service接口
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+public interface IAlarmConfigService {
+
+
+    public PagedResponse<AlarmConfig> query(JsonCriteria criteria);
+
+    public MapResponse create(AlarmConfig alarmConfig);
+
+    public MapResponse batchCreate(List<AlarmConfig> alarmConfigList);
+
+    public MapResponse batchUpdate(List<AlarmConfig> alarmConfigList);
+
+    public MapResponse batchDelete(AlarmConfig alarmConfig);
+
+    public MapResponse update(AlarmConfig param);
+
+    public  MapResponse delete(AlarmConfig alarmConfig);
+
+    public  MapResponse init(AlarmConfig alarmConfig);
+
+    MapResponse batchDeleteWhenTargetDelete(String targetId, String projectId, String groupCode);
+
+    MapResponse batchUpdateWhenTargetUpdate(String targetId, String projectId, String groupCode, String appId);
+
+    MapResponse batchUpdateWhenItemUpdate(String itemCode, String projectId, String groupCode);
+
+    MapResponse deleteOnRemoveObj(String targetId, String projectId);
+}

+ 30 - 0
src/main/java/com/persagy/apm/dmpalarm/service/IAlarmItemService.java

@@ -0,0 +1,30 @@
+package com.persagy.apm.dmpalarm.service;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmItem;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 报警条目(AlarmItem) service接口
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+public interface IAlarmItemService  {
+
+   public Map<String, AlarmItem> getItemCodeModelMap(List<String> itemCodeList);
+
+   public AlarmItem getAlarmItemByItemCode(String itemCode, String projectId, String groupCode, String appId);
+
+   public PagedResponse<AlarmItem> query(JsonCriteria criteria);
+
+   public MapResponse create(AlarmItem param);
+
+   public  MapResponse update(AlarmItem param);
+
+   public List<AlarmItem> queryList(JsonCriteria criteria);
+}

+ 27 - 0
src/main/java/com/persagy/apm/dmpalarm/service/IAlarmLogService.java

@@ -0,0 +1,27 @@
+package com.persagy.apm.dmpalarm.service;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmLog;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 报警日志(AlarmLog) service接口
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+public interface IAlarmLogService  {
+    
+	public MapResponse create(AlarmLog alarmLog);
+
+    public PagedResponse<AlarmLog> query(JsonCriteria criteria);
+
+    public Map<String, List<AlarmLog>> getAlarmLogMap(List<String> recordIdList);
+
+    public Date getIgnoreAlarmTime(String recordId);
+}

+ 24 - 0
src/main/java/com/persagy/apm/dmpalarm/service/IAlarmRecordService.java

@@ -0,0 +1,24 @@
+package com.persagy.apm.dmpalarm.service;
+
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmRecord;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+/**
+ * 报警记录(AlarmRecord) service接口
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+public interface IAlarmRecordService {
+
+	public PagedResponse<AlarmRecord> query(JsonCriteria criteria);
+
+	public MapResponse create(AlarmRecord alarmRecord);
+
+	public MapResponse update(AlarmRecord alarmRecord);
+
+	public MapResponse batchUpdate(AlarmRecord alarmRecord);
+
+}

+ 37 - 0
src/main/java/com/persagy/apm/dmpalarm/service/IAlarmTargetService.java

@@ -0,0 +1,37 @@
+package com.persagy.apm.dmpalarm.service;
+
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.fastjson.JSONObject;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmItem;
+import com.persagy.apm.dmpalarm.model.AlarmTarget;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+/**
+ * 报警匹配条件(AlarmTarget) service接口
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+public interface IAlarmTargetService  {
+
+
+    public PagedResponse<AlarmTarget> query(JsonCriteria criteria);
+
+    public MapResponse create(AlarmTarget param);
+
+    public MapResponse update(AlarmTarget param);
+
+    public MapResponse delete(AlarmTarget param);
+
+    public JSONObject getCondition(AlarmTarget targetModel, AlarmItem itemModel);
+
+    public List<AlarmTarget> getAlarmTargetsByItemCode(String itemCode, String projectId);
+
+    public AlarmTarget get(String targetId);
+
+    public Map<String, AlarmItem> getItemCodeModelMapByModelList(List<AlarmTarget> targets);
+}

+ 11 - 0
src/main/java/com/persagy/apm/dmpalarm/service/IPhysicalWorldService.java

@@ -0,0 +1,11 @@
+package com.persagy.apm.dmpalarm.service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public interface IPhysicalWorldService {
+    public Set<String> queryObjectIdListByClassCode(String projectId, String groupCode, String classCode);
+
+    public Map<String, Set<String>> queryCodeIdListMapByClassCodes(String projectId, String groupCode, List<String> classCodes);
+}

+ 67 - 0
src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmCommentServiceImpl.java

@@ -0,0 +1,67 @@
+package com.persagy.apm.dmpalarm.service.impl;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.persagy.apm.dmpalarm.criteria.CriteriaUtils;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.model.AlarmComment;
+import com.persagy.apm.dmpalarm.service.IAlarmCommentService;
+import com.persagy.apm.dmpalarm.utils.CheckRequiredParam;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 报警批注(AlarmComment) service层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+@Service("dmpAlarmCommentService")
+@Slf4j
+public class AlarmCommentServiceImpl extends BaseServiceImpl<AlarmComment> implements IAlarmCommentService {
+    @Resource
+    private CriteriaUtils criteriaUtils;
+
+    public PagedResponse<AlarmComment> query(JsonCriteria criteria) {
+        QueryWrapper<AlarmComment> queryWrapper = criteriaUtils.handleAlarmConditions(criteria, AlarmComment.class);
+        try {
+            return criteriaUtils.getPagedResponse(criteria, AlarmComment.class, queryWrapper, getBaseMapper());
+        } catch (Exception e) {
+            log.error("alarmComment query page error JsonCriteria is  {}",criteria.toString(),e);
+        }
+        return new PagedResponse<>();
+    }
+
+    @Transactional
+    public MapResponse create(AlarmComment entity) {
+        MapResponse response = new MapResponse();
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+        // 必填项校验
+        String checkResult = CheckRequiredParam.check(entity, "recordId", "content");
+        if (!StringUtils.isEmpty(checkResult)) {
+            response.setFail(checkResult);
+            return response;
+        }
+        entity.setId(UUID.randomUUID().toString());
+        entity.setCreateUser(alarmParam.userId);
+        entity.setProjectId(alarmParam.projectId);
+        entity.setGroupCode(alarmParam.groupCode);
+        entity.setCreateTime(new Date());
+        save(entity);
+        response.add("id", entity.getId());
+        return response;
+    }
+}

+ 835 - 0
src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmConfigServiceImpl.java

@@ -0,0 +1,835 @@
+package com.persagy.apm.dmpalarm.service.impl;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.common.collect.Lists;
+import com.persagy.apm.dmpalarm.config.DmpParameterStorage;
+import com.persagy.apm.dmpalarm.criteria.CriteriaUtils;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.enumeration.EnumAlarmMessageType;
+import com.persagy.apm.dmpalarm.jms.MessageProcesser;
+import com.persagy.apm.dmpalarm.model.AlarmConfig;
+import com.persagy.apm.dmpalarm.model.AlarmItem;
+import com.persagy.apm.dmpalarm.model.AlarmTarget;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmConfigService;
+import com.persagy.apm.dmpalarm.service.IAlarmItemService;
+import com.persagy.apm.dmpalarm.service.IAlarmTargetService;
+import com.persagy.apm.dmpalarm.service.IPhysicalWorldService;
+import com.persagy.apm.dmpalarm.utils.CheckRequiredParam;
+import com.persagy.apm.dmpalarm.utils.DatePatternStyle;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import cn.hutool.core.date.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 报警定义(AlarmConfig) service层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+@Service("dmpAlarmConfigService")
+@Slf4j
+public class AlarmConfigServiceImpl extends BaseServiceImpl<AlarmConfig> implements IAlarmConfigService {
+    @Resource
+    private MessageProcesser messageProcesser;
+    @Resource(name="dmpAlarmItemService")
+    private IAlarmItemService alarmItemService;
+    @Resource
+    private IAlarmTargetService alarmTargetService;
+    @Resource
+    private IPhysicalWorldService physicalWorldService;
+    @Resource
+    private CriteriaUtils criteriaUtils;
+
+    public PagedResponse<AlarmConfig> query(JsonCriteria criteria) {
+        QueryWrapper<AlarmConfig> queryWrapper = criteriaUtils.handleAlarmConditions(criteria, AlarmConfig.class);
+        return criteriaUtils.getPagedResponse(criteria, AlarmConfig.class, queryWrapper, getBaseMapper());
+    }
+
+    /**
+     * @description: 当新增对象时,自动生成对应的报警定义
+     * @param: objId 对象id
+     * @param: classCode 对象分类
+     * @param: projectId 项目id
+     * @return: com.persagy.common.web.BaseResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/20 11:30 上午
+     * @version: V1.0
+     */
+    @SuppressWarnings("rawtypes")
+	@Transactional
+    public BaseResponse createOnAddObj(String objId, String classCode, String projectId) {
+        BaseResponse response = new BaseResponse();
+        /* 查询根据对象类型查询对应的报警匹配条件 */
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("classCode", classCode);
+        criteria.getCriteria().put("projectId", projectId);
+        PagedResponse<AlarmTarget> pagedTargets = alarmTargetService.query(criteria);
+        List<AlarmTarget> targets = pagedTargets.getData();
+        /* 拼装报警定义对象 */
+        if (!CollectionUtils.isEmpty(targets)) {
+            Map<String, AlarmItem> itemCodeModelMap = alarmTargetService.getItemCodeModelMapByModelList(targets);
+            List<AlarmConfig> alarmConfigs = new ArrayList<>(targets.size());
+            for (AlarmTarget targetModel : targets) {
+                /* 拼装报警定义实体 */
+                AlarmItem itemModel = itemCodeModelMap.get(targetModel.getItemCode());
+                // 报警触发条件
+                AlarmConfig entity = generateAlarmConfigEntity(objId, targetModel, itemModel);
+                alarmConfigs.add(entity);
+            }
+            DmpMessage createdMessage = saveAll(alarmConfigs);
+            if (createdMessage != null) {
+                messageProcesser.convertAndSend(createdMessage);
+            }
+            response.setMessage("成功创建对象的相关报警定义,生成条数:" + alarmConfigs.size());
+        } else {
+            response.setMessage("没有查找到对应的匹配条件,不生成报警定义");
+        }
+        return response;
+    }
+
+    /**
+     * @description: 生成报警定义对象
+     * @param: objId 对象id
+     * @param: targetModel 匹配条件
+     * @param: itemModel 报警条目
+     * @return: com.persagy.dmp.alarm.entity.AlarmConfig
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/21 11:09 上午
+     * @version: V1.0
+     */
+    private AlarmConfig generateAlarmConfigEntity(String objId, AlarmTarget targetModel, AlarmItem itemModel) {
+        return generateAlarmConfigEntity(objId, targetModel, itemModel, null);
+    }
+
+    /**
+     * @description: 生成报警定义对象
+     * @param: objId 对象id
+     * @param: targetModel 匹配条件
+     * @param: itemModel 报警条目
+     * @param: condition 触发条件
+     * @return: com.persagy.dmp.alarm.entity.AlarmConfig
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/21 11:09 上午
+     * @version: V1.0
+     */
+    private AlarmConfig generateAlarmConfigEntity(String objId, AlarmTarget targetModel, AlarmItem itemModel, JSONObject condition) {
+        if (condition == null) {
+            condition = alarmTargetService.getCondition(targetModel, itemModel);
+        }
+        AlarmConfig entity = new AlarmConfig();
+        entity.setId(UUID.randomUUID().toString());
+        entity.setObjId(objId);
+        entity.setTargetId(targetModel.getId());
+        entity.setClassCode(targetModel.getClassCode());
+        entity.setProjectId(targetModel.getProjectId());
+        entity.setItemCode(targetModel.getItemCode());
+        entity.setCategory(itemModel.getCategory());
+        entity.setLevel(targetModel.getLevel());
+        entity.setRemark(itemModel.getRemark());
+        entity.setGroupCode(targetModel.getGroupCode());
+        entity.setCondition(condition);
+        entity.setOpen(targetModel.getOpen());
+        entity.setConcern(targetModel.getConcern());
+        entity.setUserDefined(0);
+        entity.setCreateUser("System");
+        entity.setCreateTime(new Date());
+        entity.setValid(1);
+        return entity;
+    }
+
+    /**
+     * @description: 当报警条目修改时,批量更新对应的报警定义
+     * @param: itemCode 报警条目编码
+     * @param: projectId 项目id
+     * @param: groupCode 集团编码
+     * @return: com.persagy.common.web.MapResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/20 11:30 上午
+     * @version: V1.0
+     */
+    @Transactional
+    @Override
+    public MapResponse batchUpdateWhenItemUpdate(String itemCode, String projectId, String groupCode) {
+        MapResponse response = new MapResponse();
+        // 查询报警条目
+        AlarmItem itemModel = alarmItemService.getAlarmItemByItemCode(itemCode, projectId, groupCode, null);
+        if (itemModel == null) {
+            response.setFail("自动生成报警定义失败,获取不到对应的报警条目!itemCode:" + itemCode);
+            return response;
+        }
+        /* 获取报警条目对应的所有匹配条件 */
+        List<AlarmTarget> AlarmTargets = alarmTargetService.getAlarmTargetsByItemCode(itemCode, projectId);
+        if (CollectionUtils.isEmpty(AlarmTargets)) {
+            return response;
+        }
+
+        List<String> classCodes = AlarmTargets.stream().map(AlarmTarget::getClassCode).collect(Collectors.toList());
+        try {
+            /* 获取这些匹配条件对应的设备 */
+            Map<String, Set<String>> codeIdListMap = physicalWorldService.queryCodeIdListMapByClassCodes(projectId, groupCode, classCodes);
+            /* 获取要删除和重新生成的报警定义 */
+            List<AlarmConfig> alarmConfigs2Delete = Lists.newArrayList();
+            List<AlarmConfig> alarmConfigs2Create = Lists.newArrayList();
+            // 按照匹配条件统计要修改的报警定义列表
+            for (AlarmTarget AlarmTarget : AlarmTargets) {
+                String classCode = AlarmTarget.getClassCode();
+                Set<String> objIds = codeIdListMap.get(classCode);
+                Map<String, List<AlarmConfig>> statisticsMap = statisticConfigs2Update(objIds, projectId, AlarmTarget, itemModel);
+                if (statisticsMap == null) {
+                    continue;
+                }
+                if (!CollectionUtils.isEmpty(statisticsMap.get("deleted"))) {
+                    alarmConfigs2Delete.addAll(statisticsMap.get("deleted"));
+                }
+
+                if (!CollectionUtils.isEmpty(statisticsMap.get("created"))) {
+                    alarmConfigs2Create.addAll(statisticsMap.get("created"));
+                }
+            }
+            DmpMessage message = saveAndDeleteAll(alarmConfigs2Create, alarmConfigs2Delete);
+            if (message != null) {
+                messageProcesser.convertAndSend(message);
+            }
+            return response;
+        } catch (Exception e) {
+            response.setFail("调用物理世界接口获取设备类型下的设备失败!");
+            e.printStackTrace();
+            return response;
+        }
+    }
+
+    /**
+     * @description: 当报警匹配条件修改时,批量更新对应的报警定义
+     * @param: itemCode 报警条目编码
+     * @param: classCode 对象类型编码
+     * @param: projectId 项目id
+     * @param: groupCode 集团编码
+     * @return: com.persagy.common.web.MapResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/20 11:30 上午
+     * @version: V1.0
+     */
+    @Transactional
+    @Override
+    public MapResponse batchUpdateWhenTargetUpdate(String targetId, String projectId, String groupCode, String appId) {
+        MapResponse response = new MapResponse();
+        AlarmTarget alarmTarget = alarmTargetService.get(targetId);
+        if (alarmTarget == null) {
+            response.setFail("自动生成报警定义失败,获取不到对应的报警匹配条件!targetId:" + targetId);
+            return response;
+        }
+        String itemCode = alarmTarget.getItemCode();
+        String classCode = alarmTarget.getClassCode();
+
+        /* 获取到报警匹配条件和报警条目对象 */
+        AlarmItem itemModel = alarmItemService.getAlarmItemByItemCode(itemCode, projectId, groupCode, appId);
+        if (itemModel == null) {
+            response.setFail("自动生成报警定义失败,获取不到对应的报警条目!itemCode:" + itemCode);
+            return response;
+        }
+
+        Set<String> objIds = new HashSet<>();
+        try {
+            /* 查询设备类型下的所有设备 */
+            objIds = physicalWorldService.queryObjectIdListByClassCode(projectId, groupCode, classCode);
+        } catch (Exception e) {
+            response.setFail("调用物理世界接口获取设备类型下的设备失败!");
+            e.printStackTrace();
+            return response;
+        }
+        // 统计需要删除和需要重新生成的报警定义
+        Map<String, List<AlarmConfig>> statisticMap = statisticConfigs2Update(objIds, projectId, alarmTarget, itemModel);
+        if (statisticMap == null) {
+            return response;
+        }
+        /* 删掉需要删除的报警定义,生成需要重新生成的报警定义 */
+        List<AlarmConfig> deletedAlarmConfigs = statisticMap.get("deleted");
+        List<AlarmConfig> createdAlarmConfigs = statisticMap.get("created");
+        DmpMessage message = saveAndDeleteAll(createdAlarmConfigs, deletedAlarmConfigs);
+        if (message != null) {
+            messageProcesser.convertAndSend(message);
+        }
+        return response;
+    }
+
+    /**
+     * @return DmpMessage
+     * @description: 删除报警定义,并推送删除消息
+     * @param: deletedAlarmConfigs
+     * @return: void
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/26 11:14 上午
+     * @version: V1.0
+     */
+    private DmpMessage deleteAll(List<AlarmConfig> deletedAlarmConfigs) {
+        if (!CollectionUtils.isEmpty(deletedAlarmConfigs)) {
+            DmpMessage message = generateMessage(null, deletedAlarmConfigs);
+            removeByIds(deletedAlarmConfigs.stream().map(AlarmConfig::getId).collect(Collectors.toList()));
+            return message;
+        }
+        return null;
+    }
+
+    /**
+     * @description: 创建报警定义,并推送创建消息
+     * @param: createdAlarmConfigs
+     * @return: com.persagy.dmp.rwd.model.DmpMessage
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/26 10:18 下午
+     * @version: V1.0
+     */
+    private DmpMessage saveAll(List<AlarmConfig> createdAlarmConfigs) {
+        if (!CollectionUtils.isEmpty(createdAlarmConfigs)) {
+            DmpMessage message = generateMessage(createdAlarmConfigs, null);
+            saveBatch(createdAlarmConfigs);
+            return message;
+        }
+        return null;
+    }
+
+    /**
+     * @description: 创建、删除报警定义,并推送相关消息
+     * @param: createdConfigs
+     * @param: deletedConfigs
+     * @return: com.persagy.dmp.rwd.model.DmpMessage
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/26 10:20 下午
+     * @version: V1.0
+     */
+    private DmpMessage saveAndDeleteAll(List<AlarmConfig> createdConfigs, List<AlarmConfig> deletedConfigs) {
+        DmpMessage message = generateMessage(createdConfigs, deletedConfigs);
+        /* 先删后加 */
+        if (!CollectionUtils.isEmpty(deletedConfigs)) {
+            removeByIds(deletedConfigs.stream().map(AlarmConfig::getId).collect(Collectors.toList()));
+        }
+        if (!CollectionUtils.isEmpty(createdConfigs)) {
+            saveBatch(createdConfigs);
+        }
+        return message;
+    }
+
+
+    /**
+     * @description: 报警定义变动,生成需要推送的消息
+     * @param: createdConfigs 新增的报警定义
+     * @param: deletedConfigs 删除的报警定义
+     * @return: com.persagy.dmp.rwd.model.DmpMessage
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/26 11:34 上午
+     * @version: V1.0
+     */
+    private DmpMessage generateMessage(List<AlarmConfig> createdConfigs, List<AlarmConfig> deletedConfigs) {
+        List<AlarmConfig.AlarmConfigUnique> createdConfigUniques = null;
+        List<AlarmConfig.AlarmConfigUnique> deletedConfigUniques = null;
+        if (!CollectionUtils.isEmpty(createdConfigs)) {
+            createdConfigUniques = createdConfigs.stream().map(
+                    AlarmConfig::getAlarmConfigUnique).collect(Collectors.toList());
+        }
+        if (!CollectionUtils.isEmpty(deletedConfigs)) {
+            deletedConfigUniques = deletedConfigs.stream().map(
+                    AlarmConfig::getAlarmConfigUnique).collect(Collectors.toList());
+        }
+        if (!CollectionUtils.isEmpty(createdConfigUniques) || !CollectionUtils.isEmpty(deletedConfigUniques)) {
+            DmpMessage msg = new DmpMessage();
+            msg.setMid(UUID.randomUUID().toString());
+            msg.setType(EnumAlarmMessageType.ALARM_CONFIGS_CHANGE.getValue());
+            msg.setGroupCode(DmpParameterStorage.getGroupCode());
+            msg.setProjectId(DmpParameterStorage.getProjectId());
+            msg.add("createdConfigUniques", createdConfigUniques);
+            msg.add("deletedConfigUniques", deletedConfigUniques);
+            msg.setAppId(DmpParameterStorage.getAppId());
+            msg.setSendTime(DateUtil.format(new Date(), DatePatternStyle.PATTERN_YYYYMMDDHHMMSS));
+            return msg;
+        }
+        return null;
+    }
+
+    /**
+     * @description: 按照报警匹配条件统计需要删除和重新创建的报警定义
+     * @param: objIds 设备id列表
+     * @param: projectId 项目id
+     * @param: AlarmTarget 报警匹配条件
+     * @param: itemModel 报警条目
+     * @return: java.util.Map<java.lang.String, java.util.List < com.persagy.dmp.alarm.entity.AlarmConfig>>
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/21 2:50 下午
+     * @version: V1.0
+     */
+    private Map<String, List<AlarmConfig>> statisticConfigs2Update(
+            Set<String> objIds, String projectId, AlarmTarget AlarmTarget, AlarmItem itemModel) {
+        log.info("设备id列表:" + objIds);
+        if (objIds == null) {
+            return null;
+        }
+        /* 查询这些设备的报警定义 */
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("objId", Lists.newArrayList(objIds));
+        criteria.getCriteria().put("targetId", AlarmTarget.getId());
+        criteria.getCriteria().put("itemCode", itemModel.getCode());
+        criteria.getCriteria().put("projectId", projectId);
+        List<AlarmConfig> configModels = queryList(criteria);
+        // configModels为空,是因为查询发生了错误,正常情况下没有数据configModels也不是null
+        if (configModels == null) {
+            return null;
+        }
+        /* 确认要更新的范围,自定义的报警定义不处理 */
+        // 用户自定义的报警定义
+        List<AlarmConfig> userDefinedAlarmConfigs = configModels.stream().filter(
+                configModel -> configModel.getUserDefined() == 1
+        ).collect(Collectors.toList());
+        // 自动生成的报警定义
+        List<AlarmConfig> autoAlarmConfigs = configModels.stream().filter(
+                configModel -> configModel.getUserDefined() != 1
+        ).collect(Collectors.toList());
+        /* 获取本次需要自动生成报警定义的对象id列表 */
+        Set<String> userDefinedObjIds = userDefinedAlarmConfigs.stream().map(AlarmConfig::getObjId).collect(Collectors.toSet());
+        objIds.removeAll(userDefinedObjIds);
+        /* 删掉自动生成的报警定义,按照新的匹配条件生成新的报警定义 */
+        Map<String, List<AlarmConfig>> statisticMap = new HashMap<>();
+        statisticMap.put("deleted", autoAlarmConfigs);
+
+        if (!CollectionUtils.isEmpty(objIds)) {
+            JSONObject condition = alarmTargetService.getCondition(AlarmTarget, itemModel);
+            List<AlarmConfig> alarmConfigs = new ArrayList<>();
+            for (String objId : objIds) {
+                AlarmConfig alarmConfig = generateAlarmConfigEntity(objId, AlarmTarget, itemModel, condition);
+                alarmConfigs.add(alarmConfig);
+            }
+            statisticMap.put("created", alarmConfigs);
+        }
+        return statisticMap;
+    }
+
+    public AlarmConfig get(String id) {
+        return getById(id);
+    }
+
+    @Transactional
+    public MapResponse update(AlarmConfig param) {
+        MapResponse response = new MapResponse();
+        AlarmConfig alarmConfig = get(param.getId());
+        if (alarmConfig == null) {
+            response.setFail("无法获取到要更新的数据!");
+            return response;
+        }
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+        updateEntityByParam(param, alarmConfig);
+        //		// 发生更新后,报警定义的自定义状态修改为1
+        //		alarmConfig.setUserDefined(1);
+        alarmConfig.setUpdateUser(alarmParam.userId);
+        alarmConfig.setUpdateTime(new Date());
+        save(alarmConfig);
+        response.add("id", alarmConfig.getId());
+        // 报警定义发生变化,向mq推送消息
+        DmpMessage msg = getUpdateConfigsDmpMessage(Lists.newArrayList(alarmConfig));
+        if (msg != null) {
+            response.add(msg);
+        }
+        return response;
+    }
+
+    /**
+     * 获取更新报警定义消息
+     *
+     * @param alarmConfigList 更新的报警定义id
+     * @return 更新消息
+     * @author lixing
+     * @version V1.0 2021/3/27 3:30 下午
+     */
+    private DmpMessage getUpdateConfigsDmpMessage(List<AlarmConfig> alarmConfigList) {
+        if (CollectionUtils.isEmpty(alarmConfigList)) {
+            return null;
+        }
+        DmpMessage msg = new DmpMessage();
+        msg.setMid(UUID.randomUUID().toString());
+        msg.setType(EnumAlarmMessageType.ALARM_CONFIGS_CHANGE.getValue());
+        msg.setGroupCode(DmpParameterStorage.getGroupCode());
+        msg.setProjectId(DmpParameterStorage.getProjectId());
+        List<AlarmConfig.AlarmConfigUnique> alarmConfigUniqueList = alarmConfigList.stream().
+                map(AlarmConfig::getAlarmConfigUnique).collect(Collectors.toList());
+        msg.add("updatedConfigUniques", alarmConfigUniqueList);
+        msg.setAppId(DmpParameterStorage.getAppId());
+        msg.setSendTime(DateUtil.format(new Date(), DatePatternStyle.PATTERN_YYYYMMDDHHMMSS));
+        return msg;
+    }
+
+
+    /**
+     * @description: 根据更新条件更新实体
+     * @param: param
+     * @param: alarmConfig
+     * @return: void
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/22 2:52 下午
+     * @version: V1.0
+     */
+    private void updateEntityByParam(AlarmConfig param, AlarmConfig alarmConfig) {
+        // 报警等级
+        if (param.getLevel() != null && !param.getLevel().isEmpty()) {
+            alarmConfig.setLevel(param.getLevel());
+        }
+        // 触发条件
+        if (param.getCondition() != null && !param.getCondition().isEmpty()) {
+            alarmConfig.setCondition(param.getCondition());
+        }
+        // 备注
+        if (param.getRemark() != null && !param.getRemark().isEmpty()) {
+            alarmConfig.setRemark(param.getRemark());
+        }
+        // 是否重点关注
+        if (param.getConcern() != null) {
+            alarmConfig.setConcern(param.getConcern());
+        }
+        // 是否屏蔽
+        if (param.getOpen() != null) {
+            alarmConfig.setOpen(param.getOpen());
+        }
+        // 报警定义的自定义状态
+        if (param.getUserDefined() != null) {
+            alarmConfig.setUserDefined(param.getUserDefined());
+        }
+    }
+
+    /**
+     * @description: 删除设备时,同时删除设备对应的报警定义
+     * @param: objId 对象id
+     * @param: projectId 项目id
+     * @return: com.persagy.common.web.MapResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/20 9:51 下午
+     * @version: V1.0
+     */
+    @Transactional
+    @Override
+    public MapResponse deleteOnRemoveObj(String objId, String projectId) {
+        /* 查询设备相关的报警定义 */
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("objId", objId);
+        criteria.getCriteria().put("projectId", projectId);
+        MapResponse response = new MapResponse();
+        deleteByCriteria(criteria);
+        return response;
+    }
+
+    /**
+     * @description: 条件查询
+     * @param: criteria
+     * @return: java.util.List<com.persagy.dmp.alarm.model.AlarmConfig>
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/21 2:22 下午
+     * @version: V1.0
+     */
+    private List<AlarmConfig> queryList(JsonCriteria criteria) {
+        PagedResponse<AlarmConfig> pagedResponse = query(criteria);
+        if (pagedResponse == null) {
+            return null;
+        }
+        return pagedResponse.getData();
+    }
+
+    /**
+     * @description: 初始化所有报警定义
+     * @param: param
+     * @return: com.persagy.common.web.MapResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/21 3:08 下午
+     * @version: V1.0
+     */
+    @Transactional
+    public MapResponse init(AlarmConfig param) {
+        MapResponse response = new MapResponse();
+        if (StringUtils.isEmpty(param.getProjectId())) {
+            response.setFail("项目id必填!");
+        }
+        JsonCriteria criteria = new JsonCriteria();
+        ;
+
+        List<AlarmItem> AlarmItems = alarmItemService.queryList(criteria);
+        for (AlarmItem AlarmItem : AlarmItems) {
+            batchUpdateWhenItemUpdate(AlarmItem.getCode(), param.getProjectId(), param.getGroupCode());
+        }
+        return response;
+    }
+
+    /**
+     * @description: 批量更新报警定义
+     * @param: param
+     * @return: com.persagy.common.web.MapResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/22 2:38 下午
+     * @version: V1.0
+     */
+    @Transactional
+    public MapResponse batchUpdate(List<AlarmConfig> params) {
+        MapResponse response = new MapResponse();
+        if (params == null) {
+            response.setFail("请传入要修改的报警定义!");
+            return response;
+        }
+
+        // 一次最多更新200条数据
+        if (params.size() > 200) {
+            response.setFail("一次最多更新200条数据");
+            return response;
+        }
+
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+
+        /* 更新报警定义对象 */
+        Date date = new Date();
+        List<AlarmConfig> configs = Lists.newArrayListWithCapacity(params.size());
+        for (AlarmConfig param : params) {
+            String checkResult = CheckRequiredParam.check(param, "id");
+            if (!StringUtils.isEmpty(checkResult)) {
+                response.setFail(checkResult);
+                return response;
+            }
+
+            AlarmConfig alarmConfig = getById(param.getId());
+            updateEntityByParam(param, alarmConfig);
+            configs.add(alarmConfig);
+        }
+        saveBatch(configs);
+        DmpMessage updateConfigsDmpMessage = getUpdateConfigsDmpMessage(configs);
+        messageProcesser.convertAndSend(updateConfigsDmpMessage);
+        Date date1 = new Date();
+        System.out.println("执行时间:" + (date1.getTime() - date.getTime()));
+        return response;
+    }
+
+    /**
+     * @description: 创建报警定义
+     * @param: param
+     * @return: com.persagy.common.web.MapResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/11/25 9:38 上午
+     * @version: V1.0
+     */
+    public MapResponse create(AlarmConfig param) {
+        MapResponse response = new MapResponse();
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+        AlarmConfig entity = initAlarmConfigEntity(param, alarmParam, response);
+        if (entity == null) {
+            return response;
+        }
+        save(entity);
+        // 发送报警定义创建消息
+        DmpMessage msg = generateMessage(Lists.newArrayList(entity), null);
+        messageProcesser.convertAndSend(msg);
+        response.add("id", entity.getId());
+        return response;
+    }
+
+    private AlarmConfig initAlarmConfigEntity(AlarmConfig entity, AlarmParam alarmParam, MapResponse response) {
+        // 必填项校验
+        String checkResult = CheckRequiredParam.check(entity,
+                "objId", "classCode", "itemCode", "condition", "level");
+
+        if (!StringUtils.isEmpty(checkResult)) {
+            response.setFail(checkResult);
+            return null;
+        }
+        entity.setId(UUID.randomUUID().toString());
+        entity.setCreateUser(alarmParam.userId);
+        entity.setCreateTime(new Date());
+        entity.setValid(1);
+        entity.setProjectId(alarmParam.projectId);
+        entity.setGroupCode(alarmParam.groupCode);
+        return entity;
+    }
+
+    /**
+     * 批量创建报警定义
+     *
+     * @param configModels 报警定义列表
+     * @return 报警定义id列表
+     * @author lixing
+     * @version V1.0 2021/10/11 8:08 下午
+     */
+    public MapResponse batchCreate(List<AlarmConfig> configModels) {
+        MapResponse response = new MapResponse();
+        if (configModels == null) {
+            response.setFail("请传入要创建的报警定义!");
+            return response;
+        }
+
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+        Date date = new Date();
+        List<AlarmConfig> configs = new ArrayList<>(configModels.size());
+        for (AlarmConfig configModel : configModels) {
+            AlarmConfig entity = initAlarmConfigEntity(configModel, alarmParam, response);
+            if (entity == null) {
+                response.setFail("批量创建报警条件失败,参数中存在null对象");
+                return response;
+            }
+            configs.add(entity);
+        }
+        try {
+            saveBatch(configs);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        Date date1 = new Date();
+        System.out.println("报警定义存储完成,耗时:" + (date1.getTime() - date.getTime()));
+        DmpMessage msg = generateMessage(configs, null);
+        messageProcesser.convertAndSend(msg);
+        List<String> ids = configs.stream().map(AlarmConfig::getId).collect(Collectors.toList());
+        date1 = new Date();
+        System.out.println("执行时间:" + (date1.getTime() - date.getTime()));
+        response.add("ids", ids);
+        return response;
+    }
+
+    /**
+     * @description: 报警匹配条件删除时,删除对应的报警定义
+     * @param: targetId
+     * @param: projectId
+     * @param: groupCode
+     * @return: com.persagy.common.web.MapResponse
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/12/10 11:45 上午
+     * @version: V1.0
+     */
+    @Transactional
+    @Override
+    public MapResponse batchDeleteWhenTargetDelete(String targetId, String projectId, String groupCode) {
+        MapResponse mapResponse = new MapResponse();
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("targetId", targetId);
+        criteria.getCriteria().put("projectId", projectId);
+        criteria.getCriteria().put("groupCode", groupCode);
+        // 非用户自定义的
+        criteria.getCriteria().put("userDefined", 0);
+        deleteByCriteria(criteria);
+        return mapResponse;
+    }
+
+    /**
+     * @description: 根据条件删除
+     * @param: criteria
+     * @return: void
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/12/10 2:04 下午
+     * @version: V1.0
+     */
+    private void deleteByCriteria(JsonCriteria criteria) {
+        List<AlarmConfig> configs = queryList(criteria);
+        if (configs == null) {
+            return;
+        }
+        DmpMessage deletedMessage = deleteAll(configs);
+        if (deletedMessage != null) {
+            messageProcesser.convertAndSend(deletedMessage);
+        }
+    }
+
+    /**
+     * 删除报警定义,真删
+     *
+     * @param param 报警定义对象AlarmConfig,只取id
+     * @return 是否删除成功
+     * @author lixing
+     * @version V1.0 2021/3/20 10:49 上午
+     */
+    public MapResponse delete(AlarmConfig param) {
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("id", param.getId());
+        deleteByCriteria(criteria);
+        return new MapResponse();
+    }
+
+    /**
+     * 批量删除报警定义,真删
+     *
+     * @param param 批量删除对象AlarmConfigs
+     * @return 是否删除成功
+     * @author lixing
+     * @version V1.0 2021/3/20 10:59 上午
+     */
+    @Transactional
+    public MapResponse batchDelete(AlarmConfig param) {
+        MapResponse response = new MapResponse();
+        List<AlarmConfig> alarmConfigs = param.getAlarmConfigs();
+        if (CollectionUtils.isEmpty(alarmConfigs)) {
+            response.setFail("批量删除报警定义,没有传入需要删除的对象");
+            return response;
+        }
+
+        List<String> configIds = alarmConfigs.stream().map(AlarmConfig::getId).collect(Collectors.toList());
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("id", configIds);
+        deleteByCriteria(criteria);
+
+        return response;
+    }
+}

+ 205 - 0
src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmItemServiceImpl.java

@@ -0,0 +1,205 @@
+package com.persagy.apm.dmpalarm.service.impl;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.persagy.apm.dmpalarm.criteria.CriteriaUtils;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.enumeration.EnumAlarmMessageType;
+import com.persagy.apm.dmpalarm.model.AlarmItem;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmItemService;
+import com.persagy.apm.dmpalarm.utils.DatePatternStyle;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import cn.hutool.core.date.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 报警条目(AlarmItem) service层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+@Service("dmpAlarmItemService")
+@Slf4j
+public class AlarmItemServiceImpl extends BaseServiceImpl<AlarmItem>
+        implements IAlarmItemService {
+    @Resource
+    private CriteriaUtils criteriaUtils;
+
+
+    @Override
+    public PagedResponse<AlarmItem> query(JsonCriteria criteria) {
+        // 报警条目查询中的0代表的是通用
+        try {
+            addDefaultQueryCondition(criteria, "projectId", "0");
+            addDefaultQueryCondition(criteria, "groupCode", "0");
+            addDefaultQueryCondition(criteria, "appId", "0");
+            QueryWrapper<AlarmItem> queryWrapper = criteriaUtils.handleAlarmConditions(criteria, AlarmItem.class);
+            return criteriaUtils.getPagedResponse(criteria, AlarmItem.class, queryWrapper, getBaseMapper());
+        } catch (Exception e) {
+            log.error("AlarmItem query page error JsonCriteria is {}",criteria.toString(), e);
+        }
+        return new PagedResponse<>();
+    }
+
+    /**
+     * @description: 添加默认查询条件
+     * 例如:当传入的查询条件中projectId = 1时,实际需要查询projectId = [0, 1]的数据,使用此方法将0添加到查询条件中
+     * @param: criteria
+     * @param: paramName
+     * @param: defaultCondition
+     * @return: void
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/12/5 5:29 下午
+     * @version: V1.0
+     */
+    private void addDefaultQueryCondition(JsonCriteria criteria, String paramName, String defaultCondition) {
+        // 这里不校验已有查询条件和默认查询条件是否重复
+        JSONObject queryBody = criteria.getCriteria();
+        Object obj = queryBody.get(paramName);
+        if (obj == null) {
+            queryBody.put(paramName, defaultCondition);
+        } else if (obj instanceof JSONArray || obj instanceof List) {
+            ((JSONArray) obj).add(defaultCondition);
+        } else {
+            List<String> conditions = new ArrayList<>();
+            conditions.add(defaultCondition);
+            conditions.add(obj.toString());
+            queryBody.put(paramName, conditions);
+        }
+    }
+
+    @Transactional
+    @Override
+    public MapResponse create(AlarmItem entity) {
+        MapResponse response = new MapResponse();
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+
+        entity.setCreateUser(alarmParam.userId);
+        entity.setCreateTime(new Date());
+        save(entity);
+        response.add("id", entity.getId());
+        /* 拼装需要推送至消息队列的消息 */
+        DmpMessage msg = new DmpMessage();
+        msg.setMid(UUID.randomUUID().toString());
+        msg.setType(EnumAlarmMessageType.ALARM_ITEM_CREATE.getValue());
+        msg.setGroupCode(alarmParam.groupCode);
+        msg.setProjectId(alarmParam.projectId);
+        msg.setTargetId(entity.getId());
+        msg.setStr1(entity.getCode());
+        msg.setAppId(alarmParam.appId);
+        msg.setSendTime(DateUtil.format(new Date(), DatePatternStyle.PATTERN_YYYYMMDDHHMMSS));
+        response.add(msg);
+        return response;
+    }
+
+    @Transactional
+    @Override
+    public MapResponse update(AlarmItem entity) {
+        MapResponse response = new MapResponse();
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+        entity.setUpdateUser(alarmParam.userId);
+        entity.setUpdateTime(new Date());
+        save(entity);
+        response.add("id", entity.getId());
+        /* 拼装需要推送至消息队列的消息 */
+        DmpMessage msg = new DmpMessage();
+        msg.setMid(UUID.randomUUID().toString());
+        msg.setType(EnumAlarmMessageType.ALARM_ITEM_UPDATE.getValue());
+        msg.setGroupCode(alarmParam.groupCode);
+        msg.setProjectId(alarmParam.projectId);
+        msg.setTargetId(entity.getId());
+        msg.setStr1(entity.getCode());
+        msg.setAppId(alarmParam.appId);
+        msg.setSendTime(DateUtil.format(new Date(), DatePatternStyle.PATTERN_YYYYMMDDHHMMSS));
+        response.add(msg);
+        return response;
+    }
+
+    /**
+     * @description: 根据itemCodes获取itemCode, alarmItem的映射map
+     * @param: itemCodes 报警条目编码列表
+     * @return: java.util.HashMap<java.lang.String, com.persagy.dmp.alarm.model.AlarmItem>
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/20 2:25 下午
+     * @version: V1.0
+     */
+    public Map<String, AlarmItem> getItemCodeModelMap(List<String> itemCodes) {
+        HashMap<String, AlarmItem> itemCodeModelMap = new HashMap<>();
+        if (CollectionUtils.isEmpty(itemCodes)) {
+            return itemCodeModelMap;
+        }
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("itemCode", itemCodes);
+        PagedResponse<AlarmItem> response = query(criteria);
+        if (response == null) {
+            return itemCodeModelMap;
+        }
+        List<AlarmItem> data = response.getData();
+        if (CollectionUtils.isEmpty(data)) {
+            return itemCodeModelMap;
+        }
+        return data.stream().collect(
+                Collectors.toMap(AlarmItem::getCode, itemModel -> itemModel, (k1, k2) -> k1)
+        );
+    }
+
+    public AlarmItem getAlarmItemByItemCode(String itemCode, String projectId, String groupCode, String appId) {
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("code", itemCode);
+        if (StringUtils.isNotEmpty(projectId)) {
+            criteria.getCriteria().put("projectId", projectId);
+        }
+        if (StringUtils.isNotEmpty(groupCode)) {
+            criteria.getCriteria().put("groupCode", groupCode);
+        }
+        if (StringUtils.isNotEmpty(appId)) {
+            criteria.getCriteria().put("appId", appId);
+        }
+        List<AlarmItem> AlarmItems = queryList(criteria);
+        if (CollectionUtils.isEmpty(AlarmItems)) {
+            return null;
+        }
+        return AlarmItems.get(0);
+    }
+    @Override
+    public List<AlarmItem> queryList(JsonCriteria criteria) {
+        PagedResponse<AlarmItem> pagedResponse = query(criteria);
+        if (pagedResponse == null) {
+            return null;
+        }
+        List<AlarmItem> data = pagedResponse.getData();
+        if (CollectionUtils.isEmpty(data)) {
+            return null;
+        }
+        return data;
+    }
+}

+ 119 - 0
src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmLogServiceImpl.java

@@ -0,0 +1,119 @@
+package com.persagy.apm.dmpalarm.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.enumeration.EnumAlarmLogType;
+import com.persagy.apm.dmpalarm.model.AlarmLog;
+import com.persagy.apm.dmpalarm.service.IAlarmLogService;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+
+/**
+ * 报警日志(AlarmLog) service层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+@Slf4j
+@Service
+public class AlarmLogServiceImpl extends BaseServiceImpl<AlarmLog> implements IAlarmLogService {
+
+    @Override
+    @Transactional
+    public MapResponse create(AlarmLog entity) {
+        MapResponse response = new MapResponse();
+        try {
+            AlarmParam alarmParam = prepareParam(response);
+            if (alarmParam == null) {
+                return response;
+            }
+            entity.setId(UUID.randomUUID().toString());
+            entity.setCreateTime(new Date());
+            entity.setProjectId(alarmParam.projectId);
+            entity.setGroupCode(alarmParam.groupCode);
+            entity.setCreateUser(alarmParam.userId);
+            save(entity);
+            response.add("id", entity.getId());
+        } catch (Exception e) {
+           log.error("alarmLog create error" ,e);
+        }
+        return response;
+    }
+
+    @Override
+    public PagedResponse<AlarmLog> query(JsonCriteria criteria) {
+        try {
+            QueryWrapper<AlarmLog> queryWrapper = criteriaUtils.handleAlarmConditions(criteria, AlarmLog.class);
+            return  criteriaUtils.getPagedResponse(criteria, AlarmLog.class, queryWrapper, baseMapper);
+        } catch (Exception e) {
+           log.error("alarmLog query page error JsonCriteria is {}",criteria.toString(),e);
+        }
+        return new PagedResponse<>();
+    }
+    /**
+     * 根据报警记录id批量获取 日志信息集合
+     * @param recordIdList  记录id
+     * @return map
+     */
+    @Override
+    public Map<String,List<AlarmLog>> getAlarmLogMap(List<String> recordIdList) {
+        JsonCriteria criteria=new JsonCriteria();
+        criteria.getCriteria().put("recordId",recordIdList);
+        QueryWrapper<AlarmLog> queryWrapper = criteriaUtils.handleAlarmConditions(criteria, AlarmLog.class);
+        PagedResponse<AlarmLog> resp = criteriaUtils.getPagedResponse(criteria, AlarmLog.class, queryWrapper, getBaseMapper());
+        List<AlarmLog> logs = resp.getData();
+        if (CollectionUtils.isEmpty(logs)) {
+            return new HashMap<>();
+        } else {
+            Map<String,List<AlarmLog>> alarmLogListMap = new HashMap<>();
+            logs.forEach(alarmLog -> {
+                if (!alarmLogListMap.containsKey(alarmLog.getRecordId())){
+                    alarmLogListMap.put(alarmLog.getRecordId(),new ArrayList<>());
+                }
+                alarmLogListMap.get(alarmLog.getRecordId()).add(alarmLog);
+            });
+            return alarmLogListMap;
+        }
+    }
+
+    /**
+     * 获取忽略报警的时间
+     * @param recordId
+     * @return
+     */
+    @Override
+    public Date getIgnoreAlarmTime(String recordId) {
+        // 已忽略
+        int after = 1;
+        return getCreateTime(recordId, EnumAlarmLogType.TREATMODE, after);
+    }
+
+    /**
+     * 查询日志创建时间
+     * @param recordId 报警记录id
+     * @param type 日志了下
+     * @param after
+     * @return
+     */
+    private Date getCreateTime(String recordId, EnumAlarmLogType type, int after) {
+        JsonCriteria criteria=new JsonCriteria();
+        criteria.getCriteria().put("recordId", recordId);
+        criteria.getCriteria().put("type", type);
+        criteria.getCriteria().put("after", after);
+        QueryWrapper<AlarmLog> queryWrapper = criteriaUtils.handleAlarmConditions(criteria, AlarmLog.class);
+        PagedResponse<AlarmLog> resp = criteriaUtils.getPagedResponse(criteria, AlarmLog.class, queryWrapper, getBaseMapper());
+        List<AlarmLog> logs = resp.getData();
+        if (CollectionUtils.isEmpty(logs)) {
+            return null;
+        } else {
+            return logs.get(0).getCreateTime();
+        }
+    }
+
+}

+ 325 - 0
src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmRecordServiceImpl.java

@@ -0,0 +1,325 @@
+package com.persagy.apm.dmpalarm.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.persagy.apm.dmpalarm.config.DmpParameterStorage;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.enumeration.*;
+import com.persagy.apm.dmpalarm.json.JacksonMapper;
+import com.persagy.apm.dmpalarm.model.AlarmLog;
+import com.persagy.apm.dmpalarm.model.AlarmRecord;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmLogService;
+import com.persagy.apm.dmpalarm.service.IAlarmRecordService;
+import com.persagy.apm.dmpalarm.utils.CheckRequiredParam;
+import com.persagy.apm.dmpalarm.utils.DatePatternStyle;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+/**
+ * 报警记录(AlarmRecord) service层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+@Service("dmpAlarmRecordService")
+@Slf4j
+public class AlarmRecordServiceImpl extends BaseServiceImpl<AlarmRecord> implements IAlarmRecordService {
+
+    @Resource
+    private IAlarmLogService alarmLogService;
+
+
+    @Override
+    public PagedResponse<AlarmRecord> query(JsonCriteria jsonCriteria) {
+        try {
+            QueryWrapper<AlarmRecord> queryWrapper = criteriaUtils.handleAlarmConditions(jsonCriteria, AlarmRecord.class);
+            this.addAlarmQueryCondition(jsonCriteria.getCriteria(), queryWrapper);
+            PagedResponse<AlarmRecord> resp = criteriaUtils.getPagedResponse(jsonCriteria, AlarmRecord.class, queryWrapper, baseMapper);
+
+            PagedResponse<AlarmRecord> resultAlarmRecordList = new PagedResponse<>();
+            resultAlarmRecordList.setCount(resp.getCount());
+            List<AlarmRecord> dataList = resp.getData();
+            if (CollectionUtils.isEmpty(dataList)) {
+                return resultAlarmRecordList;
+            }
+
+            // 如果需要查询日志相关的信息,需使用withColumns参数
+            Set<String> withColumns = jsonCriteria.getWithColumns();
+            boolean withLogInfo = !CollectionUtils.isEmpty(withColumns);
+
+            Map<String, List<AlarmLog>> alarmLogListMap = new HashMap<>();
+            // 获取报警日志
+            if (withLogInfo && (withColumns.contains(EnumAlarmRecordWithColumns.ignoreTime.name())
+                    || withColumns.contains(EnumAlarmRecordWithColumns.treatEndTime.name()))) {
+                List<String> recordIdList = new ArrayList<>();
+                dataList.forEach(alarmRecord -> recordIdList.add(alarmRecord.getId()));
+                alarmLogListMap = alarmLogService.getAlarmLogMap(recordIdList);
+            }
+
+            List<AlarmRecord> alarmRecordModels = new ArrayList<>(dataList.size());
+            for (AlarmRecord entity : dataList) {
+                alarmRecordModels.add(entity);
+
+                if (!withLogInfo) {
+                    continue;
+                }
+                // 如果需要日志信息
+                List<AlarmLog> alarmLogList = new ArrayList<>();
+                if (alarmLogListMap.containsKey(entity.getId())) {
+                    alarmLogList = alarmLogListMap.get(entity.getId());
+                }
+                if (withColumns.contains(EnumAlarmRecordWithColumns.ignoreTime.name())) {
+                    Date ignoreAlarmTime = getCreateTime(alarmLogList, EnumAlarmLogType.TREATMODE, 1);
+                    entity.setIgnoreTime(ignoreAlarmTime);
+                }
+                if (withColumns.contains(EnumAlarmRecordWithColumns.treatEndTime.name())) {
+                    Date treatEndTime = getCreateTime(alarmLogList, EnumAlarmLogType.TREATSTATE, 3);
+                    entity.setTreatEndTime(treatEndTime);
+                }
+            }
+            resultAlarmRecordList.setData(alarmRecordModels);
+            return resultAlarmRecordList;
+        } catch (Exception e) {
+            log.error("alarmRecord query page error JsonCriteria is {}", jsonCriteria.toString(), e);
+        }
+        return new PagedResponse<>();
+    }
+
+    public Date getCreateTime(List<AlarmLog> alarmLogList, EnumAlarmLogType type, int after) {
+        Date createTime = null;
+        if (!CollectionUtils.isEmpty(alarmLogList)) {
+            for (AlarmLog alarmLog : alarmLogList) {
+                if (type.equals(alarmLog.getType()) && alarmLog.getAfter() == after) {
+                    createTime = alarmLog.getCreateTime();
+                }
+            }
+        }
+        return createTime;
+    }
+
+    /**
+     * 添加查询报警条件 CURRENT 当前报警 HISTORY 历史报警
+     *
+     * @param <T>           entity object
+     * @param criteria      JSONObject
+     * @param queryWrappers query alarm criteria
+     */
+    private <T> void addAlarmQueryCondition(JSONObject criteria, QueryWrapper<T> queryWrappers) {
+        String listType = criteria.getString("listType");
+        if (EnumAlarmListType.CURRENT.name().equals(listType)) {
+            queryWrappers.and(andWrapper -> andWrapper.eq(AlarmRecord.PROP_STATE, EnumAlarmState.UN_HANDLE.getType())
+                    .or(orw -> orw.eq(AlarmRecord.PROP_TREAT_STATE, EnumAlarmState.UN_HANDLE.getType())
+                            .eq(AlarmRecord.PROP_TREAT_STATE, EnumAlarmTreatState.HANDLING.getType())));
+        }
+
+        if (EnumAlarmListType.HISTORY.name().equals(listType)) {
+            queryWrappers.and(andWrapper -> andWrapper.eq(AlarmRecord.PROP_STATE, EnumAlarmState.END.getType())
+                    .or(orw -> orw.eq(AlarmRecord.PROP_STATE, EnumAlarmState.EXPIRE.getType())
+                            .eq(AlarmRecord.PROP_TREAT_STATE, EnumAlarmTreatState.DONE.getType())));
+
+        }
+    }
+
+    @Override
+    @Transactional
+    public MapResponse create(AlarmRecord entity) {
+        MapResponse response = new MapResponse();
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+        // 必填项校验
+        String checkResult = CheckRequiredParam.check(entity, "itemCode", "objId", "level");
+        if (!StringUtils.isEmpty(checkResult)) {
+            response.setFail(checkResult);
+            return response;
+        }
+
+        String id = UUID.randomUUID().toString();
+        // 如果创建时,入参包含id,则使用入参中的id。但需要先校验id是否已存在
+        if (!StringUtils.isEmpty(entity.getId())) {
+
+            AlarmRecord alarmRecord = getById(entity.getId());
+            if (null != alarmRecord) {
+                response.setFail("已存在相同id的报警记录!创建失败!");
+                return response;
+            } else {
+                id = entity.getId();
+            }
+        }
+        entity.setId(id);
+        entity.setCreateUser(alarmParam.userId);
+        if (entity.getCreateTime() != null) {
+            entity.setCreateTime(entity.getCreateTime());
+        } else {
+            entity.setCreateTime(new Date());
+        }
+        // 默认处理状态为未处理
+        if (entity.getTreatState() == null) {
+            entity.setTreatState(1);
+        }
+        entity.setValid(1);
+        entity.setProjectId(alarmParam.projectId);
+        entity.setGroupCode(alarmParam.groupCode);
+        save(entity);
+        response.add("id", entity.getId());
+        // 推送消息至mq
+        DmpMessage msg = new DmpMessage();
+        msg.setMid(UUID.randomUUID().toString());
+        msg.setType(EnumAlarmMessageType.ALARM_RECORD_CREATE.getValue());
+        return getMapResponse(entity, response, msg);
+    }
+
+    private MapResponse getMapResponse(AlarmRecord entity, MapResponse response, DmpMessage msg) {
+        msg.setGroupCode(DmpParameterStorage.getGroupCode());
+        msg.setProjectId(DmpParameterStorage.getProjectId());
+        msg.setTargetId(entity.getId());
+        msg.add("obj", JacksonMapper.toSimpleJson(entity));
+        msg.setAppId(DmpParameterStorage.getAppId());
+        msg.setSendTime(DateUtil.format(new Date(), DatePatternStyle.PATTERN_YYYYMMDDHHMMSS));
+        response.add(msg);
+        return response;
+    }
+
+    private AlarmLog initAlarmLogModel(AlarmRecord param) {
+        AlarmLog alarmLog = new AlarmLog();
+        alarmLog.setRecordId(param.getId());
+        alarmLog.setCreateTime(new Date());
+        alarmLog.setCreateUser(DmpParameterStorage.getUserId());
+        alarmLog.setProjectId(DmpParameterStorage.getProjectId());
+        alarmLog.setGroupCode(DmpParameterStorage.getGroupCode());
+        return alarmLog;
+    }
+
+    @Override
+    @Transactional
+    public MapResponse update(AlarmRecord param) {
+        MapResponse response = new MapResponse();
+        AlarmRecord alarmRecord = getById(param.getId());
+        if (alarmRecord == null) {
+            response.setFail("无法获取到要更新的数据!");
+            return response;
+        }
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+        if (param.getName() != null && !param.getName().isEmpty()) {
+            alarmRecord.setName(param.getName());
+        }
+        if (param.getRemark() != null && !param.getRemark().isEmpty()) {
+            alarmRecord.setRemark(param.getRemark());
+        }
+        // 状态修改记录日志
+        if (param.getState() != null) {
+            if (!param.getState().equals(alarmRecord.getState())) {
+                AlarmLog alarmLog = initAlarmLogModel(param);
+                alarmLog.setType(EnumAlarmLogType.ALARMSTATE);
+                alarmLog.setNature(alarmRecord.getNature());
+                alarmLog.setBefore(alarmRecord.getState());
+                alarmLog.setAfter(param.getState());
+                alarmLogService.create(alarmLog);
+            }
+            alarmRecord.setState(param.getState());
+        }
+        if (param.getNature() != null) {
+            alarmRecord.setNature(param.getNature());
+        }
+        // 处理方式修改记录日志
+        if (param.getTreatMode() != null) {
+            if (!param.getTreatMode().equals(alarmRecord.getTreatMode())) {
+                AlarmLog alarmLogModel = initAlarmLogModel(param);
+                alarmLogModel.setType(EnumAlarmLogType.TREATMODE);
+                alarmLogModel.setNature(alarmRecord.getNature());
+                alarmLogModel.setBefore(alarmRecord.getTreatMode());
+                alarmLogModel.setAfter(param.getTreatMode());
+                alarmLogService.create(alarmLogModel);
+            }
+            alarmRecord.setTreatMode(param.getTreatMode());
+        }
+        // 处理状态更改记录日志
+        if (param.getTreatState() != null) {
+            if (!param.getTreatState().equals(alarmRecord.getTreatState())) {
+                AlarmLog alarmLogModel = initAlarmLogModel(param);
+                alarmLogModel.setType(EnumAlarmLogType.TREATSTATE);
+                alarmLogModel.setNature(alarmRecord.getNature());
+                alarmLogModel.setBefore(alarmRecord.getTreatState());
+                alarmLogModel.setAfter(param.getTreatState());
+                alarmLogService.create(alarmLogModel);
+            }
+            alarmRecord.setTreatState(param.getTreatState());
+        }
+
+        // 恢复值
+        if (param.getEndInfo() != null) {
+            alarmRecord.setEndInfo(param.getEndInfo());
+        }
+        // 恢复时间
+        if (param.getEndTime() != null) {
+            alarmRecord.setEndTime(param.getEndTime());
+        }
+        // 工单id
+        if (param.getOrderId() != null) {
+            alarmRecord.setOrderId(param.getOrderId());
+        }
+        // 工单状态
+        if (param.getOrderState() != null) {
+            alarmRecord.setOrderState(param.getOrderState());
+        }
+        // 补充说明
+        if (param.getSupplement() != null) {
+            alarmRecord.setSupplement(param.getSupplement());
+        }
+        // 报警等级
+        if (!StringUtils.isEmpty(param.getLevel())) {
+            alarmRecord.setLevel(param.getLevel());
+        }
+        alarmRecord.setUpdateUser(alarmParam.userId);
+        alarmRecord.setUpdateTime(new Date());
+        save(alarmRecord);
+
+        response.add("id", alarmRecord.getId());
+        // 推送消息至mq
+        DmpMessage msg = new DmpMessage();
+        msg.setMid(UUID.randomUUID().toString());
+        msg.setType(EnumAlarmMessageType.ALARM_RECORD_UPDATE.getValue());
+        return getMapResponse(alarmRecord, response, msg);
+
+    }
+
+    @Override
+    @Transactional
+    public MapResponse batchUpdate(AlarmRecord param) {
+        MapResponse response = new MapResponse();
+
+        List<AlarmRecord> alarmRecordModelList = param.getAlarmRecordModels();
+        if (CollectionUtils.isEmpty(alarmRecordModelList)) {
+            response.setFail("批量更新报警记录,没有传入需要更新的对象");
+            return response;
+        }
+
+        // 一次最多更新200条数据
+        if (alarmRecordModelList.size() > 200) {
+            response.setFail("一次最多更新200条数据");
+            return response;
+        }
+
+        List<DmpMessage> msgList = new ArrayList<>();
+        alarmRecordModelList.forEach(alarmRecordModel -> {
+            MapResponse updateResponse = update(alarmRecordModel);
+            msgList.addAll(updateResponse.getMessageList());
+        });
+        response.add(msgList);
+        return response;
+    }
+}

+ 336 - 0
src/main/java/com/persagy/apm/dmpalarm/service/impl/AlarmTargetServiceImpl.java

@@ -0,0 +1,336 @@
+package com.persagy.apm.dmpalarm.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.persagy.apm.dmpalarm.config.DmpParameterStorage;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.enumeration.EnumAlarmMessageType;
+import com.persagy.apm.dmpalarm.model.AlarmItem;
+import com.persagy.apm.dmpalarm.model.AlarmTarget;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+import com.persagy.apm.dmpalarm.service.IAlarmItemService;
+import com.persagy.apm.dmpalarm.service.IAlarmTargetService;
+import com.persagy.apm.dmpalarm.utils.DatePatternStyle;
+import com.persagy.apm.dmpalarm.web.MapResponse;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+import com.persagy.common.utils.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * 报警匹配条件(AlarmTarget) service层
+ *
+ * @author lixing
+ * @version V1.0 2021-12-09 10:44:19
+ */
+@Service
+@Slf4j
+public class AlarmTargetServiceImpl extends BaseServiceImpl<AlarmTarget>
+        implements IAlarmTargetService {
+    @Resource(name="dmpAlarmItemService")
+    private IAlarmItemService alarmItemService;
+
+    public PagedResponse<AlarmTarget> query(JsonCriteria criteria) {
+        try {
+            // 默认查询未删除的数据
+            criteria.getCriteria().put("valid", 1);
+            QueryWrapper<AlarmTarget> queryWrapper = criteriaUtils.handleAlarmConditions(criteria, AlarmTarget.class);
+            PagedResponse<AlarmTarget> resp = criteriaUtils.getPagedResponse(criteria, AlarmTarget.class, queryWrapper, getBaseMapper());
+            PagedResponse<AlarmTarget> result = new PagedResponse<>();
+            result.setCount(resp.getCount());
+            List<AlarmTarget> dataList = resp.getData();
+            if (dataList != null && dataList.size() > 0) {
+                Map<String, AlarmItem> itemCodeModelMap = getItemCodeModelMap(dataList);
+                List<AlarmTarget> collect = dataList.stream().map(entity -> {
+                    // 获取报警条目的触发条件
+                    String itemCode = entity.getItemCode();
+                    entity.setCondition(getCondition(entity, itemCodeModelMap.get(itemCode)));
+                    return entity;
+                }).collect(Collectors.toList());
+                result.setData(collect);
+            }
+            return result;
+        } catch (Exception e) {
+           log.error("alarmTarget query page error JsonCriteria is {}",criteria.toString(),e);
+        }
+        return new PagedResponse<>();
+    }
+
+    @Transactional
+    public MapResponse create(AlarmTarget entity) {
+        MapResponse response = new MapResponse();
+
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+        if (org.springframework.util.StringUtils.isEmpty(entity.getItemCode())) {
+            response.setFail("报警条目编码必填");
+        }
+        if (org.springframework.util.StringUtils.isEmpty(entity.getClassCode())) {
+            response.setFail("对象类型编码必填");
+        }
+
+        // 获取设备条目对象
+        AlarmItem alarmItem = alarmItemService.getAlarmItemByItemCode(entity.getItemCode(), alarmParam.projectId, alarmParam.groupCode, alarmParam.appId);
+        if (alarmItem == null) {
+            response.setFail("无法获取到对应的报警条目,创建失败!");
+            return response;
+        }
+
+        entity.setId(UUID.randomUUID().toString());
+        entity.setCreateUser(alarmParam.userId);
+        entity.setCreateTime(new Date());
+        entity.setProjectId(alarmParam.projectId);
+        entity.setGroupCode(alarmParam.groupCode);
+        // 继承alarmItem的一些属性
+        if (org.springframework.util.StringUtils.isEmpty(entity.getLevel())) {
+            entity.setLevel(alarmItem.getLevel());
+        }
+        save(entity);
+        response.add("id", entity.getId());
+        /* 拼装需要推送至消息队列的消息 */
+        DmpMessage msg = new DmpMessage();
+        msg.setMid(UUID.randomUUID().toString());
+        msg.setType(EnumAlarmMessageType.ALARM_TARGET_CREATE.getValue());
+        msg.setGroupCode(alarmParam.groupCode);
+        msg.setProjectId(alarmParam.projectId);
+        msg.setTargetId(entity.getId());
+        msg.setStr1(entity.getItemCode());
+        msg.setStr2(entity.getClassCode());
+        msg.setAppId(alarmParam.appId);
+        msg.setSendTime(DateUtil.format(new Date(), DatePatternStyle.PATTERN_YYYYMMDDHHMMSS));
+        response.add(msg);
+        return response;
+    }
+
+
+    /**
+     * @description: 判断匹配条件更新是否会影响报警定义
+     * @param: param 匹配条件更新信息
+     * @param: alarmTarget 匹配条件字段
+     * @return: boolean
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/22 8:55 下午
+     * @version: V1.0
+     */
+    private boolean influenceConfigs(AlarmTarget param, AlarmTarget alarmTarget) {
+//        boolean itemCodeChange = !StringUtils.isEmpty(param.getItemCode()) &&
+//                !param.getItemCode().equals(alarmTarget.getItemCode());
+        boolean levelChange = !org.springframework.util.StringUtils.isEmpty(param.getLevel()) &&
+                !param.getLevel().equals(alarmTarget.getLevel());
+        boolean classCodeChange = !org.springframework.util.StringUtils.isEmpty(param.getClassCode()) &&
+                !param.getClassCode().equals(alarmTarget.getClassCode());
+        boolean concernChange = param.getConcern() != null &&
+                !param.getConcern().equals(alarmTarget.getConcern());
+        boolean openChange = param.getOpen() != null &&
+                !param.getOpen().equals(alarmTarget.getOpen());
+        boolean conditionChange = !StringUtils.isEmpty(param.getCondition()) &&
+                !param.getCondition().equals(alarmTarget.getCondition());
+
+        return levelChange || classCodeChange || concernChange || openChange || conditionChange;
+    }
+
+    @Transactional
+    public MapResponse update(AlarmTarget param) {
+        MapResponse response = new MapResponse();
+        AlarmTarget alarmTarget = getById(param.getId());
+        if (alarmTarget == null) {
+            response.setFail("无法获取到要更新的数据!");
+            return response;
+        }
+        AlarmParam alarmParam = prepareParam(response);
+        if (alarmParam == null) {
+            return response;
+        }
+        /* 判断是否会影响报警定义 */
+        boolean influenceConfigs = influenceConfigs(param, alarmTarget);
+
+        if (param.getItemCode() != null && !param.getItemCode().isEmpty()) {
+            alarmTarget.setItemCode(param.getItemCode());
+        }
+//        if (param.getClassCode() != null && !param.getClassCode().isEmpty()) {
+//            alarmTarget.setClassCode(param.getClassCode());
+//        }
+        if (param.getLevel() != null && !param.getLevel().isEmpty()) {
+            alarmTarget.setLevel(param.getLevel());
+        }
+        if (param.getConcern() != null) {
+            alarmTarget.setConcern(param.getConcern());
+        }
+        if (param.getOpen() != null) {
+            alarmTarget.setOpen(param.getOpen());
+        }
+        if (param.getCondition() != null && !param.getCondition().isEmpty()) {
+            alarmTarget.setCondition(param.getCondition());
+        }
+        if (param.getValid() != null) {
+            alarmTarget.setValid(param.getValid());
+        }
+        alarmTarget.setUpdateUser(alarmParam.userId);
+        alarmTarget.setUpdateTime(new Date());
+        save(alarmTarget);
+        response.add("id", alarmTarget.getId());
+        if (influenceConfigs) {
+            /* 拼装需要推送至消息队列的消息 */
+            DmpMessage msg = new DmpMessage();
+            msg.setMid(UUID.randomUUID().toString());
+            msg.setType(EnumAlarmMessageType.ALARM_TARGET_UPDATE.getValue());
+            msg.setGroupCode(alarmParam.groupCode);
+            msg.setProjectId(alarmParam.projectId);
+            msg.setTargetId(alarmTarget.getId());
+            msg.setStr1(alarmTarget.getItemCode());
+            msg.setStr2(alarmTarget.getClassCode());
+            msg.setAppId(alarmParam.appId);
+            msg.setSendTime(DateUtil.format(new Date(), DatePatternStyle.PATTERN_YYYYMMDDHHMMSS));
+            response.add(msg);
+        }
+        return response;
+    }
+
+    @Transactional
+    public MapResponse delete(AlarmTarget param) {
+        MapResponse response = new MapResponse();
+        param.setValid(0);
+        update(param);
+
+        /* 拼装需要推送至消息队列的消息 */
+        DmpMessage msg = new DmpMessage();
+        msg.setMid(UUID.randomUUID().toString());
+        msg.setType(EnumAlarmMessageType.ALARM_TARGET_DELETE.getValue());
+        msg.setGroupCode(DmpParameterStorage.getGroupCode());
+        msg.setProjectId(DmpParameterStorage.getProjectId());
+        msg.setTargetId(param.getId());
+        msg.setStr1(param.getItemCode());
+        msg.setStr2(param.getClassCode());
+        msg.setAppId(DmpParameterStorage.getAppId());
+        msg.setSendTime(DateUtil.format(new Date(), DatePatternStyle.PATTERN_YYYYMMDDHHMMSS));
+        response.add(msg);
+        return response;
+    }
+
+    /**
+     * @description: 根据给定的一组target,获取target所属的报警条目itemCode, alarmItem的映射map
+     * @param: targetModelList
+     * @return: java.util.HashMap<java.lang.String, com.persagy.dmp.alarm.model.AlarmItem>
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/20 2:32 下午
+     * @version: V1.0
+     */
+    @Override
+    public Map<String, AlarmItem> getItemCodeModelMapByModelList(List<AlarmTarget> targetModelList) {
+        List<String> itemCodeList = targetModelList.stream().map(AlarmTarget::getItemCode).collect(Collectors.toList());
+        return alarmItemService.getItemCodeModelMap(itemCodeList);
+    }
+
+    /**
+     * @description: 根据给定的一组target,获取target所属的报警条目itemCode, alarmItem的映射map
+     * @param: targetList
+     * @return: java.util.HashMap<java.lang.String, com.persagy.dmp.alarm.model.AlarmItem>
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/20 2:45 下午
+     * @version: V1.0
+     */
+    public Map<String, AlarmItem> getItemCodeModelMap(List<AlarmTarget> targetList) {
+        List<String> itemCodeList = targetList.stream().map(AlarmTarget::getItemCode).collect(Collectors.toList());
+        return alarmItemService.getItemCodeModelMap(itemCodeList);
+    }
+
+    /**
+     * @description: 获取匹配条件的触发条件:匹配条件自己的触发条件与所属报警条目的触发条件取并集
+     * @param: AlarmTarget 匹配条件对象
+     * @param: AlarmItem 报警条目对象
+     * @return: ObjectNode
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/20 2:07 下午
+     * @version: V1.0
+     */
+    @Override
+    public JSONObject getCondition(AlarmTarget AlarmTarget, AlarmItem alarmItem) {
+        JSONObject result = null;
+        if (AlarmTarget != null && AlarmTarget.getCondition() != null) {
+            result = AlarmTarget.getCondition();
+        } else if (alarmItem != null) {
+            result = alarmItem.getCondition();
+        }
+        return result;
+    }
+
+    /**
+     * @description: 根据报警条目编码和设备类型编码获取匹配条件对象
+     * @param: itemCode 报警条目编码
+     * @param: classCode 设备类型编码
+     * @param: projectId 项目id
+     * @return: com.persagy.dmp.alarm.model.AlarmTarget
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/21 11:53 上午
+     * @version: V1.0
+     */
+    public AlarmTarget getAlarmTarget(String itemCode, String classCode, String projectId) {
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("itemCode", itemCode);
+        criteria.getCriteria().put("classCode", classCode);
+        criteria.getCriteria().put("projectId", projectId);
+        PagedResponse<AlarmTarget> pagedResponse = query(criteria);
+        if (pagedResponse == null) {
+            return null;
+        }
+        List<AlarmTarget> data = pagedResponse.getData();
+        if (CollectionUtils.isEmpty(data)) {
+            return null;
+        }
+        return data.get(0);
+    }
+
+    /**
+     * @description: 根据报警条目编码获取匹配条件对象
+     * @param: itemCode 报警条目编码
+     * @param: projectId 项目id
+     * @return: java.util.List<com.persagy.dmp.alarm.model.AlarmTarget>
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/21 12:13 下午
+     * @version: V1.0
+     */
+    @Override
+    public List<AlarmTarget> getAlarmTargetsByItemCode(String itemCode, String projectId) {
+        JsonCriteria criteria = new JsonCriteria();
+        criteria.getCriteria().put("itemCode", itemCode);
+        criteria.getCriteria().put("projectId", projectId);
+        PagedResponse<AlarmTarget> pagedResponse = query(criteria);
+        if (pagedResponse == null) {
+            return null;
+        }
+        List<AlarmTarget> data = pagedResponse.getData();
+        if (CollectionUtils.isEmpty(data)) {
+            return null;
+        }
+        return data;
+    }
+
+    @Override
+    public AlarmTarget get(String targetId) {
+        return getById(targetId);
+    }
+}

+ 47 - 0
src/main/java/com/persagy/apm/dmpalarm/service/impl/BaseServiceImpl.java

@@ -0,0 +1,47 @@
+package com.persagy.apm.dmpalarm.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.persagy.apm.dmpalarm.config.DmpParameterStorage;
+import com.persagy.apm.dmpalarm.criteria.CriteriaUtils;
+import com.persagy.apm.dmpalarm.web.BaseResponse;
+
+public class BaseServiceImpl<T> extends ServiceImpl<BaseMapper<T>, T> {
+    @Autowired
+    protected CriteriaUtils criteriaUtils;
+
+    protected static class AlarmParam {
+        String groupCode;
+        String userId;
+        String projectId;
+        String appId;
+    }
+
+
+    protected AlarmParam prepareParam(BaseResponse<?> resp) {
+        AlarmParam param = new AlarmParam();
+        param.groupCode = DmpParameterStorage.getGroupCode();
+        param.userId = DmpParameterStorage.getUserId();
+        param.projectId = DmpParameterStorage.getProjectId();
+        param.appId = DmpParameterStorage.getAppId();
+        if (param.userId == null || param.userId.isEmpty()) {
+            resp.setResult("fail");
+            resp.setMessage("userId 必须有值");
+            return null;
+        }
+        if (param.groupCode == null || param.groupCode.isEmpty()) {
+            resp.setResult("fail");
+            resp.setMessage("groupCode 必须有值");
+            return null;
+        }
+        if (param.projectId == null || param.projectId.isEmpty()) {
+            resp.setResult("fail");
+            resp.setMessage("projectId 必须有值");
+            return null;
+        }
+        return param;
+    }
+
+}

+ 82 - 0
src/main/java/com/persagy/apm/dmpalarm/service/impl/PhysicalWorldServiceImpl.java

@@ -0,0 +1,82 @@
+package com.persagy.apm.dmpalarm.service.impl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+
+import org.springframework.stereotype.Service;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Sets;
+import com.persagy.apm.dmpalarm.client.PhysicalWorldClient;
+import com.persagy.apm.dmpalarm.criteria.JsonCriteria;
+import com.persagy.apm.dmpalarm.service.IPhysicalWorldService;
+import com.persagy.apm.dmpalarm.web.PagedResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Service
+@Slf4j
+public class PhysicalWorldServiceImpl implements IPhysicalWorldService {
+
+    @Resource
+    private PhysicalWorldClient physicalWorldClient;
+
+
+    public Set<String> queryObjectIdListByClassCode(
+            @NotNull String projectId,
+            @NotNull String groupCode,
+            @NotNull String classCode) {
+        JsonCriteria criteria=new JsonCriteria();
+        criteria.getCriteria().put("classCode", classCode);
+        criteria.getCriteria().put("valid", 1);
+        PagedResponse<ObjectNode> objectNodePagedResponse = physicalWorldClient.queryObj(projectId, groupCode, criteria);
+        log.info("物理世界查询对象返回值:", objectNodePagedResponse == null ? null : objectNodePagedResponse.toString());
+        List<ObjectNode> data = objectNodePagedResponse.getData();
+        Set<String> objIdList = new HashSet<>();
+        for (ObjectNode obj : data) {
+            String id = obj.get("id").asText();
+            objIdList.add(id);
+        }
+        return objIdList;
+    }
+
+    /**
+     * @description: 查询设备类型和设备id列表的映射关系
+     * @param: projectId
+     * @param: classCodes
+     * @return: java.util.Map
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/10/21 2:27 下午
+     * @version: V1.0
+     */
+    public Map<String, Set<String>> queryCodeIdListMapByClassCodes(
+            @NotNull String projectId,
+            @NotNull String groupCode,
+            @NotNull List<String> classCodes) {
+        JsonCriteria criteria=new JsonCriteria();
+        criteria.getCriteria().put("classCode", classCodes);
+        criteria.getCriteria().put("valid", 1);
+        PagedResponse<ObjectNode> objectNodePagedResponse = physicalWorldClient.queryObj(projectId, groupCode, criteria);
+        log.info("物理世界查询对象返回值:", objectNodePagedResponse == null ? null : objectNodePagedResponse.toString());
+        List<ObjectNode> data = objectNodePagedResponse.getData();
+        Map<String, Set<String>> resultMap = new HashMap<>();
+        for (ObjectNode obj : data) {
+            String id = obj.get("id").asText();
+            String classCode = obj.get("classCode").asText();
+            if (resultMap.get(classCode) == null) {
+                resultMap.put(classCode, Sets.newHashSet(id));
+            } else {
+                resultMap.get(classCode).add(id);
+            }
+        }
+        return resultMap;
+    }
+}

+ 101 - 0
src/main/java/com/persagy/apm/dmpalarm/utils/CheckRequiredParam.java

@@ -0,0 +1,101 @@
+package com.persagy.apm.dmpalarm.utils;
+
+import org.springframework.util.StringUtils;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * @description: 必填项校验
+ * @author: lixing
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/11/25 9:46 上午
+ * @version: V1.0
+ **/
+public class CheckRequiredParam {
+    /**
+     * @description: 反射校验必填项
+     * @param: t
+     * @param: params
+     * @return: java.lang.String
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/11/25 9:49 上午
+     * @version: V1.0
+     */
+    public static <T> String check(T t, String... params) {
+        // message用来存放校验结果
+        StringBuilder message = new StringBuilder();
+        Class<?> clazz = t.getClass();
+        // 校验参数
+        for (String param : params) {
+            if (StringUtils.isEmpty(param)) {
+                message.append("校验必填项参数错误,参数不能为空");
+                return message.toString();
+            }
+            try {
+                // 属性, 这里需要注意getField方法无法获取私有属性,应使用getDeclaredField方法
+                Field field = clazz.getDeclaredField(param);
+                // 属性类型
+                Class<?> fieldType = field.getType();
+
+                // get方法
+                Method method = clazz.getMethod("get" + firstUpperCase(param));
+
+                // 执行get方法,验证是否为空
+                try {
+                    if (fieldType == String.class) {
+                        String result = (String) method.invoke(t);
+                        if (StringUtils.isEmpty(result)) {
+                            message.append(param).append("必填!");
+                        }
+                    } else {
+                        Object result = method.invoke(t);
+                        if (result == null) {
+                            message.append(param).append("必填!");
+                        }
+                    }
+
+                } catch (Exception e) {
+                    message.append(e.getMessage());
+                    return message.toString();
+                }
+
+            } catch (NoSuchFieldException e) {
+                message.append("校验必填项参数错误,").
+                        append(clazz.getSimpleName()).
+                        append("不包含属性:").
+                        append(param);
+                return message.toString();
+            } catch (NoSuchMethodException e) {
+                message.append("校验必填项参数错误,").
+                        append(clazz.getSimpleName()).
+                        append("不包含方法:get").
+                        append(firstUpperCase(param)).
+                        append("()");
+                return message.toString();
+            }
+        }
+        return message.toString();
+    }
+
+    /**
+     * @description: 字符串首字母大写
+     * @param: s
+     * @return: java.lang.String
+     * @exception:
+     * @author: lixing
+     * @company: Persagy Technology Co.,Ltd
+     * @since: 2020/11/25 10:08 上午
+     * @version: V1.0
+     */
+    private static String firstUpperCase(String s) {
+        if (StringUtils.isEmpty(s)) {
+            return null;
+        }
+        char[] chars = s.toCharArray();
+        chars[0] -= 32;
+        return String.valueOf(chars);
+    }
+}

+ 17 - 0
src/main/java/com/persagy/apm/dmpalarm/utils/DatePatternStyle.java

@@ -0,0 +1,17 @@
+package com.persagy.apm.dmpalarm.utils;
+/**
+ * 日期各式样式
+ * @author gaoyu
+ *
+ */
+public class DatePatternStyle {
+
+	public static final String PATTERN_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+	public static final String PATTERN_YYYYMMDDHHMMSS2 = "yyyy-MM-dd HH:mm:ss";
+	public static final String PATTERN_YYYYMMDD = "yyyyMMdd";
+	public static final String PATTERN_HHMMSS = "HHmmss";
+	public static final String PATTERN_HHMM = "HHmm";
+	public static final String PATTERN_MM = "MM";
+	public static final String PATTERN_YYYY = "yyyy";
+	public static final String PATTERN_YYYYMM = "yyyyMM";
+}

+ 33 - 0
src/main/java/com/persagy/apm/dmpalarm/utils/MD5Utils.java

@@ -0,0 +1,33 @@
+package com.persagy.apm.dmpalarm.utils;
+
+import java.security.MessageDigest;
+
+public class MD5Utils {
+
+	public static String getSign(String str) {
+		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+		try {
+			byte[] btInput = str.getBytes();
+			// 获得MD5摘要算法的 MessageDigest 对象
+			MessageDigest mdInst = MessageDigest.getInstance("MD5");
+			// 使用指定的字节更新摘要
+			mdInst.update(btInput);
+			// 获得密文
+			byte[] md = mdInst.digest();
+			// 把密文转换成十六进制的字符串形式
+			int j = md.length;
+			char arr[] = new char[j * 2];
+			int k = 0;
+			for (int i = 0; i < j; i++) {
+				byte byte0 = md[i];
+				arr[k++] = hexDigits[byte0 >>> 4 & 0xf];
+				arr[k++] = hexDigits[byte0 & 0xf];
+			}
+			return new String(arr);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+}

+ 32 - 0
src/main/java/com/persagy/apm/dmpalarm/utils/SpringUtils.java

@@ -0,0 +1,32 @@
+package com.persagy.apm.dmpalarm.utils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+
+/**
+ * @author: yaoll
+ * @date: 2020-10-22
+ * @verison: 1.0
+ */
+public class SpringUtils implements BeanFactoryPostProcessor {
+
+	private static ConfigurableListableBeanFactory beanFactory;
+
+	@Override
+	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+		SpringUtils.beanFactory = beanFactory;
+	}
+
+	public static <T> T getBean(Class<T> aClass) {
+		return beanFactory.getBean(aClass);
+	}
+
+	public static <T> T getBean(String beanName, Class<T> aClass) {
+		if (beanFactory.containsBean(beanName)) {
+			return beanFactory.getBean(beanName, aClass);
+		} else {
+			return null;
+		}
+	}
+}

+ 44 - 0
src/main/java/com/persagy/apm/dmpalarm/utils/UtilsTools.java

@@ -0,0 +1,44 @@
+package com.persagy.apm.dmpalarm.utils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class UtilsTools {
+	private static Pattern linePattern = Pattern.compile("_(\\w)");
+	private static Pattern humpPattern = Pattern.compile("[A-Z]");
+	
+	public static  ThreadLocal<String> myTableNameSuffix = new ThreadLocal<>();
+
+	/**
+	 * 下划线转驼峰
+	 * 
+	 * @param str
+	 * @return
+	 */
+	public static String lineToHump(String str) {
+		str = str.toLowerCase();
+		Matcher matcher = linePattern.matcher(str);
+		StringBuffer sb = new StringBuffer();
+		while (matcher.find()) {
+			matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
+		}
+		matcher.appendTail(sb);
+		return sb.toString();
+	}
+
+	/**
+	 * 驼峰转下划线
+	 * 
+	 * @param str
+	 * @return
+	 */
+	public static String humpToLine(String str) {
+		Matcher matcher = humpPattern.matcher(str);
+		StringBuffer sb = new StringBuffer();
+		while (matcher.find()) {
+			matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
+		}
+		matcher.appendTail(sb);
+		return sb.toString();
+	}
+}

+ 72 - 0
src/main/java/com/persagy/apm/dmpalarm/web/BaseResponse.java

@@ -0,0 +1,72 @@
+package com.persagy.apm.dmpalarm.web;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.persagy.apm.dmpalarm.model.DmpMessage;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-04
+ * @verison: 1.0
+ */
+public class BaseResponse<T> {
+
+	public static final String SUCCESS = "success";
+	public static final String FAIL = "fail";
+	public static final String EXCEPTION = "exception";
+
+	@Getter
+	@Setter
+	private String result;
+
+	@Getter
+	@Setter
+	private String message;
+
+	@Getter
+	@Setter
+	protected T data;
+
+	@JsonIgnore
+	@Getter
+	private List<DmpMessage> messageList;
+
+	public void setFail(String message) {
+		setResult(FAIL);
+		setMessage(message);
+	}
+
+	public BaseResponse() {
+		super();
+		this.result = SUCCESS;
+	}
+
+	public BaseResponse(String result, String message) {
+		super();
+		this.result = result;
+		this.message = message;
+	}
+
+	public boolean success() {
+		return SUCCESS.equals(this.result);
+	}
+
+	public void add(DmpMessage msg){
+		if (messageList == null) {
+			messageList = new LinkedList<>();
+		}
+		messageList.add(msg);
+	}
+
+	public void add(List<DmpMessage> msgs){
+		if (messageList == null) {
+			messageList = new LinkedList<>();
+		}
+		messageList.addAll(msgs);
+	}
+}

+ 28 - 0
src/main/java/com/persagy/apm/dmpalarm/web/ListResponse.java

@@ -0,0 +1,28 @@
+package com.persagy.apm.dmpalarm.web;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-04
+ * @verison: 1.0
+ */
+public class ListResponse<T> extends BaseResponse<List<T>> {
+
+	public void add(T t) {
+		if (data == null) {
+			data = new LinkedList<>();
+		}
+		data.add(t);
+	}
+
+	@Override
+	public List<T> getData() {
+		List<T> data = super.getData();
+		if (data == null) {
+			data = new LinkedList<>();
+		}
+		return data;
+	}
+}

+ 42 - 0
src/main/java/com/persagy/apm/dmpalarm/web/MapResponse.java

@@ -0,0 +1,42 @@
+package com.persagy.apm.dmpalarm.web;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-04
+ * @verison: 1.0
+ */
+public class MapResponse extends BaseResponse<Map<String, Object>>{
+
+	public MapResponse() {
+		super();
+		super.setResult(SUCCESS);
+	}
+
+	//	@JsonAnySetter
+	public void add(String name, Object value) {
+		if (data == null) {
+			data = new HashMap<String, Object>();
+		}
+		data.put(name, value);
+	}
+
+	//	@JsonAnyGetter
+	@Override
+	public Map<String, Object> getData() {
+		return data;
+	}
+
+	public String getString(String key) {
+		return MapUtils.getString(data, key);
+	}
+
+	public Integer getInteger(String key) {
+		return MapUtils.getInteger(data, key);
+	}
+
+}

+ 28 - 0
src/main/java/com/persagy/apm/dmpalarm/web/PagedResponse.java

@@ -0,0 +1,28 @@
+package com.persagy.apm.dmpalarm.web;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-04
+ * @verison: 1.0
+ */
+public class PagedResponse<T> extends ListResponse<T> {
+
+	@Getter
+	@Setter
+	private Long count;
+
+	@SuppressWarnings("unchecked")
+	public List<T> getData() {
+		if (data == null) {
+			return Collections.EMPTY_LIST;
+		} else {
+			return data;
+		}
+	}
+}

+ 1 - 1
src/main/resources/db/init/data.sql

@@ -77,7 +77,7 @@ VALUES ('ACATAH_SupplyAirTempSet', '送风温度设定', 'ACATAH', '℃', NULL,
 REPLACE INTO `monitor_indicator`
 VALUES ('ACATAH_SupplyFanFreq', '送风机频率', 'ACATAH', 'Hz', NULL, 'Eqdx', NULL, NULL, NULL, NULL, NULL, 1);
 REPLACE INTO `monitor_indicator`
-VALUES ('ACATFU_ChillWaterOutTemp', '冷水出口温度', 'ACATFU', NULL, NULL, 'Eqdx', NULL, NULL, NULL, NULL, NULL, 1);
+VALUES ('ACATFU_ChillWaterOutTemp', '冷水出口温度', 'ACATFU', '℃', NULL, 'Eqdx', NULL, NULL, NULL, NULL, NULL, 1);
 REPLACE INTO `monitor_indicator`
 VALUES ('ACATFU_ChillWaterOutTempdifference', '连续时刻出水温度差', 'ACATFU', '℃', NULL, 'Eqdx', NULL, NULL, NULL, NULL, NULL,
         1);