love_php/app/Http/Controllers/RedPacketActivityController.php

525 lines
19 KiB
PHP
Raw Normal View History

2026-04-02 09:20:51 +08:00
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Participant;
use App\Models\FruitHistory;
use App\Models\SendNewYearPacketNotice;
use Illuminate\Support\Facades\Cache;
use App\Jobs\ParticipantShareNotice;
use App\Jobs\ParticipantAddShare;
use App\Jobs\ParticipantPickUpRedPacket;
use App\Jobs\ParticipantPickUpFinalRedPacket;
use App\Utils\Str;
use App\Repositories\Eloquent\SmsRepository as Sms;
use App\Models\ParticipantRedPacket;
use App\Jobs\SendServiceNews;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
USE App\Jobs\PartcipantSecondFinalPacket;
class RedPacketActivityController extends Controller
{
protected $sms;
public function __construct(Sms $sms)
{
$this->sms = $sms;
}
//活动进度接口
public function userActivityFruit(Request $request)
{
//公众号openid
$official_openid = $request->input('official_openid');
$from_official_openid = $request->input('from_official_openid');
//参与者
$participant = $this->getParticipant($official_openid);
if (empty($participant)) {
$is_auth = 0;
return $this->success('ok', compact('participant', 'is_auth'));
}
$key = Participant::PART_KEY;
$key = $key.$official_openid;
//是否关注公众号
$subscribe = User::hasSubscribeOfficialWithOpenid($official_openid);
if ($subscribe != $participant->subscribe) {
$participant->subscribe = $subscribe;
$participant->save();
Cache::forever($key, $participant);
}
//已授权
$is_auth = 1;
$result = $this->activityTime();
$start_pick_up_packet = $result['start_pick_up_packet'];
$end_pick_up_fruit = $result['end_pick_up_fruit'];
/* if(in_array($official_openid , ['okaDW0y9vmK5P1URU40PrYWjL2SA','okaDW0xC88hHhXfMEy8BZRtJAyUg'])){
$end_pick_up_fruit = '2020-01-25 00:00:00';
//start_pick_up_packet 红包开启时间
$start_pick_up_packet = '2020-01-25 18:00:00';
}*/
return $this->success('ok', compact('participant', 'is_auth', 'start_pick_up_packet', 'end_pick_up_fruit'));
}
public function activityTime()
{
if (config('app.env') == 'local') {
//end_pick_up_fruit 果子领取结束时间
$end_pick_up_fruit = '2020-01-25 00:00:00';
//start_pick_up_packet 红包开启时间
$start_pick_up_packet = '2020-01-25 20:00:00';
}else{
//end_pick_up_fruit 果子领取结束时间
$end_pick_up_fruit = '2020-02-25 00:00:00';
//start_pick_up_packet 红包开启时间
$start_pick_up_packet = '2020-02-25 20:00:00';
}
return compact('end_pick_up_fruit', 'start_pick_up_packet');
}
/**
* 获取果实
*/
public function pickUpFruit(Request $request)
{
$result = $this->activityTime();
$end_pick_up_fruit = $result['end_pick_up_fruit'];
if (date('Y-m-d H:i:s') > $end_pick_up_fruit) {
return $this->failure('收集果子时间已到,暂无法继续收集');
}
//分享人openid
$from_official_openid = $request->input('from_official_openid');
//公众号openid
$official_openid = $request->input('official_openid');
//参与者
$participant = $this->getParticipant($official_openid);
if (empty($participant) || ($participant && $participant->chance <= 0)) {
return $this->failure('暂无获取果实机会,请继续邀请好友获取更多果实!');
}
//分享者更新数据
if (!empty($from_official_openid) && $from_official_openid != $official_openid && empty($participant->is_helper)) {
$result = $this->participantAddChanceAndNotice($from_official_openid, $participant);
}
//添加参与者添加果实
$participant = $this->participantAddFruit($participant);
return $this->success('ok', $participant);
}
/**
* 参与者
*/
public function getParticipant($official_openid)
{
$key = Participant::PART_KEY;
$key = $key.$official_openid;
// if (Cache::has($key)) {
// $participant = Cache::get($key);
// }else{
$participant = Participant::where('official_openid', $official_openid)->first();
if (empty($participant)) {
return $participant;
}
Cache::forever($key, $participant);
// }
return $participant;
}
//分享者添加获取果子的机会和通知
public function participantAddChanceAndNotice($official_openid, $partner)
{
$participant = $this->getParticipant($official_openid);
if (empty($participant)) {
return false;
}
//添加获取果实机会
$this->participantAddChance($participant);
//添加一次分享记录
$this->participantAddShare($participant, $partner);
//发送一次分享模板消息
$this->sendParticipantShareNotice($participant, $partner);
return;
}
/**
* 模板消息通知
*/
public function sendParticipantShareNotice($participant, $partner)
{
$array = [
'participant'=>$participant->toArray(),
'participant_helper'=>$partner->toArray(),
];
ParticipantShareNotice::dispatch($array)->onQueue('love');
}
/**
* 添加分享记录
*/
public function participantAddShare($participant, $partner)
{
$array = [
'participant'=>$participant,
'partner'=>$partner,
];
//创建分享任务
ParticipantAddShare::dispatch($array)->onQueue('love');
}
/**
* 添加获取果实机会
*/
public function participantAddChance($participant)
{
$key = Participant::PART_KEY;
$key = $key.$participant->official_openid;
// \DB::beginTransaction();
try{
//添加一次机会
$participant->increment('chance', 1);
//更新緩存
Cache::forever($key, $participant);
// \DB::commit();
} catch (\Exception $e) {
// \DB::rollback();
}
if ($participant->fruit_num + $participant->chance == 9) {
//如果是第三个果子时,客服通知
$this->sendNinthFruitNotice($participant);
}
return $participant;
}
/**
* 获取果实
*/
public function participantAddFruit($participant)
{
$key = Participant::PART_KEY;
$key = $key.$participant->official_openid;
// \DB::beginTransaction();
try {
//添加一次果实并且减少一次机会
$participant->increment('fruit_num', 1);
$participant->decrement('chance', 1);
$participant->is_helper = 1;
$participant->save();
//更新緩存
Cache::forever($key, $participant);
// \DB::commit();
} catch (\Exception $e) {
// \DB::rollback();
}
return $participant;
}
/**
* 发送第九个果子机会时的客服消息
*/
public function sendNinthFruitNotice($participant)
{
$text = $this->getNinthFruitServiceText($participant);
$array = [
'official_openid'=>$participant->official_openid,
'text'=>$text,
];
SendServiceNews::dispatch($array)->onQueue('love');
}
public function getNinthFruitServiceText($participant)
{
$nickname = $participant->nickname?:'你好';
$url = env('APP_URL').'/red/packet/activity/wechat/auth';
$text = $nickname.',恭喜您!已有8个好友为您助力您可以获得瓜分大奖的机会<a href="'.$url.'">立即领取GO!</a>
温馨提示:果子数目越多,瓜分的金额越大哦。继续邀请好友助力集果。';
return $text;
}
/**
* 助力人列表
*/
public function shareHistorites(Request $request)
{
$is_auth = 1;
$official_openid = $request->official_openid;
//参与人
$participant = $this->getParticipant($official_openid);
//获取好友助力列表
$share_list = $this->getShareHistories($participant);
return $this->success('ok', compact('is_auth', 'share_list', 'participant'));
}
/**
* 获取好友助力列表
*/
public function getShareHistories($participant)
{
$key = Participant::PART_SHARE_KEY;
$key = $key.$participant->official_openid;
// if (Cache::has($key)) {
// $share_list = Cache::get($key);
// }else{
$share_list = FruitHistory::where('participant_id', $participant->id)->with('participant_helper')->orderBy('id','desc')->paginate(10);
Cache::forever($key, $share_list);
// }
return $share_list;
}
/**
* 领三个果子时的红包
*/
public function pickUpRedPacket(Request $request)
{
return $this->failure('活动已结束');
//当前时间
if (time() >= strtotime('2020-02-25')) {
return $this->failure('收集果子时间已到,暂无法继续收集');
}
$is_auth = 0;
$participant_count = Participant::where('mobile', $request->mobile)->count();
if($participant_count){
return $this->failure("手机号码已被使用");
}
$official_openid = $request->input('official_openid');
if (empty($official_openid)) {
return $this->success('ok', compact('is_auth'));
}
$participant = $this->getParticipant($official_openid);
if (empty($participant)) {
return $this->success('ok', compact('is_auth'));
}
//检测参与者资格
$result = $this->checkParticipant($request, $participant);
if ($result) {
return $this->failure($result);
}
//红包金额
if (date("Y-m-d H:i:s") < '2020-1-15') {
$amount = 0.30;
}else{
$amount = 0.35;
}
$array = [
'mobile'=>$request->mobile,
'participant'=>$participant,
'amount'=>$amount,
];
//领红包
ParticipantPickUpRedPacket::dispatch($array)->onQueue('love');
$is_auth = 1;
return $this->success('ok', compact('is_auth', 'amount'));
}
/**
* 检测参与者是否有领红包资格
*/
public function checkParticipant($request, $participant)
{
//是否关注公众号
$subscribe = User::hasSubscribeOfficialWithOpenid($participant->official_openid);
if (empty($subscribe)) {
return '你还未关注公众号';
}
//是否有机会打到三个果子
if ($participant->fruit_num < 3) {
$num = 3 - $participant->fruit_num;
return '您的果子数还差'.$num.'个才能领取红包';
}
//是否已经领取过
if ($participant->mobile || $participant->is_pick_up) {
return '您已经领取过红包,请继续完成任务';
}
$mobile = $request->input('mobile');
//判断手机号
$is_mobile = Str::isMobile($mobile);
if (empty($is_mobile)) {
return '手机号格式有误';
}
//验证码
$code = $request->input('code');
if (empty($code)) {
return '请输入验证码';
}
//检验验证码
$result = $this->sms->check($mobile, $code);
return $result;
}
/**
* 领取最后的红包
*/
public function pickUpFinalRedPacket(Request $request)
{
// if (date('Y-m-d H:i:s') < "2020-2-25 20:00:00" || date('Y-m-d H:i:s') > '2020-3-1 08:00:00') {
// return $this->failure('开奖时间未到');
// }
return $this->failure('活动已结束');
$official_openid = $request->input('official_openid');
$participant = $this->getParticipant($official_openid);
if (empty($participant)) {
$is_auth = 0;
return $this->success('ok', compact('is_auth', 'participant'));
}
//检查条件
$result = $this->checkFinalParticipant($participant);
if ($result) {
return $this->failure($result);
}
// if (date('Y-m-d H:i:s') > "2020-1-14 10:00:00" && date('Y-m-d H:i:s') < "2020-1-15") {//测试环境
// $packet = ParticipantRedPacket::whereNull('participant_id')->orderBy('id', 'asc')->first();
// }else{
// $packet = $this->getFinalPacket($participant);
// }
$packet = $this->getFinalPacketV2($participant);
if (empty($packet)) {
return $this->failure('领取红包失败');
}
$array = [
'participant'=>$participant,
'packet'=>$packet,
];
if (!is_array($packet)) {
// ParticipantPickUpFinalRedPacket::dispatch($array)->onQueue('love');
}
//领红包
Redis::setnx($official_openid.'_fruit', 1);
return $this->success('ok', $packet);
}
public function getFinalPacket($participant)
{
$fruit_num = $participant->fruit_num;
if ($fruit_num >= 9 && $fruit_num < 12) {
$packet = ParticipantRedPacket::whereNull('participant_id')->where('price', '<=', Participant::FIRST_MAX_MONEY)->first();
}elseif ($fruit_num >= 12 && $fruit_num < 20) {
$packet = ParticipantRedPacket::whereNull('participant_id')->whereBetween('price', [Participant::SECOND_MIN_MONEY,Participant::SECOND_MAX_MONEY])->first();
}elseif ($fruit_num >= 20 && $fruit_num < 50) {
$packet = ParticipantRedPacket::whereNull('participant_id')->whereBetween('price', [Participant::THIRD_MIN_MONEY,Participant::THIRD_MAX_MONEY])->first();
}elseif ($fruit_num >= 50) {
$packet = ParticipantRedPacket::whereNull('participant_id')->where('price', '>', Participant::FOURTH_MIN_MONEY)->first();
}
return $packet;
}
public function getFinalPacketV2($participant)
{
$fruit_num = FruitHistory::where('created_at', '>=', '2020-2-1')->where('created_at', '<', '2020-2-25')->where('participant_id', $participant->id)->count();
if ($fruit_num >= 9 && $fruit_num < 12) {
$packet = ParticipantRedPacket::whereNull('participant_id')->where('price', '<=', Participant::FIRST_MAX_MONEY)->first();
}elseif ($fruit_num >= 12 && $fruit_num < 20) {
$packet = ParticipantRedPacket::whereNull('participant_id')->whereBetween('price', [Participant::SECOND_MIN_MONEY,Participant::SECOND_MAX_MONEY])->first();
}elseif ($fruit_num >= 20 && $fruit_num < 50) {
$packet = ParticipantRedPacket::whereNull('participant_id')->whereBetween('price', [Participant::THIRD_MIN_MONEY,Participant::THIRD_MAX_MONEY])->first();
}elseif ($fruit_num >= 50) {
$packet = ParticipantRedPacket::whereNull('participant_id')->where('price', '>', Participant::FOURTH_MIN_MONEY)->first();
}else{
// $packet = ParticipantRedPacket::whereNull('participant_id')->where('price', '<=', Participant::FIRST_MAX_MONEY)->first();
//随机生成红包
// $packet = $this->randParticipantPacket($participant);
}
return $packet;
}
public function randParticipantPacket($participant)
{
$trade_no = \CommonUtilsService::getTradeNO();
$packet = [
'participant_id' => $participant->id,
'price'=>'0.'.rand(3, 9),
'trade_no'=>$trade_no,
'created_at'=>date('Y-m-d H:i:s'),
'updated_at'=>date('Y-m-d H:i:s'),
];
$packet['official_openid'] = $participant->official_openid;
$this->giveRandParticipantPacket($packet);
return $packet;
}
public function giveRandParticipantPacket($packet)
{
$official_openid = $$packet['official_openid'];
unset($packet['official_openid']);
ParticipantRedPacket::insert($packet);
// $result = \WechatService::officialUserTransfer($packet['trade_no'], $official_openid, $packet['price']*100, "第二轮九果红包");
if ($result) {//转账红包失败
$return_msg = $result['return_msg'];
$packet['err_message'] = $return_msg;
$packet['is_hook'] = -1;
//抛出错误
// throw new \Exception("微信转账失败", 1);
}else{
$packet['is_hook'] = 1;
}
return;
}
/**
* 检查是否符合最后领红包资格
*/
public function checkFinalParticipant($participant){
//检查开始时间
//是否关注公众号
$subscribe = User::hasSubscribeOfficialWithOpenid($participant->official_openid);
if (empty($subscribe)) {
return '你还未关注公众号';
}
//是否集齐九个果子
// if ($participant->fruit_num < 9) {
// return '您的果子数未集齐,暂不能领红包';
// }
//上一次集齐
$last_fruit_num = FruitHistory::where('created_at', '<','2020-01-24')->where('participant_id', $participant->id)->count();
$result = ($last_fruit_num >= 8 && $participant->is_final_pick_up == 0);
//这个月是否集齐
$fruit_num = FruitHistory::where('created_at', '>=', '2020-2-1')->where('created_at', '<', '2020-2-25')->where('participant_id', $participant->id)->count();
if ($fruit_num< 8 && !$result) {
return '您本月未达到9个果子不能领取红包。';
}
//这个月是否领取
$red_packet = ParticipantRedPacket::where('created_at', '>=', '2020-2-1')->where('created_at', '<', '2020-3-1')->where('participant_id', $participant->id)->count();
if ($red_packet) {
return '您已经领取过最终的红包';
}
//是否已经领取
// $is_received = Redis::get($participant->official_openid.'_fruit');
// if ($participant->is_final_pick_up || $is_received) {
// return '您已经领取过最终的红包';
// }
return false;
}
/**
* 领取九果红包列表
*/
public function redPcaketList(Request $request){
try{
$list = Participant::select('id', 'nickname', 'avatar', 'fruit_num')->where('fruit_num', '!=', 0)->limit(50)->offset(0)->orderBy('fruit_num', 'desc')->orderBy('updated_at', 'DESC')->get();
return $this->success('ok', $list);
}catch (\Exception $e){
return $this->failure('参加活动人数过多');
}
}
/**
* 九果助力排行榜
*/
public function shareRank(Request $request){
try{
$list = Participant::select(DB::raw('fruit_num as participant_share_count'), 'nickname', 'avatar')
->where('fruit_num', '>', 0)->whereNotIn('id', [2,6,8,10,12,13,147,5891,])->orderBy('participant_share_count', 'desc')->orderBy('updated_at', 'desc')->paginate(10)->toArray();
return $this->success('ok', $list);
}catch (\Exception $e){
return $this->failure('参加活动人数过多');
}
}
}