You've already forked qlg.tsgz.moe
							
							
		
			
				
	
	
		
			319 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			319 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
<?php
 | 
						|
namespace addons\cron\model;
 | 
						|
use think\addons\BaseModel as Base;
 | 
						|
use think\Db;
 | 
						|
/**
 | 
						|
 * ============================================================================
 | 
						|
 * 计划任务业务处理
 | 
						|
 */
 | 
						|
class Crons extends Base{
 | 
						|
	/***
 | 
						|
     * 安装插件
 | 
						|
     */
 | 
						|
    public function install(){
 | 
						|
    	Db::startTrans();
 | 
						|
		try{
 | 
						|
			$hooks = ['initCronHook'];
 | 
						|
			$this->bindHoods("Cron", $hooks);
 | 
						|
			//管理员后台
 | 
						|
			$rs = Db::name('menus')->insert(["parentId"=>2,"menuName"=>"计划任务","menuSort"=>11,"dataFlag"=>1,"isShow"=>1,"menuMark"=>"cron"]);
 | 
						|
			if($rs!==false){
 | 
						|
				$datas = [];
 | 
						|
				$parentId = Db::name('menus')->getLastInsID();
 | 
						|
				$datas[] = ["menuId"=>$parentId,"privilegeCode"=>"CRON_JHRW_00","privilegeName"=>"查看计划任务","isMenuPrivilege"=>1,"privilegeUrl"=>"/addon/cron-cron-index","otherPrivilegeUrl"=>"/addon/cron-cron-pageQuery","dataFlag"=>1,"isEnable"=>1];
 | 
						|
				$datas[] = ["menuId"=>$parentId,"privilegeCode"=>"CRON_JHRW_04","privilegeName"=>"操作计划任务","isMenuPrivilege"=>0,"privilegeUrl"=>"/addon/cron-cron-toEdit","otherPrivilegeUrl"=>"/addon/cron-cron-edit,/addon/cron-cron-changeEnableStatus,/addon/cron-cron-runCron","dataFlag"=>1,"isEnable"=>1];
 | 
						|
				Db::name('privileges')->insertAll($datas);
 | 
						|
			}
 | 
						|
			installSql("cron");
 | 
						|
			Db::commit();
 | 
						|
			return true;
 | 
						|
		}catch (\Exception $e) {
 | 
						|
	 		Db::rollback();
 | 
						|
 | 
						|
	  		return false;
 | 
						|
	   	}
 | 
						|
    }
 | 
						|
 | 
						|
	/**
 | 
						|
	 * 删除菜单
 | 
						|
	 */
 | 
						|
	public function uninstall(){
 | 
						|
		Db::startTrans();
 | 
						|
		try{
 | 
						|
			$hooks = ['initCronHook'];
 | 
						|
			$this->unbindHoods("Cron", $hooks);
 | 
						|
			Db::name('menus')->where(["menuMark"=>"cron"])->delete();
 | 
						|
			Db::name('privileges')->where(["privilegeCode"=>array("like","CRON_%")])->delete();
 | 
						|
            uninstallSql("cron");//传入插件名
 | 
						|
			Db::commit();
 | 
						|
			return true;
 | 
						|
		}catch (\Exception $e) {
 | 
						|
	 		Db::rollback();
 | 
						|
	  		return false;
 | 
						|
	   	}
 | 
						|
	}
 | 
						|
	/**
 | 
						|
	 * 分页
 | 
						|
	 */
 | 
						|
	public function pageQuery(){
 | 
						|
		return $this->order('id desc')->paginate(input('limit/d'));
 | 
						|
	}
 | 
						|
	/**
 | 
						|
	 * 列表
 | 
						|
	 */
 | 
						|
    public function listQuery(){
 | 
						|
		return $this->order('id desc')->select();
 | 
						|
	}
 | 
						|
	public function getById($id){
 | 
						|
		$rs = $this->get($id);
 | 
						|
		if($rs['cronJson']!='')$rs['cronJson'] = unserialize($rs['cronJson']);
 | 
						|
		return $rs;
 | 
						|
	}
 | 
						|
    /**
 | 
						|
	 * 编辑
 | 
						|
	 */
 | 
						|
	public function edit(){
 | 
						|
		$data = input('post.');
 | 
						|
		$data['cronMinute'] = str_replace(',',',',$data['cronMinute']);
 | 
						|
		if($data['cronMinute']=='')$data['cronMinute'] = '0';
 | 
						|
		Db::startTrans();
 | 
						|
		try{
 | 
						|
			$corn = $this->get((int)$data['id']);
 | 
						|
			$corn->cronCycle = (int)$data['cronCycle'];
 | 
						|
			if(!in_array($corn->cronCycle,[0,1,2]))return WSTReturn('无效的计划时间');
 | 
						|
			if($corn->cronCycle==0)$corn->cronDay = $data['cronDay'];
 | 
						|
			if($corn->cronDay<=0 || $corn->cronDay>=32)return WSTReturn('无效的计划日期');
 | 
						|
			if($corn->cronCycle==1)$corn->cronWeek = $data['cronWeek'];
 | 
						|
			if($corn->cronWeek<0 || $corn->cronWeek>6)return WSTReturn('无效的计划星期');
 | 
						|
			$corn->cronHour = $data['cronHour'];
 | 
						|
			if($corn->cronCycle<0 || $corn->cronCycle>23)return WSTReturn('无效的计划时间');
 | 
						|
			$corn->cronMinute = $data['cronMinute'];
 | 
						|
			$json = unserialize($corn->cronJson);
 | 
						|
			if(!empty($json)){
 | 
						|
				foreach ($json as $key => $v) {
 | 
						|
					$json[$key]['fieldVal'] = input('post.'.$v['fieldCode']);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			$corn->cronJson = serialize($json);
 | 
						|
			$corn->isEnable = (int)input('post.isEnable');
 | 
						|
			$corn->nextTime = $this->getNextRunTime($corn);
 | 
						|
			$result = $corn->save();
 | 
						|
	        if(false !== $result){
 | 
						|
	        	cache('WST_CRONS',null);
 | 
						|
	        	Db::commit();
 | 
						|
	        	return WSTReturn("编辑成功", 1);
 | 
						|
	        }
 | 
						|
	    }catch (\Exception $e) {
 | 
						|
            Db::rollback();
 | 
						|
        }
 | 
						|
        return WSTReturn('编辑失败',-1);  
 | 
						|
	}
 | 
						|
	/**
 | 
						|
	 * 删除
 | 
						|
	 */
 | 
						|
    public function changeEnableStatus(){
 | 
						|
	    $id = (int)input('post.id/d');
 | 
						|
	    $status = ((int)input('post.status/d')==1)?1:0;
 | 
						|
	    Db::startTrans();
 | 
						|
		try{
 | 
						|
		    $result = $this->setField(['isEnable'=>$status,'id'=>$id]);
 | 
						|
	        if(false !== $result){
 | 
						|
	        	cache('WST_CRONS',null);
 | 
						|
	        	Db::commit();
 | 
						|
	        	return WSTReturn("操作成功", 1);
 | 
						|
	        }
 | 
						|
		}catch (\Exception $e) {
 | 
						|
            Db::rollback();
 | 
						|
        }
 | 
						|
        return WSTReturn('操作失败',-1); 
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * 执行计划任务
 | 
						|
	 */
 | 
						|
	public function runCron(){
 | 
						|
		$id = (int)input('post.id');
 | 
						|
		$cron = $this->get($id);
 | 
						|
		if(!$cron)return WSTReturn('计划任务不存在,跳过此次执行',1);
 | 
						|
		if($cron->isEnable==0)return WSTReturn('任务执行未开启中,跳过此次执行',1);
 | 
						|
		if($cron->isRunning==1)return WSTReturn('已有任务执行中,跳过此次执行',1);
 | 
						|
		$cron->runTime = date('Y-m-d H:i:s');
 | 
						|
		$cron->nextTime = $this->getNextRunTime($cron);
 | 
						|
		Db::startTrans();
 | 
						|
		try{
 | 
						|
	        $cron->isRunning = 1;
 | 
						|
	        $cron->save();
 | 
						|
	        $domain = request()->root(true);
 | 
						|
	        $domain = $domain."/".$cron->cronUrl;
 | 
						|
	        $data = $this->http($domain);
 | 
						|
	        $data = json_decode($data,true);
 | 
						|
	        $cron->isRunning = 0;
 | 
						|
	        if($data['status']==1){
 | 
						|
			    $cron->isRunSuccess = 1;
 | 
						|
	        }else{
 | 
						|
	            $cron->isRunSuccess = 0;
 | 
						|
	        }
 | 
						|
	        $cron->save();
 | 
						|
	        Db::commit();
 | 
						|
	    }catch (\Exception $e) {
 | 
						|
            Db::rollback();
 | 
						|
            $cron->isRunning = 0;
 | 
						|
            $cron->isRunSuccess = 0;
 | 
						|
            $cron->save();
 | 
						|
            return WSTReturn('执行失败');
 | 
						|
        }
 | 
						|
        return WSTReturn('执行成功',1);
 | 
						|
	}
 | 
						|
 | 
						|
	public function http($url){
 | 
						|
		$ch=curl_init($url);
 | 
						|
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置否输出到页面
 | 
						|
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30 ); //设置连接等待时间
 | 
						|
        curl_setopt($ch, CURLOPT_ENCODING, "gzip" );
 | 
						|
        $data=curl_exec($ch);
 | 
						|
        $info = curl_getinfo($ch);
 | 
						|
        curl_close($ch);
 | 
						|
        return $data;
 | 
						|
	}
 | 
						|
 | 
						|
    /**
 | 
						|
     * 执行所有定时任务
 | 
						|
     */
 | 
						|
	public function runCrons(){
 | 
						|
		$cons = $this->where('isEnable',1)->select();
 | 
						|
		$day = date('d');
 | 
						|
		$hour = date('H');
 | 
						|
		$minute = date('i');
 | 
						|
		$week = date('w');
 | 
						|
		foreach($cons as $key =>$cron){
 | 
						|
			if($cron->isRunning==1)contnie;
 | 
						|
			//判断能否执行
 | 
						|
			if(strtotime($cron->nextTime)>time())continue;
 | 
						|
			Db::startTrans();
 | 
						|
			try{
 | 
						|
				//fopen(time().'_'.rand(0,10000)."_auctionEnd.txt", "w");
 | 
						|
		        $cron->isRunning = 1;
 | 
						|
		        $cron->runTime = date('Y-m-d H:i:s');
 | 
						|
		        $cron->nextTime = $this->getNextRunTime($cron);
 | 
						|
		        $cron->save();
 | 
						|
		        $domain = request()->root(true);
 | 
						|
		        $domain = $domain."/".$cron->cronUrl;
 | 
						|
		        $data = $this->http($domain);
 | 
						|
		        $data = json_decode($data,true);
 | 
						|
		        $cron->isRunning = 0;
 | 
						|
		        if($data['status']==1){
 | 
						|
				    $cron->isRunSuccess = 1;
 | 
						|
		        }else{
 | 
						|
		            $cron->isRunSuccess = 0;
 | 
						|
		        }
 | 
						|
		        $cron->save();
 | 
						|
		        Db::commit();
 | 
						|
		    }catch (\Exception $e) {
 | 
						|
	            Db::rollback();
 | 
						|
	            $cron->isRunning = 0;
 | 
						|
	            $cron->isRunSuccess = 0;
 | 
						|
	            $cron->save();
 | 
						|
	        }
 | 
						|
		}
 | 
						|
		echo "done";
 | 
						|
	}
 | 
						|
 | 
						|
	public function getNextRunTime($cron){
 | 
						|
		$monthDay = date("t");
 | 
						|
		$today = date('j');
 | 
						|
		$thisWeek = date('w');
 | 
						|
		$thisHour = date('H');
 | 
						|
		$thisMinute = date('i');
 | 
						|
		$nextDay = date('Y-m-d');
 | 
						|
		$nextHour = 0;
 | 
						|
		$nextMinute = 0;
 | 
						|
		$isFurther = false;//标记是否要往前进一位
 | 
						|
		$tmpMinute = [];
 | 
						|
		if($cron->cronMinute==-1){
 | 
						|
            $nextMinute = date('i',strtotime('+1 Minute'));
 | 
						|
            if($nextMinute<$thisMinute)$isFurther = true;
 | 
						|
            $tmpMinute[] = $nextMinute;
 | 
						|
		}else{
 | 
						|
			$tmpMinute = explode(',',$cron->cronMinute);
 | 
						|
			sort($tmpMinute);
 | 
						|
            $isFind = false;
 | 
						|
            foreach($tmpMinute as $key => $v){
 | 
						|
                if((int)$v>59)continue;
 | 
						|
                if($thisMinute<(int)$v){
 | 
						|
                	$nextMinute = (int)$v;
 | 
						|
                	$isFind = true;
 | 
						|
                	break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if(!$isFind){
 | 
						|
            	$nextMinute = (int)$tmpMinute[0];
 | 
						|
            	$isFurther = true;
 | 
						|
            }
 | 
						|
		}
 | 
						|
		if($cron->cronHour==-1){
 | 
						|
            $nextHour = date("H",time()+($isFurther?3200:0));
 | 
						|
            $isFurther = false;
 | 
						|
            if($nextHour<$thisHour)$isFurther = true;
 | 
						|
        }else{
 | 
						|
            $nextHour = $cron->cronHour;
 | 
						|
            $isFurther = false;
 | 
						|
		}
 | 
						|
		if(time()>strtotime(date('Y-m-d')." ".$nextHour.":".$nextMinute.":00"))$isFurther = true;
 | 
						|
		if($cron->cronCycle==0){
 | 
						|
			if($isFurther){
 | 
						|
				$today = date('j',strtotime('+1 day'));
 | 
						|
			}
 | 
						|
			if($today<$cron->cronDay){
 | 
						|
                 $nextDay = date('Y-m-'.$cron->cronDay);
 | 
						|
			}else{
 | 
						|
				 $nextDay = date("Y-m",strtotime(" +1 month"))."-".$cron->cronDay;
 | 
						|
			}
 | 
						|
			if(date('j',strtotime($nextDay))!=$today){
 | 
						|
            	if($cron->cronHour==-1){
 | 
						|
            		$nextHour = 0;
 | 
						|
            	}else{
 | 
						|
                    $nextHour = $cron->cronHour;
 | 
						|
            	}
 | 
						|
            	if($cron->cronMinute==-1){
 | 
						|
            		$nextMinute = 0;
 | 
						|
            	}else{
 | 
						|
            		$nextMinute = (int)$tmpMinute[0];
 | 
						|
            	}
 | 
						|
            }
 | 
						|
		}
 | 
						|
		if($cron->cronCycle==1){
 | 
						|
			if($isFurther){
 | 
						|
				$thisWeek = date('w',strtotime('+1 day'));
 | 
						|
			}
 | 
						|
            $num = 0;
 | 
						|
            if($cron->cronWeek>$thisWeek){
 | 
						|
                $num = $cron->cronWeek - $thisWeek;
 | 
						|
            }else{
 | 
						|
            	$num = $cron->cronWeek - $thisWeek + 7;
 | 
						|
            }
 | 
						|
            $nextDay = date("Y-m-d",strtotime("+".$num." day"));
 | 
						|
            if(date('j',strtotime($nextDay))!=$today){
 | 
						|
            	if($cron->cronHour==-1){
 | 
						|
            		$nextHour = 0;
 | 
						|
            	}else{
 | 
						|
                    $nextHour = $cron->cronHour;
 | 
						|
            	}
 | 
						|
            	if($cron->cronMinute==-1){
 | 
						|
            		$nextMinute = 0;
 | 
						|
            	}else{
 | 
						|
            		$nextMinute = (int)$tmpMinute[0];
 | 
						|
            	}
 | 
						|
            }
 | 
						|
		}
 | 
						|
		if($cron->cronCycle==2){
 | 
						|
			if($isFurther){
 | 
						|
				$nextDay = date('Y-m-d',strtotime('+1 day'));
 | 
						|
			}else{
 | 
						|
				$nextDay = date('Y-m-d');
 | 
						|
			}
 | 
						|
		}
 | 
						|
		return date('Y-m-d H:i:s',strtotime($nextDay." ".$nextHour.":".$nextMinute.":00"));
 | 
						|
	}
 | 
						|
	
 | 
						|
}
 |