添加获取项目生产天数接口;添加定时任务,每天自动删除项目缓存
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.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* 启动程序
|
||||
@ -14,6 +15,7 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
||||
@SpringBootApplication
|
||||
@EnableAsync
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
|
||||
@EnableScheduling
|
||||
public class DromaraApplication {
|
||||
|
||||
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
|
||||
username: energy
|
||||
password: fikwNsk8BidXSKe4
|
||||
# # 从库数据源
|
||||
# slave:
|
||||
# lazy: true
|
||||
# type: ${spring.datasource.type}
|
||||
# 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
|
||||
# username:
|
||||
# password:
|
||||
# oracle:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: oracle.jdbc.OracleDriver
|
||||
# url: jdbc:oracle:thin:@//localhost:1521/XE
|
||||
# username: ROOT
|
||||
# password: root
|
||||
# postgres:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: org.postgresql.Driver
|
||||
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
|
||||
# username: root
|
||||
# password: root
|
||||
# sqlserver:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
|
||||
# username: SA
|
||||
# password: root
|
||||
# # 从库数据源
|
||||
# slave:
|
||||
# lazy: true
|
||||
# type: ${spring.datasource.type}
|
||||
# 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
|
||||
# username:
|
||||
# password:
|
||||
# oracle:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: oracle.jdbc.OracleDriver
|
||||
# url: jdbc:oracle:thin:@//localhost:1521/XE
|
||||
# username: ROOT
|
||||
# password: root
|
||||
# postgres:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: org.postgresql.Driver
|
||||
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
|
||||
# username: root
|
||||
# password: root
|
||||
# sqlserver:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
|
||||
# username: SA
|
||||
# password: root
|
||||
hikari:
|
||||
# 最大连接池数量
|
||||
maxPoolSize: 20
|
||||
@ -206,7 +206,7 @@ justauth:
|
||||
client-id: 449c4*********937************759
|
||||
client-secret: ac7***********1e0************28d
|
||||
redirect-uri: ${justauth.address}/social-callback?source=topiam
|
||||
scopes: [openid, email, phone, profile]
|
||||
scopes: [ openid, email, phone, profile ]
|
||||
qq:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
@ -263,6 +263,7 @@ justauth:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: ${justauth.address}/social-callback?source=gitlab
|
||||
# 和风天气 https://dev.qweather.com/
|
||||
weather:
|
||||
key-id: T65EAABUXC
|
||||
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.HttpResponse;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -21,6 +22,7 @@ import java.util.Base64;
|
||||
* @author lcj
|
||||
* @date 2025/5/12 17:33
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class WeatherManager {
|
||||
|
||||
@ -48,6 +50,7 @@ public class WeatherManager {
|
||||
.execute()) {
|
||||
int status = result.getStatus();
|
||||
if (status != HttpStatus.SUCCESS) {
|
||||
log.error("获取天气失败,状态码:{},body:{}", status, result.body());
|
||||
throw new ServiceException("获取天气失败,状态码:" + status, HttpStatus.ERROR);
|
||||
}
|
||||
body = result.body();
|
||||
|
@ -11,4 +11,14 @@ public interface BusProjectConstant {
|
||||
*/
|
||||
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.BusProjectUpdateReq;
|
||||
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.BusProjectWeatherVo;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
@ -131,4 +132,13 @@ public class BusProjectController extends BaseController {
|
||||
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.extension.plugins.pagination.Page;
|
||||
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.TableDataInfo;
|
||||
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.BusProjectUpdateReq;
|
||||
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.BusProjectWeatherVo;
|
||||
|
||||
@ -130,4 +130,12 @@ public interface IBusProjectService extends IService<BusProject> {
|
||||
*/
|
||||
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.domain.vo.IdAndNameVO;
|
||||
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.StringUtils;
|
||||
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.BusProjectUpdateReq;
|
||||
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.BusProjectWeatherVo;
|
||||
import org.dromara.project.mapper.BusProjectMapper;
|
||||
@ -85,8 +87,8 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
|
||||
private final Cache<String, String> WEATHER_CACHE =
|
||||
Caffeine.newBuilder().initialCapacity(1024)
|
||||
.maximumSize(10000L)
|
||||
// 缓存 30 分钟移除
|
||||
.expireAfterWrite(30L, TimeUnit.MINUTES)
|
||||
// 缓存 60 分钟移除
|
||||
.expireAfterWrite(60L, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
/**
|
||||
@ -532,12 +534,45 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
|
||||
// 更新本地缓存
|
||||
WEATHER_CACHE.put(cacheKey, cacheValue);
|
||||
// 更新 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);
|
||||
// 返回结果
|
||||
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()
|
||||
.eq(HseTeamMeeting::getProjectId, projectId)
|
||||
.list();
|
||||
if (CollUtil.isEmpty(teamMeetings)){
|
||||
return gisVo;
|
||||
}
|
||||
// 获取最新的班组列表
|
||||
List<HseTeamMeeting> topList = teamMeetings.stream()
|
||||
.sorted(Comparator.comparing(HseTeamMeeting::getCreateTime).reversed())
|
||||
|
Reference in New Issue
Block a user