TaskOperation.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. <?php
  2. /// @Brief 任务操作
  3. ///
  4. class TaskOperation
  5. {
  6. private $userTasks = []; // 用户任务列表
  7. private $userInfo; // 用户信息
  8. private $currTaskId; // 当前任务编号
  9. private $idb; // 用户任务db<参见IUserTaskDb>
  10. private $stepCount; // 单个任务步骤数量
  11. private $runningTaskInfo; // 正在执行的任务信息
  12. private $runningTaskId; // 正在执行的任务信息编号
  13. private $runningTaskState; // 正在执行任务的状态
  14. private $taskNoticeJson; // 任务通知json<参考TaskNoticeJson>
  15. private $isCancelTask; // 是否取消任务
  16. private static $instance = null; // 单例
  17. // @function 获取单例
  18. //
  19. // @return TaskPreconditionCompare
  20. public static function getInstance(){
  21. if (is_null(self::$instance)) { self::$instance = new TaskOperation();}
  22. return self::$instance;
  23. }
  24. // @function 初始函数
  25. //
  26. // @param userId 用户编号
  27. // @param idb 数据接口<参考IUserTaskDb>
  28. public function init($userId,$idb){
  29. $this ->idb = $idb;
  30. $this ->userInfo = $this ->getUserInfo($userId,$idb);
  31. $this ->userTasks = $this ->getUserTasks($userId,$idb);
  32. $this ->taskNoticeJson = new TaskNoticeJson();
  33. }
  34. // @function 设置是否取消任务
  35. //
  36. // @param isCancelTask 当前任务编号
  37. public function setIsCancelTask($isCancelTask = false){
  38. $this ->isCancelTask = $isCancelTask;
  39. }
  40. // @function 设置当前任务编号
  41. //
  42. // @param currTaskId 当前任务编号
  43. public function setCurrTaskId($currTaskId = 0){
  44. $this ->resetTask();
  45. $this ->currTaskId = $currTaskId;
  46. }
  47. // @function 重置任务
  48. //
  49. private function resetTask(){
  50. $this ->stepCount = 0;
  51. $this ->runningTaskInfo = null;
  52. $this ->runningTaskId = null;
  53. $this ->runningTaskState = null;
  54. $this ->isCancelTask = null;
  55. }
  56. // @function 检测用户任务是否完成
  57. //
  58. // @return 状态
  59. public function checkUserTaskIsComplete(){
  60. $this ->runningTaskId = $this ->currTaskId;
  61. // 获取任务信息
  62. $taskInfo = new TaskInfo();
  63. $this ->getTaskInfoById($this ->currTaskId,$taskInfo);
  64. // 转换前置条件信息
  65. $taskPreconditionInfo = new TaskPreconditionInfo();
  66. $this ->transformPreconditionInfo($taskInfo,$taskPreconditionInfo);
  67. $taskInfo ->precondition = $taskPreconditionInfo;
  68. // 转换后置条件信息
  69. $taskPostcondition = new TaskPostcondition();
  70. $this ->transformTaskPostcondition($taskInfo,$taskPostcondition);
  71. $taskInfo ->postcondition = $taskPostcondition;
  72. $this ->runningTaskInfo = $taskInfo;
  73. // 检测用户一个任务是否完成
  74. $this ->checkUserOneTaskIsComplete($this ->userInfo,
  75. $taskInfo ->precondition,$taskInfo ->postcondition,$taskInfo ->postcondition);
  76. }
  77. // @function 检测用户任务是否可接
  78. //
  79. // @return 状态
  80. public function checkTaskIsAccessible(){
  81. // 获取用户当前任务
  82. $taskInfo = new TaskInfo();
  83. $this ->getTaskInfoById($this ->currTaskId,$taskInfo);
  84. // 转换前置条件信息
  85. $taskPreconditionInfo = new TaskPreconditionInfo();
  86. $this ->transformPreconditionInfo($taskInfo,$taskPreconditionInfo);
  87. $taskInfo ->precondition = $taskPreconditionInfo;
  88. // 转换后置条件信息
  89. $taskPostcondition = new TaskPostcondition();
  90. $this ->transformTaskPostcondition($taskInfo,$taskPostcondition);
  91. $taskInfo ->postcondition = $taskPostcondition;
  92. // 多任务触发
  93. if (!is_null($taskInfo ->precondition ->mtaskIds)
  94. &&!empty($taskInfo ->precondition ->mtaskIds)){
  95. $taskCount = 0;
  96. foreach ($taskInfo ->precondition ->mtaskIds as $mtaskId)
  97. {
  98. $utaskInfo = null;
  99. $utaskInfo = $this ->getUserTaskInfo($mtaskId);
  100. if (TaskState::COMPLETE == $utaskInfo ->taskState){
  101. $taskCount++;
  102. }
  103. }
  104. if ($taskCount == count($taskInfo ->precondition ->mtaskIds))
  105. return true;
  106. else
  107. return null;
  108. }
  109. return $this ->checkOneTaskIsAccessible($this ->userInfo,
  110. $taskInfo ->precondition);
  111. }
  112. // @function 获取任务信息
  113. //
  114. // @param id 任务编号
  115. // @param taskInfo 任务信息<参见TaskInfo>
  116. // @return 任务信息
  117. private function getTaskInfoById($id,$taskInfo){
  118. $dbTaskInfo = $this ->idb ->getTaskInfoById($id);
  119. if (!empty($dbTaskInfo) && !is_null($dbTaskInfo)){
  120. $taskInfo ->id = $dbTaskInfo['id'];
  121. $taskInfo ->taskName = $dbTaskInfo['task_name'];
  122. $taskInfo ->taskDescription = $dbTaskInfo['task_description'];
  123. $taskInfo ->precondition = $dbTaskInfo['precondition'];
  124. $taskInfo ->prefunction = $dbTaskInfo['prefunction'];
  125. $taskInfo ->postcondition = $dbTaskInfo['postcondition'];
  126. $taskInfo ->postfunction = $dbTaskInfo['postfunction'];
  127. $taskInfo ->stepFuns = $dbTaskInfo['stepfunction'];
  128. $taskInfo ->stepCount = $dbTaskInfo['stepcount'];
  129. $taskInfo ->stepclassname = $dbTaskInfo['stepclassname'];
  130. }
  131. return null;
  132. }
  133. // @function 检测用户一个任务是否完成
  134. //
  135. // @function userInfo 用户信息<参见UserDataInfo>
  136. // @function taskPreconditionInfo 用户信息<参见TaskPreconditionInfo>
  137. // @function taskPostcondition 任务后缀条件<参见TaskPostcondition>
  138. // @function outTaskPreconditionInfo 输出任何后缀条件信息<参见OutTaskPreconditionInfo>
  139. // @return 状态
  140. private function checkUserOneTaskIsComplete($userInfo,
  141. $taskPreconditionInfo,$taskPostcondition,$outTaskPreconditionInfo){
  142. // 获取用户任务信息
  143. $userTaskInfo = $this ->getUserTaskInfo($this ->runningTaskId);
  144. // 如果任务当前的步骤数大于0,那么起始步骤数等于任务当前的步骤数
  145. if(!is_null($userTaskInfo ->tcurrStepCount)
  146. && 0 < $userTaskInfo ->tcurrStepCount){
  147. $this ->stepCount = $userTaskInfo ->tcurrStepCount;
  148. }
  149. if (is_null($userTaskInfo ->taskState))
  150. return false;
  151. // // 如果用户的正在执行的任务已完成,就更新正在执行用户的任务状态
  152. // if (TaskState::COMPLETE == $this ->runningTaskState
  153. // && !is_null($this ->runningTaskState)){
  154. // $userTaskInfo ->taskState = $this ->runningTaskState;
  155. // }
  156. // 取消任务
  157. if (true == $this ->isCancelTask
  158. && !is_null($this ->isCancelTask)){
  159. $userTaskInfo ->taskState = TaskState::CANCEL;
  160. }
  161. if (TaskState::COMPLETE == $userTaskInfo ->taskState){
  162. // 任务完成
  163. // out_后置条件 设置
  164. // 是否激活下一个任务
  165. if (!is_null($taskPostcondition ->nextTask)
  166. && 0 < $taskPostcondition ->nextTask){
  167. $this ->resetTask();
  168. $this ->runningTaskId = $taskPostcondition ->nextTask;
  169. $this ->runningTaskInfo = new TaskInfo();
  170. $this ->getTaskInfoById($taskPostcondition ->nextTask,$this ->runningTaskInfo);
  171. // 转换前置条件信息
  172. $taskPreconditionInfo = new TaskPreconditionInfo();
  173. $this ->transformPreconditionInfo($this ->runningTaskInfo,$taskPreconditionInfo);
  174. $this ->runningTaskInfo ->precondition = $taskPreconditionInfo;
  175. // 转换后置条件信息
  176. $taskPostcondition = new TaskPostcondition();
  177. $this ->transformTaskPostcondition($this ->runningTaskInfo,$taskPostcondition);
  178. $this ->runningTaskInfo ->postcondition = $taskPostcondition;
  179. $this ->checkUserOneTaskIsComplete($this ->userInfo,
  180. $this ->runningTaskInfo ->precondition,
  181. $this ->runningTaskInfo ->postcondition,$outTaskPreconditionInfo);
  182. }
  183. // 返回 out_后置条件
  184. }elseif (TaskState::CANCEL == $userTaskInfo ->taskState)
  185. {
  186. // 任务取消
  187. // 通知到前端取消成功<由客户端执行更新用户任务状态>
  188. $stepFuncInfo = $this ->findCurrStepFunc($this ->stepCount);
  189. $this ->taskNoticeJson ->id = $this ->runningTaskId;
  190. $this ->taskNoticeJson ->stepCount = $this ->stepCount;
  191. $this ->taskNoticeJson ->stepFunc = isset($stepFuncInfo['name'])?$stepFuncInfo['name']:'';
  192. $this ->taskNoticeJson ->stepMsgType = isset($stepFuncInfo['type'])?$stepFuncInfo['type']:'';
  193. $this ->taskNoticeJson ->stepReturn = '';
  194. $this ->taskNoticeJson ->stepMsg = "你好";
  195. }elseif (TaskState::CONDUCT == $userTaskInfo ->taskState){
  196. // 任务进行
  197. $stepFuncInfo = $this ->findCurrStepFunc($this ->stepCount);
  198. $stepFuncResult = $this ->execTaskStepFunc($this ->runningTaskInfo ->stepclassname,$stepFuncInfo);
  199. if (!is_bool($stepFuncResult)
  200. && false != $stepFuncResult){
  201. $this ->taskNoticeJson ->id = $this ->runningTaskId;
  202. $this ->taskNoticeJson ->stepCount = $this ->stepCount;
  203. $this ->taskNoticeJson ->stepFunc = isset($stepFuncInfo['name'])?$stepFuncInfo['name']:'';
  204. $this ->taskNoticeJson ->stepMsgType = isset($stepFuncInfo['type'])?$stepFuncInfo['type']:'';
  205. $this ->taskNoticeJson ->stepReturn = $stepFuncResult;
  206. $this ->taskNoticeJson ->stepMsg = "你好";
  207. ++$this ->stepCount;
  208. // 如果任务步骤数执行完了,任务就完成了
  209. if ((int)$this ->runningTaskInfo ->stepCount
  210. == $this ->stepCount){
  211. $this ->taskNoticeJson ->taskState = TaskState::COMPLETE;
  212. }
  213. // 通知到前端()
  214. }
  215. }
  216. }
  217. // @function 获取用户信息
  218. //
  219. // @param userId 用户编号
  220. // @param idb 数据接口<参考IUserTaskDb>
  221. private function getUserInfo($userId,$idb){
  222. $userInfo = (new UserTaskDb()) ->getUserInfoByUserId($userId);
  223. $userDataInfo = new UserDataInfo();
  224. if (!empty($userInfo) && !is_null($userInfo)){
  225. $this ->transformUserInfo($userInfo,$userDataInfo);
  226. }
  227. return $userDataInfo;
  228. }
  229. // @function 查找当前步骤函数
  230. //
  231. // @param step 第几步
  232. // @return 步骤函数
  233. private function findCurrStepFunc($step){
  234. if (is_null($this ->runningTaskInfo))
  235. return '';
  236. if (is_null($this ->runningTaskInfo ->stepFuns) || empty($this ->runningTaskInfo ->stepFuns))
  237. return '';
  238. $this ->runningTaskInfo ->stepFuns = json_decode($this ->runningTaskInfo ->stepFuns,true);
  239. foreach ($this ->runningTaskInfo ->stepFuns
  240. as $key => $stepFun)
  241. {
  242. if ($key == $step)
  243. return $stepFun;
  244. }
  245. }
  246. // @function 执行任务步骤函数
  247. //
  248. // @param stepclassname 步骤函数保存文件名称
  249. // @param stepFuncInfo 步骤函数信息
  250. // @return 执行结果
  251. private function execTaskStepFunc($stepclassname,$stepFuncInfo)
  252. {
  253. if (is_null($stepclassname) || empty($stepclassname))
  254. return false;
  255. if (is_null($stepFuncInfo) || empty($stepFuncInfo))
  256. return false;
  257. // 如果任务步骤函数对象,不存在
  258. if (!class_exists($stepclassname))
  259. return false;
  260. // 建立任务步骤函数对象反射类
  261. $reflectStepFuncClass = new ReflectionClass($stepclassname);
  262. // 实例化任务步骤函数对象
  263. $instanceStepFuncClass = $reflectStepFuncClass->newInstanceArgs();
  264. $stepFuncName = isset($stepFuncInfo['name'])?$stepFuncInfo['name']:'';
  265. // 判断步骤函数对象,函数是否存在
  266. if (method_exists($stepclassname,$stepFuncName)){
  267. return $instanceStepFuncClass ->$stepFuncName();
  268. }
  269. return false;
  270. }
  271. // @function 转换用户信息
  272. //
  273. // source 源
  274. // target 目标<参见UserDataInfo>
  275. private function transformUserInfo($source,$target){
  276. if (isset($source['baseInfo']) && !empty($source['baseInfo'])){
  277. $userBaseInfo = new UserBaseInfo();
  278. $userBaseInfo ->age = $source['baseInfo']['age'];
  279. $userBaseInfo ->sex = $source['baseInfo']['sex'];
  280. $userBaseInfo ->time = $source['baseInfo']['time'];
  281. $userBaseInfo ->ulevel = $source['baseInfo']['ulevel'];
  282. $userBaseInfo ->place = $source['baseInfo']['place'];
  283. $userBaseInfo ->weather = $source['baseInfo']['weather'];
  284. $userBaseInfo ->age = $source['baseInfo']['age'];
  285. $target ->baseInfo = $userBaseInfo;
  286. }
  287. if (isset($source['physical']) && !empty($source['physical'])){
  288. $taskPhysicalDataPInfo = new TaskPhysicalDataPInfo();
  289. $taskPhysicalDataPInfo ->isLikeSports = $source['physical']['isLikeSports'];
  290. $taskPhysicalDataPInfo ->isHypertension = $source['physical']['isHypertension'];
  291. $taskPhysicalDataPInfo ->isHeartAttack = $source['physical']['isHeartAttack'];
  292. $taskPhysicalDataPInfo ->isAgile = $source['physical']['isAgile'];
  293. $taskPhysicalDataPInfo ->isHardBody = $source['physical']['isHardBody'];
  294. $target ->userPhysicalDataPInfo = $taskPhysicalDataPInfo;
  295. }
  296. }
  297. // @function 检测一个任务是否可接
  298. //
  299. // @param userDataInfo 用户数据信息<参见UserDataInfo>
  300. // @param taskPreconditionInfo 任务前置条件信息<参考TaskPreconditionInfo>
  301. // @return boolean
  302. private function checkOneTaskIsAccessible($userDataInfo,
  303. $taskPreconditionInfo){
  304. return TaskPreconditionCompare::getInstance() ->getResult($userDataInfo,
  305. $taskPreconditionInfo);
  306. }
  307. // @function 获取用户任务信息
  308. //
  309. // @param taskId 任务编号
  310. // @return 用户当前任务
  311. private function getUserTaskInfo($taskId)
  312. {
  313. foreach ($this ->userTasks as $userTask)
  314. {
  315. if ($userTask instanceof UserTaskInfo){
  316. if ($userTask ->taskId == $taskId)
  317. return $userTask;
  318. }
  319. if (is_array($userTask)){
  320. if ($userTask['id'] == $taskId)
  321. return $userTask;
  322. }
  323. }
  324. }
  325. // @function 获取用户任务
  326. //
  327. // @param userId 用户编号
  328. // @param idb 数据接口<参考IUserTaskDb>
  329. private function getUserTasks($userId,$idb)
  330. {
  331. $userTasks = [];
  332. $dbUserTasks = $idb ->getUserTaskByUserId($userId);
  333. foreach ($dbUserTasks as $userTask){
  334. $taskInfo = new UserTaskInfo();
  335. $this ->transformTasks($userTask,$taskInfo);
  336. $userTasks[] = $taskInfo;
  337. }
  338. return $userTasks;
  339. }
  340. // @function 获取用户任务
  341. //
  342. // @param dbTaskInfo 数据库任务信息
  343. // @param tTaskInfo 转化的信息信息<参考UserTaskInfo>
  344. private function transformTasks($dbTaskInfo,$tTaskInfo){
  345. $tTaskInfo ->userId = $dbTaskInfo['user_id'];
  346. $tTaskInfo ->taskId = $dbTaskInfo['task_id'];
  347. $tTaskInfo ->tcurrStepfun = $dbTaskInfo['tcurr_step_fun'];
  348. $tTaskInfo ->tcurrStepCount = $dbTaskInfo['tcurr_step_count'];
  349. $tTaskInfo ->taskState = 0 == $dbTaskInfo['task_state']?3:$dbTaskInfo['task_state'];
  350. }
  351. // @function 转换后置条件信息
  352. //
  353. // @param taskInfo 任务信息 <参考TaskInfo>
  354. // @param taskPostcondition 任务后置条件信息 <参考TaskPostcondition>
  355. // @return void
  356. private function transformTaskPostcondition($taskInfo,$taskPostcondition){
  357. if (!is_null($taskInfo)
  358. && !empty($taskInfo ->postfunction)) {
  359. $postfunctions = explode(',', $taskInfo->postfunction);
  360. $taskPostcondition ->nextTask = current($postfunctions);
  361. }
  362. }
  363. // @function 转换前置条件信息
  364. //
  365. // @param taskInfo 任务信息 <参考TaskInfo>
  366. // @param taskPreconditionInfo 任务前置条件信息 <参考TaskPreconditionInfo>
  367. // @return void
  368. private function transformPreconditionInfo($taskInfo,$taskPreconditionInfo){
  369. if (!is_null($taskInfo)
  370. && !empty($taskInfo ->precondition)){
  371. $precondition = json_decode($taskInfo ->precondition,true);
  372. // 转化基本数据
  373. if (isset($precondition['or'])){
  374. $taskPreconditionInfo ->age = $this ->transformPreconditionCompare('age',$precondition['or']);
  375. $taskPreconditionInfo ->sex = $this ->transformPreconditionCompare('sex',$precondition['or']);
  376. $taskPreconditionInfo ->time = $this ->transformPreconditionCompare('time',$precondition['or']);
  377. $taskPreconditionInfo ->ulevel = $this ->transformPreconditionCompare('ulevel',$precondition['or']);
  378. $taskPreconditionInfo ->place = $this ->transformPreconditionCompare('place',$precondition['or']);
  379. $taskPreconditionInfo ->weather = $this ->transformPreconditionCompare('weather',$precondition['or']);
  380. }
  381. // 转化生理信息
  382. if (isset($precondition['sl'])) {
  383. $taskPhysicalDataPInfo = new TaskPhysicalDataPInfo();
  384. $taskPhysicalDataPInfo ->isAgile = $this ->transformPreconditionCompare('isAgile',
  385. $precondition['sl']);
  386. $taskPhysicalDataPInfo ->isLikeSports = $this ->transformPreconditionCompare('isLikeSports',
  387. $precondition['sl']);
  388. $taskPhysicalDataPInfo ->isHypertension = $this ->transformPreconditionCompare('isHypertension',
  389. $precondition['sl']);
  390. $taskPhysicalDataPInfo ->isHeartAttack = $this ->transformPreconditionCompare('isHeartAttack',
  391. $precondition['sl']);
  392. $taskPhysicalDataPInfo ->isHardBody = $this ->transformPreconditionCompare('isHardBody',
  393. $precondition['sl']);
  394. $taskPreconditionInfo ->taskPhysicalDataPInfo = $taskPhysicalDataPInfo;
  395. }
  396. // 前置任务
  397. if (!empty($taskInfo ->prefunction)
  398. && !is_null($taskInfo ->prefunction))
  399. {
  400. $taskPreconditionInfo ->mtaskIds = explode(',',$taskInfo ->prefunction);
  401. $taskPreconditionInfo ->mtaskIds = array_filter($taskPreconditionInfo ->mtaskIds);
  402. }
  403. }
  404. }
  405. // @function 转化前置条件比较
  406. //
  407. // @param name
  408. // @param values
  409. // @return
  410. private function transformPreconditionCompare($name,$values){
  411. if(!empty($values))
  412. {
  413. // 获取值类型列表
  414. $valueTypes = TaskPreConditionValueType::getValueTypes();
  415. foreach ($values as $value)
  416. {
  417. // $value = json_decode($value,true);
  418. if ($value['short'] == $name){
  419. $taskCondtionInfo = new TaskCondtionInfo();
  420. // 查找值类型
  421. $valueType = TaskPreConditionValueType::findValueType($value['preRelationId'],$valueTypes);
  422. if (2 == $valueType['id']){
  423. $taskCondtionInfo ->maxValue = $value['preRelationStart'];
  424. }elseif (4 == $valueType['id'])
  425. {
  426. $taskCondtionInfo ->minValue = $value['preRelationStart'];
  427. }elseif (5 == $valueType['id'])
  428. {
  429. $taskCondtionInfo ->minValue = $value['preRelationStart'];
  430. }elseif (6 == $valueType['id']){
  431. $taskCondtionInfo ->minValue = $value['preRelationStart'];
  432. $taskCondtionInfo ->maxValue = $value['preRelationEnd'];
  433. }elseif (in_array($valueType['id'],[0,1,7,8,9,10])){
  434. $taskCondtionInfo ->equalValue = $value['preRelationName'];
  435. } else{
  436. $taskCondtionInfo ->equalValue = $value['preRelationStart'];
  437. }
  438. return $taskCondtionInfo;
  439. }
  440. }
  441. }
  442. }
  443. // @function 通知客户端
  444. //
  445. public function noticeClient(){
  446. return $this ->taskNoticeJson;
  447. }
  448. }