|
|
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.ktg.common.core.redis.RedisCache;
|
|
|
import com.ktg.common.core.text.Convert;
|
|
|
import com.ktg.common.utils.DateUtils;
|
|
|
import com.ktg.common.utils.bean.BeanUtils;
|
|
|
@@ -21,13 +22,19 @@ import com.ktg.iscs.mapper.IsMaterialsLoanMapper;
|
|
|
import com.ktg.iscs.service.IIsMaterialsLoanService;
|
|
|
import com.ktg.iscs.service.IIsMaterialsService;
|
|
|
import com.ktg.iscs.service.IIsMaterialsTypeService;
|
|
|
+import com.ktg.system.service.NotifySendService;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+import javax.annotation.Resource;
|
|
|
import java.time.Instant;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.ScheduledExecutorService;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
/**
|
|
|
* 物资借出Service业务层处理
|
|
|
@@ -36,14 +43,120 @@ import java.util.List;
|
|
|
* @date 2024-11-08
|
|
|
*/
|
|
|
@Service
|
|
|
-public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMapper, IsMaterialsLoan> implements IIsMaterialsLoanService
|
|
|
-{
|
|
|
+public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMapper, IsMaterialsLoan> implements IIsMaterialsLoanService {
|
|
|
@Autowired
|
|
|
private IsMaterialsLoanMapper isMaterialsLoanMapper;
|
|
|
@Autowired
|
|
|
private IIsMaterialsService isMaterialsService;
|
|
|
@Autowired
|
|
|
private IIsMaterialsTypeService isMaterialsTypeService;
|
|
|
+ @Resource
|
|
|
+ private NotifySendService notifySendService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisCache redisCache;
|
|
|
+
|
|
|
+ private final ConcurrentHashMap<String, Long> messages = new ConcurrentHashMap<>();
|
|
|
+ private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
|
|
+
|
|
|
+
|
|
|
+ private static final String MATERIALS_LOAN = "materials_loan:";
|
|
|
+ private static final String REMINDER = "reminder";
|
|
|
+
|
|
|
+ private static final String ALARM = "alarm";
|
|
|
+
|
|
|
+
|
|
|
+ @PostConstruct
|
|
|
+ public void init() {
|
|
|
+ // 在这里编写你的初始化代码
|
|
|
+ System.out.println("项目启动时执行一次的方法");
|
|
|
+ // 取出
|
|
|
+ List<String> keys = new ArrayList<>(redisCache.keys("materials_loan:*"));
|
|
|
+ for (String key : keys) {
|
|
|
+ // 获取基本信息
|
|
|
+ Long materialsLoanId = redisCache.getCacheObject(key);
|
|
|
+ // 获取过期时间
|
|
|
+ Long delayInSeconds = redisCache.getTtl(key);
|
|
|
+ if (key.contains(REMINDER)) {
|
|
|
+ // 如果是提醒
|
|
|
+ reminderMessage(materialsLoanId, delayInSeconds);
|
|
|
+ } else {
|
|
|
+ // 如果是告警
|
|
|
+ alarmMessage(materialsLoanId, delayInSeconds);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void reminderMessage(long materialsLoanId, long delayInSeconds) {
|
|
|
+ String messageId = REMINDER + materialsLoanId;
|
|
|
+ messages.put(messageId, materialsLoanId);
|
|
|
+ scheduler.schedule(() -> {
|
|
|
+ sendReminderMessage(messageId);
|
|
|
+ messages.remove(messageId);
|
|
|
+ }, delayInSeconds, TimeUnit.SECONDS);
|
|
|
+ // 开始缓存,避免重启项目无法持久化
|
|
|
+ redisCache.setCacheObject(MATERIALS_LOAN + messageId, materialsLoanId, (int) delayInSeconds, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sendReminderMessage(String messageId) {
|
|
|
+ Long materialsLoanId = messages.get(messageId);
|
|
|
+ if (materialsLoanId != null) {
|
|
|
+ // 发送消息的逻辑
|
|
|
+ System.out.println("开始发送消息提醒,借出数据id: " + materialsLoanId);
|
|
|
+ // 1.开始查看借出数据
|
|
|
+ IsMaterialsLoan materialsLoan = getById(materialsLoanId);
|
|
|
+ if (materialsLoan != null) {
|
|
|
+ // 1.1数据存在开始判断消息是否需要发送
|
|
|
+ if (materialsLoan.getRestitutionUserId() == null
|
|
|
+ && materialsLoan.getActualRestitutionTime() == null
|
|
|
+ && materialsLoan.getRestitutionToId() == null) {
|
|
|
+ // 没有归还则需要开始新增提醒消息
|
|
|
+ Map<String, Object> templateParams = new HashMap<>();
|
|
|
+ templateParams.put("用户", materialsLoan.getLoanUserId());
|
|
|
+ templateParams.put("物资", materialsLoan.getMaterialsId());
|
|
|
+ templateParams.put("应该归还时间", materialsLoan.getRestitutionTime());
|
|
|
+ notifySendService.sendSingleNotifyToMember(materialsLoan.getLoanUserId(),
|
|
|
+ "REMINDER_RETURN", templateParams);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void alarmMessage(long materialsLoanId, long delayInSeconds) {
|
|
|
+ String messageId = ALARM + materialsLoanId;
|
|
|
+ messages.put(messageId, materialsLoanId);
|
|
|
+ scheduler.schedule(() -> {
|
|
|
+ sendAlarmMessage(messageId);
|
|
|
+ messages.remove(messageId);
|
|
|
+ }, delayInSeconds, TimeUnit.SECONDS);
|
|
|
+ // 开始缓存,避免重启项目无法持久化
|
|
|
+ redisCache.setCacheObject(MATERIALS_LOAN + messageId, materialsLoanId, (int) delayInSeconds, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sendAlarmMessage(String messageId) {
|
|
|
+ Long materialsLoanId = messages.get(messageId);
|
|
|
+ if (materialsLoanId != null) {
|
|
|
+ // 发送消息的逻辑
|
|
|
+ System.out.println("开始发送消息告警,借出数据id: " + materialsLoanId);
|
|
|
+ // 1.开始查看借出数据
|
|
|
+ IsMaterialsLoan materialsLoan = getById(materialsLoanId);
|
|
|
+ if (materialsLoan != null) {
|
|
|
+ // 1.1数据存在开始判断消息是否需要发送
|
|
|
+ if (materialsLoan.getRestitutionUserId() == null
|
|
|
+ && materialsLoan.getActualRestitutionTime() == null
|
|
|
+ && materialsLoan.getRestitutionToId() == null) {
|
|
|
+ // 没有归还则需要开始新增提醒消息
|
|
|
+ Map<String, Object> templateParams = new HashMap<>();
|
|
|
+ templateParams.put("用户", materialsLoan.getLoanUserId());
|
|
|
+ templateParams.put("物资", materialsLoan.getMaterialsId());
|
|
|
+ templateParams.put("应该归还时间", materialsLoan.getRestitutionTime());
|
|
|
+ notifySendService.sendSingleNotifyToMember(materialsLoan.getLoanUserId(),
|
|
|
+ "REMINDER_RETURN", templateParams);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 查询物资借出
|
|
|
@@ -52,8 +165,7 @@ public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMappe
|
|
|
* @return 物资借出
|
|
|
*/
|
|
|
@Override
|
|
|
- public IsMaterialsLoan selectIsMaterialsLoanByMaterialsLoanId(Long materialsLoanId)
|
|
|
- {
|
|
|
+ public IsMaterialsLoan selectIsMaterialsLoanByMaterialsLoanId(Long materialsLoanId) {
|
|
|
return isMaterialsLoanMapper.selectIsMaterialsLoanByMaterialsLoanId(materialsLoanId);
|
|
|
}
|
|
|
|
|
|
@@ -64,8 +176,7 @@ public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMappe
|
|
|
* @return 物资借出
|
|
|
*/
|
|
|
@Override
|
|
|
- public List<IsMaterialsLoan> selectIsMaterialsLoanList(IsMaterialsLoan isMaterialsLoan)
|
|
|
- {
|
|
|
+ public List<IsMaterialsLoan> selectIsMaterialsLoanList(IsMaterialsLoan isMaterialsLoan) {
|
|
|
return isMaterialsLoanMapper.selectIsMaterialsLoanList(isMaterialsLoan);
|
|
|
}
|
|
|
|
|
|
@@ -77,12 +188,14 @@ public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMappe
|
|
|
*/
|
|
|
@Transactional
|
|
|
@Override
|
|
|
- public int insertIsMaterialsLoan(AddLoanDTO dto)
|
|
|
- {
|
|
|
+ public int insertIsMaterialsLoan(AddLoanDTO dto) {
|
|
|
Date nowDate = DateUtils.getNowDate();
|
|
|
IsMaterialsLoan isMaterialsLoan = BeanUtils.toBean(dto, IsMaterialsLoan.class);
|
|
|
isMaterialsLoan.setLoanTime(nowDate);
|
|
|
isMaterialsLoan.setCreateTime(nowDate);
|
|
|
+ // 存储提醒倒计时和告警倒计时
|
|
|
+ int re = 0;
|
|
|
+ int al = 0;
|
|
|
// 1.物资信息
|
|
|
IsMaterials materials = isMaterialsService.getById(isMaterialsLoan.getMaterialsId());
|
|
|
// 1.2开始读取类型和规则,然后计算归还时间,提醒时间
|
|
|
@@ -99,11 +212,13 @@ public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMappe
|
|
|
isMaterialsLoan.setReminderTime(restitutionTime);
|
|
|
if (materialsTypePageVO.getReminderTime() != null) {
|
|
|
// 1.2.3计算提醒时间
|
|
|
+ re = materialsTypePageVO.getLoanDuration() - materialsTypePageVO.getReminderTime();
|
|
|
Date reminderTime = formatDateTime(nowDate, materialsTypePageVO.getLoanDuration() - materialsTypePageVO.getReminderTime());
|
|
|
isMaterialsLoan.setReminderTime(reminderTime);
|
|
|
}
|
|
|
if (materialsTypePageVO.getTimeoutAlarm() != null) {
|
|
|
// 1.2.4计算告警时间
|
|
|
+ al = materialsTypePageVO.getLoanDuration() + materialsTypePageVO.getTimeoutAlarm();
|
|
|
Date timeoutAlarm = formatDateTime(nowDate, materialsTypePageVO.getLoanDuration() + materialsTypePageVO.getTimeoutAlarm());
|
|
|
isMaterialsLoan.setTimeoutAlarm(timeoutAlarm);
|
|
|
}
|
|
|
@@ -111,6 +226,19 @@ public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMappe
|
|
|
}
|
|
|
}
|
|
|
int i = isMaterialsLoanMapper.insertIsMaterialsLoan(isMaterialsLoan);
|
|
|
+ // 开始处理消息
|
|
|
+ // 1.3.1处理归还提醒
|
|
|
+ if (materials != null && isMaterialsLoan.getReminderTime() != null) {
|
|
|
+ System.out.println("设置借用提醒消息");
|
|
|
+ reminderMessage(isMaterialsLoan.getMaterialsLoanId(), re);
|
|
|
+ }
|
|
|
+ // 1.3.2处理归还告警
|
|
|
+ if (materials != null && isMaterialsLoan.getTimeoutAlarm() != null) {
|
|
|
+ System.out.println("设置借用告警消息");
|
|
|
+ alarmMessage(isMaterialsLoan.getMaterialsLoanId(), al);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
// 2.开始更新物资信息为借出状态
|
|
|
LambdaUpdateWrapper<IsMaterials> set = Wrappers.<IsMaterials>lambdaUpdate()
|
|
|
.eq(IsMaterials::getMaterialsId, isMaterialsLoan.getMaterialsId())
|
|
|
@@ -143,8 +271,7 @@ public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMappe
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@Override
|
|
|
- public int updateIsMaterialsLoan(IsMaterialsLoan isMaterialsLoan)
|
|
|
- {
|
|
|
+ public int updateIsMaterialsLoan(IsMaterialsLoan isMaterialsLoan) {
|
|
|
isMaterialsLoan.setUpdateTime(DateUtils.getNowDate());
|
|
|
return isMaterialsLoanMapper.updateIsMaterialsLoan(isMaterialsLoan);
|
|
|
}
|
|
|
@@ -156,8 +283,7 @@ public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMappe
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@Override
|
|
|
- public int deleteIsMaterialsLoanByMaterialsLoanIds(String materialsLoanIds)
|
|
|
- {
|
|
|
+ public int deleteIsMaterialsLoanByMaterialsLoanIds(String materialsLoanIds) {
|
|
|
Assert.notBlank(materialsLoanIds, "请选择需要删除的数据!");
|
|
|
Long[] longIds = Convert.toLongArray(materialsLoanIds);
|
|
|
return isMaterialsLoanMapper.deleteIsMaterialsLoanByMaterialsLoanIds(longIds);
|
|
|
@@ -170,8 +296,7 @@ public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMappe
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@Override
|
|
|
- public int deleteIsMaterialsLoanByMaterialsLoanId(Long materialsLoanId)
|
|
|
- {
|
|
|
+ public int deleteIsMaterialsLoanByMaterialsLoanId(Long materialsLoanId) {
|
|
|
return isMaterialsLoanMapper.deleteIsMaterialsLoanByMaterialsLoanId(materialsLoanId);
|
|
|
}
|
|
|
|
|
|
@@ -204,6 +329,9 @@ public class IsMaterialsLoanServiceImpl extends ServiceImpl<IsMaterialsLoanMappe
|
|
|
isMaterialsService.update(Wrappers.<IsMaterials>lambdaUpdate()
|
|
|
.eq(IsMaterials::getMaterialsId, dto.getMaterialsId())
|
|
|
.set(IsMaterials::getLoanState, 1));
|
|
|
+ // 4.清除缓存
|
|
|
+ redisCache.deleteObject(MATERIALS_LOAN + REMINDER + loanList.get(0).getMaterialsLoanId());
|
|
|
+ redisCache.deleteObject(MATERIALS_LOAN + ALARM + loanList.get(0).getMaterialsLoanId());
|
|
|
return update;
|
|
|
}
|
|
|
|