使用责任链模式优化处理流程

使用责任链模式优化处理流程

场景:需要定时任务扫描隐患整改统计信息表,对超时未处理的事件发送通知短信,流程图如下:

/images/springboot/product-5-1.png

由上图可知,当不满足过滤条件才会进行下一次判断,所以可通过责任链模式来处理业务

定义处理的handle抽象类 StatisticsHandle

public abstract class StatisticsHandle {

    public PotentialSafetyHazardStatisticsHandle nextHandle;

    public void setNext(PotentialSafetyHazardStatisticsHandle nextHandle){
        this.nextHandle = nextHandle;
    }
    public abstract void handle(PotentialSafetyHazardStatisticsBO statistics);

    protected Boolean compareDate(Date beforeDate){
        Date nowDate = new Date();
        String proValue = PropertyReaderUtils.getProValue("statistics.over.time");
        if(proValue != null) {
            int overTime = Integer.parseInt(proValue);
            Date addHour = DateUtil.addHour(beforeDate, overTime);
            return addHour.before(nowDate);
        }
        return null;
    }

    protected AlarmInfoVo getAlarmInfo(PotentialSafetyHazardStatisticsBO statistics){
        if(statistics == null){
            return null;
        }
        if(statistics.getAlarmInfo() != null){
            return statistics.getAlarmInfo();
        }
        // todo 查询数据库
        return null;
    }

    protected void sendSms(String phone, Map<String, String> paramMap){
        // todo
    }
}

实现类

AlarmDealWithHandleImpl

@Slf4j
@Service
@RequiredArgsConstructor
public class AlarmDealWithHandleImpl extends StatisticsHandle {

    private final UasAuthService uasAuthService;

    private final PotentialSafetyHazardStatisticsMapper potentialSafetyHazardStatisticsMapper;
    /**
     *
     * @param statistics
     */
    @Override
    public void handle(PotentialSafetyHazardStatisticsBO statistics) {
        if(statistics == null){
            return;
        }
        // 判断报警处理是否为未处理
        if(statistics.getAlarmInfoDealWithYn() == 0){
            // 在判断报警时间到现在是否已经超过设定的阈值
            if(this.compareDate(statistics.getCreateTime())){
                // 发送短信
                // 查询安全总监手机号
                List<AlarmHandlePersonVo> personVoList = uasAuthService.queryDirectorUserList(statistics.getOrgId().toString());
                if(CollectionUtils.isNotEmpty(personVoList)){

                    Map<String, String> paramMap = new HashMap<>();
                    AlarmInfoVo alarmInfo = this.getAlarmInfo(statistics);
                    if(alarmInfo != null) {
                        paramMap.put("content", alarmInfo.getAlarmName() + "隐患");
                        for (AlarmHandlePersonVo personVo : personVoList) {
                            this.sendSms(personVo.getPhoneNumber(), paramMap);
                        }
                        // 将报警处理字段设置为1
                        statistics.setAlarmInfoDealWithYn(1);
                        potentialSafetyHazardStatisticsMapper.updateByPrimaryKeySelective(statistics);
                    }else{
                        log.info("alarmInfo is null");
                        return;
                    }
                }else{
                    log.info("security director list is empty");
                }
            }else{
                log.info("the preset threshold has not been exceeded");
                return;
            }
        }
				// 交给下一个handle处理
        if(this.nextHandle != null){
            this.nextHandle.handle(statistics);
        }
    }
}

potentialConfirmHandleImpl

@Slf4j
@Service
@RequiredArgsConstructor
public class potentialConfirmHandleImpl extends StatisticsHandle {

    private final PotentialSafetyHazardStatisticsMapper potentialSafetyHazardStatisticsMapper;

    private final PotentialSafetyHazardMapper potentialSafetyHazardMapper;

    @Override
    public void handle(PotentialSafetyHazardStatisticsBO statistics) {
        if(statistics.getPotentialSafetyHazardId() == null){
            return;
        }
        if(statistics.getPotentialConfirmYn() == 0){
            // 判断是否逾期为确认
            if(this.compareDate(statistics.getPotentialConfirmTime())){
                // 发送短信 提醒整改责任人
                PotentialSafetyHazard potentialSafetyHazard = potentialSafetyHazardMapper.selectByPrimaryKey(statistics.getPotentialSafetyHazardId());
                if(potentialSafetyHazard != null && potentialSafetyHazard.getPicPhoneNumber() != null){
                    AlarmInfoVo alarmInfo = this.getAlarmInfo(statistics);
                    Map<String,String> paramMap = new HashMap<>();
                    if(alarmInfo != null){
                        paramMap.put("content", alarmInfo.getAlarmName() + "隐患需要整改确认");
                        this.sendSms(potentialSafetyHazard.getPicPhoneNumber(), paramMap);
                    }
                }
                // 修改确认的值
                statistics.setPotentialConfirmYn(1);
                potentialSafetyHazardStatisticsMapper.updateByPrimaryKeySelective(statistics);
            }
        }

        if(this.nextHandle != null){
            this.nextHandle.handle(statistics);
        }
    }
}

RectificationHandleImpl

@Slf4j
@Service
@RequiredArgsConstructor
public class RectificationHandleImpl extends PotentialSafetyHazardStatisticsHandle {

    private final PotentialSafetyHazardMapper potentialSafetyHazardMapper;

    private final PotentialSafetyHazardStatisticsMapper potentialSafetyHazardStatisticsMapper;

    private final UasAuthService uasAuthService;
    @Override
    public void handle(PotentialSafetyHazardStatisticsBO statistics) {

        if(statistics.getRectificationYn() == 0){
            PotentialSafetyHazard potentialSafetyHazard = potentialSafetyHazardMapper.selectByPrimaryKey(statistics.getPotentialSafetyHazardId());
            if(potentialSafetyHazard != null){
                // 获取当前时间
                LocalDateTime nowTime= LocalDateTime.now();
                // 获取整改期限
                LocalDateTime fixDeadLine = potentialSafetyHazard.getFixDeadLine();
                log.info("PotentialSafetyHazard fixDeadLine: {}", fixDeadLine);
                if(fixDeadLine != null && fixDeadLine.isBefore(nowTime)){
                    // 获取监理电话列表
                    List<AlarmHandlePersonVo> personVoList = uasAuthService.querySupervisionUserList(statistics.getOrgId().toString());
                    if(CollectionUtils.isNotEmpty(personVoList)){
                        AlarmInfoVo alarmInfo = this.getAlarmInfo(statistics);
                        // 发送短信
                        if(alarmInfo != null){
                            Map<String, String> paramMap = new HashMap<>();
                            paramMap.put("content", alarmInfo.getAlarmName() + "隐患,已超过期限");
                            personVoList.forEach(item -> this.sendSms(item.getPhoneNumber(), paramMap));
                        }

                    }
                }
                // 修改整改字段为1
                statistics.setRectificationYn(1);
                potentialSafetyHazardStatisticsMapper.updateByPrimaryKeySelective(statistics);
            }
        }

        if(this.nextHandle != null){
            this.nextHandle.handle(statistics);
        }
    }
}

创建枚举类

StatisticsHandleEnum

@Getter
public enum StatisticsHandleEnum {
    ALARM_DEAL_WITH(1, AlarmDealWithHandleImpl.class, 2, null),
    POTENTIAL_CONFIRM(2, potentialConfirmHandleImpl.class, 3, 1),
    RECTIFICATION(3, RectificationHandleImpl.class, null, 2)
    ;

    private Integer id;

    private Class<? extends StatisticsHandle> className;

    private Integer nextId;

    private Integer preId;

    StatisticsHandleEnum(Integer id, Class<? extends StatisticsHandle> className, Integer nextId, Integer preId) {
        this.id = id;
        this.className = className;
        this.nextId = nextId;
        this.preId = preId;
    }
}

创建工厂类

StatisticsHandleFactory

public class PotentialStatisticsHandleFactory {

    private static Map<Integer, StatisticsHandleEnum> map = new HashMap<>();

    static{
        for(StatisticsHandleEnum handleEnum: StatisticsHandleEnum.values()){
            map.put(handleEnum.getId(), handleEnum);
        }
    }

    public StatisticsHandle buildHandle(){
        // 1. 获取第一处理者 那么那个是第一个处理者呢 preId == null 的就是第一个handler
        StatisticsHandleEnum firstEnum = this.getFirstEnum();
        if(firstEnum != null){
            StatisticsHandle firstHandle = newHandler(firstEnum);
            if(firstHandle == null){
                return null;
            }
            setNextHandler(firstEnum, firstHandle);
            return firstHandle;
        }
        return null;
    }

    private void setNextHandler(StatisticsHandleEnum handleEnum, StatisticsHandle handle) {
        if(handleEnum != null && handle != null){
            Integer nextId = handleEnum.getNextId();
            StatisticsHandleEnum nextHandleEnum = this.getEnumById(nextId);
            StatisticsHandle nextHandle = newHandler(nextHandleEnum);
            setNextHandler(nextHandleEnum, nextHandle);
        }
    }


    /**
     * 反射实体化具体的处理者
     * @param handleEnum
     * @return
     */
    private static StatisticsHandle newHandler(StatisticsHandleEnum handleEnum){
        if(handleEnum == null){
            return null;
        }
        return SpringApplicationContextUtil.getBean(handleEnum.getClassName());
    }


    public StatisticsHandleEnum getEnumById(Integer id) {
        if(id == null){
            return null;
        }
        return map.get(id);
    }


    public StatisticsHandleEnum getFirstEnum() {
        for(StatisticsHandleEnum entity: map.values()){
            if(entity.getPreId() == null){
                return entity;
            }
        }
        return null;
    }
}

业务BO类

PotentialSafetyHazardStatisticsBO

PotentialSafetyHazardStatistics :实体类

@Data
public class PotentialSafetyHazardStatisticsBO extends PotentialSafetyHazardStatistics {

    private AlarmInfoVo alarmInfo;

}

SpringApplicationContextUtil

@Configuration
public class SpringApplicationContextUtil implements ApplicationContextAware {
    @Getter
    private static ApplicationContext context;

    public static Object getBean(String beanName) {
        return context == null ? null : context.getBean(beanName);
    }

    public static <T> T getBean(Class<T> beanClass) {
        return context == null ? null : context.getBean(beanClass);
    }

    public static String[] getBeanDefinitionNames() {
        return context == null ? null : context.getBeanDefinitionNames();
    }

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringApplicationContextUtil.context = context;
    }
}

定时任务

@Component
@Slf4j
@RequiredArgsConstructor
public class PotentialSafetyHazardStatisticsScheduled {

    private final PotentialSafetyHazardStatisticsMapper potentialSafetyHazardStatisticsMapper;

    private final PotentialStatisticsHandleFactory potentialStatisticsHandleFactory;

    @Scheduled(cron = "0 0/5 * * * ?")
    public void scanTableSendSms(){
        PotentialSafetyHazardStatisticsHandle statisticsHandle = potentialStatisticsHandleFactory.buildHandle();
        Date startTime = new Date();
        List<PotentialSafetyHazardStatistics> list = potentialSafetyHazardStatisticsMapper.list(null, null, startTime);
        Optional.ofNullable(list).orElse(new ArrayList<>()).forEach(item -> {
            PotentialSafetyHazardStatisticsBO target = new PotentialSafetyHazardStatisticsBO();
            BeanUtils.copyProperties(item, target);
            statisticsHandle.handle(target);
        });
    }
}
0%