<?php
namespace app\api\controller;

use app\common\model\CleanTask;
use app\common\model\Config;
use app\common\model\Daily;
use app\common\model\DailyTask;
use app\common\model\DeviceTask;
use app\common\model\PatrolTask;
use app\common\model\QualityTask;
use app\common\util\AppMsg;
use think\Controller;
use think\Db;

/**
 * 定时任务控制器
 * Class Timer
 * @package app\api\controller
 */

//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/patrol > timer.log 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/addPatrolTask > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/cleantask > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/Timer/daily > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/Timer/addDailyTask > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/device > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/addDeviceTask > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/waste > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/patrolStart > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/dailyStart > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/deviceStart > /dev/null 2>&1 &
//0 8 * * * /usr/bin/curl http://127.0.0.1/api/Timer/cleanStart > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/patrolPlan > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/cancelGorder > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/cancelDelay > /dev/null 2>&1 &
//20 1 * * * /usr/bin/curl http://127.0.0.1/api/Timer/attendance > /dev/null 2>&1 &
//30 1 * * * /usr/bin/curl http://127.0.0.1/api/Timer/attendanceReissue > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/attendanceResult > /dev/null 2>&1 &

//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/deviceTaskRemind > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/quality > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/addQualityTask > /dev/null 2>&1 &
//*/1 * * * * /usr/bin/curl http://127.0.0.1/api/Timer/complain > /dev/null 2>&1 &

class Timer extends Controller
{

    public function tt(){
        echo 'test';
    }
    //处理已超时的巡更任务,并从任务栏删除
    public function patrol(){
        set_time_limit(0);
        ini_set("memory_limit","1024M");

        (new PatrolTask())->timer_action();
    }

    //近12个小时的巡更任务加入到任务栏
    public function addPatrolTask(){
        (new PatrolTask())->addPatrolTask();
    }

    //处理已超时的专项保洁任务
    public function cleantask(){
        set_time_limit(0);
        ini_set("memory_limit","1024M");

        (new CleanTask())->timer_action();
    }

    //处理已超时日常工作任务,并从任务栏删除
    public function daily(){
        (new DailyTask())->timer_action();
    }

    //近12个小时的日常工作任务加入到任务栏
    public function addDailyTask(){
        (new DailyTask())->addDailyTask();
    }

    //处理已超时设备台账任务,并从任务栏删除
    public function device(){
        set_time_limit(0);
        ini_set("memory_limit","1024M");

        (new DeviceTask())->timer_action();
    }

    //近12个小时的设备台账任务加入到任务栏
    public function addDeviceTask(){
        (new DeviceTask())->addDeviceTask();
    }

    // 取消过期的延期申请
    public function cancelDelay(){
        Db::name('device_task_delay')
            ->where('status',0)
            ->where('end_time','<=',date('Y-m-d H:i:s'))
            ->update(['status'=>3,'update_time'=>date('Y-m-d H:i:s')]);
    }

    //医废未转运提醒 每分钟执行一次
    public function waste(){
        set_time_limit(0);
        ini_set("memory_limit","1024M");

        $orgids = Db::name('config_org')
            ->alias('co')
            ->join('config c','c.id = co.config_id')
            ->where('c.name','org_waste_status')
            ->where('co.value',1)
            ->column('co.org_id');
        if(!$orgids){
            exit();
        }
        $orgids2 = Db::name('config_org')
            ->alias('co')
            ->join('config c','c.id = co.config_id')
            ->where('c.name','org_waste_time')
            ->where('co.value',date('H:i'))
            ->column('co.org_id');
        if(!$orgids2){
            exit();
        }
        $orgids = array_unique(array_intersect($orgids,$orgids2));
        if(!$orgids){
            exit();
        }
        $users = [];
        foreach ($orgids as $v){
            //检查是否有未转运订单
            $ret = Db::name('waste_record')
                ->where('org_id',$v)
                ->where('status','in',[0,1])
                ->find();
            if(!$ret){
                continue;
            }

            // 检查是否设置通知人员
            $uids = model('Config')->getConfig('org_waste_user',$v);
            if($uids){
                $users = array_merge($users,explode(',',$uids));
            }
        }

        if($users){ //推送
            $length = 1000;
            $count = ceil(count($users)/$length);
            for ($i=0;$i<$count;$i++){
                $uids = array();
                $min = $i*$length;
                $max = $min + $length;
                if($max > count($users)){
                    $max = count($users);
                }
                for($j=$min;$j<$max;$j++){
                    $uids[] = $users[$j];
                }

                send_jpush($uids,AppMsg::PUSH_WASTE_UNFINISH);
            }
        }
    }

    // 巡更任务将要开始提醒 每分钟执行一次
    public function patrolStart(){
        $curTime = date('Y-m-d H:i').':00';
        $users = Db::name('patrol_task_user')
            ->alias('ptu')
            ->join('patrol_task pt','pt.id = ptu.patrol_task_id')
            ->where('pt.del',0)
            ->where('pt.status',0)
            ->where('pt.start_time',$curTime)
            ->field('ptu.user_id,patrol_mode')
            ->select();

        $userids1 = $userids2 = $userids3 = $userids4 = [];
        foreach ($users as $k=>$v){
            if($v['patrol_mode'] == 1 && !in_array($v['user_id'],$userids1)){
                $userids1[] = $v['user_id'];
            }else if($v['patrol_mode'] == 2 && !in_array($v['user_id'],$userids2)){
                $userids2[] = $v['user_id'];
            }else if($v['patrol_mode'] == 3 && !in_array($v['user_id'],$userids3)){
                $userids3[] = $v['user_id'];
            }else if($v['patrol_mode'] == 4 && !in_array($v['user_id'],$userids4)){
                $userids4[] = $v['user_id'];
            }
        }
        if($userids1){
            send_jpush($userids1,AppMsg::PUSH_PATROL,'您有新的巡更任务将要开始,请及时执行。');
        }
        if($userids2){
            send_jpush($userids2,AppMsg::PUSH_PATROL,'您有新的巡视任务将要开始,请及时执行。');
        }
        if($userids3){
            send_jpush($userids3,AppMsg::PUSH_PATROL,'您有新的巡查任务将要开始,请及时执行。');
        }
        if($userids4){
            send_jpush($userids4,AppMsg::PUSH_PATROL,'您有新的巡检任务将要开始,请及时执行。');
        }
    }

    // 专项保洁任务将要开始提醒 每天早上6点执行一次
    public function cleanStart(){
        $curTime = date('Y-m-d');
        $users = Db::name('clean_task_user')
            ->alias('ptu')
            ->join('clean_task pt','pt.id = ptu.task_id')
            ->where('pt.del',0)
            ->where('pt.status',0)
            ->where('pt.start_time',$curTime)
            ->column('ptu.user_id');

        if($users){
            send_jpush($users,AppMsg::PUSH_CLEAN,'您有新的专项保洁任务将要开始,请及时执行。');
        }
    }

    // 日常工作任务将要开始提醒 每分钟执行一次
    public function dailyStart(){
        $curTime = date('Y-m-d H:i').':00';
        $users = Db::name('daily_task_user')
            ->alias('ptu')
            ->join('daily_task pt','pt.id = ptu.task_id')
            ->where('pt.del',0)
            ->where('pt.status',0)
            ->where('pt.start_time',$curTime)
            ->column('ptu.user_id');

        if($users){
            send_jpush($users,AppMsg::PUSH_DAILY_TASK,'您有新的日常工作任务将要开始,请及时执行。');
        }
    }

    // 设备台账任务将要开始提醒 每分钟执行一次
    public function deviceStart(){
        $curTime = date('Y-m-d H:i').':00';
        $users = Db::name('device_task_user')
            ->alias('ptu')
            ->join('device_task pt','pt.id = ptu.task_id')
            ->where('pt.del',0)
            ->where('pt.status',0)
            ->where('pt.start_time',$curTime)
            ->column('ptu.user_id');

        if($users){
            send_jpush($users,AppMsg::PUSH_DEVICE_TASK,'您有新的设备台账任务将要开始,请及时执行。');
        }
    }

    //商城取消未支付订单
    public function cancelGorder(){

        $list = Db::name('g_orders')
            ->where('status',0)
            ->select();
        foreach ($list as $k=>$v){
            if(strtotime($v['create_time']) < (time()-30*60)){
                Db::name('g_orders')
                    ->where('id',$v['id'])
                    ->update([
                        'status'=>3,
                        'cancel_time'=>getTime()
                    ]);
                $goods = Db::name('g_order_goods')
                    ->where('order_id',$v['id'])
                    ->select();
                foreach ($goods  as $k1=>$v1){
                    Db::name('g_goods')
                        ->where('id',$v1['goods_id'])
                        ->setInc('stock',$v1['nums']);
                }
            }
        }
    }

    // 修改巡更计划状态 1分钟执行一次
    public function patrolPlan(){
        $curDay = date('Y-m-d');
        Db::name('patrol_plan')
            ->where('del',0)
            ->where('status',0)
            ->where('start_time','<=',$curDay)
            ->update(['status'=>1,'update_time'=>date('Y-m-d H:i:s')]);

        Db::name('patrol_plan')
            ->where('del',0)
            ->where('status','in',[0,1])
            ->where('end_time','<',$curDay)
            ->update(['status'=>2,'update_time'=>date('Y-m-d H:i:s')]);

    }

    // 更新打卡状态,每天执行一次
    public function attendance(){
        $yday = date('Y-m-d',time() - 86400);
        // 昨天不跨天进行中的状态改为已完成
        $map1[] = ['day','=',$yday];
        $map1[] = ['next','=',0];
        $map1[] = ['status','=',0];

        $yyday = date('Y-m-d',time() - 2*86400);
        // 昨天跨天进行中的状态改为已完成
        $map2[] = ['day','=',$yyday];
        $map2[] = ['next','=',1];
        $map2[] = ['status','=',0];

        $lists = Db::name('attendance_user_class')
            ->whereOr([ $map1, $map2 ])
            ->field('id,content')
            ->select();
        $lists = $lists?$lists:[];
        foreach ($lists as $k=>$v){
            $dates = json_decode($v['content'],true);
            foreach ($dates as $kk=>$vv){
                $dates[$kk]['sstatus'] = 1;
                $dates[$kk]['estatus'] = 1;
            }
            Db::name('attendance_user_class')->where('id',$v['id'])->update([
                'content' => json_encode($dates),
                'status' => 1,
                'update_time' => date('Y-m-d H:i:s')
            ]);
        }
    }

    // 昨日未打卡的日期,每天执行一次
    public function attendanceReissue(){
        $yday = date('Y-m-d',time() - 86400);
        model('AttendanceUserClass')->attendanceReissueFixed($yday); // 固定班制
        model('AttendanceUserClass')->attendanceReissueClass($yday); // 排班制
    }

    // 生成考勤结果,每分钟执行一次
    public function attendanceResult(){
        $lists = Db::name('attendance_user_class')->where('status',1)->where('result',0)->field('id,content')->limit(500)->select();
        $lists = $lists?$lists:[];

        foreach ($lists as $k=>$v){
            $content = json_decode($v['content'],true);
            $result = 1;
            $count = 0; // 打卡次数
            foreach ($content as $kk=>$vv){
                if($result != 1){
                    continue;
                }
                if($vv['ssign']){
                    $count++;
                    if($vv['ssign'] > $vv['stime']){
                        $result = 2;
                    }
                }
                if($vv['esign']){
                    $count++;
                    if($vv['esign'] < $vv['etime']){
                        $result = 2;
                    }
                }
            }
            if($count == 0){
                $result = 3;
            }
            Db::name('attendance_user_class')->where('id',$v['id'])->update(['result' => $result]);
        }

    }

    //提前五分钟提醒
    public function deviceTaskRemind(){
        $curStr= time() - 60*5;
        $date = date('Y-m-d H:i',$curStr).':00';
        $users = Db::name('device_task_user')
            ->alias('ptu')
            ->join('device_task pt','pt.id = ptu.task_id')
            ->where('pt.del',0)
            ->where('pt.status',0)
            ->where('pt.start_time',$date)
            ->column('ptu.user_id');

        send_jpush($users,AppMsg::PUSH_DEVICE_TASK,'您有新的设备维保任务将要开始,请及时执行。');
    }

    //处理已超时的巡更任务,并从任务栏删除
    public function quality(){
        set_time_limit(0);
        ini_set("memory_limit","1024M");

        (new QualityTask())->timerAction();
    }

    //近12个小时的品控任务加入到任务栏
    public function addQualityTask(){
        (new QualityTask())->addPatrolTask();
    }

    public function complain(){
        $lists = Db::name('config_org')
            ->alias('a')
            ->join('config b','a.config_id = b.id')
            ->where('b.name','org_complain_hour')
            ->field('a.org_id,a.value')
            ->select();
        $lists = $lists?$lists:[];
        foreach ($lists as $k=>$v){
            if($v['value'] > 0){
                // 获取当前组织是否设置人员,设置人员才发送超时提醒
                $users = (new Config())->getConfig('org_complain_user',$v['org_id']);
                if($users){
                    $uids = Db::name('user')->where('id','in',$users)->where('del',0)->where('enable')->column('id');
                    if($uids){
                        // 检查是否有超时未处理投诉
                        $map = [];
                        $endTime = date('Y-m-d H:i:s',time() - $v['value']*60*60);
                        $map[] = ['create_time','<',$endTime];
                        $map[] = ['status','=',0];
                        $map[] = ['org_id','=',$v['org_id']];
                        $map[] = ['del','=',0];
                        $ret = Db::name('complain')
                            ->where($map)
                            ->field('id,content,create_time,status,order_id')
                            ->find();
                        if($ret){
                            send_jpush($uids,AppMsg::PUSH_COMPLAIN_TIMEOUT);
                        }
                    }
                }
            }
        }
    }



}