love_php/app/Http/Controllers/RedPacketActivityController.php
2026-04-02 09:20:51 +08:00

525 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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('参加活动人数过多');
}
}
}