CustomClockinRecord.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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]])->orderBy('id','desc')->first(['id','custom_uid','clockin_day','clockin_time']);
  99. // 如果没有记录
  100. if ($record){
  101. if ($record['clockin_time'] >= Carbon::now()->startOfDay()->getTimestamp()){
  102. $record = ['is_clockin'=>1,'finish_day'=>$record['clockin_day']];
  103. }elseif($record['clockin_time'] >= Carbon::now()->addDays(-1)->startOfDay()->getTimestamp()){
  104. $record = ['is_clockin'=>0,'finish_day'=>$record['clockin_day']];
  105. }else{
  106. $record = ['is_clockin'=>0,'finish_day'=>0];
  107. }
  108. }else{
  109. $record = ['is_clockin'=>0,'finish_day'=>0];
  110. }
  111. // 如果没有打卡天数
  112. // 标记
  113. //$this->setMarkClock($uid,$record);
  114. // 返回结果
  115. return $record;
  116. }
  117. /**
  118. * 打卡操作
  119. *
  120. * @param int $uid 用户ID
  121. *
  122. */
  123. public function finish($uid,$activeId)
  124. {
  125. // 获取打卡任务列表,并获取最大天数
  126. $maxDay = $this->getMaxDay($activeId);
  127. // 如果是0,没有需要签到的任务
  128. if( !$maxDay ) return ['error'=>'无签到任务'];
  129. // 是否已签到
  130. $isMark = $this->isMarkClock($uid,$activeId);
  131. // 如果已经签到,不进行后续操作,返回已打卡
  132. if( $isMark['is_clockin'] ) return ['error'=>'今日已打卡'];
  133. // 如果当前已签到天数大于最大天数,从1开始计算签到天数
  134. $finishDay = $isMark['finish_day'] >= $maxDay ? 1 : $isMark['finish_day'] +1;
  135. // 通过今日天数查找对应的打卡奖励
  136. $list = $this->getOne($finishDay,$activeId);
  137. if (!$list) return ['error'=>'今日签到没有奖励'];
  138. $reward = $list['reward'] ?? 0;
  139. $coupon_id = $list['coupon_id'] ?? 0;
  140. // 组合数据,写入订单表,子表
  141. DB::beginTransaction();
  142. // 写入数据
  143. try {
  144. // 成功继续
  145. if ($reward){
  146. $result = (new CustomScore())->trade($uid,0,$reward,2,$finishDay);
  147. // 失败结束
  148. if( isset($result['error']) ) {
  149. // 回退数据
  150. DB::rollBack();
  151. // 下单失败提示
  152. return ['error'=>$result['error']];
  153. }
  154. }
  155. if ($coupon_id){
  156. $result = (new CustomCoupon())->giveCoupon($coupon_id,$uid);
  157. // 失败结束
  158. if( !$result ) {
  159. // 回退数据
  160. DB::rollBack();
  161. // 下单失败提示
  162. return ['error'=>'签到赠送优惠券失败'];
  163. }
  164. }
  165. //打卡签到记录
  166. $recordInfo = [
  167. 'custom_uid' => $uid,
  168. 'active_id' => $activeId,
  169. 'clockin_day' => $finishDay,
  170. 'clockin_time' => time(),
  171. 'score' => $reward,
  172. 'coupon_id' => $coupon_id,
  173. ];
  174. $re = (new CustomClockinRecord())->add($recordInfo);;
  175. // 失败结束
  176. if( !$re ) {
  177. // 回退数据
  178. DB::rollBack();
  179. // 下单失败提示
  180. return ['error'=>'打卡签到记录失败'];
  181. }
  182. // 提交数据
  183. DB::commit();
  184. // 打卡通过
  185. $isMark['is_clockin'] = 1;
  186. $isMark['finish_day'] = $finishDay;
  187. // 奖励返回
  188. $isMark['reward'] = $reward;
  189. $isMark['coupon'] = $coupon_id;
  190. // 返回打卡结果与奖励
  191. return $isMark;
  192. } catch (\Throwable $th) {
  193. // 回退数据
  194. DB::rollBack();
  195. // 下单失败提示
  196. return ['error'=>'打卡失败'];
  197. }
  198. }
  199. /**
  200. * 获取最大的打卡天数
  201. *
  202. */
  203. public function getMaxDay($activeId){
  204. // 查询数据
  205. $data = (new Clockin())->getActiveList($activeId);
  206. // 获取天数字段
  207. $days = array_column($data,'what_day');
  208. // 获取第一个
  209. $maxDay = $days ? max($days) : 0;
  210. // 返回结果
  211. return (int) $maxDay;
  212. }
  213. /**
  214. * 根据天数获取
  215. *
  216. */
  217. public function getOne($whatDay,$activeId=0,$field=''){
  218. // 获取列表数据
  219. $list = (new Clockin())->getActiveList($activeId);
  220. // 获取数据
  221. $one = isset($list[$whatDay]) ? $list[$whatDay] : [];
  222. // 返回值
  223. return empty($field) ? $one : ( isset($one[$field]) ? $one[$field] : null);
  224. }
  225. }