private $stepCount; // 单个任务步骤数量 private $runningTaskInfo; // 正在执行的任务信息 private $runningTaskId; // 正在执行的任务信息编号 private $runningTaskState; // 正在执行任务的状态 private $taskNoticeJson; // 任务通知json<参考TaskNoticeJson> private $isCancelTask; // 是否取消任务 private static $instance = null; // 单例 // @function 获取单例 // // @return TaskPreconditionCompare public static function getInstance(){ if (is_null(self::$instance)) { self::$instance = new TaskOperation();} return self::$instance; } // @function 初始函数 // // @param userId 用户编号 // @param idb 数据接口<参考IUserTaskDb> public function init($userId,$idb){ $this ->idb = $idb; $this ->userInfo = $this ->getUserInfo($userId,$idb); $this ->userTasks = $this ->getUserTasks($userId,$idb); $this ->taskNoticeJson = new TaskNoticeJson(); } // @function 设置是否取消任务 // // @param isCancelTask 当前任务编号 public function setIsCancelTask($isCancelTask = false){ $this ->isCancelTask = $isCancelTask; } // @function 设置当前任务编号 // // @param currTaskId 当前任务编号 public function setCurrTaskId($currTaskId = 0){ $this ->resetTask(); $this ->currTaskId = $currTaskId; } // @function 重置任务 // private function resetTask(){ $this ->stepCount = 0; $this ->runningTaskInfo = null; $this ->runningTaskId = null; $this ->runningTaskState = null; $this ->isCancelTask = null; } // @function 检测用户任务是否完成 // // @return 状态 public function checkUserTaskIsComplete(){ $this ->runningTaskId = $this ->currTaskId; // 获取任务信息 $taskInfo = new TaskInfo(); $this ->getTaskInfoById($this ->currTaskId,$taskInfo); // 转换前置条件信息 $taskPreconditionInfo = new TaskPreconditionInfo(); $this ->transformPreconditionInfo($taskInfo,$taskPreconditionInfo); $taskInfo ->precondition = $taskPreconditionInfo; // 转换后置条件信息 $taskPostcondition = new TaskPostcondition(); $this ->transformTaskPostcondition($taskInfo,$taskPostcondition); $taskInfo ->postcondition = $taskPostcondition; $this ->runningTaskInfo = $taskInfo; // 检测用户一个任务是否完成 $this ->checkUserOneTaskIsComplete($this ->userInfo, $taskInfo ->precondition,$taskInfo ->postcondition,$taskInfo ->postcondition); } // @function 检测用户任务是否可接 // // @return 状态 public function checkTaskIsAccessible(){ // 获取用户当前任务 $taskInfo = new TaskInfo(); $this ->getTaskInfoById($this ->currTaskId,$taskInfo); // 转换前置条件信息 $taskPreconditionInfo = new TaskPreconditionInfo(); $this ->transformPreconditionInfo($taskInfo,$taskPreconditionInfo); $taskInfo ->precondition = $taskPreconditionInfo; // 转换后置条件信息 $taskPostcondition = new TaskPostcondition(); $this ->transformTaskPostcondition($taskInfo,$taskPostcondition); $taskInfo ->postcondition = $taskPostcondition; // 多任务触发 if (!is_null($taskInfo ->precondition ->mtaskIds) &&!empty($taskInfo ->precondition ->mtaskIds)){ $taskCount = 0; foreach ($taskInfo ->precondition ->mtaskIds as $mtaskId) { $utaskInfo = null; $utaskInfo = $this ->getUserTaskInfo($mtaskId); if (TaskState::COMPLETE == $utaskInfo ->taskState){ $taskCount++; } } if ($taskCount == count($taskInfo ->precondition ->mtaskIds)) return true; else return null; } return $this ->checkOneTaskIsAccessible($this ->userInfo, $taskInfo ->precondition); } // @function 获取任务信息 // // @param id 任务编号 // @param taskInfo 任务信息<参见TaskInfo> // @return 任务信息 private function getTaskInfoById($id,$taskInfo){ $dbTaskInfo = $this ->idb ->getTaskInfoById($id); if (!empty($dbTaskInfo) && !is_null($dbTaskInfo)){ $taskInfo ->id = $dbTaskInfo['id']; $taskInfo ->taskName = $dbTaskInfo['task_name']; $taskInfo ->taskDescription = $dbTaskInfo['task_description']; $taskInfo ->precondition = $dbTaskInfo['precondition']; $taskInfo ->prefunction = $dbTaskInfo['prefunction']; $taskInfo ->postcondition = $dbTaskInfo['postcondition']; $taskInfo ->postfunction = $dbTaskInfo['postfunction']; $taskInfo ->stepFuns = $dbTaskInfo['stepfunction']; $taskInfo ->stepCount = $dbTaskInfo['stepcount']; $taskInfo ->stepclassname = $dbTaskInfo['stepclassname']; } return null; } // @function 检测用户一个任务是否完成 // // @function userInfo 用户信息<参见UserDataInfo> // @function taskPreconditionInfo 用户信息<参见TaskPreconditionInfo> // @function taskPostcondition 任务后缀条件<参见TaskPostcondition> // @function outTaskPreconditionInfo 输出任何后缀条件信息<参见OutTaskPreconditionInfo> // @return 状态 private function checkUserOneTaskIsComplete($userInfo, $taskPreconditionInfo,$taskPostcondition,$outTaskPreconditionInfo){ // 获取用户任务信息 $userTaskInfo = $this ->getUserTaskInfo($this ->runningTaskId); // 如果任务当前的步骤数大于0,那么起始步骤数等于任务当前的步骤数 if(!is_null($userTaskInfo ->tcurrStepCount) && 0 < $userTaskInfo ->tcurrStepCount){ $this ->stepCount = $userTaskInfo ->tcurrStepCount; } if (is_null($userTaskInfo ->taskState)) return false; // // 如果用户的正在执行的任务已完成,就更新正在执行用户的任务状态 // if (TaskState::COMPLETE == $this ->runningTaskState // && !is_null($this ->runningTaskState)){ // $userTaskInfo ->taskState = $this ->runningTaskState; // } // 取消任务 if (true == $this ->isCancelTask && !is_null($this ->isCancelTask)){ $userTaskInfo ->taskState = TaskState::CANCEL; } if (TaskState::COMPLETE == $userTaskInfo ->taskState){ // 任务完成 // out_后置条件 设置 // 是否激活下一个任务 if (!is_null($taskPostcondition ->nextTask) && 0 < $taskPostcondition ->nextTask){ $this ->resetTask(); $this ->runningTaskId = $taskPostcondition ->nextTask; $this ->runningTaskInfo = new TaskInfo(); $this ->getTaskInfoById($taskPostcondition ->nextTask,$this ->runningTaskInfo); // 转换前置条件信息 $taskPreconditionInfo = new TaskPreconditionInfo(); $this ->transformPreconditionInfo($this ->runningTaskInfo,$taskPreconditionInfo); $this ->runningTaskInfo ->precondition = $taskPreconditionInfo; // 转换后置条件信息 $taskPostcondition = new TaskPostcondition(); $this ->transformTaskPostcondition($this ->runningTaskInfo,$taskPostcondition); $this ->runningTaskInfo ->postcondition = $taskPostcondition; $this ->checkUserOneTaskIsComplete($this ->userInfo, $this ->runningTaskInfo ->precondition, $this ->runningTaskInfo ->postcondition,$outTaskPreconditionInfo); } // 返回 out_后置条件 }elseif (TaskState::CANCEL == $userTaskInfo ->taskState) { // 任务取消 // 通知到前端取消成功<由客户端执行更新用户任务状态> $stepFuncInfo = $this ->findCurrStepFunc($this ->stepCount); $this ->taskNoticeJson ->id = $this ->runningTaskId; $this ->taskNoticeJson ->stepCount = $this ->stepCount; $this ->taskNoticeJson ->stepFunc = isset($stepFuncInfo['name'])?$stepFuncInfo['name']:''; $this ->taskNoticeJson ->stepMsgType = isset($stepFuncInfo['type'])?$stepFuncInfo['type']:''; $this ->taskNoticeJson ->stepReturn = ''; $this ->taskNoticeJson ->stepMsg = "你好"; }elseif (TaskState::CONDUCT == $userTaskInfo ->taskState){ // 任务进行 $stepFuncInfo = $this ->findCurrStepFunc($this ->stepCount); $stepFuncResult = $this ->execTaskStepFunc($this ->runningTaskInfo ->stepclassname,$stepFuncInfo); if (!is_bool($stepFuncResult) && false != $stepFuncResult){ $this ->taskNoticeJson ->id = $this ->runningTaskId; $this ->taskNoticeJson ->stepCount = $this ->stepCount; $this ->taskNoticeJson ->stepFunc = isset($stepFuncInfo['name'])?$stepFuncInfo['name']:''; $this ->taskNoticeJson ->stepMsgType = isset($stepFuncInfo['type'])?$stepFuncInfo['type']:''; $this ->taskNoticeJson ->stepReturn = $stepFuncResult; $this ->taskNoticeJson ->stepMsg = "你好"; ++$this ->stepCount; // 如果任务步骤数执行完了,任务就完成了 if ((int)$this ->runningTaskInfo ->stepCount == $this ->stepCount){ $this ->taskNoticeJson ->taskState = TaskState::COMPLETE; } // 通知到前端() } } } // @function 获取用户信息 // // @param userId 用户编号 // @param idb 数据接口<参考IUserTaskDb> private function getUserInfo($userId,$idb){ $userInfo = (new UserTaskDb()) ->getUserInfoByUserId($userId); $userDataInfo = new UserDataInfo(); if (!empty($userInfo) && !is_null($userInfo)){ $this ->transformUserInfo($userInfo,$userDataInfo); } return $userDataInfo; } // @function 查找当前步骤函数 // // @param step 第几步 // @return 步骤函数 private function findCurrStepFunc($step){ if (is_null($this ->runningTaskInfo)) return ''; if (is_null($this ->runningTaskInfo ->stepFuns) || empty($this ->runningTaskInfo ->stepFuns)) return ''; $this ->runningTaskInfo ->stepFuns = json_decode($this ->runningTaskInfo ->stepFuns,true); foreach ($this ->runningTaskInfo ->stepFuns as $key => $stepFun) { if ($key == $step) return $stepFun; } } // @function 执行任务步骤函数 // // @param stepclassname 步骤函数保存文件名称 // @param stepFuncInfo 步骤函数信息 // @return 执行结果 private function execTaskStepFunc($stepclassname,$stepFuncInfo) { if (is_null($stepclassname) || empty($stepclassname)) return false; if (is_null($stepFuncInfo) || empty($stepFuncInfo)) return false; // 如果任务步骤函数对象,不存在 if (!class_exists($stepclassname)) return false; // 建立任务步骤函数对象反射类 $reflectStepFuncClass = new ReflectionClass($stepclassname); // 实例化任务步骤函数对象 $instanceStepFuncClass = $reflectStepFuncClass->newInstanceArgs(); $stepFuncName = isset($stepFuncInfo['name'])?$stepFuncInfo['name']:''; // 判断步骤函数对象,函数是否存在 if (method_exists($stepclassname,$stepFuncName)){ return $instanceStepFuncClass ->$stepFuncName(); } return false; } // @function 转换用户信息 // // source 源 // target 目标<参见UserDataInfo> private function transformUserInfo($source,$target){ if (isset($source['baseInfo']) && !empty($source['baseInfo'])){ $userBaseInfo = new UserBaseInfo(); $userBaseInfo ->age = $source['baseInfo']['age']; $userBaseInfo ->sex = $source['baseInfo']['sex']; $userBaseInfo ->time = $source['baseInfo']['time']; $userBaseInfo ->ulevel = $source['baseInfo']['ulevel']; $userBaseInfo ->place = $source['baseInfo']['place']; $userBaseInfo ->weather = $source['baseInfo']['weather']; $userBaseInfo ->age = $source['baseInfo']['age']; $target ->baseInfo = $userBaseInfo; } if (isset($source['physical']) && !empty($source['physical'])){ $taskPhysicalDataPInfo = new TaskPhysicalDataPInfo(); $taskPhysicalDataPInfo ->isLikeSports = $source['physical']['isLikeSports']; $taskPhysicalDataPInfo ->isHypertension = $source['physical']['isHypertension']; $taskPhysicalDataPInfo ->isHeartAttack = $source['physical']['isHeartAttack']; $taskPhysicalDataPInfo ->isAgile = $source['physical']['isAgile']; $taskPhysicalDataPInfo ->isHardBody = $source['physical']['isHardBody']; $target ->userPhysicalDataPInfo = $taskPhysicalDataPInfo; } } // @function 检测一个任务是否可接 // // @param userDataInfo 用户数据信息<参见UserDataInfo> // @param taskPreconditionInfo 任务前置条件信息<参考TaskPreconditionInfo> // @return boolean private function checkOneTaskIsAccessible($userDataInfo, $taskPreconditionInfo){ return TaskPreconditionCompare::getInstance() ->getResult($userDataInfo, $taskPreconditionInfo); } // @function 获取用户任务信息 // // @param taskId 任务编号 // @return 用户当前任务 private function getUserTaskInfo($taskId) { foreach ($this ->userTasks as $userTask) { if ($userTask instanceof UserTaskInfo){ if ($userTask ->taskId == $taskId) return $userTask; } if (is_array($userTask)){ if ($userTask['id'] == $taskId) return $userTask; } } } // @function 获取用户任务 // // @param userId 用户编号 // @param idb 数据接口<参考IUserTaskDb> private function getUserTasks($userId,$idb) { $userTasks = []; $dbUserTasks = $idb ->getUserTaskByUserId($userId); foreach ($dbUserTasks as $userTask){ $taskInfo = new UserTaskInfo(); $this ->transformTasks($userTask,$taskInfo); $userTasks[] = $taskInfo; } return $userTasks; } // @function 获取用户任务 // // @param dbTaskInfo 数据库任务信息 // @param tTaskInfo 转化的信息信息<参考UserTaskInfo> private function transformTasks($dbTaskInfo,$tTaskInfo){ $tTaskInfo ->userId = $dbTaskInfo['user_id']; $tTaskInfo ->taskId = $dbTaskInfo['task_id']; $tTaskInfo ->tcurrStepfun = $dbTaskInfo['tcurr_step_fun']; $tTaskInfo ->tcurrStepCount = $dbTaskInfo['tcurr_step_count']; $tTaskInfo ->taskState = 0 == $dbTaskInfo['task_state']?3:$dbTaskInfo['task_state']; } // @function 转换后置条件信息 // // @param taskInfo 任务信息 <参考TaskInfo> // @param taskPostcondition 任务后置条件信息 <参考TaskPostcondition> // @return void private function transformTaskPostcondition($taskInfo,$taskPostcondition){ if (!is_null($taskInfo) && !empty($taskInfo ->postfunction)) { $postfunctions = explode(',', $taskInfo->postfunction); $taskPostcondition ->nextTask = current($postfunctions); } } // @function 转换前置条件信息 // // @param taskInfo 任务信息 <参考TaskInfo> // @param taskPreconditionInfo 任务前置条件信息 <参考TaskPreconditionInfo> // @return void private function transformPreconditionInfo($taskInfo,$taskPreconditionInfo){ if (!is_null($taskInfo) && !empty($taskInfo ->precondition)){ $precondition = json_decode($taskInfo ->precondition,true); // 转化基本数据 if (isset($precondition['or'])){ $taskPreconditionInfo ->age = $this ->transformPreconditionCompare('age',$precondition['or']); $taskPreconditionInfo ->sex = $this ->transformPreconditionCompare('sex',$precondition['or']); $taskPreconditionInfo ->time = $this ->transformPreconditionCompare('time',$precondition['or']); $taskPreconditionInfo ->ulevel = $this ->transformPreconditionCompare('ulevel',$precondition['or']); $taskPreconditionInfo ->place = $this ->transformPreconditionCompare('place',$precondition['or']); $taskPreconditionInfo ->weather = $this ->transformPreconditionCompare('weather',$precondition['or']); } // 转化生理信息 if (isset($precondition['sl'])) { $taskPhysicalDataPInfo = new TaskPhysicalDataPInfo(); $taskPhysicalDataPInfo ->isAgile = $this ->transformPreconditionCompare('isAgile', $precondition['sl']); $taskPhysicalDataPInfo ->isLikeSports = $this ->transformPreconditionCompare('isLikeSports', $precondition['sl']); $taskPhysicalDataPInfo ->isHypertension = $this ->transformPreconditionCompare('isHypertension', $precondition['sl']); $taskPhysicalDataPInfo ->isHeartAttack = $this ->transformPreconditionCompare('isHeartAttack', $precondition['sl']); $taskPhysicalDataPInfo ->isHardBody = $this ->transformPreconditionCompare('isHardBody', $precondition['sl']); $taskPreconditionInfo ->taskPhysicalDataPInfo = $taskPhysicalDataPInfo; } // 前置任务 if (!empty($taskInfo ->prefunction) && !is_null($taskInfo ->prefunction)) { $taskPreconditionInfo ->mtaskIds = explode(',',$taskInfo ->prefunction); $taskPreconditionInfo ->mtaskIds = array_filter($taskPreconditionInfo ->mtaskIds); } } } // @function 转化前置条件比较 // // @param name // @param values // @return private function transformPreconditionCompare($name,$values){ if(!empty($values)) { // 获取值类型列表 $valueTypes = TaskPreConditionValueType::getValueTypes(); foreach ($values as $value) { // $value = json_decode($value,true); if ($value['short'] == $name){ $taskCondtionInfo = new TaskCondtionInfo(); // 查找值类型 $valueType = TaskPreConditionValueType::findValueType($value['preRelationId'],$valueTypes); if (2 == $valueType['id']){ $taskCondtionInfo ->maxValue = $value['preRelationStart']; }elseif (4 == $valueType['id']) { $taskCondtionInfo ->minValue = $value['preRelationStart']; }elseif (5 == $valueType['id']) { $taskCondtionInfo ->minValue = $value['preRelationStart']; }elseif (6 == $valueType['id']){ $taskCondtionInfo ->minValue = $value['preRelationStart']; $taskCondtionInfo ->maxValue = $value['preRelationEnd']; }elseif (in_array($valueType['id'],[0,1,7,8,9,10])){ $taskCondtionInfo ->equalValue = $value['preRelationName']; } else{ $taskCondtionInfo ->equalValue = $value['preRelationStart']; } return $taskCondtionInfo; } } } } // @function 通知客户端 // public function noticeClient(){ return $this ->taskNoticeJson; } }