1 <?php
2 /**
3 * create by jxkshu
4 * Date 2017-09-28
5 * 用户签到领取红包
6 */
7 /**
8 Redis
9 set: key signed:user:mark 标记已签到用户
10 val user_id
11
12 zset key signed:user:today:share:num 记录当天用户分享的次数,凌晨4点删除
13 score 分享的次数
14 val 用户ID
15 zset key signed:user:today:replenishment:num 记录当天用户已经补签的次数,凌晨4点删除
16 score 当天补签的次数
17 val 用户ID
18 */
19 header("content-type:text/html;charset=utf-8");
20 require_once('api.base.php');
21
22 class m_signed extends base
23 {
24 private $redis = null;
25 private $log_dir = null;
26
27 public function __construct(){
28 parent::__construct();
29
30 $this->init();
31 // parent::signer($_POST);
32 // parent::tokengoon($_POST);
33
34 // 连接redis
35 $this->redis = new MyRedis;
36 $this->redis = $this->redis->getRedisCli();
37
38 // 创建单个文件夹
39 $this->log_dir = __DIR__ . '/../log/return_red_envelope/signed/';
40 if(!is_dir($this->log_dir)):
41 mkdir($this->log_dir);
42 chmod($this->log_dir, 0777);
43 endif;
44 }
45
46
47 /**
48 * 用户 签到或者补签
49 * @param array $post 客户端传递的数据
50 * @return array 抢红包后的数据
51 */
52 public function signed($post){
53
54 parent::signer($_POST);
55 parent::tokengoon($_POST);
56 $user_id = (int)trim($post['user_id']);
57
58 // 延迟0.2秒,防并发
59 usleep(200000);
60 // 判断用户是签到还是补签
61 if( empty($post['type']) || $post['type']==0):
62 // 判断用户是否已签
63 $key = 'signed:user:mark';
64 if(($this->redis->sIsMember($key, $user_id))):
65 return ['status'=>'fail', 'msg'=>'已签到'];
66 else:
67 // 二次判断用户是否已经签到
68 $day_start = strtotime(date('Y-m-d 0:0:0',time()));
69 $day_end = strtotime(date('Y-m-d 0:0:0',time()))+86399;
70 $sql = "SELECT count(id) as total from sign_red_envelopes where uid=$user_id and time>=$day_start and time<=$day_end and amount>0";
71 $sign_num = (int) parent::result_first($sql);
72 if($sign_num>0):
73 return ['status'=>'fail', 'msg'=>'已签到'];
74 endif;
75 endif;
76 // 用户签到
77 $res = $this->userSigned($user_id, $post['time']);
78 else:
79 if( $post['time'] >= strtotime(date('Y-m-d 0:0:0'))):
80 return ['status'=>'fail', 'msg'=>'日期错误'];
81 endif;
82 $res = $this->userReplenishment($user_id, $post['time']);
83 endif;
84
85 if($res['status']=='fail'):
86 $this->writeLog(__FILE__, __LINE__, $res['msg']);
87 endif;
88 return $res;
89 }
90
91
92 /**
93 * 用户补签
94 * @param int $user_id 用户ID
95 * @param int $time 用户签到时间
96 * @return array status:状态、msg:信息、amount:奖励金额、replenishment_num:剩余可以补签的次数
97 */
98 protected function userReplenishment($user_id, $time){
99
100 // 获取用户当天已经补签的次数
101 $replenishment = $this->redis->zScore('signed:user:today:replenishment:num', $user_id);
102 // 获取用户当天线下消费额度
103 $tim = date('Ymd');
104 $sql = "SELECT sum(amount) as total_amount FROM payinfo where pay_dateint='$tim' and uid=$user_id and status=1 and is_ol_verify=0";
105 $total_amount = (int) parent::result_first($sql);
106
107 // 判断用户补签次数是否超出
108 $total_amount = (int) ($total_amount/58);
109 $replenishment = (int)$replenishment;
110 if( $total_amount<=$replenishment ):
111 return ['status'=>'fail', 'msg'=>'补签失败,消费额度不足!'];
112 endif;
113
114 // 补签次数累加1
115 $res = $this->redis->zIncrBy('signed:user:today:replenishment:num', 1, $user_id);
116 if(empty($res)):
117 return ['status'=>'fail', 'msg'=>'补签次数累加失败!'];
118 endif;
119
120 //获取用户补签奖励金额
121 $amount = mt_rand(50, 100) / 100;
122
123 // 记录用户补签信息
124 $data = [
125 'uid' => $user_id,
126 'type' => 1,
127 'amount' => $amount,
128 'time' => $time,
129 ];
130 $res = parent::insert('sign_red_envelopes', $data);
131 if(empty($res)):
132 return ['status'=>'fail', 'msg'=>'写入补签红包记录数据库失败!'];
133 endif;
134
135 // 累加用户签到奖励
136 $sql = "UPDATE userinfo SET sign_reward=(sign_reward+$amount),total_sign_reward=(total_sign_reward+$amount) where id=$user_id limit 1";
137 $res = parent::query($sql);
138 if(empty($res)):
139 return ['status'=>'fail', 'msg'=>'累加用户补签奖励失败!'];
140 endif;
141 return ['status'=>'success', 'msg'=>'用户补签成功', 'amount'=>$amount, 'replenishment_num'=>($total_amount-$replenishment)];
142 }
143
144
145
146 /**
147 * 用户签到
148 * @param int $user_id 用户ID
149 * @param int $time 用户签到时间
150 * @return array
151 */
152 protected function userSigned($user_id, $time){
153
154 // 获取签到奖励金额
155 $amount = self::getSignedAmount($user_id);
156 $data = [
157 'uid' => $user_id,
158 'amount' => $amount,
159 'time' => $time,
160 ];
161 $res = parent::insert('sign_red_envelopes', $data);
162 if(empty($res)):
163 return ['status'=>'fail', 'msg'=>'写入签到红包记录数据库失败!'];
164 endif;
165
166 // 累加用户签到奖励
167 $sql = "UPDATE userinfo SET sign_reward=(sign_reward+$amount),total_sign_reward=(total_sign_reward+$amount) where id=$user_id limit 1";
168 $res = parent::query($sql);
169 if(empty($res)):
170 return ['status'=>'fail', 'msg'=>'累加用户签到奖励失败!'];
171 endif;
172
173 // 标记用户已经签到
174 $res = $this->redis->sAdd('signed:user:mark', $user_id);
175 return ['status'=>'success', 'amount'=>$amount];
176 }
177
178
179 /**
180 * 获取用户签到奖励金额
181 * @param int $user_id
182 * @return float 奖励金额
183 */
184 protected static function getSignedAmount($user_id){
185
186 // 判断用户是不是第一次签到
187 $sql = "SELECT count(id) as total FROM sign_red_envelopes where uid=$user_id limit 1";
188 $total = parent::result_first($sql);
189
190 // 获取签到奖励金额
191 if(empty($total)):
192 // 首次签到
193 $amount = mt_rand(1,2);
194 else:
195 //提升红包额度
196 $sql = "SELECT share_num from userinfo where id=$user_id limit 1";
197 $share_num = parent::result_first($sql);
198 $share_num = ($share_num>20 ? 20 : $share_num);
199 $min = (0.1 + (0.1 * ($share_num*0.1))) * 100;
200 $max = (1 + (1*($share_num*0.05))) * 100;
201 $max = ($max>200 ? 200 : $max);
202
203 $amount = mt_rand($min, $max) / 100;
204 $amount = number_format($amount, 2);
205 endif;
206
207 return $amount;
208 }
209
210
211 // -------------------------------- 用户将奖励提转到58券
212
213
214 /**
215 * 用户将奖励提转到58券
216 * @param array $post=>user_id 用户id
217 * @return array
218 */
219 public function rewardTo58voucher($post){
220
221 parent::signer($_POST);
222 parent::tokengoon($_POST);
223 // 获取用户已经累计的签到红包
224 $sql = 'SELECT id,sign_reward FROM userinfo WHERE id='.$post['user_id'].' limit 1';
225 $userinfo = parent::fetch_first($sql);
226 if($userinfo['sign_reward']<20):
227 return ['errcode'=>'44','msg'=>'代金券未满20'];
228 endif;
229
230 // 红包转换成58券
231 $sql='UPDATE userinfo SET sign_reward=0, red_reward=(red_reward+'.$userinfo['sign_reward'].') WHERE id='.$post['user_id'].' LIMIT 1';
232 $res = parent::query($sql);
233 if(empty($res)):
234 return ['errcode'=>'3','msg'=>'服务器异常!'];
235 endif;
236 // 记录行为到红包
237 $tim = time();
238 $data = [
239 'uid'=>$post['user_id'],
240 'orderid'=>'',
241 'amount'=>$userinfo['sign_reward'],
242 'packet_status'=>1,
243 'receive_time'=>date('Y-m-d H:i:s', $tim),
244 'packet_type'=>6,
245 'add_time'=>date('Y-m-d H:i:s', $tim),
246 'dateint'=>date('Ymd', $tim),
247 ];
248 $res = parent::insert('redpacket', $data);
249 if(empty($res)):
250 return ['errcode'=>'400','msg'=>'提转成功!但记录提转信息失败!'];
251 endif;
252 return ['errcode'=>0,'msg'=>'提转成功!'];
253 }
254
255
256 /**
257 * 获取剩余补签次数
258 * @param int $user_id 用户ID
259 * @return array
260 */
261 public function getSignCard($user_id){
262
263 parent::signer($_POST);
264 parent::tokengoon($_POST);
265 // 获取用户当天已经补签的次数
266 $replenishment = $this->redis->zScore('signed:user:today:replenishment:num', $user_id);
267 // 获取用户当天线下消费额度
268 $tim = date('Ymd');
269 //$sql = "SELECT sum(amount) as total_amount FROM payinfo where pay_dateint='$tim' and uid=$user_id and status=1 and (order_type=0 or order_type=4)";
270 $sql = "SELECT sum(amount) as total_amount FROM payinfo where pay_dateint='$tim' and uid=$user_id and status=1 ";
271
272 $total_amount = (int) parent::result_first($sql);
273
274 // 判断用户补签次数是否超出
275 $total_amount = (int) ($total_amount/58);
276 $replenishment = (int) $replenishment;
277
278 return ['card_num'=>($total_amount - $replenishment)];
279 }
280
281
282 // 用户分享朋友圈来提升签到红包额度
283 public function userShareAppToPeople($user_id){
284
285 parent::signer($_POST);
286 // 将分享次数暂时记录到redis,每天凌晨定时任务在写入数据库
287 $key = 'signed:user:today:share:num';
288 $res = $this->redis->zIncrBy($key, 1, $user_id);
289 return ['signed_num'=>$res];
290 }
291
292
293 // 写日志
294 private function writeLog($fil, $row, $remarks=''){
295 $file = $this->log_dir . 'signed-'.date('Y-m').'.txt';
296 $content = $fil.' Line ' . $row . ' failed '.date('Y-m-d H:i:s')." $remarks
";
297 file_put_contents($file, $content, FILE_APPEND);
298 }
299
300
301
302
303 //---------------------------- 获取用户签到界面的信息
304
305 public function getSignPageInfo($post){
306
307 parent::signer($_POST);
308 parent::tokengoon($_POST);
309 $user_id = parent::parseuid($post);
310 $data = [];
311
312 // 分享URL
313 $tim = time();
314 $salt = '58_life_circle_sign_share';
315 $sign = mb_strcut(md5('58_life_circle_sign_share'.$tim), 0, 6, 'utf8');
316 $data['share_url'] = 'http://api.licheepay.com/lzf/html/sign_share/h5.html?uid='.$user_id.'&time='.$tim.'&sign='.$sign;
317 // 广告图
318 $data['header_advert'] = [
319 // [
320 // 'img'=> 'http://adm.licheepay.com/upload/mall/1509331172.png',
321 // 'url'=> 'app_web_$$$https://s.click.taobao.com/7IlNyYw$$$',
322 // ],
323 // [
324 // 'img'=> 'http://adm.licheepay.com/upload/mall/1509523936.png',
325 // 'url'=> 'app_web_>>>http://mp.weixin.qq.com/s/BDSD_jDgCmMxfCdieLxtxg<<<',
326 // ],
327 [
328 'img'=> 'http://adm.licheepay.com/upload/img/ad/20170508161142.png',
329 'url'=> 'app_web_>>>http://mp.weixin.qq.com/s/BDSD_jDgCmMxfCdieLxtxg<<<',
330 ],
331
332 ];
333 // 获取累计签到奖励
334 $sql = 'SELECT sign_reward,total_sign_reward FROM userinfo WHERE id='.$user_id.' limit 1';
335 $temp_user_sign = parent::fetch_first($sql);
336 $data['sign_reward'] = $temp_user_sign['sign_reward'];
337 $data['total_sign_reward'] = $temp_user_sign['total_sign_reward'];
338
339 // 签到奖励提取状态【是否可提取】
340 $data['extract_status'] = 0;
341 if($temp_user_sign['sign_reward']>=20):
342 $data['extract_status'] = 1;
343 endif;
344
345
346 // 签到说明
347 $data['sign_explain'] = '1、签到后可抢代金券红包,满20券可用
348 2、用户每天可签到一次,每次可获得随机劵奖励
349 3、代金券每月15号自动清零,满20券请及时领取
350 4、线下消费满58元,可手动补签1次,当天有效
351 5、签到后分享好友,好友参与可提高次日红包金额';
352
353 // 签到状态
354 // 判断用户是否已签
355 $data['signed_status'] = 0;
356 $key = 'signed:user:mark';
357 if(($this->redis->sIsMember($key, $user_id))):
358 $data['signed_status'] = 1;
359 endif;
360 // // 二次判断用户是否已经签到 2017-11-01屏蔽
361 $day_start = strtotime(date('Y-m-d 0:0:0',time()));
362 $day_end = strtotime(date('Y-m-d 0:0:0',time()))+86399;
363 $sql = "SELECT count(id) as total from sign_red_envelopes where uid=$user_id and time>=$day_start and time<=$day_end and amount>0";
364 $sign_num = (int) parent::result_first($sql);
365 if($sign_num<1):
366 $data['signed_status'] = 0;
367 else:
368 $data['signed_status'] = 1;
369 endif;
370
371
372 // 时间戳
373 $data['time'] = time();
374 return $data;
375 }
376
377
378
379 // 获取用户签到信息日历
380 public function getUserSignInfoCalendar($post){
381
382 parent::signer($_POST);
383 parent::tokengoon($_POST);
384 $user_id = parent::parseuid($post);
385
386 // 当前月份
387 $total_day = date('t');
388 $current_month = date('m');
389 $first_day = strtotime(date("Y-m-01"));
390 $last_day = $first_day + ($total_day*86400) - 1;
391 $sql = "SELECT FROM_UNIXTIME(time,'%e') as day,type
392 FROM sign_red_envelopes
393 WHERE uid=$user_id and time>=$first_day and time<=$last_day";
394 //获取用户签到信息
395 $sign_info = parent::fetch_all($sql);
396 // 获取用户补签卡
397 $card_num = $this->getSignCard($user_id);
398 $card_num = $card_num['card_num'];
399
400 $today = date('d');
401 // 1:未签、 2:已签到、3:已补签 4:可补签、 5:漏签、 6:不可签、
402 $temp_current = [];
403 for ($i=$total_day; $i>0; $i--) {
404 $status = 0;
405 // 签到或者补签
406 foreach ($sign_info as $sign) {
407 if($sign['day']==$i):
408 $status = empty($sign['type']) ? 2 : 3;
409 break;
410 endif;
411 }
412 // 1:未签
413 if($status==0 && $i==$today):
414 $status = 1;
415 endif;
416 //4:可补签
417 if($status==0 && $i<$today && $card_num>0):
418 $status = 4;
419 $card_num--;
420 endif;
421 // 6:不可签
422 if($status==0 && $i>$today):
423 $status = 6;
424 endif;
425 // 5:漏签
426 if($status==0):
427 $status = 5;
428 endif;
429 $temp_current[$i] = $status;
430 }
431
432
433 // 上月份
434 $last_month = date('m', time()) - 1;
435 if( $last_month<1 ):
436 $last_month = 12;
437 $time_str = (date('Y',time()) - 1) . '-12-01';
438 $total_day = date('t', strtotime($time_str));
439 $first_day = strtotime($time_str);
440 $last_day = $first_day + ($total_day*86400) - 1;
441 else:
442 $time_str = date('Y',time()) .'-'.$last_month.'-01';
443 $total_day = date('t', strtotime( $time_str));
444 $last_month = date('m', strtotime( $time_str));
445 $first_day = strtotime( $time_str);
446 $last_day = $first_day + ($total_day*86400) - 1;
447 endif;
448 $sql = "SELECT FROM_UNIXTIME(time,'%e') as day,type
449 FROM sign_red_envelopes
450 WHERE uid=$user_id and time>=$first_day and time<=$last_day";
451 //获取用户签到信息
452 $sign_info = parent::fetch_all($sql);
453 // 2:已签到、3:已补签 4:可补签、 5:漏签、
454 $temp_last = [];
455 for ($i=$total_day; $i>0; $i--) {
456 $status = 0;
457 // 签到或者补签
458 foreach ($sign_info as $sign) {
459 if($sign['day']==$i):
460 $status = empty($sign['type']) ? 2 : 3;
461 endif;
462 }
463 //可补签
464 if($status==0 && $card_num>0):
465 $status = 4;
466 $card_num--;
467 endif;
468 // 5:漏签
469 if($status==0):
470 $status = 5;
471 endif;
472
473 $temp_last[$i] = $status;
474 }
475
476
477 ksort($temp_current); //当前月份
478 ksort($temp_last); //上月份
479 $data = [
480 [
481 'month'=>$current_month,
482 'status' =>array_values($temp_current)
483 ],
484 [
485 'month' =>$last_month,
486 'status'=>array_values($temp_last)
487 ],
488 ];
489 return $data;
490 }
491
492
493 }//end