Sfoglia il codice sorgente

新增消息发送机制,新增服务中断的数据持久化机制

车车 1 anno fa
parent
commit
f03e574648

+ 15 - 7
ktg-common/src/main/java/com/ktg/common/core/redis/RedisCache.java

@@ -1,11 +1,5 @@
 package com.ktg.common.core.redis;
 
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.BoundSetOperations;
 import org.springframework.data.redis.core.HashOperations;
@@ -13,6 +7,9 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ValueOperations;
 import org.springframework.stereotype.Component;
 
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
 /**
  * spring redis 工具类
  *
@@ -74,6 +71,17 @@ public class RedisCache
         return redisTemplate.expire(key, timeout, unit);
     }
 
+    /**
+     * 获取有效时间
+     *
+     * @param key Redis键
+     * @return 过期时间,单位秒
+     */
+    public Long getTtl(final String key)
+    {
+        return redisTemplate.getExpire(key);
+    }
+
     /**
      * 获得缓存的基本对象。
      *
@@ -211,7 +219,7 @@ public class RedisCache
 
     /**
      * 删除Hash中的数据
-     * 
+     *
      * @param key
      * @param hKey
      */

+ 0 - 2
ktg-framework/src/main/java/com/ktg/framework/web/service/TokenService.java

@@ -67,9 +67,7 @@ public class TokenService
                 // 解析对应的权限以及用户信息
                 String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
                 String userKey = getTokenKey(uuid);
-                System.out.println("开始获取缓存的登录信息----------");
                 LoginUser user = redisCache.getCacheObject(userKey);
-                System.out.println("登录信息----------" + user.toString());
                 return user;
             }
             catch (Exception e)

+ 25 - 0
ktg-iscs/src/main/java/com/ktg/iscs/domain/vo/materials/CacheVO.java

@@ -0,0 +1,25 @@
+package com.ktg.iscs.domain.vo.materials;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 物资对象 is_materials
+ *
+ * @author cgj
+ * @date 2024-11-08
+ */
+@Data
+public class CacheVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+
+    @ApiModelProperty(value = "materialsLoanId")
+    private Long materialsLoanId;
+
+    @ApiModelProperty(value = "delayInSeconds")
+    private Long delayInSeconds;
+
+}

+ 144 - 16
ktg-iscs/src/main/java/com/ktg/iscs/service/impl/IsMaterialsLoanServiceImpl.java

@@ -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;
     }
 

+ 18 - 31
ktg-iscs/src/main/java/com/ktg/iscs/service/impl/IsMaterialsServiceImpl.java

@@ -7,9 +7,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ktg.common.core.text.Convert;
 import com.ktg.common.utils.DateUtils;
 import com.ktg.iscs.domain.IsMaterials;
-import com.ktg.iscs.domain.IsMaterialsLoan;
-import com.ktg.iscs.domain.dto.materials.MaterialsPageDTO;
 import com.ktg.iscs.domain.dto.materials.LoanMaterialDTO;
+import com.ktg.iscs.domain.dto.materials.MaterialsPageDTO;
+import com.ktg.iscs.domain.dto.materialsLoan.AddLoanDTO;
+import com.ktg.iscs.domain.dto.materialsLoan.ReturnLoanDTO;
 import com.ktg.iscs.domain.vo.materials.MaterialsPageVO;
 import com.ktg.iscs.mapper.IsMaterialsMapper;
 import com.ktg.iscs.service.IIsMaterialsLoanService;
@@ -29,8 +30,7 @@ import java.util.List;
  * @date 2024-11-08
  */
 @Service
-public class IsMaterialsServiceImpl extends ServiceImpl<IsMaterialsMapper, IsMaterials> implements IIsMaterialsService
-{
+public class IsMaterialsServiceImpl extends ServiceImpl<IsMaterialsMapper, IsMaterials> implements IIsMaterialsService {
     @Autowired
     private IsMaterialsMapper isMaterialsMapper;
     @Autowired
@@ -43,8 +43,7 @@ public class IsMaterialsServiceImpl extends ServiceImpl<IsMaterialsMapper, IsMat
      * @return 物资
      */
     @Override
-    public IsMaterials selectIsMaterialsByMaterialsId(Long materialsId)
-    {
+    public IsMaterials selectIsMaterialsByMaterialsId(Long materialsId) {
         return isMaterialsMapper.selectIsMaterialsByMaterialsId(materialsId);
     }
 
@@ -55,8 +54,7 @@ public class IsMaterialsServiceImpl extends ServiceImpl<IsMaterialsMapper, IsMat
      * @return 物资
      */
     @Override
-    public List<IsMaterials> selectIsMaterialsList(IsMaterials isMaterials)
-    {
+    public List<IsMaterials> selectIsMaterialsList(IsMaterials isMaterials) {
         return isMaterialsMapper.selectIsMaterialsList(isMaterials);
     }
 
@@ -67,8 +65,7 @@ public class IsMaterialsServiceImpl extends ServiceImpl<IsMaterialsMapper, IsMat
      * @return 结果
      */
     @Override
-    public int insertIsMaterials(IsMaterials isMaterials)
-    {
+    public int insertIsMaterials(IsMaterials isMaterials) {
         isMaterials.setCreateTime(DateUtils.getNowDate());
         return isMaterialsMapper.insertIsMaterials(isMaterials);
     }
@@ -80,8 +77,7 @@ public class IsMaterialsServiceImpl extends ServiceImpl<IsMaterialsMapper, IsMat
      * @return 结果
      */
     @Override
-    public int updateIsMaterials(IsMaterials isMaterials)
-    {
+    public int updateIsMaterials(IsMaterials isMaterials) {
         isMaterials.setUpdateTime(DateUtils.getNowDate());
         return isMaterialsMapper.updateIsMaterials(isMaterials);
     }
@@ -93,8 +89,7 @@ public class IsMaterialsServiceImpl extends ServiceImpl<IsMaterialsMapper, IsMat
      * @return 结果
      */
     @Override
-    public int deleteIsMaterialsByMaterialsIds(String materialsIds)
-    {
+    public int deleteIsMaterialsByMaterialsIds(String materialsIds) {
         Assert.notBlank(materialsIds, "请选择需要删除的数据!");
         Long[] longIds = Convert.toLongArray(materialsIds);
         return isMaterialsMapper.deleteIsMaterialsByMaterialsIds(longIds);
@@ -107,8 +102,7 @@ public class IsMaterialsServiceImpl extends ServiceImpl<IsMaterialsMapper, IsMat
      * @return 结果
      */
     @Override
-    public int deleteIsMaterialsByMaterialsId(Long materialsId)
-    {
+    public int deleteIsMaterialsByMaterialsId(Long materialsId) {
         return isMaterialsMapper.deleteIsMaterialsByMaterialsId(materialsId);
     }
 
@@ -131,29 +125,22 @@ public class IsMaterialsServiceImpl extends ServiceImpl<IsMaterialsMapper, IsMat
         // 3.物资信息
         IsMaterials materials = getById(dto.getMaterialsId());
         Assert.notNull(materials, "该物资不存在!");
-        Date date = new Date();
         // 4.开始更新借出表信息
         if ("0".equals(dto.getLoanState())) {
             // 4.1开始新增记录表
-            IsMaterialsLoan addMaterialsLoan = new IsMaterialsLoan();
+            AddLoanDTO addMaterialsLoan = new AddLoanDTO();
             addMaterialsLoan.setMaterialsId(dto.getMaterialsId());
             addMaterialsLoan.setLoanUserId(dto.getLoanUserId());
-            addMaterialsLoan.setLoanFromId(materials.getMaterialsCabinetId());
-            addMaterialsLoan.setLoanTime(date);
-            addMaterialsLoan.setReminderTime(date);
-            iIsMaterialsLoanService.save(addMaterialsLoan);
+            iIsMaterialsLoanService.insertIsMaterialsLoan(addMaterialsLoan);
         } else if ("1".equals(dto.getLoanState())) {
             // 4.2开始更新记录表
-            IsMaterialsLoan materialsLoan = iIsMaterialsLoanService.getOne(Wrappers.<IsMaterialsLoan>lambdaQuery()
-                    .eq(IsMaterialsLoan::getMaterialsId, dto.getMaterialsId())
-                    .orderByDesc(IsMaterialsLoan::getMaterialsLoanId)
-                    .last("limit 1"));
-            iIsMaterialsLoanService.update(Wrappers.<IsMaterialsLoan>lambdaUpdate()
-                    .eq(IsMaterialsLoan::getMaterialsLoanId, materialsLoan.getMaterialsId())
-                    .set(IsMaterialsLoan::getRestitutionUserId, dto.getRestitutionUserId())
-                    .set(IsMaterialsLoan::getRestitutionToId, dto.getRestitutionToId())
-                    .set(IsMaterialsLoan::getRestitutionTime, date));
+            ReturnLoanDTO returnLoanDTO = new ReturnLoanDTO();
+            returnLoanDTO.setMaterialsId(dto.getMaterialsId());
+            returnLoanDTO.setRestitutionUserId(dto.getRestitutionUserId());
+            returnLoanDTO.setRestitutionToId(dto.getRestitutionToId());
+            iIsMaterialsLoanService.returnIsMaterialsLoan(returnLoanDTO);
         }
         return true;
     }
+
 }

+ 1 - 1
ktg-iscs/src/main/resources/mapper/IsMaterialsLoanMapper.xml

@@ -62,7 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="restitutionUserId != null">restitution_user_id,</if>
             <if test="restitutionToId != null">restitution_to_id,</if>
             <if test="restitutionTime != null">restitution_time,</if>
-            <if test="restitutionRequired != null">restitutionRequired,</if>
+            <if test="restitutionRequired != null">restitution_required,</if>
             <if test="remark != null">remark,</if>
             <if test="delFlag != null">del_flag,</if>
             <if test="createBy != null">create_by,</if>