SystemUserTask.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. <?php
  2. namespace app\models\system;
  3. use app\models\store\StoreOrder;
  4. use app\models\user\User;
  5. use app\models\user\UserBill;
  6. use app\models\user\UserLevel;
  7. use app\models\user\UserTaskFinish;
  8. use crmeb\traits\ModelTrait;
  9. use crmeb\basic\BaseModel;
  10. /**
  11. * TODO 设置等级任务Model
  12. * Class SystemUserTask
  13. * @package app\models\system
  14. */
  15. class SystemUserTask extends BaseModel
  16. {
  17. /**
  18. * 数据表主键
  19. * @var string
  20. */
  21. protected $pk = 'id';
  22. /**
  23. * 模型名称
  24. * @var string
  25. */
  26. protected $name = 'system_user_task';
  27. use ModelTrait;
  28. /**
  29. * 任务类型
  30. * type 记录在数据库中用来区分任务
  31. * name 任务名 (任务名中的{$num}会自动替换成设置的数字 + 单位)
  32. * max_number 最大设定数值 0为不限定
  33. * min_number 最小设定数值
  34. * unit 单位
  35. * */
  36. protected static $TaskType=[
  37. [
  38. 'type'=>'SatisfactionIntegral',
  39. 'name'=>'满足积分{$num}',
  40. 'real_name'=>'积分数',
  41. 'max_number'=>0,
  42. 'min_number'=>0,
  43. 'unit'=>'分'
  44. ],
  45. [
  46. 'type'=>'ConsumptionAmount',
  47. 'name'=>'消费满{$num}',
  48. 'real_name'=>'消费金额',
  49. 'max_number'=>0,
  50. 'min_number'=>0,
  51. 'unit'=>'元'
  52. ],
  53. [
  54. 'type'=>'ConsumptionFrequency',
  55. 'name'=>'消费{$num}',
  56. 'real_name'=>'消费次数',
  57. 'max_number'=>0,
  58. 'min_number'=>0,
  59. 'unit'=>'次'
  60. ],
  61. [
  62. 'type'=>'CumulativeAttendance',
  63. 'name'=>'累计签到{$num}',
  64. 'real_name'=>'累计签到',
  65. 'max_number'=>365,
  66. 'min_number'=>1,
  67. 'unit'=>'天'
  68. ],
  69. [
  70. 'type'=>'SharingTimes',
  71. 'name'=>'分享给朋友{$num}',
  72. 'real_name'=>'分享给朋友',
  73. 'max_number'=>1000,
  74. 'min_number'=>1,
  75. 'unit'=>'次'
  76. ],
  77. [
  78. 'type'=>'InviteGoodFriends',
  79. 'name'=>'邀请好友{$num}成为下线',
  80. 'real_name'=>'邀请好友成为下线',
  81. 'max_number'=>1000,
  82. 'min_number'=>1,
  83. 'unit'=>'人'
  84. ],
  85. [
  86. 'type'=>'InviteGoodFriendsLevel',
  87. 'name'=>'邀请好友{$num}成为会员',
  88. 'real_name'=>'邀请好友成为会员',
  89. 'max_number'=>1000,
  90. 'min_number'=>1,
  91. 'unit'=>'人'
  92. ],
  93. ];
  94. public function profile()
  95. {
  96. return $this->hasOne('SystemUserLevel','level_id','id')->field('name');
  97. }
  98. public static function getTaskTypeAll()
  99. {
  100. return self::$TaskType;
  101. }
  102. /**
  103. * 获取某个任务
  104. * @param string $type 任务类型
  105. * @return array
  106. * */
  107. public static function getTaskType($type)
  108. {
  109. foreach (self::$TaskType as $item){
  110. if($item['type']==$type) return $item;
  111. }
  112. }
  113. /**
  114. * 设置任务名
  115. * @param string $type 任务类型
  116. * @param int $num 预设值
  117. * @return string
  118. * */
  119. public static function setTaskName($type,$num)
  120. {
  121. $systemType=self::getTaskType($type);
  122. return str_replace('{$num}',$num.$systemType['unit'],$systemType['name']);
  123. }
  124. /**
  125. * 累计消费金额
  126. * @param int $task_id 任务id
  127. * @param int $uid 用户id
  128. * @param int $start_time 开始时间
  129. * @param int $number 限定时间
  130. * @return boolean
  131. * */
  132. public static function ConsumptionAmount($task_id,$uid=0,$start_time=0,$number=0)
  133. {
  134. $isComplete=false;
  135. $SumPayPrice = StoreOrder::where('paid', 1)->where('refund_status', 0)->where('is_del', 0)->where('uid', $uid)->where('add_time','>',$start_time)->sum('pay_price');
  136. if($SumPayPrice >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
  137. return ['还需消费{$num}元',$SumPayPrice,$isComplete];
  138. }
  139. /**
  140. * 累计消费次数
  141. * @param int $task_id 任务id
  142. * @param int $uid 用户id
  143. * @param int $start_time 开始时间
  144. * @param int $number 限定时间
  145. * @return boolean
  146. * */
  147. public static function ConsumptionFrequency($task_id,$uid=0,$start_time=0,$number=0)
  148. {
  149. $isComplete=false;
  150. $countPay = StoreOrder::where('paid', 1)->where('refund_status', 0)->where('is_del', 0)->where('uid', $uid)->where('add_time','>',$start_time)->count();
  151. if($countPay >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
  152. return ['还需消费{$num}次',$countPay,$isComplete];
  153. }
  154. /**
  155. * 邀请好友成为会员
  156. * @param int $task_id 任务id
  157. * @param int $uid 用户id
  158. * @param int $start_time 开始时间
  159. * @param int $number 限定时间
  160. * @return boolean
  161. * */
  162. public static function InviteGoodFriendsLevel($task_id,$uid=0,$start_time=0,$number=0)
  163. {
  164. $isComplete=false;
  165. $uids=User::where('spread_uid',$uid)->where('spread_time','>',$start_time)->column('uid','uid');
  166. $levelCount=count($uids) ? UserLevel::setUserLevelCount($uids) : 0;
  167. if($levelCount >= $number) $isComplete = UserTaskFinish::setFinish($uid,$task_id) ? true : false;
  168. return ['还需邀请{$num}人成为会员',$levelCount,$isComplete];
  169. }
  170. /**
  171. * 邀请好友成为下线
  172. * @param int $task_id 任务id
  173. * @param int $uid 用户id
  174. * @param int $start_time 查询开始时间
  175. * @param int $number 限定数量
  176. * */
  177. public static function InviteGoodFriends($task_id,$uid=0,$start_time=0,$number=0)
  178. {
  179. $isComplete=false;
  180. $spreadCount=User::where('spread_uid',$uid)->where('spread_time','>',$start_time)->count();
  181. if($spreadCount >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
  182. return ['还需邀请{$num}人成为下线',$spreadCount,$isComplete];
  183. }
  184. /**
  185. * 满足积分
  186. * @param int $task_id 任务id
  187. * @param int $uid 用户id
  188. * @param int $start_time 查询开始时间
  189. * @param int $number 限定数量
  190. * @return Boolean
  191. * */
  192. public static function SatisfactionIntegral($task_id,$uid=0,$start_time=0,$number=0)
  193. {
  194. $isComplete=false;
  195. $sumNumber=UserBill::where('uid', $uid)->where('category', 'integral')->where('pm', 1)->where('add_time','>',$start_time)->where('type','in',['system_add','sign','gain'])->sum('number');
  196. if($sumNumber >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
  197. return ['还需要{$num}经验',$sumNumber,$isComplete];
  198. }
  199. /**
  200. * 分享给朋友次数完成情况
  201. * @param int $task_id 任务id
  202. * @param int $uid 用户id
  203. * @param int $start_time 查询开始时间
  204. * @param int $number 限定数量
  205. * @return Boolean
  206. * */
  207. public static function SharingTimes($task_id,$uid=0,$start_time=0,$number=0)
  208. {
  209. $isComplete=false;
  210. $sumCount=UserBill::where('uid', $uid)->where('category', 'share')->where('pm', 1)->where('add_time','>',$start_time)->where('type','share')->count();
  211. if($sumCount >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true :false;
  212. return ['还需分享{$num}次',$sumCount,$isComplete];
  213. }
  214. /**
  215. * 累计签到
  216. * @param int $task_id 任务id
  217. * @param int $uid 用户id
  218. * @param int $start_time 查询开始时间
  219. * @param int $number 限定数量
  220. * @return Boolean
  221. * */
  222. public static function CumulativeAttendance($task_id,$uid=0,$start_time=0,$number=0)
  223. {
  224. $isComplete=false;
  225. $sumCount=UserBill::where('uid', $uid)->where('category', 'integral')->where('pm', 1)->where('add_time','>',$start_time)->where('type','sign')->count();
  226. if($sumCount >= $number) $isComplete=UserTaskFinish::setFinish($uid,$task_id) ? true : false;
  227. return ['还需签到{$num}天',$sumCount,$isComplete];
  228. }
  229. /**
  230. * 设置任务完成情况
  231. * @param int $task_id 任务id
  232. * @param int $uid 用户uid
  233. * @param int $start_time 查询开始时间
  234. * @return Boolean
  235. * */
  236. public static function setTaskFinish($task_id=0,$uid=0,$start_time=0)
  237. {
  238. if(!$task_id) return self::setErrorInfo('缺少任务id参数');
  239. if(!$uid) return self::setErrorInfo('缺少用户uid');
  240. $task=self::where('id',$task_id)->where('is_show',1)->find();
  241. if(!$task) return self::setErrorInfo('任务不存在');
  242. $task_type=$task->task_type;
  243. if($task_type && method_exists(self::class,$task_type)){
  244. try{
  245. $start_time=User::getCleanTime($uid);
  246. return self::$task_type($task_id,$uid,$start_time,$task->number);
  247. }catch (\Exception $e){
  248. return self::setErrorInfo($e->getMessage());
  249. }
  250. }
  251. return self::setErrorInfo('没有此任务');
  252. }
  253. /**
  254. * 设置任务显示条件
  255. * @param string $alert 表别名
  256. * @param object $model 模型实例
  257. * @return object
  258. * */
  259. public static function visibleWhere($alert='',$model=null)
  260. {
  261. $model=$model===null ? new self() : $model;
  262. if($alert) $model=$model->alias($alert);
  263. $alert=$alert ? $alert.'.': '';
  264. return $model->where("{$alert}is_show",1);
  265. }
  266. /**
  267. * 获取等级会员任务列表
  268. * @param int $level_id 会员等级id
  269. * @param int $uid 用户id
  270. * @return array
  271. * */
  272. public static function getTashList($level_id,$uid=0,$level=null,$expire=1400)
  273. {
  274. $level_id = is_string($level_id) ? (int)$level_id : $level_id;
  275. $list = self::visibleWhere()->where('level_id',$level_id)->field('name,real_name,task_type,illustrate,number,id')->order('sort desc')->select();
  276. $list = count($list) ? $list->toArray() : [];
  277. if($uid == 0) return $list;
  278. if($level === null) $level = SystemUserLevel::getLevelInfo($uid);
  279. //获取下一个vip的id
  280. $LeveId = SystemUserLevel::getNextLevelId($level['id']);
  281. $is_clear = SystemUserLevel::getClear($level['id']);
  282. if($is_clear == false && $LeveId == $level_id) $is_clear=true;
  283. $reach_count = self::getTaskComplete($level_id,$uid,true);
  284. return [
  285. 'list'=>$list,
  286. 'reach_count'=>$reach_count,
  287. 'task'=>self::tidyTask($list,$uid,$is_clear,User::getCleanTime($uid)),
  288. ];
  289. }
  290. /**
  291. * 获取未完成任务的详细值
  292. * @param array $item 任务
  293. * @param int $uid 用户id
  294. * @param int $startTime 开始时间
  295. * @return array
  296. * */
  297. protected static function set_task_type($item,$uid,$startTime=0){
  298. $task=['task_type_title'=>'','new_number'=>0,'speed'=>0,'finish'=>0];
  299. $task_type=$item['task_type'];
  300. switch ($task_type) {
  301. case 'SatisfactionIntegral':
  302. case 'ConsumptionAmount':
  303. case 'ConsumptionFrequency':
  304. case 'CumulativeAttendance':
  305. case 'SharingTimes':
  306. case 'InviteGoodFriends':
  307. case 'InviteGoodFriendsLevel':
  308. try{
  309. list($task_type_title,$num,$isComplete)=self::$task_type($item['id'],$uid,$startTime,$item['number']);
  310. if($isComplete){
  311. $task['finish']=1;
  312. $task['speed']=100;
  313. $task['speed']=$item['number'];
  314. $task['new_number']=$item['number'];
  315. }else{
  316. $numdata=bcsub($item['number'],$num,0);
  317. $task['task_type_title']=str_replace('{$num}',$numdata,$task_type_title);
  318. $task['speed']=bcdiv($num,$item['number'],2);
  319. $task['speed']=bcmul($task['speed'],100,0);
  320. $task['new_number']=$num;
  321. }
  322. }catch (\Exception $e){}
  323. break;
  324. }
  325. return [$task['new_number'],$task['speed'],$task['task_type_title'],$task['finish']];
  326. }
  327. /**
  328. * 设置任务完成状态,已被使用
  329. * @param int $level_id 会员id
  330. * @param int $uid 用户id
  331. * @return Boolean
  332. * */
  333. public static function setTarkStatus($level_id,$uid)
  334. {
  335. $taskIds=self::visibleWhere()->where('level_id',$level_id)->column('id','id');
  336. if(!count($taskIds)) return true;
  337. return UserTaskFinish::where('uid',$uid)->where('task_id','in',$taskIds)->update(['status'=>1]);
  338. }
  339. /**
  340. * 检查当前等级是否完成全部任务
  341. * @param int $level_id 会员id
  342. * @param int $uid 用户uid
  343. * @return boolean
  344. * */
  345. public static function getTaskComplete($level_id,$uid,$isCount=false)
  346. {
  347. $taskIds=self::visibleWhere()->where('level_id',$level_id)->column('id','id');
  348. $taskIdsCount=count($taskIds);
  349. //如果当前会员没有任务默认为直接升级为下一等级
  350. if($taskIdsCount){
  351. if($isCount){
  352. return UserTaskFinish::group('task_id')->where('uid',$uid)->where('task_id','in',$taskIds)->count();
  353. }else{
  354. $finishCount = UserTaskFinish::group('task_id')->where('status',$isCount ? 1 : 0)->where('uid',$uid)->where('task_id','in',implode(',', $taskIds))->count();
  355. }
  356. //如果当前任务有完成其一的,查询当前完成的任务数量,如果有任务完成则达成当前vip
  357. if(self::visibleWhere()->where('id','in',implode(',', $taskIds))->where('is_must',0)->count() && $finishCount){
  358. return true;
  359. }
  360. return $finishCount >= $taskIdsCount;
  361. }
  362. if($isCount) return 0;
  363. //如果没有设置任务当前等级无需购买则返回false
  364. if(SystemUserLevel::be(['id'=>$level_id,'is_pay'=>0])) return false;
  365. return true;
  366. }
  367. /**
  368. * 设置任务内容完成情况
  369. * @param array $task 任务列表
  370. * @param int $uid 用户id
  371. * @热图图呢 array
  372. * */
  373. public static function tidyTask($task,$uid,$is_clear,$startTime){
  374. if(!is_array($task)) return $task;
  375. foreach ($task as &$item){
  376. //如果已完成该任务进度直接为100
  377. if(UserTaskFinish::where('uid',$uid)->where('task_id',$item['id'])->count()){
  378. $item['new_number']=$item['number'];
  379. $item['speed']=100;
  380. $item['finish']=1;
  381. $item['task_type_title']='';
  382. }else{
  383. // if($is_clear){
  384. list($new_number, $speed, $task_type_title, $finish) = self::set_task_type($item, $uid, $startTime);
  385. $item['new_number'] = $new_number;
  386. $item['speed'] = $speed;
  387. $item['task_type_title'] = $task_type_title;
  388. $item['finish'] = $finish;
  389. // }else {
  390. // list($new_number, $speed, $task_type_title, $finish) = self::set_task_type($item,-1,time()+86400);
  391. // $item['new_number'] = $new_number;
  392. // $item['speed'] = $speed;
  393. // $item['task_type_title'] = $task_type_title;
  394. // $item['finish'] = $finish;
  395. // }
  396. }
  397. }
  398. return $task;
  399. }
  400. }