异常订阅处理

This commit is contained in:
andy 2026-08-26 16:01:25 +08:00
parent 02fe04e6a2
commit 770d1fa42c
13 changed files with 322 additions and 25 deletions

View File

@ -9,7 +9,6 @@ import com.evo.attendance.domain.vo.RzAttendanceDetailTimeLineVO;
import com.evo.attendance.mapper.RzAttendanceDetailMapper;
import com.evo.attendance.mapper.RzAttendancePhotoMapper;
import com.evo.attendance.service.RzAttendanceDetailService;
import com.evo.attendance.service.RzAttendancePhotoService;
import com.evo.common.constant.Constants;
import com.evo.common.core.domain.entity.SysDept;
import com.evo.common.utils.Collections;
@ -18,9 +17,11 @@ import com.evo.common.utils.ParamUtils;
import com.evo.common.utils.StringUtils;
import com.evo.personnelMatters.domain.RzLeaveDetail;
import com.evo.personnelMatters.mapper.RzLeaveDetailMapper;
import com.evo.system.domain.ExceptionNotification;
import com.evo.system.domain.SysStaff;
import com.evo.system.mapper.SysDeptMapper;
import com.evo.system.mapper.SysStaffMapper;
import com.evo.system.service.ExceptionNotificationService;
import com.evo.wechat.service.SendClientService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
@ -29,14 +30,11 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
@ -60,7 +58,8 @@ public class RzAttendanceDetailServiceImpl extends ServiceImpl<RzAttendanceDetai
private SysStaffMapper sysStaffMapper;
@Autowired
private RzAttendancePhotoMapper rzAttendancePhotoMapper;
@Autowired
private ExceptionNotificationService exceptionNotificationService;
@Override
public RzAttendanceDetail addDetail(RzAttendance attendance, String rules, String sn, Date date, String remark, String photo) {
return addOrUpdateDetail("clock_in", attendance,rules,sn,date,remark, photo);
@ -150,6 +149,7 @@ public class RzAttendanceDetailServiceImpl extends ServiceImpl<RzAttendanceDetai
//查询所有上次打开时间距今天超过3天的员工信息
List<Map<String, Object>> threeDayNotCheckList = super.getBaseMapper().getThreeDayNotCheck();
if(Collections.isNotEmpty(threeDayNotCheckList)){
Long overdueLimit = ParamUtils.overdueLimit();
for (Map<String, Object> threeDayNotCheck : threeDayNotCheckList){
//用户Id
Integer userId = Integer.valueOf(String.valueOf(threeDayNotCheck.get("userId")));
@ -178,7 +178,7 @@ public class RzAttendanceDetailServiceImpl extends ServiceImpl<RzAttendanceDetai
}
//剩余时长> 3天, 继续检查请假
if(holidayDates.size() > 3){
if(Long.valueOf(holidayDates.size()).compareTo(overdueLimit) > -1){
//排除假期
List<String> leaveDays = Collections.emptyList();
for (String holidayDate : holidayDates){
@ -200,25 +200,45 @@ public class RzAttendanceDetailServiceImpl extends ServiceImpl<RzAttendanceDetai
holidayDates.removeAll(holidays);
}
//如果假期还是> 3天, 则准备推送
if(holidayDates.size() > 3){
if(Long.valueOf(holidayDates.size()).compareTo(overdueLimit) > -1){
ExceptionNotification exceptionNotification = exceptionNotificationService.getExceptionNotification(2, holidayDates.size());
List<SysStaff> sysStaffList = Collections.emptyList();
if(exceptionNotification == null){
// 如果异常订阅为空, 默认使用人资办通知
sysStaffList.addAll(sysStaffMapper.queryysStaffByDeptId(Collections.asList(28l)));
}else{
// 异常订阅的信息
sysStaffList.addAll(sysStaffMapper.selectList(new LambdaQueryWrapper<>(new SysStaff()).in(SysStaff::getUserId, Collections.asList(exceptionNotification.getUserIds().split(",")))));
}
SysStaff sysStaff = sysStaffMapper.selectById(userId);
if(sysStaff != null) {
SysDept sysDept = sysDeptMapper.selectById(sysStaff.getDeptId());
String deptName = sysDept != null ? sysDept.getDeptName() : "未知";
String userName = sysStaff.getName();
// 查询人资办人员信息
List<SysStaff> rzb = sysStaffMapper.queryysStaffByDeptId(Collections.asList(28l));
if(Collections.isNotEmpty(rzb)){
for (SysStaff rz : rzb){
sendAttendanceDetail(userName, rz.getName(), deptName, rz.getOpenid());
}
}
//查询部门负责人
SysStaff leaderSysStaff = sysStaffMapper.selectLeaderSysStaffByDeptId(sysStaff.getDeptId());
if(leaderSysStaff != null){
sendAttendanceDetail(userName, leaderSysStaff.getName(), deptName, leaderSysStaff.getOpenid());
}
for (SysStaff rz : sysStaffList){
sendAttendanceDetail(sysStaff.getName(), rz.getName(), deptName, rz.getOpenid());
}
// SysStaff sysStaff = sysStaffMapper.selectById(userId);
// if(sysStaff != null) {
// SysDept sysDept = sysDeptMapper.selectById(sysStaff.getDeptId());
// String deptName = sysDept != null ? sysDept.getDeptName() : "未知";
// String userName = sysStaff.getName();
// // 查询人资办人员信息
// List<SysStaff> rzb = sysStaffMapper.queryysStaffByDeptId(Collections.asList(28l));
// if(Collections.isNotEmpty(rzb)){
// for (SysStaff rz : rzb){
// sendAttendanceDetail(userName, rz.getName(), deptName, rz.getOpenid());
// }
// }
// //查询部门负责人
// SysStaff leaderSysStaff = sysStaffMapper.selectLeaderSysStaffByDeptId(sysStaff.getDeptId());
// if(leaderSysStaff != null){
// sendAttendanceDetail(userName, leaderSysStaff.getName(), deptName, leaderSysStaff.getOpenid());
// }
// }
}
}
}

View File

@ -125,6 +125,16 @@ public class ParamUtils {
RzSysParam param= paramService.getRzSysParam("是否发送微信通知", "send_we_chat","true","是否允许发送微信通知");
return Boolean.valueOf(param.getParamValue());
}
public static Boolean sendEveryDayCheckInWeiXin(){
RzSysParam param= paramService.getRzSysParam("是否发送每天未打卡考勤信息到微信通知", "send_every_day_check_in_we_chat","false","是否发送每天未打卡考勤信息到微信通知");
return Boolean.valueOf(param.getParamValue());
}
public static Long overdueLimit(){
RzSysParam param= paramService.getRzSysParam("超期未打开天数", "overdue_limit","5","超期未打开天数");
return Long.valueOf(param.getParamValue());
}
/***
* 不住宿的实习生人员

View File

@ -0,0 +1,105 @@
package com.evo.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.evo.common.annotation.Log;
import com.evo.common.annotation.RepeatSubmit;
import com.evo.common.core.controller.BaseController;
import com.evo.common.core.domain.AjaxResult;
import com.evo.common.core.page.TableDataInfo;
import com.evo.common.enums.BusinessType;
import com.evo.common.utils.Collections;
import com.evo.common.utils.StringUtils;
import com.evo.system.domain.ExceptionNotification;
import com.evo.system.domain.SysStaff;
import com.evo.system.mapper.SysDeptMapper;
import com.evo.system.mapper.SysStaffMapper;
import com.evo.system.service.ExceptionNotificationService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* @desc:
* @ClassName:ExceptionNotificationController
* @date: 2026年08月25日 17:18
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@RestController
@RequestMapping("/system/exceptionNotification")
public class ExceptionNotificationController extends BaseController {
@Resource
private ExceptionNotificationService exceptionNotificationService;
@Resource
private SysStaffMapper sysStaffMapper;
@Resource
private SysDeptMapper sysDeptMapper;
/**
* 查询员工管理列表
*/
@PreAuthorize("@ss.hasPermi('system:exceptionNotification:list')")
@GetMapping("/list")
public TableDataInfo list(ExceptionNotification exceptionNotification) {
startPage();
List<ExceptionNotification> list = exceptionNotificationService.list(new LambdaQueryWrapper<ExceptionNotification>()
.eq(exceptionNotification.getNotificationType() != null, ExceptionNotification::getNotificationType, exceptionNotification.getNotificationType()));
list.stream().forEach(item->{
if(StringUtils.isNotEmpty(item.getUserIds())){
item.setUserNames(sysStaffMapper.selectNameByUserIds(Collections.asList(item.getUserIds().split(",")).stream().map(Long::parseLong).collect(Collectors.toList())));
}
if(StringUtils.isNotEmpty(item.getDeptIds())){
item.setDeptNames(sysDeptMapper.selectNameByIds(Collections.asList(item.getDeptIds().split(",")).stream().map(Long::parseLong).collect(Collectors.toList())));
}
});
return getDataTable(list);
}
/**
* 新增员工管理
*/
@PreAuthorize("@ss.hasPermi('system:exceptionNotification:add')")
@Log(title = "异常规则", businessType = BusinessType.INSERT)
@PostMapping
@RepeatSubmit
public AjaxResult add(@RequestBody ExceptionNotification exceptionNotification) {
exceptionNotificationService.save(exceptionNotification);
return AjaxResult.success();
}
/**
* 获取员工管理详细信息
*/
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(exceptionNotificationService.getById(id));
}
@PreAuthorize("@ss.hasPermi('system:exceptionNotification:edit')")
@Log(title = "异常规则", businessType = BusinessType.UPDATE)
@PutMapping
@RepeatSubmit
public AjaxResult edit(@RequestBody ExceptionNotification exceptionNotification) {
exceptionNotificationService.updateById(exceptionNotification);
return AjaxResult.success();
}
/**
* 删除员工管理
*/
@PreAuthorize("@ss.hasPermi('system:exceptionNotification:delete')")
@Log(title = "异常规则", businessType = BusinessType.DELETE)
@DeleteMapping("/{id}")
public AjaxResult delete(@PathVariable Long id){
return toAjax(exceptionNotificationService.removeById(id));
}
}

View File

@ -0,0 +1,42 @@
package com.evo.system.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
/**
* 异常接收人
* @ClassName:ExceptionNotification
* @date: 2026年08月24日 16:15
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
public class ExceptionNotification implements Serializable {
private static final long serialVersionUID = 1L;
Long id;
String userIds;
@TableField(exist = false)
String userNames;
String deptIds;
@TableField(exist = false)
String deptNames;
/***
* 什么类型的通知
* 1. 未打卡通知
* 2 超过N天未打卡通知
* 3. 异常通知
*/
Integer notificationType;
/***
* 超过几天通知
* 做级别限制, 比如说, 3天通知部门负责人, 5天通知人资办, 10田通知公司高层
*/
Integer day;
}

View File

@ -0,0 +1,19 @@
package com.evo.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.system.domain.ExceptionNotification;
import com.evo.system.domain.SysStaffDetail;
import java.util.List;
/**
* 员工详情Mapper接口
*
* @author evo
* @date 2024-11-22
*/
public interface ExceptionNotificationMapper extends BaseMapper<ExceptionNotification>
{
List<ExceptionNotification> getExceptionNotification(Integer type);
}

View File

@ -20,6 +20,9 @@ public interface SysDeptMapper extends BaseMapper<SysDept>
* @return 部门信息集合
*/
public List<SysDept> selectDeptList(SysDept dept);
public String selectNameByIds(@Param("deptIds") List<Long> deptIds);
/**
* 根据角色ID查询部门树信息
*

View File

@ -24,6 +24,8 @@ public interface SysStaffMapper extends BaseMapper<SysStaff>
*/
public SysStaff selectSysStaffByUserId(Long userId);
public String selectNameByUserIds(@Param("userIds") List<Long> userIds);
/**
* 查询员工管理列表
*

View File

@ -0,0 +1,18 @@
package com.evo.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.system.domain.ExceptionNotification;
/**
* 异常通知接口
* @ClassName:ExceptionNotificationService
* @date: 2026年08月24日 16:43
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface ExceptionNotificationService extends IService<ExceptionNotification> {
ExceptionNotification getExceptionNotification(Integer type, Integer day);
}

View File

@ -0,0 +1,36 @@
package com.evo.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.common.utils.Collections;
import com.evo.system.domain.ExceptionNotification;
import com.evo.system.mapper.ExceptionNotificationMapper;
import com.evo.system.service.ExceptionNotificationService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @desc:
* @ClassName:ExceptionNotificationServiceImpl
* @date: 2026年08月25日 13:17
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Service
public class ExceptionNotificationServiceImpl extends ServiceImpl<ExceptionNotificationMapper, ExceptionNotification> implements ExceptionNotificationService {
@Override
public ExceptionNotification getExceptionNotification(Integer type, Integer day){
List<ExceptionNotification> list = getBaseMapper().getExceptionNotification(type);
if(Collections.isEmpty(list)){
return null;
}
for (ExceptionNotification notification : list) {
if (day >= notification.getDay()) {
return notification;
}
}
return list.get(0);
}
}

View File

@ -22,6 +22,7 @@ import com.evo.system.domain.SysStaff;
import com.evo.system.service.DeptMonthHistoryService;
import com.evo.system.service.ISysDeptService;
import com.evo.system.service.ISysStaffService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -30,6 +31,7 @@ import java.text.ParseException;
import java.util.Date;
import java.util.List;
@Slf4j
@Component
public class TaskController {
@ -135,6 +137,10 @@ public class TaskController {
*/
@Scheduled(cron = "0 0 9 * * ?")
public void autoAbnormalAttendance(){
if(!ParamUtils.sendEveryDayCheckInWeiXin()){
log.info("系统停止发送每天未打卡通知信息;");
return;
}
rzAttendanceService.sendAbnormalAttendance();
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.evo.system.mapper.ExceptionNotificationMapper">
<select id="getExceptionNotification" parameterType="java.lang.Integer" resultType="com.evo.system.domain.ExceptionNotification">
select * from exception_notification where notification_type = #{type} order by day desc
</select>
</mapper>

View File

@ -53,6 +53,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by d.parent_id
</select>
<select id="selectNameByIds" parameterType="List" resultType="java.lang.String">
select GROUP_CONCAT(dept_name) from sys_dept
<where>
<if test="deptIds != null">
dept_id in
<foreach collection="deptIds" item="deptId" open="(" separator="," close=")">
#{deptId}
</foreach>
</if>
</where>
</select>
<select id="selectDeptListByRoleId" resultType="Long">
select d.dept_id
from sys_dept d

View File

@ -92,6 +92,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
</select>
<select id="selectNameByUserIds" parameterType="List" resultType="java.lang.String">
select GROUP_CONCAT(name) from sys_staff
<where>
<if test="userIds != null">
user_id in
<foreach collection="userIds" item="userId" open="(" separator="," close=")">
#{userId}
</foreach>
</if>
</where>
</select>
<select id="selectSysStaffByDingUserId" parameterType="String" resultMap="SysStaffResult">
<include refid="selectSysStaffVo"/>
where ding_user_id = #{dingUserId}