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 \n\r"; 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