0领取失败 $result = [ 'status' => 1, 'coupon_text' => '继续努力~' ]; // 错误日志记录 $errorData = [ 'coupon_ids' =>$ids, 'user_id' =>$userId, 'receiveType' =>$receiveType, 'sendUserId' =>$sendUserId, 'phone' =>$phone ]; $receiveSsdb = []; try{ Db::transaction( function() use ($ids,$receiveType,$userId,$sendUserId,$phone,$now,&$result,&$errorData,&$receiveSsdb) { $success = []; $fail = []; $isr = []; //读写锁,完全控制,性能低 $coupons = Coupon::whereIn('id', $ids)->lockForUpdate() ->select('id','title','status','inventory','inventory_use','start_time','end_time','full_amount','discounts','active_type') ->get(); foreach($coupons as $coupon){ $errorData['coupon_id'] = $coupon->id; //如果优惠卷库存小于等于已领取的数量 或者 未在活动时间内可领取, 否则返回领取失败的优惠券 if ( $coupon->status == 1 && $coupon->inventory > $coupon->inventory_use && $coupon->start_time <= $now && $coupon->end_time >= $now && $coupon->active_type == 2 ) { // 查询一次能领取的数量 $couponReceiveType = CouponUserRecType::where('system_coupon_user_id',$coupon->id)->select('one_receive_number'); if (env('SUB_CHANNEL') == 1) { $couponReceiveType->where('receive_type',$receiveType); } $couponReceiveType = $couponReceiveType->first(); // 优惠券可领取数量 >= 本次领取数量 if($coupon->inventory - $coupon->inventory_use >= $couponReceiveType->one_receive_number){ // 判断是否领取过 存在记录则领取过 $isReceive = CouponRec::select('id') ->where('system_coupon_user_id',$coupon->id) ->where('user_id',$userId) ->exists(); if(!$isReceive){ //记录已领取的数量 $coupon->inventory_use += $couponReceiveType->number; $couponReceive = new CouponRec; $couponReceive->user_id = $userId; $couponReceive->system_coupon_user_id = $coupon->id; $couponReceive->order_main_id = 0; $couponReceive->receive_time = $now; $couponReceive->number = $couponReceiveType->one_receive_number; $couponReceive->number_remain = $couponReceiveType->one_receive_number; $couponReceive->status = 0; $couponReceive->update_time = $now; $couponReceive->receive_type = $receiveType; $couponReceive->send_user_id = $sendUserId; $couponReceive->phone = $phone; // if ( $couponReceive->save() && $coupon->save() ) { // $success[] = $coupon; // $receiveSsdb[] = $coupon->id;; // } }else{ $fail[] = $coupon; $receiveSsdb[] = $coupon->id; $result['status'] = 2; $result['coupon_text'] = '您已领取!赶快去下单吧~'; $errorData['msg'] = '用户已经领取了优惠券'; $this->log->event( LogLabel::COUPON_LOG, $errorData ); } }else{ $fail[] = $coupon; $errorData['remain_receive_number'] = $coupon->inventory - $coupon->inventory_use; $errorData['one_receive_number'] = $couponReceiveType->one_receive_number; $errorData['msg'] = '优惠券剩余数量不足'; $this->log->event( LogLabel::COUPON_LOG, $errorData ); } }else{ $fail[] = $coupon; $errorData['msg'] = '优惠券已经过期或者被禁用或者已领完'; $this->log->event( LogLabel::COUPON_LOG, $errorData ); } } $result['data'] = [ 'success' => $success, 'fail' => $fail ]; if(count($success) > 0){ $result['status'] = 0; $result['coupon_text'] = '恭喜您领取成功!'; } }); } catch (Exception $e){ $errorData['msg'] = $e->getMessage(); $this->log->event( LogLabel::COUPON_LOG, $errorData ); } if(count($receiveSsdb) > 0){ $saveSsdb = []; foreach($receiveSsdb as $kssdb => $vssdb){ $saveSsdb[] = $kssdb; $saveSsdb[] = $vssdb; } // 记录到ssdb $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); if(false === $ssdb->exec('hset',SsdbKeysPrefix::COUPON_REBATE_RECEIVE.$userId,$saveSsdb)){ $errorData['msg'] = '记录领取优惠券到ssdb失败'; $this->log->event( LogLabel::COUPON_LOG, $errorData ); }; } return $result; } public function isCouponRebate($user_id) { $res = Db::table('ims_system_coupon_user as u') ->leftjoin('ims_system_coupon_user_receive as r','u.id','=','r.system_coupon_user_id') ->where([ ['r.user_id','=',$user_id], ['r.receive_type','=',4], ['u.active_type','=',2], ]) ->select('r.id') ->first(); return $res; } public function getActiveInfo() { $time = time(); $res = Db::table('ims_system_coupon_user') ->where([ ['status','=',1], ['active_type','=',2], ['start_time','<=',$time], ['end_time','>',$time], ]) ->whereRaw('inventory > inventory_use') ->orderBy('addtime','desc') ->get(); return $res; } }