|
@@ -0,0 +1,253 @@
|
|
|
|
+<?php namespace App\Models\Score;
|
|
|
|
+
|
|
|
|
+use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
|
|
+use Illuminate\Database\Eloquent\Model;
|
|
|
|
+use App\Facades\Servers\Redis\Redis;
|
|
|
|
+use App\Models\CustomScore;
|
|
|
|
+use Illuminate\Support\Carbon;
|
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 打卡任务模型
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+class Clockin extends Model
|
|
|
|
+{
|
|
|
|
+ use HasFactory;
|
|
|
|
+
|
|
|
|
+ // 与模型关联的表名
|
|
|
|
+ protected $table = 'score_clockin';
|
|
|
|
+ // 是否主动维护时间戳
|
|
|
|
+ public $timestamps = false;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加数据
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+ public function add($data)
|
|
|
|
+ {
|
|
|
|
+ // 时间
|
|
|
|
+ $data['insert_time'] = time();
|
|
|
|
+ $data['update_time'] = time();
|
|
|
|
+ // 写入数据表
|
|
|
|
+ $id = $this->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'=>'打卡失败'];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取活动打卡列表
|
|
|
|
+ *@param int $active_id 打卡活动id
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+ public function getActiveList($active_id=0,$force=true)
|
|
|
|
+ {
|
|
|
|
+ // 结果数据
|
|
|
|
+ $list = $force ? [] : cache('score:clockin:list:'.$active_id);
|
|
|
|
+ $where = [
|
|
|
|
+ 'status'=>0,
|
|
|
|
+ 'active_id'=>$active_id
|
|
|
|
+ ];
|
|
|
|
+ // 不存在数据
|
|
|
|
+ if ( !$list ) {
|
|
|
|
+ // 从数据库获取数据
|
|
|
|
+ $data = $this->query()
|
|
|
|
+ ->where($where)
|
|
|
|
+ ->orderBy('what_day')
|
|
|
|
+ ->orderBy('id')
|
|
|
|
+ ->get(['id','what_day','status','reward','active_id','coupon_id']);
|
|
|
|
+ // 是否有数据
|
|
|
|
+ $data = $data ? $data->toArray() : [];
|
|
|
|
+ // 循环处理数据
|
|
|
|
+ $list = [];
|
|
|
|
+ // 进行更新
|
|
|
|
+ foreach ($data as $value) {
|
|
|
|
+ // 重组数据
|
|
|
|
+ $list[$value['what_day']] = $value;
|
|
|
|
+ }
|
|
|
|
+ // 存起来
|
|
|
|
+ cache(['score:clockin:list:'.$active_id=>$list]);
|
|
|
|
+ }
|
|
|
|
+ // 返回结果
|
|
|
|
+ return $list;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|