package cn.iocoder.yudao.module.mes.service.dv.metering;
|
|
import cn.hutool.core.util.StrUtil;
|
import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.dv.metering.MesDvMeteringDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.dv.metering.MesDvMeteringMapper;
|
import cn.iocoder.yudao.module.mes.dal.redis.dv.metering.MesDvMeteringRemindRedisDAO;
|
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
import jakarta.annotation.Resource;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
|
import java.time.LocalDate;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* MES 计量器具到期提醒 Service 实现类
|
*
|
* @author 超级管理员
|
*/
|
@Slf4j
|
@Service
|
public class MesDvMeteringRemindServiceImpl implements MesDvMeteringRemindService {
|
|
/**
|
* 提醒天数配置 KEY(infra_config)
|
*/
|
private static final String REMIND_DAYS_CONFIG_KEY = "mes.dv-metering.remind-days";
|
/**
|
* 提醒天数默认值
|
*/
|
private static final int DEFAULT_REMIND_DAYS = 30;
|
/**
|
* 到期提醒站内信模板编号
|
*/
|
private static final String REMIND_TEMPLATE_CODE = "mes_metering_expire_remind";
|
|
@Resource
|
private MesDvMeteringMapper meteringMapper;
|
@Resource
|
private MesDvMeteringRemindRedisDAO meteringRemindRedisDAO;
|
@Resource
|
private ConfigApi configApi;
|
@Resource
|
private NotifyMessageSendApi notifyMessageSendApi;
|
|
@Override
|
public void sendExpireRemind() {
|
try {
|
// 1. 抢当天扫描门闩,避免多实例/多次并发重复扫描
|
LocalDate today = LocalDate.now();
|
if (!meteringRemindRedisDAO.tryAcquireScanLock(today)) {
|
return;
|
}
|
// 2. 读取提醒天数(默认 30)
|
int remindDays = getRemindDays();
|
// 3. 查询 [today, today + remindDays] 到期的器具
|
List<MesDvMeteringDO> list = meteringMapper.selectListByNextCheckDateBetween(
|
today, today.plusDays(remindDays));
|
// 4. 逐台发送站内信(按器具 + 到期日去重)
|
for (MesDvMeteringDO metering : list) {
|
if (metering.getChargeUserId() == null || metering.getNextCheckDate() == null) {
|
continue;
|
}
|
if (!meteringRemindRedisDAO.tryMarkReminded(metering.getId(), metering.getNextCheckDate())) {
|
continue;
|
}
|
sendRemindMessage(metering);
|
}
|
} catch (Exception ex) {
|
// best-effort:提醒失败不影响列表查询
|
log.error("[sendExpireRemind][发送计量器具到期提醒失败]", ex);
|
}
|
}
|
|
private int getRemindDays() {
|
String value = configApi.getConfigValueByKey(REMIND_DAYS_CONFIG_KEY);
|
if (StrUtil.isBlank(value)) {
|
return DEFAULT_REMIND_DAYS;
|
}
|
try {
|
return Integer.parseInt(value.trim());
|
} catch (NumberFormatException ex) {
|
log.warn("[getRemindDays][配置 {} 的值 {} 非法,使用默认值 {}]", REMIND_DAYS_CONFIG_KEY, value, DEFAULT_REMIND_DAYS);
|
return DEFAULT_REMIND_DAYS;
|
}
|
}
|
|
private void sendRemindMessage(MesDvMeteringDO metering) {
|
Map<String, Object> params = new HashMap<>();
|
params.put("meteringCode", metering.getCode());
|
params.put("meteringName", metering.getName());
|
params.put("nextCheckDate", metering.getNextCheckDate().toString());
|
NotifySendSingleToUserReqDTO reqDTO = new NotifySendSingleToUserReqDTO()
|
.setUserId(metering.getChargeUserId())
|
.setTemplateCode(REMIND_TEMPLATE_CODE)
|
.setTemplateParams(params);
|
notifyMessageSendApi.sendSingleMessageToAdmin(reqDTO);
|
}
|
|
}
|