query()->insertGetId($data); // 如果操作失败 if( !$id ) return ['error'=>'新增失败']; // 更新缓存 $this->getList(true); // 返回结果 return $id; } /** * 添加数据 * */ public function edit($id,$data) { // 更新时间 $data['update_time'] = time(); // 写入数据表 $result = $this->query()->where(['id'=>$id])->update($data); // 如果操作失败 if( !$result ) return ['error'=>'修改失败']; // 更新缓存 $this->getList(true); // 返回结果 return $result; } /** * 获取列表 * @param bool $force 是否强制更新 * */ public function getList($force=false) { // 结果数据 $list = $force ? [] : cache('score:clockin:list'); // 不存在数据 if ( !$list ) { // 从数据库获取数据 $data = $this->query()->where([['status','=',0]])->orderBy('what_day')->orderBy('id')->get(['id','what_day','status','reward']); // 是否有数据 $data = $data ? $data->toArray() : []; // 循环处理数据 $list = []; // 进行更新 foreach ($data as $value) { // 重组数据 $list[$value['what_day']] = $value; } // 存起来 cache(['score:clockin:list'=>$list]); } // 返回结果 return $list; } /** * 根据天数获取 * */ public function getOne($whatDay,$field=''){ // 获取列表数据 $list = $this->getList(); // 获取数据 $one = isset($list[$whatDay]) ? $list[$whatDay] : []; // 返回值 return empty($field) ? $one : ( isset($one[$field]) ? $one[$field] : null); } /** * 今日是否已签到 * * @param int $uid 用户ID * */ public function isMarkClock($uid){ // 如果没有id if( !$uid ) return ['is_clockin'=>0,'finish_day'=>0]; // 获取缓存 $record = cache('score:clockin:mark:uid:'.$uid,[]); // 返回结果 if( $record ) return $record; // 模型实例 $Record = new Record(); // 通过查询今日打卡积分记录 $record = $Record->query()->where([['custom_uid','=',$uid],['buy_type','=',2],['status','=',1],['pay_time','>=',Carbon::now()->startOfDay()->getTimestamp()]])->first(['id','pay_type','pay_time']); // 如果没有记录 $record = $record ? ['is_clockin'=>1,'finish_day'=>$record['pay_type']] : ['is_clockin'=>0,'finish_day'=>0]; // 如果没有打卡天数 if( !$record['finish_day'] ) { // 获取昨天的打卡记录。以获取已打卡天数 $record['finish_day'] = (int) $Record->query()->where([['custom_uid','=',$uid],['buy_type','=',2],['status','=',1],['pay_time','>=',Carbon::now()->addDays(-1)->startOfDay()->getTimestamp()],['pay_time','<=',Carbon::now()->addDays(-1)->endOfDay()->getTimestamp()]])->value('pay_type'); } // 标记 $this->setMarkClock($uid,$record); // 返回结果 return $record; } /** * 设置打卡 * * @param int $uid 用户ID * */ public function setMarkClock($uid,$record){ // 存起来 cache(['score:clockin:mark:uid:'.$uid=>$record],now()->endOfDay()); // 返回结果 return $record; } /** * 获取最大的打卡天数 * */ public function getMaxDay(){ // 查询数据 $data = $this->getList(); // 获取天数字段 $days = array_column($data,'what_day'); // 获取第一个 $maxDay = $days ? max($days) : 0; // 返回结果 return (int) $maxDay; } /** * 打卡操作 * * @param int $uid 用户ID * */ public function finish($uid) { // 获取打卡任务列表,并获取最大天数 $maxDay = $this->getMaxDay(); // 如果是0,没有需要签到的任务 if( !$maxDay ) return ['error'=>'无签到任务']; // 是否已签到 $isMark = $this->isMarkClock($uid); // 如果已经签到,不进行后续操作,返回已打卡 if( $isMark['is_clockin'] ) return ['error'=>'今日已打卡']; // 如果当前已签到天数大于最大天数,从1开始计算签到天数 $finishDay = $isMark['finish_day'] >= $maxDay ? 1 : $isMark['finish_day'] +1; // 通过今日天数查找对应的打卡奖励 $reward = $this->getOne($finishDay,'reward'); // 组合数据,写入订单表,子表 DB::beginTransaction(); // 写入数据 try { // 成功继续 $result = (new CustomScore())->trade($uid,0,$reward,2,$finishDay); // 失败结束 if( isset($result['error']) ) { // 回退数据 DB::rollBack(); // 下单失败提示 return ['error'=>$result['error']]; } // 提交数据 DB::commit(); // 打卡通过 $isMark['is_clockin'] = 1; $isMark['finish_day'] = $finishDay; // 标记 $this->setMarkClock($uid,$isMark); // 奖励返回 $isMark['reward'] = $reward; // 返回打卡结果与奖励 return $isMark; } catch (\Throwable $th) { // 回退数据 DB::rollBack(); // 下单失败提示 return ['error'=>'打卡失败']; } } }