diff --git a/health-watch/health-watch-api/src/main/java/com/renkang/watch/vo/WatchDataItemVO.java b/health-watch/health-watch-api/src/main/java/com/renkang/watch/vo/WatchDataItemVO.java index 5d6321f..f2408cb 100644 --- a/health-watch/health-watch-api/src/main/java/com/renkang/watch/vo/WatchDataItemVO.java +++ b/health-watch/health-watch-api/src/main/java/com/renkang/watch/vo/WatchDataItemVO.java @@ -1,9 +1,11 @@ package com.renkang.watch.vo; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; +import java.util.Date; /** * 手表数据条目 VO @@ -20,10 +22,10 @@ public class WatchDataItemVO implements Serializable { private static final long serialVersionUID = 1L; /** - * 工号 + * 员工编号 */ - @Schema(title = "工号") - private String workNo; + @Schema(title = "员工编号") + private String employeeNum; /** * 手表编号 @@ -36,4 +38,11 @@ public class WatchDataItemVO implements Serializable { */ @Schema(title = "姓名") private String realName; + + /** + * 绑定日期 + */ + @Schema(title = "绑定日期") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + private Date bindDate; } diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/DeptStatisticDataController.java b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/DeptStatisticDataController.java index 0bdb686..b972eca 100644 --- a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/DeptStatisticDataController.java +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/DeptStatisticDataController.java @@ -391,7 +391,7 @@ public class DeptStatisticDataController extends JeecgController exportDeptDetailAsync(DepartStatsFilter filter) { deptStatisticDataService.exportDeptDetailAsync(filter); - return Result.OK("导出结果请在个用户明细导出记录查看"); + return Result.OK("导出结果请在用户明细导出记录查看"); } diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/WatchApiController.java b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/WatchApiController.java index a317105..ab07ab2 100644 --- a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/WatchApiController.java +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/controller/WatchApiController.java @@ -8,14 +8,18 @@ import com.renkang.watch.vo.WatchDataItemVO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.annotation.RequiresPermissions; import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.util.AjaxJson; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -58,33 +62,37 @@ public class WatchApiController { ajaxJson.setSuccess(true); return ajaxJson; } + @GetMapping(value = "getIdcardByWatchNo") @Operation(summary = "根据手表编码获取最新的身份证号") @ResponseBody public Result getIdcardByWatchNo(@RequestParam("watchNo") String watchNo) { - String idcard = watchDeviceService.getIdcardByWatchNo(watchNo); - Map map = new HashMap<>(); - map.put("idcard",idcard); + String idcard = watchDeviceService.getIdcardByWatchNo(watchNo); + Map map = new HashMap<>(); + map.put("idcard", idcard); return Result.ok(map); } /** - * 查询手表数据总页数 + * 查询手表用户数据总页数 * - * @param workNo 工号(可空,模糊匹配) - * @param pageSize 每页大小(可空,默认 10) + * @param employeeNum 员工编号(可空,模糊匹配) + * @param pageSize 每页大小(可空,默认 10) + * @param bindDate 绑定日期(可空,格式 yyyy-MM-dd) * @return 包含 pageCount 字段的 Map */ - @GetMapping(value = "getWatchDataPageCount") - @Operation(summary = "查询手表数据总页数") + @GetMapping(value = "getWatchUserDataPageCount") + @Operation(summary = "查询手表用户数据总页数") @ResponseBody - public Result> getWatchDataPageCount(@RequestParam(value = "workNo", required = false) String workNo, - @RequestParam(value = "pageSize", required = false) Integer pageSize) { + @RequiresPermissions("watch:user:data:query") + public Result> getWatchUserDataPageCount(@RequestParam(value = "employeeNum", required = false) String employeeNum, + @RequestParam(value = "pageSize", required = false) Integer pageSize, + @RequestParam(value = "bindDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date bindDate) { if (pageSize != null && pageSize > 200) { return Result.error("pageSize 不能超过 200"); } int actualPageSize = (pageSize == null || pageSize <= 0) ? 10 : pageSize; - Integer pageCount = watchDeviceService.getWatchDataPageCount(workNo, actualPageSize); + Integer pageCount = watchDeviceService.getWatchUserDataPageCount(employeeNum, actualPageSize, bindDate); Map map = new HashMap<>(); map.put("pageCount", pageCount); map.put("pageSize", actualPageSize); @@ -92,23 +100,43 @@ public class WatchApiController { } /** - * 分页查询手表数据列表 + * 分页查询手表用户数据列表 * - * @param workNo 工号(可空,模糊匹配) - * @param pageNo 页码(默认 1) - * @param pageSize 每页大小(默认 10) + * @param employeeNum 员工编号(可空,模糊匹配) + * @param pageNo 页码(默认 1) + * @param pageSize 每页大小(默认 10) + * @param bindDate 绑定日期(可空,格式 yyyy-MM-dd) * @return 手表数据条目分页 */ - @GetMapping(value = "getWatchDataByPage") - @Operation(summary = "分页查询手表数据列表") + @GetMapping(value = "getWatchUserDataByPage") + @Operation(summary = "分页查询手表用户数据列表") @ResponseBody - public Result> getWatchDataByPage(@RequestParam(value = "workNo", required = false) String workNo, - @RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo, - @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) { + @RequiresPermissions("watch:user:data:query") + public Result> getWatchUserDataByPage(@RequestParam(value = "employeeNum", required = false) String employeeNum, + @RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo, + @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, + @RequestParam(value = "bindDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date bindDate) { if (pageSize != null && pageSize > 200) { return Result.error("pageSize 不能超过 200"); } - IPage page = watchDeviceService.getWatchDataByPage(workNo, pageNo, pageSize); + IPage page = watchDeviceService.getWatchUserDataByPage(employeeNum, pageNo, pageSize, bindDate); return Result.ok(page); } + + /** + * 全量查询手表用户数据列表(不分页) + * + * @param employeeNum 员工编号(可空,模糊匹配) + * @param bindDate 绑定日期(可空,格式 yyyy-MM-dd) + * @return 手表数据条目列表 + */ + @GetMapping(value = "getWatchUserDataAll") + @Operation(summary = "全量查询手表用户数据列表(不分页)") + @ResponseBody + @RequiresPermissions("watch:user:data:query") + public Result> getWatchUserDataAll(@RequestParam(value = "employeeNum", required = false) String employeeNum, + @RequestParam(value = "bindDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date bindDate) { + List list = watchDeviceService.getWatchUserDataAll(employeeNum, bindDate); + return Result.ok(list); + } } diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/mapper/xml/WatchDataMapper.xml b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/mapper/xml/WatchDataMapper.xml index 042a066..c7c9aaf 100644 --- a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/mapper/xml/WatchDataMapper.xml +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/mapper/xml/WatchDataMapper.xml @@ -304,7 +304,7 @@ insert into QH_WAT_DATA (id, userid, username, orgcode, watch_no, type, data_value, last_update_time) - (select #{id,jdbcType=VARCHAR}, bind_user_id, #{username,jdbcType=VARCHAR}, #{orgcode,jdbcType=VARCHAR}, watch_no, 6, sum(calorie), data_date + (select #{id,jdbcType=VARCHAR}, bind_user_id, #{username,jdbcType=VARCHAR}, #{orgcode,jdbcType=VARCHAR}, watch_no, 6, calorie, data_date from (select bind_user_id, watch_no, sum(calorie) as calorie, data_date, ROW_NUMBER() OVER (PARTITION BY bind_user_id, watch_no ORDER BY data_date desc) as rn from QH_WAT_DATA_WORKOUT @@ -340,7 +340,7 @@ insert into QH_WAT_DATA (id, userid, username, orgcode, watch_no, type, data_value, last_update_time) - (select #{id,jdbcType=VARCHAR}, bind_user_id, #{username,jdbcType=VARCHAR}, #{orgcode,jdbcType=VARCHAR}, watch_no, 7, max(data_value), data_date + (select #{id,jdbcType=VARCHAR}, bind_user_id, #{username,jdbcType=VARCHAR}, #{orgcode,jdbcType=VARCHAR}, watch_no, 7, data_value, data_date from (select bind_user_id, watch_no, max(data_value) as data_value, data_date, ROW_NUMBER() OVER (PARTITION BY bind_user_id, watch_no ORDER BY data_date desc) as rn from QH_WAT_DATA_DISTANCE @@ -376,7 +376,7 @@ insert into QH_WAT_DATA (id, userid, username, orgcode, watch_no, type, data_value, last_update_time) - (select #{id,jdbcType=VARCHAR}, bind_user_id, #{username,jdbcType=VARCHAR}, #{orgcode,jdbcType=VARCHAR}, watch_no, 8, max(data_value), data_date + (select #{id,jdbcType=VARCHAR}, bind_user_id, #{username,jdbcType=VARCHAR}, #{orgcode,jdbcType=VARCHAR}, watch_no, 8, data_value, data_date from (select bind_user_id, watch_no, max(data_value) as data_value, data_date, ROW_NUMBER() OVER (PARTITION BY bind_user_id, watch_no ORDER BY data_date desc) as rn from QH_WAT_DATA_STEPS diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/IWatchDeviceService.java b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/IWatchDeviceService.java index 5fdc037..1d880d3 100644 --- a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/IWatchDeviceService.java +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/IWatchDeviceService.java @@ -237,21 +237,37 @@ public interface IWatchDeviceService extends IService { void deleteKeyUser(String userId,String errorType); /** - * 查询手表数据总页数 + * 查询手表用户数据总页数 * - * @param workNo 工号(可空,模糊匹配) - * @param pageSize 每页大小(可空,默认 10) + * @param employeeNum 员工编号(可空,模糊匹配) + * @param pageSize 每页大小(可空,默认 10) + * @param bindDate 绑定日期(可空,精确匹配当天) * @return 总页数 */ - Integer getWatchDataPageCount(String workNo, Integer pageSize); + Integer getWatchUserDataPageCount(String employeeNum, Integer pageSize, java.util.Date bindDate); /** - * 分页查询手表数据列表 + * 分页查询手表用户数据列表 * - * @param workNo 工号(可空,模糊匹配) - * @param pageNo 页码 - * @param pageSize 每页大小 + * @param employeeNum 员工编号(可空,模糊匹配) + * @param pageNo 页码 + * @param pageSize 每页大小 + * @param bindDate 绑定日期(可空,精确匹配当天) * @return 手表数据条目分页 */ - IPage getWatchDataByPage(String workNo, Integer pageNo, Integer pageSize); + IPage getWatchUserDataByPage(String employeeNum, Integer pageNo, Integer pageSize, java.util.Date bindDate); + + /** + * 全量查询手表用户数据列表(不分页) + * + * @param employeeNum 员工编号(可空,模糊匹配) + * @param bindDate 绑定日期(可空,精确匹配当天) + * @return 手表数据条目列表 + */ + java.util.List getWatchUserDataAll(String employeeNum, java.util.Date bindDate); + + /** + * 刷新全量手表用户数据缓存(由定时任务调用,刷新 employeeNum=null、bindDate=null 的全量缓存) + */ + void refreshWatchUserDataAllCache(); } diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchDeviceServiceImpl.java b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchDeviceServiceImpl.java index af37605..3627fb6 100644 --- a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchDeviceServiceImpl.java +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/service/impl/WatchDeviceServiceImpl.java @@ -2349,23 +2349,33 @@ public class WatchDeviceServiceImpl extends ServiceImpl */ @Override - public Integer getWatchDataPageCount(String workNo, Integer pageSize) { + public Integer getWatchUserDataPageCount(String employeeNum, Integer pageSize, Date bindDate) { + String cacheKey = buildCacheKey("watch:data:page:count", employeeNum, bindDate, String.valueOf(pageSize)); + String cached = stringRedisTemplate.opsForValue().get(cacheKey); + if (cached != null) { + log.info("[缓存命中] key={} value={}", cacheKey, cached); + return Integer.valueOf(cached); + } int size = (pageSize == null || pageSize <= 0) ? 10 : pageSize; LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.isNotNull(WatchDevice::getBindUserId); wrapper.ne(WatchDevice::getBindUserId, ""); - if (StrUtil.isNotBlank(workNo)) { - List userIds = sysBaseAPI.getUserIdsByDepartAndUsername(null, null, null, workNo); + if (StrUtil.isNotBlank(employeeNum)) { + List userIds = sysBaseAPI.getUserIdsByDepartAndUsername(null, null, null, employeeNum); if (CollectionUtil.isEmpty(userIds)) { return 0; } wrapper.in(WatchDevice::getBindUserId, userIds); } + applyBindDateFilter(wrapper, bindDate); long total = watchDeviceMapper.selectCount(wrapper); if (total <= 0) { return 0; } - return (int) ((total + size - 1) / size); + int pageCount = (int) ((total + size - 1) / size); + stringRedisTemplate.opsForValue().set(cacheKey, String.valueOf(pageCount), 2, java.util.concurrent.TimeUnit.HOURS); + log.info("[缓存写入] key={} value={}", cacheKey, pageCount); + return pageCount; } /** @@ -2377,31 +2387,118 @@ public class WatchDeviceServiceImpl extends ServiceImpl */ @Override - public IPage getWatchDataByPage(String workNo, Integer pageNo, Integer pageSize) { + public IPage getWatchUserDataByPage(String employeeNum, Integer pageNo, Integer pageSize, Date bindDate) { int pn = (pageNo == null || pageNo <= 0) ? 1 : pageNo; int ps = (pageSize == null || pageSize <= 0) ? 10 : pageSize; Page voPage = new Page<>(pn, ps); + String cacheKey = buildCacheKey("watch:data:page", employeeNum, bindDate, pn + ":" + ps); + String cached = stringRedisTemplate.opsForValue().get(cacheKey); + if (cached != null) { + log.info("[缓存命中] key={}", cacheKey); + com.alibaba.fastjson.JSONObject jsonObj = com.alibaba.fastjson.JSONObject.parseObject(cached); + Page cachedPage = new Page<>(pn, ps); + cachedPage.setTotal(jsonObj.getLongValue("total")); + java.util.List records = com.alibaba.fastjson.JSONArray.parseArray( + jsonObj.getString("records"), WatchDataItemVO.class); + cachedPage.setRecords(records); + return cachedPage; + } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.isNotNull(WatchDevice::getBindUserId); wrapper.ne(WatchDevice::getBindUserId, ""); - // 通过工号过滤:先查 health-system 拿到 userIds,再用 userId 过滤 QH_WAT_DEVICE - if (StrUtil.isNotBlank(workNo)) { - List userIds = sysBaseAPI.getUserIdsByDepartAndUsername(null, null, null, workNo); + // 通过员工编号过滤:先查 health-system 拿到 userIds,再用 userId 过滤 QH_WAT_DEVICE + if (StrUtil.isNotBlank(employeeNum)) { + List userIds = sysBaseAPI.getUserIdsByDepartAndUsername(null, null, null, employeeNum); if (CollectionUtil.isEmpty(userIds)) { return voPage; } wrapper.in(WatchDevice::getBindUserId, userIds); } - wrapper.orderByDesc(WatchDevice::getCreateDate); + applyBindDateFilter(wrapper, bindDate); + wrapper.orderByDesc(WatchDevice::getBindDate); Page page = watchDeviceMapper.selectPage(new Page<>(pn, ps), wrapper); BeanUtil.copyProperties(page, voPage, "records"); if (CollectionUtil.isEmpty(page.getRecords())) { return voPage; } - // 跨服务批量查询用户基本信息(工号、姓名) - List userIdList = page.getRecords().stream() + List records = buildWatchDataItemVOList(page.getRecords()); + voPage.setRecords(records); + + // 写入缓存 + com.alibaba.fastjson.JSONObject cacheObj = new com.alibaba.fastjson.JSONObject(); + cacheObj.put("total", voPage.getTotal()); + cacheObj.put("records", records); + stringRedisTemplate.opsForValue().set(cacheKey, cacheObj.toJSONString(), 2, java.util.concurrent.TimeUnit.HOURS); + log.info("[缓存写入] key={} total={} size={}", cacheKey, voPage.getTotal(), records.size()); + return voPage; + } + + /** + * 全量查询手表数据列表(不分页) + *

+ * 仅查询已绑定用户的设备,支持按工号和绑定日期过滤,结果缓存 1 小时 + *

+ */ + @Override + public java.util.List getWatchUserDataAll(String employeeNum, Date bindDate) { + String cacheKey = buildCacheKey("watch:api:user:data:all", employeeNum, bindDate, null); + String cached = stringRedisTemplate.opsForValue().get(cacheKey); + if (cached != null) { + log.info("[缓存命中] key={}", cacheKey); + return com.alibaba.fastjson.JSONArray.parseArray(cached, WatchDataItemVO.class); + } + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.isNotNull(WatchDevice::getBindUserId); + wrapper.ne(WatchDevice::getBindUserId, ""); + if (StrUtil.isNotBlank(employeeNum)) { + List userIds = sysBaseAPI.getUserIdsByDepartAndUsername(null, null, null, employeeNum); + if (CollectionUtil.isEmpty(userIds)) { + return java.util.Collections.emptyList(); + } + wrapper.in(WatchDevice::getBindUserId, userIds); + } + applyBindDateFilter(wrapper, bindDate); + wrapper.orderByDesc(WatchDevice::getBindDate); + + List devices = watchDeviceMapper.selectList(wrapper); + if (CollectionUtil.isEmpty(devices)) { + return java.util.Collections.emptyList(); + } + java.util.List result = buildWatchDataItemVOList(devices); + stringRedisTemplate.opsForValue().set(cacheKey, com.alibaba.fastjson.JSONArray.toJSONString(result), 2, java.util.concurrent.TimeUnit.HOURS); + log.info("[缓存写入] key={} size={}", cacheKey, result.size()); + return result; + } + + /** + * 构建绑定日期范围过滤条件(取当天 00:00:00 ~ 次日 00:00:00) + */ + private void applyBindDateFilter(LambdaQueryWrapper wrapper, Date bindDate) { + if (bindDate == null) { + return; + } + java.util.Calendar cal = java.util.Calendar.getInstance(); + cal.setTime(bindDate); + cal.set(java.util.Calendar.HOUR_OF_DAY, 0); + cal.set(java.util.Calendar.MINUTE, 0); + cal.set(java.util.Calendar.SECOND, 0); + cal.set(java.util.Calendar.MILLISECOND, 0); + Date start = cal.getTime(); + cal.add(java.util.Calendar.DAY_OF_MONTH, 1); + Date end = cal.getTime(); + wrapper.ge(WatchDevice::getBindDate, start); + wrapper.lt(WatchDevice::getBindDate, end); + } + + /** + * 批量查询用户信息并组装 WatchDataItemVO 列表 + */ + private java.util.List buildWatchDataItemVOList(List devices) { + List userIdList = devices.stream() .map(WatchDevice::getBindUserId) .filter(StrUtil::isNotBlank) .distinct() @@ -2411,18 +2508,52 @@ public class WatchDeviceServiceImpl extends ServiceImpl u, (a, b) -> a)); - List records = page.getRecords().stream().map(device -> { + return devices.stream().map(device -> { WatchDataItemVO vo = new WatchDataItemVO(); vo.setWatchNo(device.getWatchNo()); + vo.setBindDate(device.getBindDate()); LoginUserNew user = userMap.get(device.getBindUserId()); if (user != null) { - vo.setWorkNo(user.getWorkNo()); + vo.setEmployeeNum(user.getWorkNo()); vo.setRealName(user.getRealname()); } return vo; }).collect(Collectors.toList()); - voPage.setRecords(records); - return voPage; + } + + /** + * 构建 Redis 缓存 key,null 参数用 "null" 占位 + */ + private String buildCacheKey(String prefix, String workNo, Date bindDate, String extra) { + String dateStr = bindDate == null ? "null" + : new java.text.SimpleDateFormat("yyyy-MM-dd").format(bindDate); + String wn = StrUtil.isBlank(workNo) ? "null" : workNo; + StringBuilder sb = new StringBuilder(prefix).append(":").append(wn).append(":").append(dateStr); + if (extra != null) { + sb.append(":").append(extra); + } + return sb.toString(); + } + + /** + * 刷新全量手表用户数据缓存(由定时任务调用) + * 查询全量已绑定设备数据并强制写入缓存,覆盖旧值 + */ + @Override + public void refreshWatchUserDataAllCache() { + String cacheKey = buildCacheKey("watch:api:user:data:all", null, null, null); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.isNotNull(WatchDevice::getBindUserId); + wrapper.ne(WatchDevice::getBindUserId, ""); + wrapper.orderByDesc(WatchDevice::getBindDate); + List devices = watchDeviceMapper.selectList(wrapper); + if (CollectionUtil.isEmpty(devices)) { + stringRedisTemplate.delete(cacheKey); + return; + } + java.util.List result = buildWatchDataItemVOList(devices); + stringRedisTemplate.opsForValue().set(cacheKey, com.alibaba.fastjson.JSONArray.toJSONString(result), 2, java.util.concurrent.TimeUnit.HOURS); + log.info("[缓存刷新] key={} size={}", cacheKey, result.size()); } } diff --git a/health-watch/health-watch-biz/src/main/java/com/renkang/watch/task/WatchUserDataCacheJob.java b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/task/WatchUserDataCacheJob.java new file mode 100644 index 0000000..95e3a99 --- /dev/null +++ b/health-watch/health-watch-biz/src/main/java/com/renkang/watch/task/WatchUserDataCacheJob.java @@ -0,0 +1,36 @@ +package com.renkang.watch.task; + +import com.renkang.watch.service.IWatchDeviceService; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 手表用户数据全量缓存刷新任务 + *

+ * 定时刷新 Redis 中 watch:api:user:data:all:null:null 缓存,供 getWatchUserDataAll 接口使用。 + * 具体执行频率在 xxl-job 控制台配置,handler 名称:watch-user-data-cache-refresh + *

+ */ +@Component +@Slf4j +@RequiredArgsConstructor +public class WatchUserDataCacheJob { + + private final IWatchDeviceService watchDeviceService; + + /** + * 刷新手表用户全量数据缓存 + */ + @XxlJob("watch-user-data-cache-refresh") + public void refreshCache() { + log.info("------开始刷新手表用户全量数据缓存------"); + try { + watchDeviceService.refreshWatchUserDataAllCache(); + log.info("======手表用户全量数据缓存刷新完成======"); + } catch (Exception e) { + log.error("手表用户全量数据缓存刷新失败", e); + } + } +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java index 0c25342..9eb7c7b 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java @@ -105,6 +105,10 @@ public class JeecgBootExceptionHandler implements ResponseBodyAdvice { return Result.error(errorInfoEnum.getError()); } //update-end---author:zyf ---date:20220411 for:处理Sentinel限流自定义异常 + //吞提示信息了,这里先单独处理一下吧 + if(e.getMessage().startsWith("已存在")){ + return Result.error(e.getMessage()); + } return Result.error("系统异常,请稍后再试", e.getMessage()); } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/export/ExportUtils.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/export/ExportUtils.java index 3e3f250..65e38f3 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/export/ExportUtils.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/export/ExportUtils.java @@ -18,6 +18,7 @@ import org.jeecgframework.poi.excel.ExcelExportUtil; import org.jeecgframework.poi.excel.entity.ExportParams; import org.jeecgframework.poi.excel.entity.enmus.ExcelType; import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.web.context.request.RequestContextHolder; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -108,6 +109,8 @@ public class ExportUtils { if (ObjectUtil.isNotNull(threadLocal)) { T o = threadLocal.get(); return executor.submit(() -> { + // 清除线程池复用线程可能残留的 HTTP 请求上下文,避免 Feign 拦截器读到过期 token + RequestContextHolder.resetRequestAttributes(); UserTokenContext.setToken(token); threadLocal.set(o); EXPORT_LOCAL.set(info); @@ -125,6 +128,8 @@ public class ExportUtils { }); } else { return executor.submit(() -> { + // 清除线程池复用线程可能残留的 HTTP 请求上下文,避免 Feign 拦截器读到过期 token + RequestContextHolder.resetRequestAttributes(); UserTokenContext.setToken(token); EXPORT_LOCAL.set(info); try { diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/util/RSAEncryptUtils.java b/jeecg-boot-base-core/src/main/java/org/jeecg/util/RSAEncryptUtils.java index 81fbabc..fb2803c 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/util/RSAEncryptUtils.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/util/RSAEncryptUtils.java @@ -199,7 +199,7 @@ public class RSAEncryptUtils { // Map keyMap; // String cipherText; // // 原始明文 - String content = "UserPwd@123!"; + String content = "v6BQj8452!j8KYj"; // // // 生成密钥对 // keyMap = initKey(1024);