CustomClockinRecord.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php namespace App\Models;
  2. use Illuminate\Database\Eloquent\Factories\HasFactory;
  3. use Illuminate\Database\Eloquent\Model;
  4. use App\Facades\Servers\Redis\Redis;
  5. use App\Models\CustomScore;
  6. use App\Models\Score\Clockin;
  7. use Illuminate\Support\Carbon;
  8. use Illuminate\Support\Facades\DB;
  9. /**
  10. * 打卡活动
  11. *
  12. */
  13. class CustomClockinRecord extends Model
  14. {
  15. use HasFactory;
  16. // 与模型关联的表名
  17. protected $table = 'custom_clockin_record';
  18. // 是否主动维护时间戳
  19. public $timestamps = false;
  20. // 定义时间戳字段名
  21. // const CREATED_AT = 'insert_time';
  22. // const UPDATED_AT = 'update_time';
  23. /**
  24. * 添加数据
  25. *
  26. */
  27. public function add($data)
  28. {
  29. // 时间
  30. $data['insert_time'] = time();
  31. $data['update_time'] = time();
  32. // 写入数据表
  33. $id = $this->query()->insertGetId($data);
  34. // 返回结果
  35. return $id;
  36. }
  37. /**
  38. * 添加数据
  39. *
  40. */
  41. public function edit($id,$data)
  42. {
  43. // 更新时间
  44. $data['update_time'] = time();
  45. // 写入数据表
  46. $result = $this->query()->where(['id'=>$id])->update($data);
  47. // 如果操作失败
  48. if( !$result ) return $result;
  49. // 更新缓存
  50. $this->getList(true);
  51. // 返回结果
  52. return $result;
  53. }
  54. /**
  55. * 获取列表
  56. * @param Bool $force 是否强制更新
  57. *
  58. */
  59. public function getList($force = false)
  60. {
  61. // 结果数据
  62. $list = $force ? [] : cache('admin:clockin:active:list');
  63. $where[] = ['status'=>0];
  64. $where[] = ['end_time','>=',time()];
  65. // 不存在数据
  66. if ( !$list ) {
  67. // 从数据库获取数据
  68. $data = $this->query()->where($where)->get(['id','name','banner_img','active_rule','status','start_time','end_time','tag_scope','city_ids']);
  69. // 是否有数据
  70. $data = $data ? $data->toArray() : [];
  71. // 循环处理数据
  72. $list = [];
  73. // 进行更新
  74. foreach ($data as $value) {
  75. // 重组数据
  76. $list[$value['id']] = $value;
  77. }
  78. // 存起来
  79. cache(['admin:clockin:active:list'=>$list]);
  80. }
  81. // 返回结果
  82. return $list;
  83. }
  84. /**
  85. * 今日是否已签到
  86. *
  87. * @param int $uid 用户ID
  88. *
  89. */
  90. public function isMarkClock($uid,$activeId){
  91. // 如果没有id
  92. if( !$uid ) return ['is_clockin'=>0,'finish_day'=>0];
  93. // 获取缓存
  94. //$record = cache('score:clockin:mark:uid:'.$uid,[]);
  95. // 返回结果
  96. // if( $record ) return $record;
  97. // 通过查询今日打卡积分记录
  98. $record = $this->query()->where([['active_id','=',$activeId],['custom_uid','=',$uid],['clockin_time','>=',Carbon::now()->startOfDay()->getTimestamp()]])->first(['id','custom_uid','clockin_day','clockin_time']);
  99. // 如果没有记录
  100. $record = $record ? ['is_clockin'=>1,'finish_day'=>$record['clockin_day']] : ['is_clockin'=>0,'finish_day'=>0];
  101. // 标记
  102. //$this->setMarkClock($uid,$record);
  103. // 返回结果
  104. return $record;
  105. }
  106. /**
  107. * 打卡操作
  108. *
  109. * @param int $uid 用户ID
  110. *
  111. */
  112. public function finish($uid,$activeId)
  113. {
  114. // 获取打卡任务列表,并获取最大天数
  115. $maxDay = $this->getMaxDay($activeId);
  116. // 如果是0,没有需要签到的任务
  117. if( !$maxDay ) return ['error'=>'无签到任务'];
  118. // 是否已签到
  119. $isMark = $this->isMarkClock($uid,$activeId);
  120. // 如果已经签到,不进行后续操作,返回已打卡
  121. if( $isMark['is_clockin'] ) return ['error'=>'今日已打卡'];
  122. // 如果当前已签到天数大于最大天数,从1开始计算签到天数
  123. $finishDay = $isMark['finish_day'] >= $maxDay ? 1 : $isMark['finish_day'] +1;
  124. // 通过今日天数查找对应的打卡奖励
  125. $list = $this->getOne($finishDay,$activeId);
  126. if (!$list) return ['error'=>'今日签到没有奖励'];
  127. $reward = $list['reward'] ?? 0;
  128. $coupon_id = $list['coupon_id'] ?? 0;
  129. // 组合数据,写入订单表,子表
  130. DB::beginTransaction();
  131. // 写入数据
  132. try {
  133. // 成功继续
  134. if ($reward){
  135. $result = (new CustomScore())->trade($uid,0,$reward,2,$finishDay);
  136. // 失败结束
  137. if( isset($result['error']) ) {
  138. // 回退数据
  139. DB::rollBack();
  140. // 下单失败提示
  141. return ['error'=>$result['error']];
  142. }
  143. }
  144. if ($coupon_id){
  145. $data = [
  146. 'coupon_id' => $coupon_id,
  147. 'custom_uid' => $uid,
  148. ];
  149. $result = (new CustomCoupon())->add($data);
  150. // 失败结束
  151. if( !$result ) {
  152. // 回退数据
  153. DB::rollBack();
  154. // 下单失败提示
  155. return ['error'=>'签到赠送优惠券失败'];
  156. }
  157. }
  158. //打卡签到记录
  159. $recordInfo = [
  160. 'custom_uid' => $uid,
  161. 'active_id' => $activeId,
  162. 'clockin_day' => $finishDay,
  163. 'clockin_time' => time(),
  164. 'score' => $reward,
  165. 'coupon_id' => $coupon_id,
  166. ];
  167. $re = (new CustomClockinRecord())->add($recordInfo);;
  168. // 失败结束
  169. if( !$re ) {
  170. // 回退数据
  171. DB::rollBack();
  172. // 下单失败提示
  173. return ['error'=>'打卡签到记录失败'];
  174. }
  175. // 提交数据
  176. DB::commit();
  177. // 打卡通过
  178. $isMark['is_clockin'] = 1;
  179. $isMark['finish_day'] = $finishDay;
  180. // 奖励返回
  181. $isMark['reward'] = $reward;
  182. $isMark['coupon'] = $coupon_id;
  183. // 返回打卡结果与奖励
  184. return $isMark;
  185. } catch (\Throwable $th) {
  186. // 回退数据
  187. DB::rollBack();
  188. // 下单失败提示
  189. return ['error'=>'打卡失败'];
  190. }
  191. }
  192. /**
  193. * 获取最大的打卡天数
  194. *
  195. */
  196. public function getMaxDay($activeId){
  197. // 查询数据
  198. $data = (new Clockin())->getActiveList($activeId);
  199. // 获取天数字段
  200. $days = array_column($data,'what_day');
  201. // 获取第一个
  202. $maxDay = $days ? max($days) : 0;
  203. // 返回结果
  204. return (int) $maxDay;
  205. }
  206. /**
  207. * 根据天数获取
  208. *
  209. */
  210. public function getOne($whatDay,$activeId=0,$field=''){
  211. // 获取列表数据
  212. $list = (new Clockin())->getActiveList($activeId);
  213. // 获取数据
  214. $one = isset($list[$whatDay]) ? $list[$whatDay] : [];
  215. // 返回值
  216. return empty($field) ? $one : ( isset($one[$field]) ? $one[$field] : null);
  217. }
  218. }