user_id = $user_id; $this->match_id = $id; $this->init($is_force); $this->checkStatus(); } /** * 初始化数据 * @throws Exception */ private function init($is_force = false) { $redisKey = CampaignConstants::getUserMatchKey($this->user_id); if (!$is_force) { $data = Redis::instance()->hGetAll($redisKey); if (!!!$data) $is_force = true; } if ($is_force) { //@todo 需要处理 先给默认值了 $maps = [ 'user_id' => $this->user_id, ]; if (!is_null($this->match_id)) { $maps['match_id'] = ['eq', $this->match_id]; } $dbRow = model("CampaignUserMatch")->setConnect($this->user_id) ->where($maps) ->order("id desc") ->find(); if (!$dbRow) { throw new Exception("您还没报名", 20001); } $data = $dbRow->toArray(); Redis::instance()->hMSet($redisKey, $data); Redis::instance()->expire($redisKey, 86400); } //更新字段进入 foreach ($data as $k=>$v) { $this->$k = $v; } } /** * 打卡 */ public function sign() { $this->getSignState(); if ($this->today_sign_status == 0) { //进行打卡 $campKey = CampaignConstants::getUserMatchReadKey($this->user_id); $campVal = Redis::instance()->get($campKey); $readNumber = Redis::instance()->hGet(CampaignConstants::getCampaignRedisKey($this->active_id),'read_number'); //$todo 打卡条件后续验证 看完指定章节数才可以哦 不满足返回201 if ($campVal === false || $campVal < $readNumber) { return ['code' => 201, 'msg' => '您还没完成前置条件']; } try { $update['num'] = ['exp', 'num+1']; $this->num++; if ($this->num == $this->period) { $update['status'] = 3; $this->status = 3; } $todaySignNum = 0; //更新我的打卡状态 场次信息 if (model("CampaignUserMatch")->setConnect($this->user_id)->update($update, ['id' => $this->id])) { $matchUpdate = [ 'puncher_num' => ['exp', "puncher_num + 1"] ]; if ($this->status == 3) { //完成 更新成功人数 $matchUpdate['success_num'] = ['exp', "success_num + 1"]; } if (model("CampaignMatch")->update($matchUpdate, ['id' => $this->match_id])) { //每日签到数据 $dayCollectRow = model("MatchDayCollect")->where('match_id', 'eq', $this->match_id)->where('createdate', 'eq', date("Ymd"))->find(); if ($dayCollectRow) { model("MatchDayCollect")->update(['num' => ['exp', "num+1"]], ['match_id' => $this->match_id, 'createdate' => date("Ymd")]); } else { model("MatchDayCollect")->insert(['match_id' => $this->match_id, 'createdate' => date("Ymd"), 'uv' => 0, 'num' => 1, 'updatetime' => time(), 'createtime' => time()]); } //更新打卡人数 $todaySignNum = CampaignService::instance()->setSignNumToday($this->match_id); } else { throw new Exception('打卡失败', 208); } $result = ['code' => 200, 'msg' => '本次打卡成功', 'today_sign_num' => $todaySignNum]; $this->flushState = 1; } else { throw new Exception('打卡失败', 207); } } catch (Exception $e) { Log::error('打卡失败:--msg:'.$e->getMessage()."--code:".$e->getCode() . '--line:'.$e->getLine()); $result = ['code' => 202, 'msg' => '打卡失败']; } } else { if ($this->today_sign_status == 1) { $result = ['code' => 203, 'msg' => '今日已打卡']; } else if ($this->today_sign_status == 2) { $result = ['code' => 204, 'msg' => '需补卡']; } else if ($this->today_sign_status == -1) { $result = ['code' => 205, 'msg' => '报名成功,明日可打卡']; } else { $result = ['code' => 206, 'msg' => '活动失败']; } } return $result; } /** * 补卡 */ public function cSign() { $this->getSignState(); if ($this->today_sign_status == 2 && $this->is_again ==0) { //可进行签到 //$todo 支付才可以哦 微支付 返回201 需要先支付 $cSignKey = CampaignConstants::getUserClickCSignKey($this->user_id); $uOrderKey = CampaignConstants::getUserPayOrderKey($this->user_id); $uOrderVal = Redis::instance()->get($uOrderKey); if ($uOrderVal === false) { //未支付 if (Redis::instance()->setnx($cSignKey, time())) { Redis::instance()->expire($cSignKey, 86400); } return ['code' => 201, 'msg' => '请先充值']; } try { $update = [ 'is_again' => 1, 'num' => ['exp', 'num+1'], ]; $this->is_again = 1; $this->num++; if ($this->num == $this->period) { $update['status'] = 3; $this->status = 3; } if (model("CampaignUserMatch")->setConnect($this->user_id)->update($update, ['id' => $this->id])) { $result = ['code' => 200, 'msg' => '补卡成功']; $matchUpdate = [ 'puncher_num' => ['exp', "puncher_num + 1"] ]; if ($this->status == 3) { //完成 更新成功人数 $matchUpdate['success_num'] = ['exp', "success_num + 1"]; } if (model("CampaignMatch")->update($matchUpdate, ['id' => $this->match_id])) { //每日签到数据 model("MatchDayCollect")->update(['num' => ['exp', "num+1"]], ['match_id' => $this->match_id, 'createdate' => date("Ymd", strtotime("-1 days"))]); //每日签到数据 $yestdayCollectRow = model("MatchDayCollect")->where('match_id', 'eq', $this->match_id)->where('createdate', 'eq', date("Ymd", strtotime("-1 days")))->find(); if ($yestdayCollectRow) { model("MatchDayCollect")->update(['num' => ['exp', "num+1"]], ['match_id' => $this->match_id, 'createdate' => date("Ymd", strtotime("-1 days"))]); } else { model("MatchDayCollect")->insert(['match_id' => $this->match_id, 'createdate' => date("Ymd", strtotime("-1 days")), 'uv' => 0, 'num' => 1, 'updatetime' => time(), 'createtime' => time()]); } } else { throw new Exception('补卡失败', 207); } $this->flushState = 1; } else { throw new Exception('补卡失败', 208); } } catch (Exception $e) { Log::error('补卡失败:--msg:'.$e->getMessage()."--code:".$e->getCode() . '--line:'.$e->getLine()); $result = ['code' => 202, 'msg' => '补卡失败']; } } else { $result = ['code' => 203, 'msg' => '不满足补卡条件']; } return $result; } /** * 检测当前状态 有变动需更新 */ public function checkStatus() { if (in_array($this->status, [1, 2, 3])) { $today = strtotime(date("Ymd")); //当前第几天 $days = ceil(($today-strtotime($this->match_date))/86400); //差几天 $day = $days - $this->num; if ($this->status == 1) { if ($day == 1 || $day == 2) { //更新为打卡中 $status = 2; } else if ($day > 2) { //更新为失败 $status = 5; } } elseif ($this->status == 2) { //打卡中 更新为失败 if ($this->is_again == 1) { //已补卡 if ($day > 1) { //更新为失败 $status = 5; } } else { if ($day > 2) { //更新为失败 $status = 5; } } } if (isset($status)) { //更新 if (model("CampaignUserMatch")->setConnect($this->user_id)->update(['status' => $status], ['id' => $this->id])) { $this->status = $status; $this->flushState = 1; $this->getSignState(); } else { throw new Exception("我的场次信息更新失败", 20002); } } } } /** * 获取当前打卡状态 * @return array */ public function getSignState() { //我的场次状态 $matchStatus = $this->getState(); switch ($matchStatus['status']) { case 1: $this->today_sign_status = -1; //报名状态 不可打卡 break; case 2: $today = strtotime(date("Ymd")); //当前第几天 $days = ceil(($today-strtotime( $this->match_date ) )/86400); $day = $days - $this->num; if ($day == 0) { $this->today_sign_status = 1; //今日已打卡 } elseif ($day == 1) { $this->today_sign_status = 0; //今日未打卡 } elseif ($day == 2) { $this->today_sign_status = 2; //今日未打卡 昨日也未打卡 } else { $this->today_sign_status = -2;//失败状态 不可打卡 理论上不存在 } break; default: $this->today_sign_status = -2; //失败状态 不可打卡 } return $this->today_sign_status; } /** * 获取场次状态 */ public function getState() { switch ($this->status) { case 1: $state = ['status' => 1, 'state' => '报名状态']; break; case 2: $state = ['status' => 2, 'state' => '打卡中']; break; case 3: $state = ['status' => 3, 'state' => '挑战成功']; break; case 4: $state = ['status' => 4, 'state' => '领奖']; break; case 5: $state = ['status' => 5, 'state' => '失败']; break; default: $state = ['status' => 5, 'state' => '失败']; } return $state; } public function __destruct() { // TODO: Implement __destruct() method. //将变动写入redis if ($this->flushState == 1) { $redisKey = CampaignConstants::getUserMatchKey($this->user_id, $this->match_id); Redis::instance()->hMSet($redisKey, $this->attributes); Redis::instance()->expire($redisKey, 86400); } } public function __set($name, $value) { // TODO: Implement __set() method. $this->attributes[$name] = $value; } public function __get($name) { // TODO: Implement __get() method. return $this->attributes[$name]; } }