Initial commit

This commit is contained in:
jackyu66git
2026-03-23 11:52:51 +08:00
commit ea8d889fbe
1114 changed files with 92438 additions and 0 deletions
+75
View File
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>oneone-alert</artifactId>
<groupId>com.oneone.cloud</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>alert-boot</artifactId>
<dependencies>
<!--Spring Cloud & Alibaba -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!-- 注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- 配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.oneone.cloud</groupId>
<artifactId>common-web</artifactId>
</dependency>
<dependency>
<groupId>com.oneone.cloud</groupId>
<artifactId>common-mybatis-plus</artifactId>
</dependency>
<dependency>
<artifactId>velocity</artifactId>
<groupId>org.apache.velocity</groupId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>com.oneone.cloud</groupId>
<artifactId>alert-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,19 @@
package com.oneone.alert;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableFeignClients(basePackages = {"com.oneone.alert.api.feign"})
@SpringBootApplication
@EnableDiscoveryClient
@EnableScheduling
@EnableAsync
public class AlertApplication {
public static void main(String[] args) {
SpringApplication.run(AlertApplication.class, args);
}
}
@@ -0,0 +1,8 @@
package com.oneone.alert.common;
public class AlertConstant {
public static final String ACTION_DATA_TOPIC="actionDataLog";
public static final String ACTION_DATA_GROUP="actionDataGroup";
public static final String USER_BEHAVIOR_TOPIC="user-behavior";
}
@@ -0,0 +1,25 @@
package com.oneone.alert.common;
import lombok.Getter;
/**
* @author mice
* @version 1.0
* @date 2022-03-24 19:13
*/
public enum EventStatusEnum {
NO_SEND(0,"未发送"),
SENT(1,"已经发送"),
DEAL(2,"已处理"),
;
EventStatusEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
@Getter
private Integer code;
@Getter
private String desc;
}
@@ -0,0 +1,29 @@
package com.oneone.alert.common;
/**
* @author mice
* @version 1.0
* @date 2022-04-20 13:51
*/
public interface FeishuConstants {
/**
* 登录
*/
String LOGIN_URL = "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal";
/**
* 发送消息
*/
String MESSAGES = "https://open.feishu.cn/open-apis/im/v1/messages";
/**
* 群发
*/
String BATCH_SEND = "https://open.feishu.cn/open-apis/message/v4/batch_send/";
/**
* 群发
*/
String QUERY_UID = "https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id";
}
@@ -0,0 +1,19 @@
package com.oneone.alert.config;
import com.oneone.alert.common.AlertConstant;
import org.apache.kafka.clients.admin.NewTopic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class KafkaInitialConfiguration {
@Bean
public NewTopic initialTopic() {
return new NewTopic(AlertConstant.ACTION_DATA_TOPIC,8, (short) 2 );
}
}
@@ -0,0 +1,19 @@
package com.oneone.alert.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author mice
* @version 1.0
* @date 2023-02-20 18:09
*/
@Data
@ConfigurationProperties(prefix = "sender-config")
@Configuration
public class SenderProperties {
private String appId="cli_a4859ac07439500d";
private String appSecret="fjMoNtzKU7VOlaJR5psPAhWH2bzzz6Dz";
}
@@ -0,0 +1,48 @@
package com.oneone.alert.controller;
import com.oneone.alert.common.AlertConstant;
import com.oneone.alert.pojo.entity.ActionData;
import com.oneone.alert.service.ActionDataService;
import com.oneone.common.result.Result;
import com.oneone.common.util.JsonUtils;
import com.oneone.common.web.util.UserContext;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
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;
/**
* 数据收集表
* @author mice
* @date 2023-05-09 16:58:58
* @version 1.0
*/
@RestController
@RequestMapping("app-api/v1/actiondata")
@Tag(name = "数据收集表管理")
public class ActionDataController {
@Autowired
private ActionDataService actionDataService;
@Autowired
private KafkaTemplate<String, Object> kafkaTemplate;
@Operation(summary = "新增数据收集表")
@PostMapping("/save")
public Result<Boolean> save(@RequestBody ActionData actionData) {
actionData.setMemberId(UserContext.getUserIdIfPresentDefault());
kafkaTemplate.send(AlertConstant.ACTION_DATA_TOPIC, JsonUtils.toJSONString(actionData));
// actionDataService.save(actionData)
return Result.success(true);
}
}
@@ -0,0 +1,45 @@
package com.oneone.alert.controller;
import com.google.common.collect.ImmutableMap;
import com.oneone.alert.common.AlertConstant;
import com.oneone.alert.pojo.entity.ActionData;
import com.oneone.alert.service.ActionDataService;
import com.oneone.common.result.Result;
import com.oneone.common.util.JsonUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
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;
/**
* 数据收集表
* @author mice
* @date 2023-05-09 16:58:58
* @version 1.0
*/
@RestController
@RequestMapping("api/v1/actiondata")
@Tag(name = "admin-数据收集表管理")
public class AdminActionDataController {
@Autowired
private ActionDataService actionDataService;
@Autowired
private KafkaTemplate<String, Object> kafkaTemplate;
@Operation(summary = "新增数据收集表")
@PostMapping("/save")
public Result<Boolean> save(@RequestBody ActionData actionData) {
kafkaTemplate.send(AlertConstant.ACTION_DATA_TOPIC, JsonUtils.toJSONString(actionData));
kafkaTemplate.send("user-behavior", JsonUtils.toJSONString(ImmutableMap.of("action", actionData.getBusinessType())));
return Result.success(true);
}
}
@@ -0,0 +1,93 @@
package com.oneone.alert.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oneone.alert.pojo.entity.AlertStage;
import com.oneone.alert.service.AlertStageService;
import com.oneone.common.result.Result;
import com.oneone.common.web.security.annotation.RequiresPermissions;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
* 通知策略
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
@RestController
@RequestMapping("api/v1/alertstage")
@RequiredArgsConstructor
@Tag(name = "通知策略管理")
public class AlertStageController {
private final AlertStageService alertStageService;
/**
* 分页查询
* @param page 分页对象
* @param alertStage 通知策略
* @return
*/
@Operation(summary = "分页查询")
@GetMapping("/page" )
@RequiresPermissions("alert:alertstage:list")
public Result<IPage<AlertStage>> getAlertStagePage(Page page, AlertStage alertStage) {
return Result.success(alertStageService.page(page, Wrappers.query(alertStage)));
}
/**
* 通过id查询通知策略
* @param id id
* @return Result
*/
@Operation(summary = "通过id查询")
@GetMapping("/{id}" )
@RequiresPermissions("alert:alertstage:getById")
public Result<AlertStage> getById(@PathVariable("id" ) Long id) {
return Result.success(alertStageService.getById(id));
}
/**
* 新增通知策略
* @param alertStage 通知策略
* @return Result
*/
@Operation(summary = "新增通知策略")
@PostMapping
@RequiresPermissions("alert:alertstage:add")
public Result<Boolean> save(@RequestBody AlertStage alertStage) {
return Result.success(alertStageService.save(alertStage));
}
/**
* 修改通知策略
* @param alertStage 通知策略
* @return Result
*/
@Operation(summary = "修改通知策略")
@PutMapping
@RequiresPermissions("alert:alertstage:edit")
public Result<Boolean> updateById(@RequestBody AlertStage alertStage) {
return Result.success(alertStageService.updateById(alertStage));
}
/**
* 通过id删除通知策略
* @param id id
* @return Result
*/
@Operation(summary = "通过id删除通知策略")
@DeleteMapping("/{id}" )
@RequiresPermissions("alert:alertstage:delete")
public Result<Boolean> removeById(@PathVariable Long id) {
return Result.success(alertStageService.removeById(id));
}
}
@@ -0,0 +1,93 @@
package com.oneone.alert.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oneone.alert.pojo.entity.CodeStageRel;
import com.oneone.alert.service.CodeStageRelService;
import com.oneone.common.result.Result;
import com.oneone.common.web.security.annotation.RequiresPermissions;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
* 通知策略-事件
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
@RestController
@RequestMapping("alert/codestagerel")
@RequiredArgsConstructor
@Tag(name = "通知策略-事件管理")
public class CodeStageRelController {
private final CodeStageRelService codeStageRelService;
/**
* 分页查询
* @param page 分页对象
* @param codeStageRel 通知策略-事件
* @return
*/
@Operation(summary = "分页查询")
@GetMapping("/page" )
@RequiresPermissions("alert:codestagerel:list")
public Result<IPage<CodeStageRel>> getCodeStageRelPage(Page page, CodeStageRel codeStageRel) {
return Result.success(codeStageRelService.page(page, Wrappers.query(codeStageRel)));
}
/**
* 通过id查询通知策略-事件
* @param id id
* @return Result
*/
@Operation(summary = "通过id查询")
@GetMapping("/{id}" )
@RequiresPermissions("alert:codestagerel:getById")
public Result<CodeStageRel> getById(@PathVariable("id" ) Long id) {
return Result.success(codeStageRelService.getById(id));
}
/**
* 新增通知策略-事件
* @param codeStageRel 通知策略-事件
* @return Result
*/
@Operation(summary = "新增通知策略-事件")
@PostMapping
@RequiresPermissions("alert:codestagerel:add")
public Result<Boolean> save(@RequestBody CodeStageRel codeStageRel) {
return Result.success(codeStageRelService.save(codeStageRel));
}
/**
* 修改通知策略-事件
* @param codeStageRel 通知策略-事件
* @return Result
*/
@Operation(summary = "修改通知策略-事件")
@PutMapping
@RequiresPermissions("alert:codestagerel:edit")
public Result<Boolean> updateById(@RequestBody CodeStageRel codeStageRel) {
return Result.success(codeStageRelService.updateById(codeStageRel));
}
/**
* 通过id删除通知策略-事件
* @param id id
* @return Result
*/
@Operation(summary = "通过id删除通知策略-事件")
@DeleteMapping("/{id}" )
@RequiresPermissions("alert:codestagerel:delete")
public Result<Boolean> removeById(@PathVariable Long id) {
return Result.success(codeStageRelService.removeById(id));
}
}
@@ -0,0 +1,121 @@
package com.oneone.alert.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oneone.alert.api.common.AlterConstant;
import com.oneone.alert.api.param.EventParam;
import com.oneone.alert.pojo.entity.Event;
import com.oneone.alert.service.EventLogService;
import com.oneone.alert.service.EventService;
import com.oneone.common.result.Result;
import com.oneone.common.util.Func;
import com.oneone.common.web.security.annotation.RequiresPermissions;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
* 事件
* @author mice
* @date 2022-04-20 12:10:02
* @version 1.0
*/
@RestController
@RequestMapping("api/v1/event")
@RequiredArgsConstructor
@Tag(name = "事件管理")
public class EventController {
private final EventService eventService;
private final EventLogService eventLogService;
/**
* 分页查询
* @param page 分页对象
* @param event 事件
* @return
*/
@Operation(summary = "分页查询")
@GetMapping("/page" )
@RequiresPermissions("alert:event:list")
public Result<IPage<Event>> getEventPage(Page page, Event event) {
return Result.success(eventService.page(page, Wrappers.query(event)));
}
/**
* 通过id查询事件
* @param id id
* @return Result
*/
@Operation(summary = "通过id查询")
@GetMapping("/{id}" )
@RequiresPermissions("alert:event:getById")
public Result<Event> getById(@PathVariable("id" ) Long id) {
return Result.success(eventService.getById(id));
}
/**
* 新增事件
* @param event 事件
* @return Result
*/
@Operation(summary = "新增事件")
@PostMapping
@RequiresPermissions("alert:event:add")
public Result<Boolean> save(@RequestBody Event event) {
return Result.success(eventService.save(event));
}
/**
* 修改事件
* @param event 事件
* @return Result
*/
@Operation(summary = "修改事件")
@PutMapping
@RequiresPermissions("alert:event:edit")
public Result<Boolean> updateById(@RequestBody Event event) {
return Result.success(eventService.updateById(event));
}
/**
* 通过id删除事件
* @param id id
* @return Result
*/
@Operation(summary = "通过id删除事件")
@DeleteMapping("/{id}" )
@RequiresPermissions("alert:event:delete")
public Result<Boolean> removeById(@PathVariable Long id) {
return Result.success(eventService.removeById(id));
}
@Operation(summary = "事件推送")
@PostMapping("pushEvent")
@RequiresPermissions("alert:event:pushEvent")
public Result<Boolean> pushEvent(@RequestBody EventParam param) {
// eventService.pushEvent(param);
if(Func.isEmpty(param.getCode())){
param.setCode(AlterConstant.BusyCode.UNKNOWN.getCode());
}
eventLogService.saveLog(param);
return Result.success();
}
@Operation(summary = "事件推送")
@PostMapping("pushEventLog")
@RequiresPermissions("alert:event:pushEventLog")
public Result<Boolean> pushEventLog(@RequestBody EventParam param) {
eventLogService.saveLog(param);
return Result.success();
}
}
@@ -0,0 +1,93 @@
package com.oneone.alert.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oneone.alert.pojo.entity.EventLog;
import com.oneone.alert.service.EventLogService;
import com.oneone.common.result.Result;
import com.oneone.common.web.security.annotation.RequiresPermissions;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
* 事件
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
@RestController
@RequestMapping("alert/eventlog")
@RequiredArgsConstructor
@Tag(name = "事件管理")
public class EventLogController {
private final EventLogService eventLogService;
/**
* 分页查询
* @param page 分页对象
* @param eventLog 事件
* @return
*/
@Operation(summary = "分页查询")
@GetMapping("/page" )
@RequiresPermissions("alert:eventlog:list")
public Result<IPage<EventLog>> getEventLogPage(Page page, EventLog eventLog) {
return Result.success(eventLogService.page(page, Wrappers.query(eventLog)));
}
/**
* 通过id查询事件
* @param id id
* @return Result
*/
@Operation(summary = "通过id查询")
@GetMapping("/{id}" )
@RequiresPermissions("alert:eventlog:getById")
public Result<EventLog> getById(@PathVariable("id" ) Long id) {
return Result.success(eventLogService.getById(id));
}
/**
* 新增事件
* @param eventLog 事件
* @return Result
*/
@Operation(summary = "新增事件")
@PostMapping
@RequiresPermissions("alert:eventlog:add")
public Result<Boolean> save(@RequestBody EventLog eventLog) {
return Result.success(eventLogService.save(eventLog));
}
/**
* 修改事件
* @param eventLog 事件
* @return Result
*/
@Operation(summary = "修改事件")
@PutMapping
@RequiresPermissions("alert:eventlog:edit")
public Result<Boolean> updateById(@RequestBody EventLog eventLog) {
return Result.success(eventLogService.updateById(eventLog));
}
/**
* 通过id删除事件
* @param id id
* @return Result
*/
@Operation(summary = "通过id删除事件")
@DeleteMapping("/{id}" )
@RequiresPermissions("alert:eventlog:delete")
public Result<Boolean> removeById(@PathVariable Long id) {
return Result.success(eventLogService.removeById(id));
}
}
@@ -0,0 +1,38 @@
package com.oneone.alert.handler;
import com.oneone.alert.common.AlertConstant;
import com.oneone.alert.pojo.dto.UserBehaviorEvent;
import com.oneone.alert.pojo.entity.ActionData;
import com.oneone.alert.service.ActionDataService;
import com.oneone.common.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class KafkaHandler {
@Autowired
private ActionDataService actionDataService;
@Autowired
private KafkaTemplate<String, Object> kafkaTemplate;
// 消费监听
@KafkaListener(topics = {AlertConstant.ACTION_DATA_TOPIC}
,groupId = AlertConstant.ACTION_DATA_GROUP)
public void onMessage1(ConsumerRecord<?, ?> record) {
// 消费的哪个topic、partition的消息,打印出消息内容
// System.out.println("简单消费:" + record.topic() + "-" + record.partition() + "-" + record.value());
String value = (String) record.value();
ActionData actionData = JsonUtils.strToClass(value, ActionData.class);
actionDataService.save(actionData);
UserBehaviorEvent userBehaviorEvent = new UserBehaviorEvent(actionData.getMemberId().intValue(),actionData.getBusinessType(),System.currentTimeMillis(),actionData.getDataField1());
String userBehaviorEventStr = JsonUtils.toJSONString(userBehaviorEvent);
kafkaTemplate.send(AlertConstant.USER_BEHAVIOR_TOPIC,userBehaviorEventStr);
}
}
@@ -0,0 +1,16 @@
package com.oneone.alert.mapper;
import com.oneone.alert.pojo.entity.ActionData;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @desc 数据收集表
* @author mice
* @date 2023-05-09 16:58:58
* @version 1.0
*/
@Mapper
public interface ActionDataMapper extends BaseMapper<ActionData> {
}
@@ -0,0 +1,16 @@
package com.oneone.alert.mapper;
import com.oneone.alert.pojo.entity.AlertStage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @desc 通知策略
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
@Mapper
public interface AlertStageMapper extends BaseMapper<AlertStage> {
}
@@ -0,0 +1,16 @@
package com.oneone.alert.mapper;
import com.oneone.alert.pojo.entity.CodeStageRel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @desc 通知策略-事件
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
@Mapper
public interface CodeStageRelMapper extends BaseMapper<CodeStageRel> {
}
@@ -0,0 +1,20 @@
package com.oneone.alert.mapper;
import com.oneone.alert.pojo.entity.EventLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
/**
* @desc 事件
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
@Mapper
public interface EventLogMapper extends BaseMapper<EventLog> {
@Select(" select count(1) from t_event_log t where t.`code`=#{code} and \n" +
" t.gmt_create> date_add(now(), interval -#{timeMinute} minute);")
int getInTimeCount(Integer timeMinute, String code);
}
@@ -0,0 +1,16 @@
package com.oneone.alert.mapper;
import com.oneone.alert.pojo.entity.Event;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @desc 事件
* @author mice
* @date 2022-04-20 12:10:02
* @version 1.0
*/
@Mapper
public interface EventMapper extends BaseMapper<Event> {
}
@@ -0,0 +1,10 @@
package com.oneone.alert.pojo.dto;
import com.oneone.alert.pojo.entity.AlertStage;
import com.oneone.alert.pojo.entity.CodeStageRel;
import lombok.Data;
@Data
public class CodeStageRelDTO extends CodeStageRel {
private AlertStage stage;
}
@@ -0,0 +1,15 @@
package com.oneone.alert.pojo.dto;
import lombok.Data;
/**
* @author mice
* @version 1.0
* @date 2022-04-20 14:56
*/
@Data
public class Message {
private String msgType;
private String content;
}
@@ -0,0 +1,15 @@
package com.oneone.alert.pojo.dto;
import lombok.*;
@Data
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class UserBehaviorEvent {
private int userId;
private String action;
private long timestamp;
private String filed1;
}
@@ -0,0 +1,118 @@
package com.oneone.alert.pojo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* @desc 数据收集表
* @author mice
* @date 2023-05-09 16:58:58
* @version 1.0
*/
@Data
@TableName("t_action_data")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "数据收集表")
public class ActionData extends Model<ActionData> {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(type = IdType.AUTO)
@Schema(description="",hidden = true)
private Integer id;
/**
* 业务类型
*/
@Schema(description="业务类型")
private String businessType;
/**
* 用户id
*/
@Schema(description="用户id",hidden = true)
private Long memberId;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField1;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField2;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField3;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField4;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField5;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField6;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField7;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField8;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField9;
/**
* 数据字段节点
*/
@Schema(description="数据字段节点")
private String dataField10;
/**
* 创建时间
*/
@Schema(description="创建时间",hidden = true)
private LocalDateTime gmtCreate;
/**
* 更新时间
*/
@Schema(description="更新时间",hidden = true)
private LocalDateTime gmtModified;
}
@@ -0,0 +1,82 @@
package com.oneone.alert.pojo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* @desc 通知策略
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
@Data
@TableName("t_alert_stage")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "通知策略")
public class AlertStage extends Model<AlertStage> {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(type = IdType.AUTO)
@Schema(description="")
private Long id;
/**
* 分钟
*/
@Schema(description="分钟")
private Integer timeMinute;
/**
* 条数
*/
@Schema(description="条数")
private Integer num;
/**
* 通知类型0飞书
*/
@Schema(description="通知类型0飞书")
private Integer notifyType;
/**
* 通知手机号
*/
@Schema(description="通知手机号")
private String notifyPhone;
/**
* 默认策略
*/
@Schema(description="默认策略")
private Integer isDefault;
/**
* 告警等级
*/
@Schema(description="告警等级")
private Integer level;
/**
* 创建时间
*/
@Schema(description="创建时间")
private LocalDateTime gmtCreate;
/**
* 更新时间
*/
@Schema(description="更新时间")
private LocalDateTime gmtModified;
}
@@ -0,0 +1,67 @@
package com.oneone.alert.pojo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* @desc 通知策略-事件
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
@Data
@TableName("t_code_stage_rel")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "通知策略-事件")
public class CodeStageRel extends Model<CodeStageRel> {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(type = IdType.AUTO)
@Schema(description="")
private Long id;
/**
* 业务code
*/
@Schema(description="业务code")
private String code;
/**
* 策略id
*/
@Schema(description="策略id")
private Long stageId;
/**
* 通知标题
*/
@Schema(description="通知标题")
private String title;
@Schema(description="应用")
private String app;
/**
* 创建时间
*/
@Schema(description="创建时间")
private LocalDateTime gmtCreate;
/**
* 更新时间
*/
@Schema(description="更新时间")
private LocalDateTime gmtModified;
}
@@ -0,0 +1,97 @@
package com.oneone.alert.pojo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* @desc 事件
* @author mice
* @date 2022-04-20 12:10:02
* @version 1.0
*/
@Data
@TableName("t_event")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "事件")
public class Event extends Model<Event> {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(type = IdType.AUTO)
@Schema(description="")
private Long id;
/**
* 日志id
*/
@Schema(description="日志id")
private Long logId;
/**
* 业务code
*/
@Schema(description="业务code")
private String code;
/**
* 标题
*/
@Schema(description="标题")
private String title;
/**
* 告警等级
*/
@Schema(description="告警等级")
private Integer level;
/**
* 应用
*/
@Schema(description="应用")
private String app;
/**
* 通知人id [userId:userName,1:陈浩]
*/
@Schema(description="通知人id")
private String notifyUser;
/**
* 内容
*/
@Schema(description="内容")
private String content;
/**
* 事件状态
*/
@Schema(description="事件状态")
private Integer status;
/**
* 创建时间
*/
@Schema(description="创建时间")
private LocalDateTime gmtCreate;
/**
* 更新时间
*/
@Schema(description="更新时间")
private LocalDateTime gmtModified;
@Schema(description="策略id")
private Long stageId;
}
@@ -0,0 +1,166 @@
package com.oneone.alert.pojo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* @desc 事件
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
@Data
@TableName("t_event_log")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "事件")
public class EventLog extends Model<EventLog> {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(type = IdType.AUTO)
@Schema(description="")
private Long id;
/**
* 业务code
*/
@Schema(description="业务code")
private String code;
/**
* 服务ID
*/
@Schema(description="服务ID")
private String serviceId;
/**
* 服务器名
*/
@Schema(description="服务器名")
private String serverHost;
/**
* 服务器IP地址
*/
@Schema(description="服务器IP地址")
private String serverIp;
/**
* 操作方式
*/
@Schema(description="操作方式")
private String method;
/**
* 请求URI
*/
@Schema(description="请求URI")
private String requestUri;
/**
* 用户代理
*/
@Schema(description="用户代理")
private String userAgent;
/**
* 堆栈
*/
@Schema(description="堆栈")
private String stackTrace;
/**
* 异常名
*/
@Schema(description="异常名")
private String exceptionName;
/**
* 异常信息
*/
@Schema(description="异常信息")
private String message;
/**
* 错误行数
*/
@Schema(description="错误行数")
private Integer lineNumber;
/**
* 操作IP地址
*/
@Schema(description="操作IP地址")
private String remoteIp;
/**
* 方法类
*/
@Schema(description="方法类")
private String methodClass;
/**
* 文件名
*/
@Schema(description="文件名")
private String fileName;
/**
* 方法名
*/
@Schema(description="方法名")
private String methodName;
/**
* 操作提交的数据
*/
@Schema(description="操作提交的数据")
private String params;
/**
* 事件状态
*/
@Schema(description="事件状态")
private Boolean status;
/**
* 创建时间
*/
@Schema(description="创建时间")
private LocalDateTime gmtCreate;
/**
* 更新时间
*/
@Schema(description="更新时间")
private LocalDateTime gmtModified;
/**
* 指定通知内容
*/
@Schema(description="指定通知内容")
private String content;
/**
* 指定通知标题
*/
@Schema(description="指定通知标题")
private String title;
/**
* 指定通知手机号
*/
@Schema(description="指定通知手机号")
private String notifyUser;
}
@@ -0,0 +1,15 @@
package com.oneone.alert.sender;
import com.oneone.alert.pojo.entity.Event;
/**
* @author mice
* @version 1.0
* @date 2022-04-20 13:43
*/
public interface BaseSender {
void send(Event event);
void refreshToken();
}
@@ -0,0 +1,256 @@
package com.oneone.alert.sender;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.oneone.alert.common.EventStatusEnum;
import com.oneone.alert.config.SenderProperties;
import com.oneone.alert.pojo.entity.Event;
import com.oneone.alert.sender.resp.FSUser;
import com.oneone.alert.sender.resp.FSUserResp;
import com.oneone.alert.service.EventService;
import com.oneone.common.result.Result;
import com.oneone.common.util.Func;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.StringWriter;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.oneone.alert.common.FeishuConstants.*;
/**
* @author mice
* @version 1.0
* @date 2022-04-20 12:20
*/
@Component
@Slf4j
public class FeishuSender implements BaseSender {
// @Value("${feishu.config.app_id:cli_a2d5cb988439500b}")
// private String app_id;
// @Value("${feishu.config.app_secret:G3WIWRns1BD5HyxJyfWpy6Sqo4LMyVYY}")
// private String app_secret;
@Autowired
SenderProperties senderProperties;
private final String BEARER = "Bearer ";
private String accessToken;
private final LoadingCache<String, String> LOCAL_CACHE = CacheBuilder.newBuilder()
.maximumSize(20)
.expireAfterAccess(30, TimeUnit.MINUTES)
.build(
new CacheLoader<String,String>() {
@Override
public String load(String phone) {
return getUserIdByPhone(phone);
}
}
);
@Autowired
@Lazy
private EventService eventService;
{
//设置velocity资源加载器
Properties prop = new Properties();
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
Velocity.init(prop);
}
@Async("asyncExecutor")
@Override
public void send(Event event) {
HttpRequest post = HttpUtil.createPost(BATCH_SEND);
post.header("Authorization", BEARER + accessToken);
String content = interactive(event);
Map<String, Object> params = new HashMap<>();
params.put("msg_type", "interactive");
params.put("card", JSONObject.parseObject(content));
String users = event.getNotifyUser();
List<String> notifyUsers = new ArrayList<>();
List<String> phones=Arrays.asList(users.split(","));
for(String phone:phones){
String uid=LOCAL_CACHE.getUnchecked(phone);
if(Func.isEmpty(uid)){
continue;
}
notifyUsers.add(uid);
}
if(Func.isEmpty(notifyUsers)){
log.error("消息推送失败,未找到用户:{}",event.getNotifyUser());
return;
}
params.put("open_ids", notifyUsers);
post.body(JSONObject.toJSONString(params));
HttpResponse httpResponse = post.execute();
log.info("消息推送结果:{}",httpResponse.body());
Event update = new Event();
update.setId(event.getId());
update.setStatus(EventStatusEnum.SENT.getCode());
eventService.updateById(update);
}
public List<FSUser> getUserIdByPhoneList(List<String> phones) {
HttpRequest post = HttpUtil.createPost(QUERY_UID);
post.header("Authorization", BEARER + accessToken);
if(Func.isEmpty(phones)){
return Collections.EMPTY_LIST;
}
HashMap params=new HashMap();
params.put("mobiles",phones);
post.body(JSONObject.toJSONString(params));
HttpResponse httpResponse = post.execute();
String result=httpResponse.body();
log.info("uid查询结果:{}",result);
Result<FSUserResp> r=JSONObject.parseObject(result,new TypeReference<Result<FSUserResp>>(){});
log.info(JSONObject.toJSONString(r));
if(!Result.isSuccess(r)){
log.info("uid查询失败");
return Collections.EMPTY_LIST;
}
return r.getData().getUser_list().stream().filter(s->!Func.isEmpty(s.getUser_id())).collect(Collectors.toList());
}
public String getUserIdByPhone(String phone) {
HttpRequest post = HttpUtil.createPost(QUERY_UID);
post.header("Authorization", BEARER + accessToken);
if(Func.isEmpty(phone)){
return null;
}
HashMap params=new HashMap();
params.put("mobiles",Arrays.asList(phone));
post.body(JSONObject.toJSONString(params));
HttpResponse httpResponse = post.execute();
String result=httpResponse.body();
log.info("uid查询结果:{}",result);
Result<FSUserResp> r=JSONObject.parseObject(result,new TypeReference<Result<FSUserResp>>(){});
log.info(JSONObject.toJSONString(r));
if(!Result.isSuccess(r)){
log.info("uid查询失败");
return null;
}
List<FSUser> user_list=r.getData().getUser_list().stream().filter(s->Func.isNotEmpty(s.getUser_id())).collect(Collectors.toList());
if(Func.isEmpty(user_list)){
return null;
}
return user_list.get(0).getUser_id();
}
//@Scheduled(fixedDelay = 10000)
public void test() {
Event event = new Event();
event.setId(1l);
event.setApp("藏品服务");
event.setGmtCreate(LocalDateTime.now());
event.setLevel(1);
event.setTitle("库存不足");
event.setContent("藏品1库存不足");
event.setNotifyUser("[\"f622a54a:陈浩\"]");
HttpRequest post = HttpUtil.createPost(BATCH_SEND);
post.header("Authorization", BEARER + accessToken);
String content = interactive(event);
Map<String, Object> params = new HashMap<>();
params.put("msg_type", "interactive");
params.put("card", JSONObject.parseObject(content));
String users = event.getNotifyUser();
List<String> notifyUsers = new ArrayList<>();
JSONArray.parseArray(users, String.class).forEach(s -> {
String[] userInfo = s.split(":");
String userId = userInfo[0];
notifyUsers.add(userId);
});
params.put("user_ids", notifyUsers);
post.body(JSONObject.toJSONString(params));
HttpResponse httpResponse = post.execute();
log.info(httpResponse.body());
}
private String interactive(Event event) {
Map<String, Object> param = new HashMap<>();
param.put("title", event.getTitle());
param.put("app", event.getApp());
param.put("level", event.getLevel());
param.put("gmtCreate", LocalDateTimeUtil.formatNormal(event.getGmtCreate()));
param.put("id", event.getId());
String content = event.getContent().replaceAll("\"","\\\\\\\"");
param.put("content",content);
// String users = event.getNotifyUser();
// List<String> notifyUsers = new ArrayList<>();
// JSONArray.parseArray(users, String.class).forEach(s -> {
// String[] userInfo = s.split(":");
// String username = userInfo[1];
// notifyUsers.add(username);
// });
// param.put("notifyUsers", StringUtils.join(notifyUsers,','));
StringWriter sw = new StringWriter();
VelocityContext context = new VelocityContext(param);
Template tpl = Velocity.getTemplate("template/alert.json", "UTF-8");
tpl.merge(context, sw);
return sw.toString();
}
@Scheduled(fixedDelay = 600000)
public void refreshToken() {
Map<String, String> params = new HashMap<>();
params.put("app_id", senderProperties.getAppId());
params.put("app_secret", senderProperties.getAppSecret());
String result = HttpUtil.post(LOGIN_URL, JSONObject.toJSONString(params));
log.info("飞书app_access_token:" + result);
JSONObject tokenObj = JSONObject.parseObject(result);
accessToken = tokenObj.getString("app_access_token");
}
public static void main(String[] args) {
FeishuSender send=new FeishuSender();
Event event=new Event();
event.setTitle("Feishu");
event.setContent("ceshi");
event.setNotifyUser("18381357800");
event.setApp("app");
event.setLevel(1);
send.send(event);
// Map<String, Object> param = new HashMap<>();
// param.put("app", "test");
// param.put("level", 1);
// param.put("gmtCreate", LocalDateTime.now());
//
// StringWriter sw = new StringWriter();
// VelocityContext context = new VelocityContext(param);
// Template tpl = Velocity.getTemplate("template/alert.json", "UTF-8");
// tpl.merge(context, sw);
// System.out.println("模板文件渲染结果==> " + sw.toString());
}
}
@@ -0,0 +1,11 @@
package com.oneone.alert.sender.resp;
import lombok.Data;
import java.io.Serializable;
@Data
public class FSUser implements Serializable {
private String mobile;
private String user_id;
}
@@ -0,0 +1,11 @@
package com.oneone.alert.sender.resp;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class FSUserResp implements Serializable {
private List<FSUser> user_list;
}
@@ -0,0 +1,18 @@
package com.oneone.alert.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oneone.alert.pojo.entity.ActionData;
import java.util.Map;
/**
* @desc 数据收集表
* @author mice
* @date 2023-05-09 16:58:58
* @version 1.0
*/
public interface ActionDataService extends IService<ActionData> {
}
@@ -0,0 +1,18 @@
package com.oneone.alert.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oneone.alert.pojo.entity.AlertStage;
import java.util.Map;
/**
* @desc 通知策略
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
public interface AlertStageService extends IService<AlertStage> {
}
@@ -0,0 +1,26 @@
package com.oneone.alert.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.oneone.alert.pojo.dto.CodeStageRelDTO;
import com.oneone.alert.pojo.entity.CodeStageRel;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @desc 通知策略-事件
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
public interface CodeStageRelService extends IService<CodeStageRel> {
CodeStageRelDTO getByCodeWithCache(String code);
}
@@ -0,0 +1,20 @@
package com.oneone.alert.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oneone.alert.api.param.EventParam;
import com.oneone.alert.pojo.entity.EventLog;
import java.util.Map;
/**
* @desc 事件
* @author mice
* @date 2023-03-13 12:03:18
* @version 1.0
*/
public interface EventLogService extends IService<EventLog> {
void saveLog(EventParam param);
}
@@ -0,0 +1,26 @@
package com.oneone.alert.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oneone.alert.api.param.EventParam;
import com.oneone.alert.pojo.entity.Event;
import java.util.Map;
/**
* @desc 事件
* @author mice
* @date 2022-04-20 12:10:02
* @version 1.0
*/
public interface EventService extends IService<Event> {
/**
* 推送事件
* @param event
*/
void pushEvent(EventParam event);
void saveAndPush(Event event);
}
@@ -0,0 +1,17 @@
package com.oneone.alert.service.impl;
import org.springframework.stereotype.Service;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oneone.alert.mapper.ActionDataMapper;
import com.oneone.alert.pojo.entity.ActionData;
import com.oneone.alert.service.ActionDataService;
@Service("actionDataService")
public class ActionDataServiceImpl extends ServiceImpl<ActionDataMapper, ActionData> implements ActionDataService {
}
@@ -0,0 +1,17 @@
package com.oneone.alert.service.impl;
import org.springframework.stereotype.Service;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oneone.alert.mapper.AlertStageMapper;
import com.oneone.alert.pojo.entity.AlertStage;
import com.oneone.alert.service.AlertStageService;
@Service("alertStageService")
public class AlertStageServiceImpl extends ServiceImpl<AlertStageMapper, AlertStage> implements AlertStageService {
}
@@ -0,0 +1,74 @@
package com.oneone.alert.service.impl;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.oneone.alert.api.common.AlterConstant;
import com.oneone.alert.pojo.dto.CodeStageRelDTO;
import com.oneone.alert.pojo.entity.AlertStage;
import com.oneone.alert.service.AlertStageService;
import com.oneone.common.constant.GlobalConstants;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oneone.alert.mapper.CodeStageRelMapper;
import com.oneone.alert.pojo.entity.CodeStageRel;
import com.oneone.alert.service.CodeStageRelService;
@Service("codeStageRelService")
public class CodeStageRelServiceImpl extends ServiceImpl<CodeStageRelMapper, CodeStageRel> implements CodeStageRelService {
@Autowired
AlertStageService alertStageService;
private final LoadingCache<String, CodeStageRelDTO> LOCAL_CACHE = CacheBuilder.newBuilder()
.maximumSize(512)
.expireAfterAccess(30, TimeUnit.MINUTES)
.build(
new CacheLoader<String, CodeStageRelDTO>() {
@Override
public CodeStageRelDTO load(String code) {
return getByCode(code);
}
}
);
private CodeStageRelDTO getByCode(String code){
CodeStageRel one = this.lambdaQuery().eq(CodeStageRel::getCode, code).one();
if(one==null){
AlertStage stage = alertStageService.lambdaQuery().eq(AlertStage::getIsDefault, GlobalConstants.STATUS_YES )
.one();
if(stage==null){
return null;
}
CodeStageRelDTO dto=new CodeStageRelDTO();
dto.setStage(stage);
dto.setCode(code);
return dto;
}
CodeStageRelDTO dto=new CodeStageRelDTO();
BeanUtils.copyProperties(one, dto);
AlertStage stage = alertStageService.getById(dto.getStageId());
if(stage==null){
return null;
}
dto.setStage(stage);
return dto;
}
@Override
public CodeStageRelDTO getByCodeWithCache(String code) {
return LOCAL_CACHE.getUnchecked(code);
}
}
@@ -0,0 +1,82 @@
package com.oneone.alert.service.impl;
import com.oneone.alert.api.common.AlterConstant;
import com.oneone.alert.api.param.EventParam;
import com.oneone.alert.pojo.dto.CodeStageRelDTO;
import com.oneone.alert.pojo.entity.AlertStage;
import com.oneone.alert.pojo.entity.Event;
import com.oneone.alert.service.CodeStageRelService;
import com.oneone.alert.service.EventService;
import com.oneone.common.util.Func;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oneone.alert.mapper.EventLogMapper;
import com.oneone.alert.pojo.entity.EventLog;
import com.oneone.alert.service.EventLogService;
@Service("eventLogService")
public class EventLogServiceImpl extends ServiceImpl<EventLogMapper, EventLog> implements EventLogService {
@Autowired
EventService eventService;
@Autowired
CodeStageRelService codeStageRelService;
@Override
public void saveLog(EventParam param) {
EventLog log =new EventLog();
BeanUtils.copyProperties(param,log);
this.save(log);
if(Func.isNotEmpty(param.getNotifyUser())){
Event event=new Event();
BeanUtils.copyProperties(param,event);
event.setLogId(log.getId());
eventService.saveAndPush(event);
return;
}
saveAndPushWithStage(log,param);
}
@Async("asyncExecutor")
public void saveAndPushWithStage(EventLog log,EventParam param){
String code=log.getCode();
if(Func.isEmpty(code)){
code= AlterConstant.BusyCode.UNKNOWN.getCode();
}
CodeStageRelDTO codeState = codeStageRelService.getByCodeWithCache(code);
if(codeState==null){
return;
}
AlertStage stage=codeState.getStage();
if(stage.getNum()>0){
int count=baseMapper.getInTimeCount(stage.getTimeMinute(),code);
if(count<stage.getNum()){
return;
}
}
Event event=new Event();
BeanUtils.copyProperties(param,event);
event.setLogId(log.getId());
event.setNotifyUser(stage.getNotifyPhone());
event.setStageId(stage.getId());
if(Func.isEmpty(param.getTitle()) ){
event.setTitle(codeState.getTitle());
}
if(Func.isEmpty(param.getApp()) ) {
event.setApp(codeState.getApp());
}
event.setLevel(stage.getLevel());
eventService.saveAndPush(event);
}
}
@@ -0,0 +1,51 @@
package com.oneone.alert.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oneone.alert.api.param.EventParam;
import com.oneone.alert.mapper.EventMapper;
import com.oneone.alert.pojo.entity.Event;
import com.oneone.alert.sender.BaseSender;
import com.oneone.alert.service.EventService;
import com.oneone.common.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
@Service("eventService")
@Slf4j
public class EventServiceImpl extends ServiceImpl<EventMapper, Event> implements EventService {
@Autowired
@Lazy
private BaseSender sender;
@Override
public void pushEvent(EventParam eventParam){
Event event = new Event();
BeanUtils.copyProperties(eventParam,event);
// TODO 告警人配置
event.setNotifyUser("[\"f622a54a:陈浩\"]");
event.setGmtCreate(LocalDateTime.now());
baseMapper.insert(event);
log.info("接收到推送消息:{}", JsonUtils.toJSONString(eventParam));
sender.send(event);
}
@Async("asyncExecutor")
@Override
public void saveAndPush(Event event) {
baseMapper.insert(event);
if(event.getGmtCreate()==null){
event.setGmtCreate(LocalDateTime.now());
}
sender.send(event);
}
}
@@ -0,0 +1,113 @@
{
"header": {
"template": "red",
"title": {
"content": "${level}级报警 - 告警平台",
"tag": "plain_text"
}
},
"elements": [
{
"fields": [
{
"is_short": false,
"text": {
"content": "📋 项目:${app}",
"tag": "lark_md"
}
},
{
"is_short": false,
"text": {
"content": "🕐 时间:${gmtCreate}",
"tag": "lark_md"
}
},
{
"is_short": false,
"text": {
"content": "🔢 事件 ID${id}",
"tag": "lark_md"
}
},
{
"is_short": false,
"text": {
"content": "告警内容:",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"elements": [
{
"tag": "div",
"text": {
"content": "**${content}**",
"tag": "lark_md"
}
}
],
"tag": "note"
},
{
"actions": [
{
"tag": "button",
"text": {
"content": "跟进处理",
"tag": "plain_text"
},
"type": "primary",
"value": {
"key1": "value1"
}
},
{
"options": [
{
"text": {
"content": "屏蔽10分钟",
"tag": "plain_text"
},
"value": "1"
},
{
"text": {
"content": "屏蔽30分钟",
"tag": "plain_text"
},
"value": "2"
},
{
"text": {
"content": "屏蔽1小时",
"tag": "plain_text"
},
"value": "3"
},
{
"text": {
"content": "屏蔽24小时",
"tag": "plain_text"
},
"value": "4"
}
],
"placeholder": {
"content": "暂时屏蔽报警",
"tag": "plain_text"
},
"tag": "select_static",
"value": {
"key": "value"
}
}
],
"tag": "action"
}
]
}
@@ -0,0 +1,21 @@
server:
port: 8901
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
cloud:
nacos:
# 注册中心
discovery:
server-addr: http://192.168.100.151:8848
namespace: d2010a44-0999-4b45-9af8-2a0f028a97c3
# 配置中心
config:
server-addr: http://192.168.100.151:8848
file-extension: yaml
shared-configs[0]:
data-id: oneone-common.yaml
refresh: true
namespace: d2010a44-0999-4b45-9af8-2a0f028a97c3
@@ -0,0 +1,16 @@
server:
port: 8901
spring:
cloud:
nacos:
# 注册中心
discovery:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
# 配置中心
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yaml
shared-configs[0]:
data-id: oneone-common.yaml
refresh: true
@@ -0,0 +1,16 @@
server:
port: 8901
spring:
cloud:
nacos:
# 注册中心
discovery:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
# 配置中心
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yaml
shared-configs[0]:
data-id: oneone-common.yaml
refresh: true
@@ -0,0 +1,5 @@
spring:
application:
name: oneone-alert
profiles:
active: dev
@@ -0,0 +1,100 @@
{
"header": {
"template": "red",
"title": {
"content": "${level}级-${title}",
"tag": "plain_text"
}
},
"elements": [
{
"fields": [
{
"is_short": false,
"text": {
"content": "📋 项目:${app}",
"tag": "lark_md"
}
},
{
"is_short": false,
"text": {
"content": "🕐 时间:${gmtCreate}",
"tag": "lark_md"
}
},
{
"is_short": false,
"text": {
"content": "🔢 事件 ID${id}",
"tag": "lark_md"
}
},
{
"is_short": false,
"text": {
"content": "**告警内容:**\n**${content}**",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"actions": [
{
"tag": "button",
"text": {
"content": "跟进处理",
"tag": "plain_text"
},
"type": "primary",
"value": {
"key1": "value1"
}
},
{
"options": [
{
"text": {
"content": "屏蔽10分钟",
"tag": "plain_text"
},
"value": "1"
},
{
"text": {
"content": "屏蔽30分钟",
"tag": "plain_text"
},
"value": "2"
},
{
"text": {
"content": "屏蔽1小时",
"tag": "plain_text"
},
"value": "3"
},
{
"text": {
"content": "屏蔽24小时",
"tag": "plain_text"
},
"value": "4"
}
],
"placeholder": {
"content": "暂时屏蔽报警",
"tag": "plain_text"
},
"tag": "select_static",
"value": {
"key": "value"
}
}
],
"tag": "action"
}
]
}