diff --git a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/SysLogsVo.java b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/SysLogsVo.java index ff6414b..b08431b 100644 --- a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/SysLogsVo.java +++ b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/SysLogsVo.java @@ -149,6 +149,10 @@ public class SysLogsVo { private String type; private String capacity; + /** + * 0未处理,1已处理 + */ + private String warningStatus; /** * 越权记录 diff --git a/bonus-common/bonus-common-config/src/main/java/com/bonus/config/SystemConfig.java b/bonus-common/bonus-common-config/src/main/java/com/bonus/config/SystemConfig.java index 6a0dede..22c8775 100644 --- a/bonus-common/bonus-common-config/src/main/java/com/bonus/config/SystemConfig.java +++ b/bonus-common/bonus-common-config/src/main/java/com/bonus/config/SystemConfig.java @@ -15,6 +15,7 @@ import java.util.List; @ConfigurationProperties(prefix = "system-config") @Data public class SystemConfig { + /** * 登录配置 */ @@ -44,6 +45,11 @@ public class SystemConfig { */ private PasswordConfig passwordConfig; + /** + * websocketUrl + */ + private String webSocketurl; + @Data @RefreshScope public static class LoginConfig { diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/service/impl/SysLogServiceImpl.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/service/impl/SysLogServiceImpl.java index d141e07..05a945a 100644 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/service/impl/SysLogServiceImpl.java +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/service/impl/SysLogServiceImpl.java @@ -1,5 +1,7 @@ package com.bonus.system.service.impl; +import com.bonus.system.warning.SysWarning; +import com.bonus.system.warning.WaringLogEvent; import com.google.common.collect.Maps; import com.bonus.common.core.utils.DateUtils; @@ -15,6 +17,8 @@ import com.bonus.system.api.domain.SysLogsVo; import com.bonus.system.api.model.LoginUser; import com.bonus.system.mapper.SysLogMapper; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; @@ -24,7 +28,7 @@ import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; import java.util.Map; -import com.bonus.common.log.enums.LogType; + /** * @author:cwchen * @date:2024-02-28-14:02 @@ -38,16 +42,13 @@ public class SysLogServiceImpl implements ISysLogService { @Resource(name = "SysLogMapper") private SysLogMapper mapper; + @Autowired + private ApplicationEventPublisher eventPublisher; + @Override @Transactional(rollbackFor = Exception.class) public AjaxResult saveLogs(SysLogsVo sysLog) { try { - //weiweiw -// if(sysLog.getResult() == SystemGlobal.SUCCESS_NUM){ -// sysLog.setFruit("成功"); -// }else { -// sysLog.setFruit("失败"); -// } //如果是异常日志 if(SystemGlobal.LOG_ERR.equals(sysLog.getErrType()) && StringUtils.isEmpty(sysLog.getModel())) { SysLogsVo sysLog1=mapper.getModule(sysLog.getOperUri()); @@ -61,6 +62,7 @@ public class SysLogServiceImpl implements ISysLogService { } } mapper.saveLogs(sysLog); + eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(sysLog.getLogId(),"测试系统日志告警","",sysLog.getIp(),sysLog.getGrade(),sysLog.getOperaUserName()))); } catch (Exception e) { log.error("保存系统日志"); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); @@ -72,8 +74,10 @@ public class SysLogServiceImpl implements ISysLogService { public void saveLogs(SysLogsVo sysLog, HttpServletRequest request) { try{ // sysLog.setFruit("失败"); - sysLog.setLogId(IdUtils.fastUUID()); - sysLog.setIp(IpUtils.getIpAddr(request)); + String loginUuid = IdUtils.fastUUID(); + String ip = IpUtils.getIpAddr(request); + sysLog.setLogId(loginUuid); + sysLog.setIp(ip); sysLog.setGrade("高"); sysLog.setErrType("越权访问"); sysLog.setFailureReason("页面未授权"); @@ -95,6 +99,7 @@ public class SysLogServiceImpl implements ISysLogService { } mapper.saveLogs(sysLog); } + eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(loginUuid,"越权访问","",ip,"高",user.getUsername()))); }catch (Exception e){ log.error(e.toString(),e); } diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/service/impl/SysOperLogServiceImpl.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/service/impl/SysOperLogServiceImpl.java index 84e6e77..d551145 100644 --- a/bonus-modules/bonus-system/src/main/java/com/bonus/system/service/impl/SysOperLogServiceImpl.java +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/service/impl/SysOperLogServiceImpl.java @@ -9,7 +9,11 @@ import com.bonus.common.core.utils.StringUtils; import com.bonus.common.log.enums.OperaType; import com.bonus.system.api.domain.SysLogsVo; import com.bonus.system.domain.SysLogsMenuHead; +import com.bonus.system.warning.SysWarning; +import com.bonus.system.warning.WaringLogEvent; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import com.bonus.system.api.domain.SysOperLog; import com.bonus.system.mapper.SysOperLogMapper; @@ -30,6 +34,9 @@ public class SysOperLogServiceImpl implements ISysOperLogService private SysOperLogMapper operLogMapper; public static final String MENU_TYPE_FILE = "F"; + @Autowired + private ApplicationEventPublisher eventPublisher; + /** * 新增操作日志 * @@ -94,6 +101,7 @@ public class SysOperLogServiceImpl implements ISysOperLogService */ @Override public int addLogs(SysLogsVo sysLogsVo) { + eventPublisher.publishEvent(new WaringLogEvent(new SysWarning(sysLogsVo.getLogId(),"测试系统日志告警","",sysLogsVo.getIp(),sysLogsVo.getGrade(),sysLogsVo.getOperaUserName()))); return operLogMapper.addLogs(sysLogsVo); } diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/SysWarning.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/SysWarning.java new file mode 100644 index 0000000..0ea1f38 --- /dev/null +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/SysWarning.java @@ -0,0 +1,33 @@ +package com.bonus.system.warning; + +import lombok.Data; + +import java.util.Date; + +@Data +public class SysWarning { + + public SysWarning(String warningId,String warningEvent, String warningContent,String warningIp,String warningGrade, String operaUserName ){ + this.warningId = warningId; + this.warningEvent = warningEvent; + this.warningContent = warningContent; + this.warningIp = warningIp; + this.warningGrade = warningGrade; + this.operaUserName = operaUserName; + } + private String warningId; + + private String warningEvent = ""; + + private String warningContent = ""; + + private String warningIp = ""; + + private String warningGrade = ""; + + private String operaUserName = ""; + + private Date warningTime; + + private String warningStatus = "0"; +} diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WaringLogEvent.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WaringLogEvent.java new file mode 100644 index 0000000..fbf788b --- /dev/null +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WaringLogEvent.java @@ -0,0 +1,20 @@ +package com.bonus.system.warning; + +import org.springframework.context.ApplicationEvent; + + +public class WaringLogEvent extends ApplicationEvent { + + private final SysWarning sysWarning; + + public WaringLogEvent(SysWarning logEvent) { + super(logEvent); + this.sysWarning = logEvent; + } + + + public SysWarning getSysWarning(){ + return this.sysWarning; + } + +} \ No newline at end of file diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WarningListen.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WarningListen.java new file mode 100644 index 0000000..95ee57c --- /dev/null +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WarningListen.java @@ -0,0 +1,52 @@ +package com.bonus.system.warning; +import com.bonus.system.service.ISysLogService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.WebSocketSession; + +import javax.annotation.Resource; +import java.io.IOException; + +@Component +@Slf4j +public class WarningListen { + + @Autowired + private SimpMessagingTemplate messagingTemplate; + + @Resource(name = "ISysLogService") + private ISysLogService service; + + public static void closeSession(WebSocketSession session) throws IOException { + session.close(); + } + + @EventListener + public void onLogSaved(WaringLogEvent event) { + try { + SysWarning warning = event.getSysWarning(); + sendAlert(warning); + } catch (Exception e) { + log.error("处理日志告警失败", e); + } + } + + // 发送告警消息 + public void sendAlert(SysWarning alert) { + messagingTemplate.convertAndSend("/topic/alerts", alert); + log.info("*************************告警消息已发送:{}", alert); + } + + // 处理用户确认消息 + @MessageMapping("/alert-handled") + public void handleAlert(String alertId) { + // 在这里处理告警确认逻辑 + System.out.println("Alert " + alertId + " has been handled"); + + } + +} \ No newline at end of file diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WebSocketConfig.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WebSocketConfig.java new file mode 100644 index 0000000..52a0c7e --- /dev/null +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WebSocketConfig.java @@ -0,0 +1,31 @@ +package com.bonus.system.warning; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.config.annotation.*; + +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer, WebSocketConfigurer { + + @Autowired + private WebSocketHandler webSocketHandler; + @Override + public void configureMessageBroker(MessageBrokerRegistry config) { + config.enableSimpleBroker("/topic"); + config.setApplicationDestinationPrefixes("/app"); + } + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws-alert").withSockJS(); + } + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(webSocketHandler, "/ws-alert") + .setAllowedOrigins("*"); // 允许跨域 + } +} \ No newline at end of file diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WebSocketHandler.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WebSocketHandler.java new file mode 100644 index 0000000..a331e90 --- /dev/null +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/warning/WebSocketHandler.java @@ -0,0 +1,40 @@ +package com.bonus.system.warning; + +import org.springframework.web.socket.*; +import org.springframework.web.socket.handler.TextWebSocketHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CopyOnWriteArrayList; + +@Component +public class WebSocketHandler extends TextWebSocketHandler { + private static final Logger logger = LoggerFactory.getLogger(WebSocketHandler.class); + private static final CopyOnWriteArrayList sessions = new CopyOnWriteArrayList<>(); + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + sessions.add(session); + logger.info("WebSocket 连接成功: " + session.getId()); + } + + @Override + protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { + String payload = message.getPayload(); + logger.info("接收到消息: " + payload); + + // 处理接收到的消息(例如广播给所有客户端) + for (WebSocketSession wsSession : sessions) { + if (wsSession.isOpen()) { + wsSession.sendMessage(new TextMessage("服务端回应: " + payload)); + } + } + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { + sessions.remove(session); + logger.info("WebSocket 连接关闭: " + session.getId()); + } +} diff --git a/bonus-modules/bonus-system/src/main/resources/mapper/system/SysLogMapper.xml b/bonus-modules/bonus-system/src/main/resources/mapper/system/SysLogMapper.xml index 807d807..be33550 100644 --- a/bonus-modules/bonus-system/src/main/resources/mapper/system/SysLogMapper.xml +++ b/bonus-modules/bonus-system/src/main/resources/mapper/system/SysLogMapper.xml @@ -5,21 +5,56 @@ insert into sys_logs( - log_id,opera_user_name,ip,user_id, - model,oper_time,method,params, - operate_detail,oper_type,oper_uri, - log_type,result,times, - failure_reason,grade,err_type, - method_type,title,result_data + log_id, + opera_user_name, + ip, + user_id, + model, + oper_time, + method, + params, + operate_detail, + oper_type, + oper_uri, + log_type, + result, + times, + failure_reason, + grade, + err_type, + method_type, + title, + result_data, + warning_status, )values ( - #{logId},#{operaUserName},#{ip},#{userId}, - #{model},#{operTime},#{method},#{params}, - #{operateDetail},#{operaType},#{operUri}, - #{logType},#{result},#{times}, - #{failureReason},#{grade},#{errType}, - #{methodType},#{title},#{resultData} - ) + {logId}, + {operaUserName}, + {ip}, + {userId}, + {model}, + {operTime}, + {method}, + {params}, + {operateDetail}, + {operaType}, + {operUri}, + {logType}, + {result}, + {times}, + {failureReason}, + {grade}, + {errType}, + {methodType}, + {title}, + {resultData}, + {warningStatus}, + + + update sys_warning + set warning_status = #{warningStatus} + where log_id = #{logId} + diff --git a/bonus-modules/bonus-system/src/main/resources/mapper/system/SysWarningMapper.xml b/bonus-modules/bonus-system/src/main/resources/mapper/system/SysWarningMapper.xml new file mode 100644 index 0000000..a48f619 --- /dev/null +++ b/bonus-modules/bonus-system/src/main/resources/mapper/system/SysWarningMapper.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + insert into sys_warning( + warning_id, + warning_event, + warning_content, + warning_ip, + warning_grade, + opera_user_name, + warning_time, + warning_status, + )values( + #{warningId}, + #{warningEvent}, + #{warningContent}, + #{warningIp}, + #{warningGrade}, + #{operaUserName}, + sysdate, + #{warningStatus}, + ) + + + + update sys_warning + set warning_status = #{warningStatus} + where warning_id = #{warningId} + + + +