[feat]设备耗材到期提醒

This commit is contained in:
yunpeng.zhang 2024-01-04 17:31:27 +08:00
parent 9f9edf8cef
commit 342271520f
11 changed files with 212 additions and 11 deletions

View File

@ -105,4 +105,14 @@ public class EquipmentConsumablesController extends BaseController {
@PathVariable Long[] consumableIds) { @PathVariable Long[] consumableIds) {
return toAjax(iEquipmentConsumablesService.deleteWithValidByIds(Arrays.asList(consumableIds), true)); return toAjax(iEquipmentConsumablesService.deleteWithValidByIds(Arrays.asList(consumableIds), true));
} }
/**
* 耗材到期提醒定时任务
* @return
*/
@PostMapping("/dueNoticeJob")
public R<Void> dueNotice(){
iEquipmentConsumablesService.dueNotice();
return R.ok();
}
} }

View File

@ -1,5 +1,6 @@
package com.eqc.common.utils; package com.eqc.common.utils;
import cn.hutool.core.date.LocalDateTimeUtil;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.DateFormatUtils;
@ -165,4 +166,24 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
return Date.from(zdt.toInstant()); return Date.from(zdt.toInstant());
} }
/**
* 修改为一天的开始时间例如2020-02-02 00:00:00
*/
public static Date beginOfDay(Date date){
if (date == null) {
return null;
}
return toDate(LocalDateTimeUtil.beginOfDay(LocalDateTimeUtil.of(date)));
}
/**
* 修改为一天的结束时间例如2020-02-02 23:59:59
*/
public static Date endOfDay(Date date){
if (date == null) {
return null;
}
return toDate(LocalDateTimeUtil.endOfDay(LocalDateTimeUtil.of(date)));
}
} }

View File

@ -1,7 +1,7 @@
--- # 监控配置 --- # 监控配置
spring.boot.admin.client: spring.boot.admin.client:
# 增加客户端开关 # 增加客户端开关
enabled: true enabled: false
# 设置 Spring Boot Admin Server 地址 # 设置 Spring Boot Admin Server 地址
url: http://localhost:9090/admin url: http://localhost:9090/admin
instance: instance:

View File

@ -53,6 +53,10 @@ public class EquipmentConsumables extends BaseEntity {
* 使用期效单位 * 使用期效单位
*/ */
private String validityUint; private String validityUint;
/**
* 到期时间
*/
private Date dueTime;
/** /**
* 负责人到期后通知其更换 * 负责人到期后通知其更换
*/ */

View File

@ -44,37 +44,37 @@ public class EquipmentConsumablesBo extends BaseEntity {
/** /**
* 耗材编号 * 耗材编号
*/ */
@NotBlank(message = "耗材编号不能为空", groups = { AddGroup.class, EditGroup.class }) //@NotBlank(message = "耗材编号不能为空", groups = { AddGroup.class, EditGroup.class })
private String consumableNo; private String consumableNo;
/** /**
* 开始使用时间 * 开始使用时间
*/ */
@NotNull(message = "开始使用时间不能为空", groups = { AddGroup.class, EditGroup.class }) //@NotNull(message = "开始使用时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date activationTime; private Date activationTime;
/** /**
* 使用期效 * 使用期效
*/ */
@NotNull(message = "使用期效不能为空", groups = { AddGroup.class, EditGroup.class }) //@NotNull(message = "使用期效不能为空", groups = { AddGroup.class, EditGroup.class })
private Long validity; private Long validity;
/** /**
* 使用期效单位 * 使用期效单位
*/ */
@NotBlank(message = "使用期效单位不能为空", groups = { AddGroup.class, EditGroup.class }) //@NotBlank(message = "使用期效单位不能为空", groups = { AddGroup.class, EditGroup.class })
private String validityUint; private String validityUint;
/** /**
* 负责人到期后通知其更换 * 负责人到期后通知其更换
*/ */
@NotNull(message = "负责人,到期后通知其更换不能为空", groups = { AddGroup.class, EditGroup.class }) //@NotNull(message = "负责人,到期后通知其更换不能为空", groups = { AddGroup.class, EditGroup.class })
private Long chargeUser; private Long chargeUser;
/** /**
* 状态 0正在使用1已报废 2未使用过 * 状态 0正在使用1已报废 2未使用过
*/ */
@NotNull(message = "状态 0正在使用1已报废 2未使用过不能为空", groups = { AddGroup.class, EditGroup.class }) @NotNull(message = "状态不能为空", groups = { AddGroup.class, EditGroup.class })
private String status; private String status;
/** /**

View File

@ -0,0 +1,65 @@
/*
* @(#) ConsumableNoticeDto.java
*
* Copyright 2024 rebound
*/
package com.eqc.system.domain.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* ConsumableNoticeDto 耗材到期通知Dto对象
*
* @author yunpeng.zhang
* @version 1.0 2024/1/4
*/
@Data
public class ConsumableNoticeDto implements Serializable {
/**
* 主键
*/
private Long consumableId;
/**
* 设备
*/
private Long equipmentId;
private String equipmentNo;
private String equipmentName;
private String equipmentDept;
private String equipmentLocation;
/**
* 耗材名称
*/
private String consumableName;
/**
* 耗材编号
*/
private String consumableNo;
/**
* 开始使用时间
*/
private Date activationTime;
/**
* 到期时间
*/
private Date dueTime;
/**
* 负责人到期后通知其更换
*/
private Long chargeUser;
private String chargeUserName;
private String chargeNickName;
private String chargeUserEmail;
private String chargeUserPhonenumber;
/**
* 状态 0正在使用1已报废 2未使用过
*/
private String status;
/**
* 备注
*/
private String remark;
}

View File

@ -63,8 +63,15 @@ public class EquipmentConsumablesVo implements Serializable {
* 使用期效单位 * 使用期效单位
*/ */
@ExcelProperty(value = "使用期效单位") @ExcelProperty(value = "使用期效单位")
@ExcelDictFormat(dictType = "sys_time_unit")
private String validityUint; private String validityUint;
/**
* 到期时间
*/
@ExcelProperty(value = "到期时间")
private Date dueTime;
/** /**
* 负责人到期后通知其更换 * 负责人到期后通知其更换
*/ */
@ -74,7 +81,8 @@ public class EquipmentConsumablesVo implements Serializable {
/** /**
* 状态 0正在使用1已报废 2未使用过 * 状态 0正在使用1已报废 2未使用过
*/ */
@ExcelProperty(value = "状态 0正在使用1已报废 2未使用过") @ExcelProperty(value = "状态")
@ExcelDictFormat(dictType = "consumable_status")
private String status; private String status;
/** /**

View File

@ -1,8 +1,13 @@
package com.eqc.system.mapper; package com.eqc.system.mapper;
import com.eqc.system.domain.EquipmentConsumables; import com.eqc.system.domain.EquipmentConsumables;
import com.eqc.system.domain.dto.ConsumableNoticeDto;
import com.eqc.system.domain.vo.EquipmentConsumablesVo; import com.eqc.system.domain.vo.EquipmentConsumablesVo;
import com.eqc.common.core.mapper.BaseMapperPlus; import com.eqc.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/** /**
* 设备耗材Mapper接口 * 设备耗材Mapper接口
@ -12,4 +17,11 @@ import com.eqc.common.core.mapper.BaseMapperPlus;
*/ */
public interface EquipmentConsumablesMapper extends BaseMapperPlus<EquipmentConsumablesMapper, EquipmentConsumables, EquipmentConsumablesVo> { public interface EquipmentConsumablesMapper extends BaseMapperPlus<EquipmentConsumablesMapper, EquipmentConsumables, EquipmentConsumablesVo> {
/**
* 获取即将到期需要提醒的耗材
* @param date 与到期时间相比较查询出距离到期时间还有一段时间的耗材
* @return
*/
List<ConsumableNoticeDto> selectNoticeList(@Param("date") Date date);
} }

View File

@ -46,4 +46,10 @@ public interface IEquipmentConsumablesService {
* 校验并批量删除设备耗材信息 * 校验并批量删除设备耗材信息
*/ */
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 设备到期提醒
*/
void dueNotice();
} }

View File

@ -1,12 +1,17 @@
package com.eqc.system.service.impl; package com.eqc.system.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.eqc.common.utils.DateUtils;
import com.eqc.common.utils.StreamUtils;
import com.eqc.common.utils.StringUtils; import com.eqc.common.utils.StringUtils;
import com.eqc.common.core.page.TableDataInfo; import com.eqc.common.core.page.TableDataInfo;
import com.eqc.common.core.domain.PageQuery; import com.eqc.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eqc.common.utils.email.MailUtils;
import com.eqc.system.domain.dto.ConsumableNoticeDto;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.eqc.system.domain.bo.EquipmentConsumablesBo; import com.eqc.system.domain.bo.EquipmentConsumablesBo;
@ -15,9 +20,8 @@ import com.eqc.system.domain.EquipmentConsumables;
import com.eqc.system.mapper.EquipmentConsumablesMapper; import com.eqc.system.mapper.EquipmentConsumablesMapper;
import com.eqc.system.service.IEquipmentConsumablesService; import com.eqc.system.service.IEquipmentConsumablesService;
import java.util.List; import java.time.LocalDate;
import java.util.Map; import java.util.*;
import java.util.Collection;
/** /**
* 设备耗材Service业务层处理 * 设备耗材Service业务层处理
@ -79,6 +83,8 @@ public class EquipmentConsumablesServiceImpl implements IEquipmentConsumablesSer
public Boolean insertByBo(EquipmentConsumablesBo bo) { public Boolean insertByBo(EquipmentConsumablesBo bo) {
EquipmentConsumables add = BeanUtil.toBean(bo, EquipmentConsumables.class); EquipmentConsumables add = BeanUtil.toBean(bo, EquipmentConsumables.class);
validEntityBeforeSave(add); validEntityBeforeSave(add);
//计算到期时间
add.setDueTime(calDueTime(add.getActivationTime(),add.getValidity(), add.getValidityUint()));
boolean flag = baseMapper.insert(add) > 0; boolean flag = baseMapper.insert(add) > 0;
if (flag) { if (flag) {
bo.setConsumableId(add.getConsumableId()); bo.setConsumableId(add.getConsumableId());
@ -86,6 +92,34 @@ public class EquipmentConsumablesServiceImpl implements IEquipmentConsumablesSer
return flag; return flag;
} }
/**
* 计算到期时间 忽略开始时间的时分秒 计算后时间的当天0点设为到期时间
* @param activationTime 开始使用时间
* @param validity 使用期效
* @param validityUint 使用期效单位 Y年 M月 D天
* @return
*/
private Date calDueTime(Date activationTime, Long validity, String validityUint){
if (activationTime == null || validity == null || StringUtils.isBlank(validityUint)){
return null;
}
Date dueTime;
switch (validityUint) {
case "Y":
dueTime = DateUtils.addYears(activationTime, validity.intValue());
break;
case "M":
dueTime = DateUtils.addMonths(activationTime, validity.intValue());
break;
case "D":
dueTime = DateUtils.addDays(activationTime, validity.intValue());
break;
default:
return null;
}
return DateUtils.beginOfDay(dueTime);
}
/** /**
* 修改设备耗材 * 修改设备耗材
*/ */
@ -93,6 +127,7 @@ public class EquipmentConsumablesServiceImpl implements IEquipmentConsumablesSer
public Boolean updateByBo(EquipmentConsumablesBo bo) { public Boolean updateByBo(EquipmentConsumablesBo bo) {
EquipmentConsumables update = BeanUtil.toBean(bo, EquipmentConsumables.class); EquipmentConsumables update = BeanUtil.toBean(bo, EquipmentConsumables.class);
validEntityBeforeSave(update); validEntityBeforeSave(update);
update.setDueTime(calDueTime(update.getActivationTime(),update.getValidity(), update.getValidityUint()));
return baseMapper.updateById(update) > 0; return baseMapper.updateById(update) > 0;
} }
@ -113,4 +148,17 @@ public class EquipmentConsumablesServiceImpl implements IEquipmentConsumablesSer
} }
return baseMapper.deleteBatchIds(ids) > 0; return baseMapper.deleteBatchIds(ids) > 0;
} }
/**
* 设备到期提醒 提前七天开始提醒
*/
@Override
public void dueNotice() {
//当前时间+7天
String subject = "设备耗材即将到期提醒";
Date date = DateUtils.addDays(DateUtils.beginOfDay(DateUtils.getNowDate()), 7);
List<ConsumableNoticeDto> consumableNotices = baseMapper.selectNoticeList(date);
Map<Long, List<ConsumableNoticeDto>> userNoticeMap = StreamUtils.groupByKey(consumableNotices, ConsumableNoticeDto::getChargeUser);
}
} }

View File

@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="activationTime" column="activation_time"/> <result property="activationTime" column="activation_time"/>
<result property="validity" column="validity"/> <result property="validity" column="validity"/>
<result property="validityUint" column="validity_uint"/> <result property="validityUint" column="validity_uint"/>
<result property="dueTime" column="due_time"/>
<result property="chargeUser" column="charge_user"/> <result property="chargeUser" column="charge_user"/>
<result property="status" column="status"/> <result property="status" column="status"/>
<result property="createBy" column="create_by"/> <result property="createBy" column="create_by"/>
@ -20,6 +21,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateTime" column="update_time"/> <result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/> <result property="remark" column="remark"/>
</resultMap> </resultMap>
<select id="selectNoticeList" resultType="com.eqc.system.domain.dto.ConsumableNoticeDto">
select
c.consumable_id as comsumableId,
c.equipment_id as equipmentId,
e.equipment_no as equipmentNo,
e.equipment_name as equipmentName,
dept.dept_name as equipmentDept,
e.location as equipmentLocation,
c.consumable_name as consumableName,
c.consumable_no as consumableNo,
c.activation_time as activationTime,
c.due_time as dueTime,
c.charge_user as chargeUser,
u.user_name as chargeUserName,
u.nick_name as chargeNickName,
u.email as chargeUserEmail,
u.phonenumber as chargeUserPhonenumber,
c.status as status,
c.remark as remark
from equipment_consumables c
join equipments e on c.equipment_id = e.equipment_id
left join sys_user u on u.user_id = c.charge_user
left join sys_dept dept on e.department = dept.dept_id
where u.del_flag = '0' and dept.del_flag = '0'
and c.status = '0' and c.due_time >= #{date}
</select>
</mapper> </mapper>