From 83a557e166c3de87f6c055ec3fc8e02cb1991c65 Mon Sep 17 00:00:00 2001 From: wu Date: Wed, 8 May 2024 17:09:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9D=83=E9=99=90=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 12 + .../yingji/controller/AlarmController.java | 50 +++- .../exception/GlobalExceptionHandler.java | 84 ++++++ .../java/com/yingji/quartz/AlarmQuartz.java | 21 +- .../com/yingji/quartz/SaveAlarmQuartz.java | 3 +- .../java/com/yingji/redis/RedisCache.java | 248 ++++++++++++++++++ .../yingji/service/impl/AlarmServiceImpl.java | 7 +- src/main/resources/application.yml | 31 ++- 8 files changed, 439 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/yingji/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/com/yingji/redis/RedisCache.java diff --git a/pom.xml b/pom.xml index f0d21e9..0350035 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,18 @@ 2.7.6 + + + + cn.dev33 + sa-token-spring-boot-starter + 1.37.0 + + + + org.springframework.boot + spring-boot-starter-data-redis + org.springframework.boot spring-boot-starter-web diff --git a/src/main/java/com/yingji/controller/AlarmController.java b/src/main/java/com/yingji/controller/AlarmController.java index 9170e49..3701b46 100644 --- a/src/main/java/com/yingji/controller/AlarmController.java +++ b/src/main/java/com/yingji/controller/AlarmController.java @@ -1,7 +1,7 @@ package com.yingji.controller; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import cn.dev33.satoken.stp.StpUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yingji.base.controller.BaseController; import com.yingji.base.domain.AjaxResult; @@ -10,7 +10,6 @@ import com.yingji.entity.dto.request.AlarmFindRequest; import com.yingji.service.AlarmService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -44,13 +43,14 @@ public class AlarmController extends BaseController { /** * 分页条件查询所有数据 * - * @param page 分页条件 - * @param req 查询条件 + * @param page 分页条件 + * @param req 查询条件 * @return 所有数据 */ @GetMapping @ApiOperation(value = "分页条件查询报警事件", response = Alarm.class) public AjaxResult page(Page page, AlarmFindRequest req) { + StpUtil.checkLogin(); return success(alarmService.page(page, req)); } @@ -63,6 +63,8 @@ public class AlarmController extends BaseController { @GetMapping("/findAll") @ApiOperation(value = "条件查询所有报警事件", response = Alarm.class) public AjaxResult findAll(AlarmFindRequest req) { + StpUtil.checkLogin(); +// StpUtil.renewTimeout(100); return success(alarmService.findAll(req)); } @@ -75,6 +77,7 @@ public class AlarmController extends BaseController { @GetMapping("{id}") @ApiOperation(value = "通过主键查询单条报警事件", response = Alarm.class) public AjaxResult getById(@PathVariable Serializable id) { + StpUtil.checkLogin(); return success(alarmService.getById(id)); } @@ -87,6 +90,7 @@ public class AlarmController extends BaseController { @PostMapping @ApiOperation(value = "新增报警事件", response = Alarm.class) public AjaxResult insert(@RequestBody Alarm alarm) { + StpUtil.checkLogin(); return success(alarmService.save(alarm)); } @@ -99,6 +103,7 @@ public class AlarmController extends BaseController { @PutMapping @ApiOperation(value = "修改报警事件") public AjaxResult update(@RequestBody Alarm alarm) { + StpUtil.checkLogin(); return success(alarmService.updateById(alarm)); } @@ -111,6 +116,7 @@ public class AlarmController extends BaseController { @DeleteMapping @ApiOperation(value = "删除报警事件") public AjaxResult delete(@RequestParam("idList") List idList) { + StpUtil.checkLogin(); return success(alarmService.removeByIds(idList)); } @@ -118,14 +124,46 @@ public class AlarmController extends BaseController { * 同步数据 * * @param startTime 查询条件 - * @param size 查询条数 + * @param size 查询条数 * @return 所有数据 */ @GetMapping("/synchronous") @ApiOperation(value = "同步数据") public AjaxResult synchronous(String startTime, Integer size) { - alarmService.synchronous(startTime,size); + StpUtil.checkLogin(); + alarmService.synchronous(startTime, size); return success(); } + + @ApiOperation(value = "登录") + @GetMapping("doLogin") + public AjaxResult doLogin(String clientId, String clientSecret) { + // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对 + if ("9219a5c1612c398c".equals(clientId) && "88aba31a35e3a713".equals(clientSecret)) { + StpUtil.login(10001); + return success((Object)StpUtil.getTokenValue()); + } + return error("错误的授权码"); + } + + @ApiOperation(value = "查询登录状态") + @GetMapping("isLogin") + public String isLogin() { + return "当前会话是否登录:" + StpUtil.isLogin(); + } + +// public static void main(String[] args) { +// String encode = Base64.encode("123QWQAVA1314543"); +// System.err.println(encode); +// MD5 md5 = MD5.create(); +// String s = md5.digestHex16(encode); +// System.err.println(s); +// +// String encode2 = Base64.encode("321123QWQAVAORZ"); +// System.err.println(encode2); +// MD5 md52 = MD5.create(); +// String s2 = md5.digestHex16(encode2); +// System.err.println(s2); +// } } diff --git a/src/main/java/com/yingji/exception/GlobalExceptionHandler.java b/src/main/java/com/yingji/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..062e4df --- /dev/null +++ b/src/main/java/com/yingji/exception/GlobalExceptionHandler.java @@ -0,0 +1,84 @@ +package com.yingji.exception; + +import cn.dev33.satoken.exception.NotLoginException; +import com.yingji.base.domain.AjaxResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.validation.BindException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.servlet.http.HttpServletRequest; + +/** + * 全局异常处理器 + * + * @author wu + */ +@RestControllerAdvice +public class GlobalExceptionHandler { + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, + HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return AjaxResult.error(e.getMessage()); + } + + + /** + * 拦截未知的运行时异常 + */ + @ExceptionHandler(RuntimeException.class) + public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生未知异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 系统异常 + */ + @ExceptionHandler(Exception.class) + public AjaxResult handleException(Exception e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public AjaxResult handleBindException(BindException e) { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 登录异常 + */ + @ExceptionHandler(NotLoginException.class) + public AjaxResult handleDemoModeException(NotLoginException e) { + return AjaxResult.error(e.getMessage()); + } +} diff --git a/src/main/java/com/yingji/quartz/AlarmQuartz.java b/src/main/java/com/yingji/quartz/AlarmQuartz.java index d9b740d..fc494d8 100644 --- a/src/main/java/com/yingji/quartz/AlarmQuartz.java +++ b/src/main/java/com/yingji/quartz/AlarmQuartz.java @@ -2,6 +2,7 @@ package com.yingji.quartz; import cn.hutool.core.util.StrUtil; import com.yingji.entity.dto.request.AlarmRequest; +import com.yingji.redis.RedisCache; import com.yingji.service.AlarmService; import com.yingji.service.SourceService; import org.slf4j.Logger; @@ -33,6 +34,9 @@ public class AlarmQuartz { @Resource private SourceService sourceService; + @Resource + private RedisCache redisCache; + /** * 保存所有id */ @@ -43,10 +47,17 @@ public class AlarmQuartz { if (StrUtil.isEmpty(token)) { return; } - // 获取五分钟前的时间 - LocalDateTime yesterday = LocalDateTime.now().minusMinutes(5); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmm"); - String yesterdayStr = yesterday.format(formatter) + "00"; + String yesterdayStr; + String effectiveTimeStr = redisCache.getCacheObject("effectiveTimeStr"); + log.info("redis的缓存时间是==========================" + effectiveTimeStr ); + if (StrUtil.isNotEmpty(effectiveTimeStr)) { + yesterdayStr = effectiveTimeStr; + } else { + // 获取五分钟前的时间 + LocalDateTime yesterday = LocalDateTime.now().minusMinutes(5); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmm"); + yesterdayStr = yesterday.format(formatter) + "00"; + } // 定义起始页 int pageIndex = 1; // 定义每页显示条数 @@ -64,6 +75,7 @@ public class AlarmQuartz { while (true) { List data = alarmService.findDataIdList(req, token); if (data == null) { + redisCache.setCacheObject("effectiveTimeStr", yesterdayStr); return; } sourceService.addList(data); @@ -72,6 +84,7 @@ public class AlarmQuartz { req.setPageIndex(pageIndex++); log.info("第" + pageIndex + "页==========================" + size + "条数据"); } else { + redisCache.deleteObject("effectiveTimeStr"); break; } } diff --git a/src/main/java/com/yingji/quartz/SaveAlarmQuartz.java b/src/main/java/com/yingji/quartz/SaveAlarmQuartz.java index cbf4106..0dd4708 100644 --- a/src/main/java/com/yingji/quartz/SaveAlarmQuartz.java +++ b/src/main/java/com/yingji/quartz/SaveAlarmQuartz.java @@ -63,10 +63,11 @@ public class SaveAlarmQuartz { Alarm alarm = alarmService.findDataList(alarmRequest, token); if (alarm != null) { alarm.setSourceId(x); + // todo 暂时不做去重操作 list.add(alarm); sourceService.delBySourceId(x); successNum++; - Thread.sleep(2000); + Thread.sleep(1000); } } catch (Exception e) { failuresNum++; diff --git a/src/main/java/com/yingji/redis/RedisCache.java b/src/main/java/com/yingji/redis/RedisCache.java new file mode 100644 index 0000000..faa2a01 --- /dev/null +++ b/src/main/java/com/yingji/redis/RedisCache.java @@ -0,0 +1,248 @@ +package com.yingji.redis; + +import org.springframework.data.redis.core.BoundSetOperations; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * spring redis 工具类 + * + * @author wu + **/ +@SuppressWarnings(value = {"unchecked", "rawtypes"}) +@Component +public class RedisCache { + + @Resource + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public void setCacheObject(final String key, final T value) { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) { + redisTemplate.opsForValue().set(key, value, timeout, timeUnit); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout) { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout, final TimeUnit unit) { + return redisTemplate.expire(key, timeout, unit); + } + + /** + * 获取有效时间 + * + * @param key Redis键 + * @return 有效时间 + */ + public long getExpire(final String key) { + return redisTemplate.getExpire(key); + } + + /** + * 判断 key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public Boolean hasKey(String key) { + return redisTemplate.hasKey(key); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public T getCacheObject(final String key) { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public boolean deleteObject(final String key) { + return redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public boolean deleteObject(final Collection collection) { + return redisTemplate.delete(collection) > 0; + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public long setCacheList(final String key, final List dataList) { + Long count = redisTemplate.opsForList().rightPushAll(key, dataList); + return count == null ? 0 : count; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public List getCacheList(final String key) { + return redisTemplate.opsForList().range(key, 0, -1); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public BoundSetOperations setCacheSet(final String key, final Set dataSet) { + BoundSetOperations setOperation = redisTemplate.boundSetOps(key); + Iterator it = dataSet.iterator(); + while (it.hasNext()) { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public Set getCacheSet(final String key) { + return redisTemplate.opsForSet().members(key); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public void setCacheMap(final String key, final Map dataMap) { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(key, dataMap); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public Map getCacheMap(final String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public void setCacheMapValue(final String key, final String hKey, final T value) { + redisTemplate.opsForHash().put(key, hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public T getCacheMapValue(final String key, final String hKey) { + HashOperations opsForHash = redisTemplate.opsForHash(); + return opsForHash.get(key, hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public List getMultiCacheMapValue(final String key, final Collection hKeys) { + return redisTemplate.opsForHash().multiGet(key, hKeys); + } + + /** + * 删除Hash中的某条数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return 是否成功 + */ + public boolean deleteCacheMapValue(final String key, final String hKey) { + return redisTemplate.opsForHash().delete(key, hKey) > 0; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(final String pattern) { + return redisTemplate.keys(pattern); + } +} diff --git a/src/main/java/com/yingji/service/impl/AlarmServiceImpl.java b/src/main/java/com/yingji/service/impl/AlarmServiceImpl.java index 6fbb106..26c5c10 100644 --- a/src/main/java/com/yingji/service/impl/AlarmServiceImpl.java +++ b/src/main/java/com/yingji/service/impl/AlarmServiceImpl.java @@ -22,7 +22,6 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Collections; import java.util.List; @@ -211,13 +210,13 @@ public class AlarmServiceImpl extends ServiceImpl implements /** * 分页条件查询数据 * - * @param page 分页条件 - * @param req 查询条件 + * @param page 分页条件 + * @param req 查询条件 * @return 数据 */ @Override public Page page(Page page, AlarmFindRequest req) { - return baseMapper.page(page,req); + return baseMapper.page(page, req); } /** diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 619c609..b4067ab 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,10 +4,37 @@ spring: profiles: active: dev + redis: + host: localhost + port: 6379 + password: + database: 1 + jedis: + pool: + max-active: 8 # 最大连接数 + max-wait: 1ms # 最大阻塞时间 + max-idle: 4 + min-idle: 0 # 日志配置 logging: level: - com.yingji: error - org.springframework: error + com.yingji: info + org.springframework: info + +sa-token: + # token 名称(同时也是 cookie 名称) + token-name: token + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 + timeout: 86400 + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) + is-concurrent: true + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) + is-share: true + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) + token-style: uuid + # 是否输出操作日志 + is-log: true