All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nxyfan.framework.task.service.impl.SysTaskServiceImpl Maven / Gradle / Ivy

package com.nxyfan.framework.task.service.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nxyfan.framework.common.enums.CommonSortOrderEnum;
import com.nxyfan.framework.common.exception.CommonException;
import com.nxyfan.framework.common.page.CommonPageRequest;
import com.nxyfan.framework.common.timer.CommonTimerTaskRunner;
import com.nxyfan.framework.task.entity.SysTask;
import com.nxyfan.framework.task.enums.SysTaskStateEnum;
import com.nxyfan.framework.task.enums.SysTaskTypeEnum;
import com.nxyfan.framework.task.mapper.SysTaskMapper;
import com.nxyfan.framework.task.param.SysTaskPageParam;
import com.nxyfan.framework.task.param.SysTaskSaveParam;
import com.nxyfan.framework.task.service.SysTaskService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronUtil;
import cn.hutool.extra.spring.SpringUtil;

/** 
 *
 * Describe: 定时任务Service接口实现类
 * Author: caoyang  
 * Create Time: 2022年12月5日 下午3:15:11 
 * Copyright @ 2022 51LIFE  
 */
@Service
public class SysTaskServiceImpl extends ServiceImpl implements SysTaskService {

	@Override
	public Page page(SysTaskPageParam pageParam) {
		QueryWrapper queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotEmpty(pageParam.getTaskCode())) {
            queryWrapper.lambda().eq(SysTask::getTaskCode, pageParam.getTaskCode());
        }
        if(ObjectUtil.isNotEmpty(pageParam.getTaskName())) {
            queryWrapper.lambda().like(SysTask::getTaskName, pageParam.getTaskName());
        }
        if(ObjectUtil.isNotEmpty(pageParam.getTaskType())) {
            queryWrapper.lambda().eq(SysTask::getTaskType, pageParam.getTaskType());
        }
        if(ObjectUtil.isNotEmpty(pageParam.getState())) {
            queryWrapper.lambda().eq(SysTask::getState, pageParam.getState());
        }
        if(ObjectUtil.isAllNotEmpty(pageParam.getSortField(), pageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(pageParam.getSortOrder());
            queryWrapper.orderBy(true, pageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()), StrUtil.toUnderlineCase(pageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(SysTask::getCreateDateTime);
        }
        return this.page(CommonPageRequest.defaultPage(pageParam, null), queryWrapper);
	}

	@Override
	public List getClassNameList() {
		Map commonTimerTaskRunnerMap = SpringUtil.getBeansOfType(CommonTimerTaskRunner.class);
        if(ObjectUtil.isNotEmpty(commonTimerTaskRunnerMap)) {
            Collection values = commonTimerTaskRunnerMap.values();
            return values.stream().map(commonTimerTaskRunner -> commonTimerTaskRunner.getClass().getName()).collect(Collectors.toList());
        }else {
            return CollectionUtil.newArrayList();
        }
	}
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void save(SysTaskSaveParam saveParam) {
		SysTaskTypeEnum.validate(saveParam.getTaskType());
        if(!CronExpression.isValidExpression(saveParam.getCronExpression())) {
            throw CommonException.bizException("cron表达式:{}格式不正确", saveParam.getCronExpression());
        }
        try {
            Class actionClass = Class.forName(saveParam.getClassName());
            if(!CommonTimerTaskRunner.class.isAssignableFrom(actionClass)) {
                List actionClassArr = StrUtil.split(saveParam.getClassName(), StrUtil.DOT);
                throw CommonException.bizException("定时任务对应的类:{}不符合要求", actionClassArr.get(actionClassArr.size() - 1));
            }
        }catch(ClassNotFoundException e) {
            throw CommonException.bizException("定时任务找不到对应的类,名称为:{}", saveParam.getClassName());
        }
        
		if(StrUtil.isBlank(saveParam.getTaskFlow())) {
			boolean hasSameTask = this.count(new LambdaQueryWrapper()
	                .eq(SysTask::getClassName, saveParam.getClassName())
	                .eq(SysTask::getCronExpression, saveParam.getCronExpression())) > 0;
	        if(hasSameTask) {
	            throw CommonException.bizException("存在重复执行的定时任务,名称为:{}", saveParam.getTaskName());
	        }
	        SysTask entity = BeanUtil.toBean(saveParam, SysTask.class);
			entity.setState(SysTaskStateEnum.STOPPED.getValue());
			this.save(entity);
		}else {
			boolean hasSameTask = this.count(new LambdaQueryWrapper()
	                .eq(SysTask::getClassName, saveParam.getClassName())
	                .eq(SysTask::getCronExpression, saveParam.getCronExpression())
	                .ne(SysTask::getTaskFlow, saveParam.getTaskFlow())) > 0;
	        if(hasSameTask) {
	            throw CommonException.bizException("存在重复的定时任务,名称为:{}", saveParam.getTaskName());
	        }
			SysTask entity = this.queryEntity(saveParam.getTaskFlow());
			if(entity.getState().equals(SysTaskStateEnum.RUNNING.getValue())) {
	            throw CommonException.bizException("运行中的定时任务不可编辑,id值为:{}", saveParam.getTaskFlow());
	        }
	        BeanUtil.copyProperties(saveParam, entity);
	        this.updateById(entity);
		}
	}
	
	@Override
    public SysTask queryEntity(String flow) {
		SysTask entity = this.getById(flow);
        if(ObjectUtil.isEmpty(entity)) {
            throw CommonException.bizException("定时任务不存在,id值为:{}", flow);
        }
        return entity;
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delete(String taskFlow) {
		SysTask entity = this.queryEntity(taskFlow);
		if(entity.getState().equals(SysTaskStateEnum.RUNNING.getValue())) {
			// 将运行中的定时任务停止
	        CronUtil.remove(taskFlow);
        }
		this.removeById(entity);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void stop(String taskFlow) {
		SysTask entity = this.queryEntity(taskFlow);
        if(entity.getState().equals(SysTaskStateEnum.STOPPED.getValue())) {
            throw CommonException.bizException("定时任务已经处于停止状态,id值为:{}", taskFlow);
        }
        // 将运行中的定时任务停止
        CronUtil.remove(taskFlow);
        // 更新运行状态
        this.update(new LambdaUpdateWrapper().eq(SysTask::getTaskFlow, taskFlow).set(SysTask::getState, SysTaskStateEnum.STOPPED.getValue()));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void run(String taskFlow) {
		SysTask entity = this.queryEntity(taskFlow);
        if(entity.getState().equals(SysTaskStateEnum.RUNNING.getValue())) {
            throw new CommonException("定时任务已经处于运行状态,id值为:{}", taskFlow);
        }
        CronUtil.schedule(taskFlow, entity.getCronExpression(), () -> {
            try {
                // 运行定时任务
                ((CommonTimerTaskRunner) SpringUtil.getBean(Class.forName(entity.getClassName()))).action();
            }catch (ClassNotFoundException e) {
                throw new CommonException("定时任务找不到对应的类,名称为:{}", entity.getClassName());
            }
        });
        // 更新运行状态
        this.update(new LambdaUpdateWrapper().eq(SysTask::getTaskFlow, taskFlow).set(SysTask::getState, SysTaskStateEnum.RUNNING.getValue()));
	}

	@Override
	public void init() {
		List list = this.list(new LambdaQueryWrapper().eq(SysTask::getState, SysTaskStateEnum.RUNNING.getValue()));
		if(ObjectUtil.isNotEmpty(list)) {
			for(SysTask task: list) {
				CronUtil.schedule(task.getTaskFlow(), task.getCronExpression(), () -> {
		            try {
		                // 运行定时任务
		                ((CommonTimerTaskRunner) SpringUtil.getBean(Class.forName(task.getClassName()))).action();
		            }catch (ClassNotFoundException e) {
		                throw new CommonException("定时任务找不到对应的类,名称为:{}", task.getClassName());
		            }
		        });
			}
			// 支持秒级
	        CronUtil.setMatchSecond(true);
	        // 开启定时任务
	        CronUtil.start();
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy