添加获取项目生产天数接口;添加定时任务,每天自动删除项目缓存
This commit is contained in:
@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||||||
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
|
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
|
||||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
import org.springframework.scheduling.annotation.EnableAsync;
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动程序
|
* 启动程序
|
||||||
@ -14,6 +15,7 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
|||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableAsync
|
@EnableAsync
|
||||||
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
|
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
|
||||||
|
@EnableScheduling
|
||||||
public class DromaraApplication {
|
public class DromaraApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -52,32 +52,32 @@ spring:
|
|||||||
url: jdbc:mysql://192.168.110.199:3306/energy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
url: jdbc:mysql://192.168.110.199:3306/energy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||||
username: energy
|
username: energy
|
||||||
password: fikwNsk8BidXSKe4
|
password: fikwNsk8BidXSKe4
|
||||||
# # 从库数据源
|
# # 从库数据源
|
||||||
# slave:
|
# slave:
|
||||||
# lazy: true
|
# lazy: true
|
||||||
# type: ${spring.datasource.type}
|
# type: ${spring.datasource.type}
|
||||||
# driverClassName: com.mysql.cj.jdbc.Driver
|
# driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
|
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
|
||||||
# username:
|
# username:
|
||||||
# password:
|
# password:
|
||||||
# oracle:
|
# oracle:
|
||||||
# type: ${spring.datasource.type}
|
# type: ${spring.datasource.type}
|
||||||
# driverClassName: oracle.jdbc.OracleDriver
|
# driverClassName: oracle.jdbc.OracleDriver
|
||||||
# url: jdbc:oracle:thin:@//localhost:1521/XE
|
# url: jdbc:oracle:thin:@//localhost:1521/XE
|
||||||
# username: ROOT
|
# username: ROOT
|
||||||
# password: root
|
# password: root
|
||||||
# postgres:
|
# postgres:
|
||||||
# type: ${spring.datasource.type}
|
# type: ${spring.datasource.type}
|
||||||
# driverClassName: org.postgresql.Driver
|
# driverClassName: org.postgresql.Driver
|
||||||
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
|
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
|
||||||
# username: root
|
# username: root
|
||||||
# password: root
|
# password: root
|
||||||
# sqlserver:
|
# sqlserver:
|
||||||
# type: ${spring.datasource.type}
|
# type: ${spring.datasource.type}
|
||||||
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
|
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||||
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
|
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
|
||||||
# username: SA
|
# username: SA
|
||||||
# password: root
|
# password: root
|
||||||
hikari:
|
hikari:
|
||||||
# 最大连接池数量
|
# 最大连接池数量
|
||||||
maxPoolSize: 20
|
maxPoolSize: 20
|
||||||
@ -206,7 +206,7 @@ justauth:
|
|||||||
client-id: 449c4*********937************759
|
client-id: 449c4*********937************759
|
||||||
client-secret: ac7***********1e0************28d
|
client-secret: ac7***********1e0************28d
|
||||||
redirect-uri: ${justauth.address}/social-callback?source=topiam
|
redirect-uri: ${justauth.address}/social-callback?source=topiam
|
||||||
scopes: [openid, email, phone, profile]
|
scopes: [ openid, email, phone, profile ]
|
||||||
qq:
|
qq:
|
||||||
client-id: 10**********6
|
client-id: 10**********6
|
||||||
client-secret: 1f7d08**********5b7**********29e
|
client-secret: 1f7d08**********5b7**********29e
|
||||||
@ -263,6 +263,7 @@ justauth:
|
|||||||
client-id: 10**********6
|
client-id: 10**********6
|
||||||
client-secret: 1f7d08**********5b7**********29e
|
client-secret: 1f7d08**********5b7**********29e
|
||||||
redirect-uri: ${justauth.address}/social-callback?source=gitlab
|
redirect-uri: ${justauth.address}/social-callback?source=gitlab
|
||||||
|
# 和风天气 https://dev.qweather.com/
|
||||||
weather:
|
weather:
|
||||||
key-id: T65EAABUXC
|
key-id: T65EAABUXC
|
||||||
project-id: 2JTHPUQ5YY
|
project-id: 2JTHPUQ5YY
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package org.dromara.job.cycle;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.project.constant.BusProjectConstant;
|
||||||
|
import org.springframework.data.redis.core.Cursor;
|
||||||
|
import org.springframework.data.redis.core.ScanOptions;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class IncSyncDeleteProjectCache {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
// 每天凌晨 12 点执行
|
||||||
|
@Scheduled(cron = "0 0 0 * * ?")
|
||||||
|
public void run() {
|
||||||
|
log.info("执行定时任务:清理项目缓存");
|
||||||
|
// 构建扫描选项
|
||||||
|
ScanOptions scanOptions = ScanOptions.scanOptions()
|
||||||
|
.match(BusProjectConstant.PROJECT_CACHE_REDIS_KEY_PREFIX + "*")
|
||||||
|
.count(1000) // 每次 scan 的数量
|
||||||
|
.build();
|
||||||
|
Set<String> keysToDelete = new HashSet<>();
|
||||||
|
Cursor<byte[]> cursor = stringRedisTemplate.getConnectionFactory()
|
||||||
|
.getConnection()
|
||||||
|
.scan(scanOptions);
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
keysToDelete.add(new String(cursor.next()));
|
||||||
|
}
|
||||||
|
// 批量删除
|
||||||
|
if (!keysToDelete.isEmpty()) {
|
||||||
|
stringRedisTemplate.delete(keysToDelete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package org.dromara.manager.weathermanager;
|
|||||||
import cn.hutool.http.HttpRequest;
|
import cn.hutool.http.HttpRequest;
|
||||||
import cn.hutool.http.HttpResponse;
|
import cn.hutool.http.HttpResponse;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.constant.HttpStatus;
|
import org.dromara.common.core.constant.HttpStatus;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -21,6 +22,7 @@ import java.util.Base64;
|
|||||||
* @author lcj
|
* @author lcj
|
||||||
* @date 2025/5/12 17:33
|
* @date 2025/5/12 17:33
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class WeatherManager {
|
public class WeatherManager {
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ public class WeatherManager {
|
|||||||
.execute()) {
|
.execute()) {
|
||||||
int status = result.getStatus();
|
int status = result.getStatus();
|
||||||
if (status != HttpStatus.SUCCESS) {
|
if (status != HttpStatus.SUCCESS) {
|
||||||
|
log.error("获取天气失败,状态码:{},body:{}", status, result.body());
|
||||||
throw new ServiceException("获取天气失败,状态码:" + status, HttpStatus.ERROR);
|
throw new ServiceException("获取天气失败,状态码:" + status, HttpStatus.ERROR);
|
||||||
}
|
}
|
||||||
body = result.body();
|
body = result.body();
|
||||||
|
@ -11,4 +11,14 @@ public interface BusProjectConstant {
|
|||||||
*/
|
*/
|
||||||
String PROJECT_WEATHER_LIST_VO_REDIS_KEY_PREFIX = "project:weather:list";
|
String PROJECT_WEATHER_LIST_VO_REDIS_KEY_PREFIX = "project:weather:list";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目安全生产天数缓存的 Redis Key 前缀
|
||||||
|
*/
|
||||||
|
String PROJECT_SAFETY_DAYS_REDIS_KEY_PREFIX = "project:safetyDays";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目缓存的 Redis Key 前缀
|
||||||
|
*/
|
||||||
|
String PROJECT_CACHE_REDIS_KEY_PREFIX = "project";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import org.dromara.project.domain.req.project.BusProjectCreateReq;
|
|||||||
import org.dromara.project.domain.req.project.BusProjectQueryReq;
|
import org.dromara.project.domain.req.project.BusProjectQueryReq;
|
||||||
import org.dromara.project.domain.req.project.BusProjectUpdateReq;
|
import org.dromara.project.domain.req.project.BusProjectUpdateReq;
|
||||||
import org.dromara.project.domain.vo.project.BusProjectContractorListVo;
|
import org.dromara.project.domain.vo.project.BusProjectContractorListVo;
|
||||||
|
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
|
||||||
import org.dromara.project.domain.vo.project.BusProjectVo;
|
import org.dromara.project.domain.vo.project.BusProjectVo;
|
||||||
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
||||||
import org.dromara.project.service.IBusProjectService;
|
import org.dromara.project.service.IBusProjectService;
|
||||||
@ -131,4 +132,13 @@ public class BusProjectController extends BaseController {
|
|||||||
return R.ok(projectService.getWeather(id));
|
return R.ok(projectService.getWeather(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询项目安全天数
|
||||||
|
*/
|
||||||
|
@GetMapping("/safetyDay/{id}")
|
||||||
|
public R<BusProjectSafetyDayVo> getSafetyDay(@NotNull(message = "主键不能为空")
|
||||||
|
@PathVariable Long id) {
|
||||||
|
return R.ok(projectService.getSafetyDay(id));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.dromara.project.domain.vo.project;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lcj
|
||||||
|
* @date 2025/5/14 9:34
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class BusProjectSafetyDayVo implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = -1479490255029878315L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全生产天数
|
||||||
|
*/
|
||||||
|
private Integer safetyDay;
|
||||||
|
|
||||||
|
}
|
@ -3,7 +3,6 @@ package org.dromara.project.service;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.project.domain.BusProject;
|
import org.dromara.project.domain.BusProject;
|
||||||
@ -11,6 +10,7 @@ import org.dromara.project.domain.req.project.BusProjectCreateReq;
|
|||||||
import org.dromara.project.domain.req.project.BusProjectQueryReq;
|
import org.dromara.project.domain.req.project.BusProjectQueryReq;
|
||||||
import org.dromara.project.domain.req.project.BusProjectUpdateReq;
|
import org.dromara.project.domain.req.project.BusProjectUpdateReq;
|
||||||
import org.dromara.project.domain.vo.project.BusProjectContractorListVo;
|
import org.dromara.project.domain.vo.project.BusProjectContractorListVo;
|
||||||
|
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
|
||||||
import org.dromara.project.domain.vo.project.BusProjectVo;
|
import org.dromara.project.domain.vo.project.BusProjectVo;
|
||||||
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
||||||
|
|
||||||
@ -130,4 +130,12 @@ public interface IBusProjectService extends IService<BusProject> {
|
|||||||
*/
|
*/
|
||||||
List<BusProjectWeatherVo> getWeather(Long id);
|
List<BusProjectWeatherVo> getWeather(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目安全天数
|
||||||
|
*
|
||||||
|
* @param id 项目id
|
||||||
|
* @return 安全天数
|
||||||
|
*/
|
||||||
|
BusProjectSafetyDayVo getSafetyDay(Long id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import org.dromara.common.core.constant.HttpStatus;
|
|||||||
import org.dromara.common.core.constant.SystemConstants;
|
import org.dromara.common.core.constant.SystemConstants;
|
||||||
import org.dromara.common.core.domain.vo.IdAndNameVO;
|
import org.dromara.common.core.domain.vo.IdAndNameVO;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
import org.dromara.common.core.utils.DateUtils;
|
||||||
import org.dromara.common.core.utils.ObjectUtils;
|
import org.dromara.common.core.utils.ObjectUtils;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
@ -36,6 +37,7 @@ import org.dromara.project.domain.req.project.BusProjectCreateReq;
|
|||||||
import org.dromara.project.domain.req.project.BusProjectQueryReq;
|
import org.dromara.project.domain.req.project.BusProjectQueryReq;
|
||||||
import org.dromara.project.domain.req.project.BusProjectUpdateReq;
|
import org.dromara.project.domain.req.project.BusProjectUpdateReq;
|
||||||
import org.dromara.project.domain.vo.project.BusProjectContractorListVo;
|
import org.dromara.project.domain.vo.project.BusProjectContractorListVo;
|
||||||
|
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
|
||||||
import org.dromara.project.domain.vo.project.BusProjectVo;
|
import org.dromara.project.domain.vo.project.BusProjectVo;
|
||||||
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
||||||
import org.dromara.project.mapper.BusProjectMapper;
|
import org.dromara.project.mapper.BusProjectMapper;
|
||||||
@ -85,8 +87,8 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
|
|||||||
private final Cache<String, String> WEATHER_CACHE =
|
private final Cache<String, String> WEATHER_CACHE =
|
||||||
Caffeine.newBuilder().initialCapacity(1024)
|
Caffeine.newBuilder().initialCapacity(1024)
|
||||||
.maximumSize(10000L)
|
.maximumSize(10000L)
|
||||||
// 缓存 30 分钟移除
|
// 缓存 60 分钟移除
|
||||||
.expireAfterWrite(30L, TimeUnit.MINUTES)
|
.expireAfterWrite(60L, TimeUnit.MINUTES)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -532,12 +534,45 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
|
|||||||
// 更新本地缓存
|
// 更新本地缓存
|
||||||
WEATHER_CACHE.put(cacheKey, cacheValue);
|
WEATHER_CACHE.put(cacheKey, cacheValue);
|
||||||
// 更新 Redis 缓存,设置 5 - 10 分钟随机过期,防止雪崩
|
// 更新 Redis 缓存,设置 5 - 10 分钟随机过期,防止雪崩
|
||||||
int cacheExpireTime = 30 * 60 + RandomUtil.randomInt(0, 300);
|
int cacheExpireTime = 60 * 60 + RandomUtil.randomInt(0, 300);
|
||||||
valueOps.set(cacheKey, cacheValue, cacheExpireTime, TimeUnit.SECONDS);
|
valueOps.set(cacheKey, cacheValue, cacheExpireTime, TimeUnit.SECONDS);
|
||||||
// 返回结果
|
// 返回结果
|
||||||
return weatherList;
|
return weatherList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目安全天数
|
||||||
|
*
|
||||||
|
* @param id 项目id
|
||||||
|
* @return 安全天数
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public BusProjectSafetyDayVo getSafetyDay(Long id) {
|
||||||
|
// 构建缓存 key
|
||||||
|
String cacheKey = String.format("%s:%s", BusProjectConstant.PROJECT_SAFETY_DAYS_REDIS_KEY_PREFIX, id);
|
||||||
|
// 查询分布式缓存(Redis)
|
||||||
|
ValueOperations<String, String> valueOps = stringRedisTemplate.opsForValue();
|
||||||
|
String cachedValue = valueOps.get(cacheKey);
|
||||||
|
if (cachedValue != null) {
|
||||||
|
// 如果命中Redis,返回结果
|
||||||
|
return JSONUtil.toBean(cachedValue, BusProjectSafetyDayVo.class);
|
||||||
|
}
|
||||||
|
BusProject project = this.getById(id);
|
||||||
|
if (project == null) {
|
||||||
|
throw new ServiceException("项目信息不存在", HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
|
int days = DateUtils.differentDaysByMillisecond(project.getCreateTime(), new Date());
|
||||||
|
BusProjectSafetyDayVo safetyDayVo = new BusProjectSafetyDayVo();
|
||||||
|
safetyDayVo.setSafetyDay(days);
|
||||||
|
// 更新缓存
|
||||||
|
String cacheValue = JSONUtil.toJsonStr(safetyDayVo);
|
||||||
|
// 更新 Redis 缓存
|
||||||
|
int cacheExpireTime = 12;
|
||||||
|
valueOps.set(cacheKey, cacheValue, cacheExpireTime, TimeUnit.HOURS);
|
||||||
|
// 返回结果
|
||||||
|
return safetyDayVo;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据天气图标获取天气类别
|
* 根据天气图标获取天气类别
|
||||||
*
|
*
|
||||||
|
@ -150,6 +150,9 @@ public class HseSafetyInspectionServiceImpl extends ServiceImpl<HseSafetyInspect
|
|||||||
List<HseTeamMeeting> teamMeetings = teamMeetingService.lambdaQuery()
|
List<HseTeamMeeting> teamMeetings = teamMeetingService.lambdaQuery()
|
||||||
.eq(HseTeamMeeting::getProjectId, projectId)
|
.eq(HseTeamMeeting::getProjectId, projectId)
|
||||||
.list();
|
.list();
|
||||||
|
if (CollUtil.isEmpty(teamMeetings)){
|
||||||
|
return gisVo;
|
||||||
|
}
|
||||||
// 获取最新的班组列表
|
// 获取最新的班组列表
|
||||||
List<HseTeamMeeting> topList = teamMeetings.stream()
|
List<HseTeamMeeting> topList = teamMeetings.stream()
|
||||||
.sorted(Comparator.comparing(HseTeamMeeting::getCreateTime).reversed())
|
.sorted(Comparator.comparing(HseTeamMeeting::getCreateTime).reversed())
|
||||||
|
Reference in New Issue
Block a user