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

465 lines
21 KiB
PHP

<?php
namespace App\Http\Controllers\Server\Admin;
use App\Jobs\SendTemplateMsg;
use App\Models\ConsultAccount;
use App\Models\Consultation;
use App\Models\Course\Course;
use App\Models\Course\UserCourses;
use App\Models\Server\MerchantAccount;
use App\Models\Server\MerchantEvaluate;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\MerchantShop;
use App\Models\Server\CollageGroup;
use App\Models\Server\CollageGroupBatch;
use App\Models\Server\CollageGroupHistories;
use App\Models\CommunityActivity;
use App\Models\Server\MerchantUser;
use App\Models\Server\TouristOrder;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use function foo\func;
class CollageGroupController extends Controller
{
//拼团控制器
//创建拼团信息
public function createCollageGroup(Request $request){
$m_id = $request->account_id;
$type = $request->type;
$type_id = $request->type_id;
switch ($type) {
case 'community':
case 'service':
$result = CommunityActivity::where('merchant_id',$m_id)->where('id',$type_id)->first();
break;
case 'shop':
$result = MerchantShop::where('merchant_id',$m_id)->where('id',$type_id)->first();
break;
case 'course':
$result = Course::where('merchant_id',$m_id)->where('id',$type_id)->first();
break;
case 'consult':
$result = Consultation::find($type_id);
$result->merchant_id = ConsultAccount::where('id',$result->consult_account_id)->value('merchant_id');
break;
case 'evaluate':
$result = MerchantEvaluate::find($type_id);
break;
default:
return $this->failure('类型不存在或不受支持');
break;
}
if(!$result){
return $this->failure('服务不存在');
}
$merchant = MerchantAccount::find($request->account_id);
$is_exist = $merchant->checkCollageGroup($result);;
if($is_exist) return $this->failure('你选择的商品已存在拼团信息,请勿重复创建');
$price = $request->price;
$describe = $request->describe;
$require_num = $request->require_num ?? 2;
$num = $request->num ?? 1;
$sku = $request->sku;
$start_time = $request->start_time;
$end_time = $request->end_time;
if($start_time > $end_time) return $this->failure('成团开始时间需要小于成团结束时间');
$expire_in = $request->expire_in;
if(!$type || !$type_id || !$describe || !$start_time || !$end_time || !$sku || !$expire_in)
return $this->failure('完善表单信息');
if($type == 'community'){
if($result->class == 'one' && $result->apply_deadline < $end_time)
return $this->failure('成团结束时间必须小于活动截止报名时间');
}
$array = [
'price' => $price,
'describe' => $describe,
'require_num' => $require_num,
'num' => $num,
'sku' => json_encode($sku),
'start_time' => $start_time,
'end_time' => $end_time,
'expire_in' => $expire_in,
'type' => $type,
'type_id' => $type_id,
];
$collage = $merchant->addCollageGroup($result,$array);
return $this->success('ok');
}
//获取当前拼团商品信息
public function goodDetail(Request $request){
$type = $request->type;
$type_id = $request->type_id;
if($type == 'community' || $type=='service'){
$result = CommunityActivity::where('id',$type_id)->select('id','title','sku','price')->first();
}elseif($type == 'shop'){
$result = MerchantShop::where('id',$type_id)->select('id','title','sku','price')->first();
}elseif($type == 'course'){
$result = Course::where('merchant_id',$request->account_id)->where('id',$type_id)->first();
}elseif($type == 'consult'){
$result = Consultation::where('id',$type_id)->first();
}
if($result && $result->sku){
$result->sku = json_decode($result->sku,true);
}
return $this->success('ok',$result);
}
//修改拼团
public function setGroup(Request $request,$group_id){
$group = CollageGroup::find($group_id);
try {
if(!$group) return $this->failure('拼团信息不存在,无法修改');
if($request->has('describe')) {
$group->describe = $request->describe;
}
$time = date('Y-m-d H:i:s');
if($request->has('require_num') && $request->require_num != $group->require_num) {
$result = CollageGroupHistories::whereHas('tOrder', function($sql){
$sql->whereIn('pay_status',[1,4]);
})->where('group_id',$group_id)->where('status',0)->where('deadline','>',$time)->first();
if($result) return $this->failure('该活动目前存在未完成拼团,暂不支持修改');
$group->require_num = $request->require_num;
}
if($request->has('expire_in')) {
$group->expire_in = $request->expire_in;
}
if($request->has('start_time')) {
$group->start_time = $request->start_time;
}
if($request->has('end_time')){
$group->end_time = $request->end_time;
if($request->start_time && $request->end_time && $request->start_time > $request->end_time)
return $this->failure('成团开始时间需要小于成团结束时间');
}
if($request->input('sku')) {
$min_price = [];
$group->sku = json_encode($request->sku);
foreach ($request->sku as $key => $skus) {
$min_price[] = $skus['discount_price'];
}
//取最低价格为展示价
$group->price = min($min_price);
}
if($group->type == 'community'){
$activity = CommunityActivity::find($group->type_id);
if($activity->class == 'one' && $activity->apply_deadline < $request->end_time)
return $this->failure('成团结束时间必须小于活动截止报名时间');
}
$group->save();
return $this->success('ok');
} catch (\Exception $e) {
$this->getError($e);
return $this->failure('服务器休息,请稍后再试');
}
}
//拼团详情
public function groupDetail(Request $request){
try {
$id = $request->id;
$group = CollageGroup::where('id',$id)->first();
$group->sku = json_decode($group->sku,true);
return $this->success('ok',$group);
} catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
//拼团列表
public function groups(Request $request){
try {
$m_id = $request->account_id;
$keyword = trim($request->keyword);
$type = $request->input('type');
$origin_type = ($type == 'activity' || $type == 'service')?'community':$type;
$groups = CollageGroup::where('m_id',$m_id);
if($keyword){
$groups = $groups->whereHas($origin_type,function($sql) use($keyword){
$sql->where('title','like',"%$keyword%");
});
}
if($type){
$groups = $groups->where('type', $origin_type);
}
if ($origin_type == 'community') {
$groups = $groups->with($origin_type.':id,title,pic');
if ($type == 'activity') {
$groups = $groups->whereHas($origin_type, function($sql) {
$sql->where('class', 'one');
});
}elseif ($type == 'service') {
$groups = $groups->whereHas($origin_type, function($sql) {
$sql->where('class', 'many');
});
}
}elseif ($origin_type == 'course') {
$groups = $groups->with('course:id,title,thumb as pic');
}elseif ($origin_type == 'shop') {
$groups = $groups->with('shop:id,title,icon as pic');
}elseif ($origin_type == 'evaluate') {
$groups = $groups->with('evaluate:id,title,image as pic');
}elseif ($origin_type == 'consult') {
$groups = $groups->with('consult:id,title,pic');
}
$groups = $groups->orderBy('id','desc')->select('id', 'm_id', 'type', 'type_id', 'price', 'created_at','start_time', 'end_time', 'expire_in')->paginate();
foreach ($groups as $group) {
if ($type == 'course') {
$group->community = $group->course;
unset($group->course);
}elseif($type == 'shop') {
$group->community = $group->shop;
unset($group->course);
}elseif($type == 'consult') {
$group->community = $group->consult;
unset($group->course);
}elseif($type == 'evaluate') {
$group->community = $group->evaluate;
unset($group->course);
}
// $type = $value->type;
// $value->$type;
// $group->sku = json_decode($group->sku,true);
}
return $this->success('ok',$groups);
} catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
//删除拼团信息
public function removeGroup(Request $request,$group_id){
try {
$group = CollageGroup::find($group_id);
if(!$group) return $this->failure('拼团信息不存在或已被他人删除');
$history = CollageGroupHistories::with('tOrder')->whereHas('tOrder',function($sql){
$sql->whereIn('pay_status',[1,4]);
})->where('group_id',$group_id)->first();
if($history) return $this->failure('本团已有人发起拼团,无法删除');
$group->delete();
return $this->success('ok');
} catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
//所有未完成拼团列表
public function unfinishedGroups(Request $request){
$m_id = $request->account_id;
$group_id = $request->group_id;
$group_status = $request->group_status ?? 0;
$time = date('Y-m-d H:i:s');
$keyword = trim($request->keyword);
$histories = CollageGroupHistories::with('tOrder')->whereHas('tOrder',function($sql){
$sql->whereIn('pay_status',[1,4]);
})->where('group_id',$group_id)->where('is_initiator',1)->where('status',$group_status);
// if($group_status == 0){//未成团
// $histories = $histories->where('deadline','>',$time);
// }
if($keyword){
$histories = $histories->whereHas('mUser.mpUser',function($query) use($keyword){
$query->where('nickname','like',"%$keyword%")
->orWhere('mobile','like',"%$keyword%");
});
}
$histories = $histories->orderBy('deadline','desc')->paginate();
foreach ($histories as $key => $history) {
$require_num = $history->group->require_num;
$group = $history->group;
if(!$group) continue;
$type = $group->type;
$history->title = $group->$type ? $group->$type->title : '未获取';
if($group->type == 'community'){
$history->type = $group->$type->class == 'many'? 'service':'activity';
}else{
$history->type = $group->type;
}
$initiator_id = CollageGroupHistories::where('group_id',$history->group_id)->where('deadline',$history->deadline)
->where('is_initiator',1)->value('m_user_id');
//已经参与人数
$user_ids = CollageGroupHistories::with('tOrder')->whereHas('tOrder',function($sql){
$sql->whereIn('pay_status',[1,4]);
})->where('group_id',$history->group_id)->where('deadline',$history->deadline)
->orderBy('id','desc')->pluck('m_user_id')->toArray();
$str = implode(',', $user_ids);
$num = count($user_ids);
$need = ($require_num - $num) > 0 ? $require_num - $num : 0;
$history->need_count = $need;
// $user_id = $history->mUser->user_id;
// $user = User::find($user_id);
// $history->avatar = $user ? $user->getOriginal('circle_avatar') : User::DefaultAvatar;
$history->avatar = $history->mUser->pic?:User::DefaultAvatar;
$history->nickname = $history->mUser->nickname ? : '未获取';
$users = MerchantUser::whereIn('id',$user_ids)->select('id','user_id','pic','nickname')
->orderByRaw(DB::raw('FIELD(id,'.$str.') desc'))->get();
$batch = CollageGroupBatch::where('history_id',$history->id)->value('batch');
$virtual_num = CollageGroupBatch::where('history_id',0)->where('batch',$batch)->get()->count();//本团虚拟用户数量
$group_users = [];
foreach ($users as $key => $value) {
// if($value->user_id){
$group_users[$key]['avatar'] = $value->pic? : User::DefaultAvatar;
$group_users[$key]['nickname'] = $value->nickname;
// }else{
// $group_users[$key]['avatar'] = User::DefaultAvatar;
// $group_users[$key]['nickname'] = '匿名用户';
// }
$group_users[$key]['is_initiator'] = $value->id == $initiator_id ? 1 : 0;
}
if($virtual_num > 0){
for ($i=1; $i <=$virtual_num ; $i++) {
$group_users[$key+$i]['avatar'] = User::DefaultAvatar;
$group_users[$key+$i]['nickname'] = '虚拟用户';
$group_users[$key+$i]['is_initiator'] = 0;
}
}
$history->group_users = $group_users;
$history->virtual_num = $virtual_num;
unset($history->mUser->mpUser);
unset($history->mUser);
unset($history->tOrder);
unset($history->group->$type);
unset($history->group);
}
return $this->success('ok',$histories);
}
//一键成团
public function handFinishGroup(Request $request){
DB::beginTransaction();
try {
$m_id = $request->account_id;
$history = CollageGroupHistories::where('id',$request->history_id)->first();
$group = CollageGroup::where('id',$history->group_id)->first();
$batch = CollageGroupBatch::where('history_id',$request->history_id)->value('batch');
$count = CollageGroupBatch::where('batch',$batch)->get()->count();//当前几人
$need_count = $group->require_num - $count;//需要几人
$insert = [];
for ($i=0; $i < $need_count ; $i++) {
$insert_sub = [
'history_id' => 0,//0为虚拟用户
'batch' => $batch,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
$insert[] = $insert_sub;
}
//插入虚拟用户
if(!empty($insert)) CollageGroupBatch::insert($insert);
//拼团成功
$history_ids = CollageGroupBatch::where('batch',$batch)->where('history_id','<>',0)->pluck('history_id');
CollageGroupHistories::whereIn('id',$history_ids)->update(['status'=>1]);
//本次拼团成功(给所有拼团人员发)
$m_order_ids = CollageGroupHistories::whereIn('id',$history_ids)->pluck('m_order_id')->toArray();
$orders = TouristOrder::whereIn('id',$m_order_ids)->whereIn('pay_status',[1,4])->get();
foreach ($orders as $order) {
if ($order->channel == "福恋小程序") {
$param = $this->getGroupParams($order,$group,$history->deadline,1);
\WechatService::sendJoinGroupNotice($param);
}else{
//修改拼团对应的服务用户记录
if ($group->type == 'course') {
UserCourses::whereHas('torder', function($sql) {
$sql->whereIn('pay_status',[1,4]);
})->where('course_id', $group->type_id)
->where('merchant_user_id', $order->account_id)->update(['status'=>1]);
$jump_url = urlencode(env('APP_URL') . '/pu/#/courseDetail/' . $group->type_id);
$url = env('APP_URL') . '/api/official/live/wechat/FamilyAuth?merchant_id=' . $m_id .
'&anchor_openid=&url=' . $jump_url;
$first = "您的课程拼团订单已成功拼团!";
}elseif ($group->type == 'activity') {
$first = '恭喜你,本次拼团成功';
$jump_url = urlencode(env('APP_URL') . '/pu/#/activityDetails/' . $group->type_id);
$url = env('APP_URL') . '/api/official/live/wechat/FamilyAuth?merchant_id=' . $m_id .
'&anchor_openid=&url=' . $jump_url;
}else {
continue;
}
$param = [
'touser'=> $order->open_id,
'template_id'=>config('wechat.tpls.buy_success_notice'),
'url'=>$url,
'data' => [
'first' => $first,
'keyword1' => $order->desc,
'keyword2' => $order->trade_no,
'keyword3' => "".$order->price,
'keyword4' => $order->created_at->toDateTimeString(),
'remark' => '点击详情可查看课程',
]
];
//通知用户
SendTemplateMsg::dispatch($param)->onQueue("love");
}
}
DB::commit();
return $this->success('ok');
} catch (\Exception $e) {
DB::rollBack();
$this->getError($e);
return $this->failure();
}
}
public function getGroupParams($order,$group,$deadline,$status = 0){
$history_id = CollageGroupHistories::where('m_order_id',$order->id)->value('id');
$param['openid'] = $order->open_id;
$param['order_id'] = $order->id;
$param['title'] = mb_substr($order->desc,0,8).'..';
$param['price'] = $order->price.'元';
$param['num'] = $group->require_num.'人';
$param['deadline'] = $deadline;
//发送给团员的温馨提示
$param['team_desc'] = '您已成功参与拼团,具体拼团成败请留意通知';
//发送给团张的温馨提示
$param['lead_desc'] = '本团有效期为'.$group->expire_in.'小时 赶紧邀请好友来拼团吧';
$param['desc'] = '恭喜你,本次拼团已成功';
$param['status'] = $status;
$param['history_id'] = $history_id;
return $param;
}
/**
* @param Request $request
* 旧拼团数据转换
*/
public function collageGroupTransfer(Request $request){
$old_collect_groups = CollageGroup::all();
foreach ($old_collect_groups as $old_collect_group){
switch ($old_collect_group->type){
case 'community':
case 'service':
$service = CommunityActivity::class;
break;
case 'shop':
$service = MerchantShop::class;
break;
case 'course':
$service = Course::class;
break;
case 'consult':
$service = Consultation::class;
break;
default:
return $this->failure('类型不存在或不受支持');
break;
}
$old_collect_group->collageable_id = $old_collect_group->type_id;
$old_collect_group->collageable_type = $service;
$old_collect_group->save();
}
}
}