all(); $validator = v::key('bank_name', v::optional(v::stringType()->length(1, 100)->setName(trans('bank_name', [], 'message')))) ->key('account', v::optional(v::stringType()->length(1, 255)->setName(trans('bank_account', [], 'message')))) ->key('account_name', v::optional(v::stringType()->length(1, 100)->setName(trans('bank_account_name', [], 'message')))) ->key('bank_code', v::optional(v::stringType()->length(1, 100)->setName(trans('bank_code', [], 'message')))) ->key('wallet_address', v::optional(v::stringType()->length(1, 255)->setName(trans('wallet_address', [], 'message')))) ->key('qr_code', v::optional(v::stringType()->setName(trans('qr_code', [], 'message')))); try { $validator->assert($data); } catch (AllOfException $e) { return jsonFailResponse(getValidationMessages($e)); } if (!empty($data['account']) && PlayerBank::query()->where('account', $data['account']) ->where('pay_type', $player->channel->pay_type)->exists()) { return jsonFailResponse(trans('bank_card_has_bind', [], 'message')); } $payType = $player->channel->pay_type; //USDT判断 if (!empty($data['wallet_address'])) { $payType = 4; if (PlayerBank::query()->where('wallet_address', $data['wallet_address'])->where('pay_type', 4)->exists()) { return jsonFailResponse(trans('bank_card_has_bind', [], 'message')); } } $bankNum = PlayerBank::query() ->where('player_id', $player->id) ->where('status', 1) ->where('pay_type', $player->channel->pay_type) ->count(); if ($bankNum > 2) { return jsonFailResponse(trans('bank_card_max_three', [], 'message')); } $playerBank = new PlayerBank(); $playerBank->player_id = $player->id; $playerBank->bank_name = $data['bank_name']; $playerBank->account = $data['account']; $playerBank->account_name = $data['account_name']; $playerBank->wallet_address = $data['wallet_address'] ?? ''; $playerBank->qr_code = $data['qr_code'] ?? ''; $playerBank->bank_code = $data['bank_code']; $playerBank->pay_type = $payType; if (!$playerBank->save()) { return jsonFailResponse(trans('add_bank_card_fail', [], 'message')); } return jsonSuccessResponse(trans('add_bank_card_success', [], 'message')); } /** * 修改银行卡 * @param Request $request * @return Response * @throws GameException * @throws PlayerCheckException */ public function editBankCard(Request $request): Response { $player = checkPlayer(); $data = $request->all(); $validator = v::key('bank_name', v::notEmpty()->stringType()->length(1, 100)->setName(trans('bank_name', [], 'message'))) ->key('account_name', v::notEmpty()->stringType()->length(1, 100)->setName(trans('bank_account_name', [], 'message'))) ->key('bank_code', v::notEmpty()->stringType()->length(1, 100)->setName(trans('bank_code', [], 'message'))) ->key('id', v::notEmpty()->stringType()->length(1, 100)->setName(trans('id', [], 'message'))); try { $validator->assert($data); } catch (AllOfException $e) { return jsonFailResponse(getValidationMessages($e)); } if (PlayerBank::query()->where('player_id', $player->id)->where('status', 1)->count() > 2) { return jsonFailResponse(trans('bank_card_max_three', [], 'message')); } $playerBank = PlayerBank::query()->find($data['id']); if ($playerBank->player_id != $player->id) { return jsonFailResponse(trans('edit_bank_card_fail', [], 'message')); } $playerBank->bank_name = $data['bank_name']; $playerBank->account = $data['account']; $playerBank->account_name = $data['account_name']; $playerBank->bank_code = $data['bank_code']; if (!$playerBank->save()) { return jsonFailResponse(trans('edit_bank_card_fail', [], 'message')); } return jsonSuccessResponse(trans('edit_bank_card_success', [], 'message')); } /** * 银行卡列表 * @param Request $request * @return Response * @throws PlayerCheckException|GameException */ public function bankCardList(Request $request): Response { $player = checkPlayer(); $data = $request->all(); $validator = v::key('page', v::intVal()->setName(trans('page', [], 'message'))) ->key('size', v::intVal()->setName(trans('size', [], 'message'))); try { $validator->assert($data); } catch (AllOfException $e) { return jsonFailResponse(getValidationMessages($e)); } return jsonSuccessResponse('success', [ 'bank_list' => PlayerBank::query() ->where('player_id', $player->id) ->where('status', 1) ->where('pay_type', $player->channel->pay_type) ->whereNull('deleted_at') ->select(['id', 'bank_name', 'account', 'account_name']) ->forPage($data['page'] ?? 1, $data['size'] ?? 10) ->orderBy('created_at', 'desc') ->get() ->toArray(), ]); } /** * 银行卡列表 * @return Response * @throws PlayerCheckException|GameException|\think\Exception */ public function bankList(): Response { $player = checkPlayer(false); return jsonSuccessResponse('success', [ 'bank_list' => BankList::query() ->select(['bank_name', 'bank_code']) ->where('pay_type', $player->channel->pay_type) ->where('type', '!=', 1) ->whereNull('deleted_at') ->get() ->toArray(), ]); } /** * 删除银行卡 * @param Request $request * @return Response * @throws PlayerCheckException|GameException */ public function deleteBankCard(Request $request): Response { $player = checkPlayer(); $data = $request->all(); $validator = v::key('id', v::intVal()->notEmpty()->setName(trans('bank_card_id', [], 'message'))); try { $validator->assert($data); } catch (AllOfException $e) { return jsonFailResponse(getValidationMessages($e)); } $bankCard = PlayerBank::withTrashed()->where('player_id', $player->id)->where('id', $data['id'])->first(); if (!$bankCard) { return jsonFailResponse(trans('bank_card_not_found', [], 'message')); } if ($bankCard->status == 0) { return jsonFailResponse(trans('bank_card_disabled', [], 'message')); } if (!empty($bankCard->deleted_at)) { return jsonFailResponse(trans('bank_card_deleted', [], 'message')); } $bankCard->delete(); return jsonSuccessResponse(trans('success', [], 'message')); } /** * 上传支付凭证 * @param Request $request * @return Response * @throws GameException * @throws PlayerCheckException */ public function uploadCertificate(Request $request): Response { checkPlayer(); $file = $request->file('certificate'); $filePath = ''; if ($file && $file->isValid()) { if ($file->getSize() > 3 * 1024 * 1024) { return jsonFailResponse(trans('image_upload_size_fail', ['{size}' => '3M'], 'message')); } $allowedExtensions = ['png', 'jpg', 'jpeg']; $extension = $file->getUploadExtension(); if (!in_array($extension, $allowedExtensions)) { return jsonFailResponse(trans('image_upload_fail', [], 'message')); } $savePath = '/storage/certificate/' . date("Ymd", time()) . "/"; $newPath = public_path() . $savePath; if (!file_exists($newPath)) { //检查是否有该文件夹,如果没有就创建,并给予最高权限 mkdir($newPath, 0755, true); } $extension = $file->getUploadExtension(); $filename = time() . '_' . uniqid() . ".{$extension}"; //文件名 $newPath = $newPath . $filename; $file->move($newPath); $filePath = env('APP_URL', 'http://127.0.0.1:8787') . $savePath . $filename; } if (!$filePath) { return jsonFailResponse(trans('failed_to_upload_recharge_voucher', [], 'message')); } return jsonSuccessResponse('success', ['file_path' => $filePath]); } /** * 玩家充值 * @param Request $request * @return Response * @throws PlayerCheckException * @throws Exception */ public function playerRecharge(Request $request): Response { $player = checkPlayer(); $data = $request->all(); $validator = v::key('id', v::notEmpty()->intVal()->setName(trans('recharge_setting_id', [], 'message'))) ->key('certificate', v::notEmpty()->url()->notEmpty()->setName(trans('certificate', [], 'message'))); try { $validator->assert($data); } catch (AllOfException $e) { return jsonFailResponse(getValidationMessages($e)); } $rechargeRecord = PlayerRechargeRecord::where('player_id', $player->id) ->where('status', PlayerRechargeRecord::STATUS_WAIT) ->where('type', PlayerRechargeRecord::TYPE_REGULAR) ->first(); if (!empty($rechargeRecord)) { return jsonFailResponse(trans('has_not_unfinished_recharge', [], 'message')); } /** @var Channel $channel */ $channel = Channel::where('department_id', $player->department_id)->first(); if (empty($channel)) { return jsonFailResponse(trans('channel_not_found', [], 'message')); } if ($channel->recharge_status == 0) { return jsonFailResponse(trans('recharge_closed', [], 'message')); } $lang = locale(); $lang = Str::replace('_', '-', $lang); /** @var ChannelRechargeSetting $channelRechargeSetting */ $channelRechargeSetting = ChannelRechargeSetting::with(['channel_recharge_method' => function ($query) use ($lang) { $query->select(['id', 'account', 'currency'])->with(['methodLang' => function ($query) use ($lang) { $query->select(['id', 'bank_name', 'sub_bank', 'owner', 'name', 'method_id', 'lang'])->where('lang', $lang); }]); }])->whereHas('channel_recharge_method', function ($query) { $query->whereNull('deleted_at')->where('status', 1); }) ->where('department_id', $player->department_id) ->where('status', 1) ->where('id', $data['id']) ->whereNull('deleted_at') ->first(); if (empty($channelRechargeSetting)) { return jsonFailResponse(trans('channel_recharge_setting_not_found', [], 'message')); } try { $allCoins = bcadd($channelRechargeSetting->coins_num, $channelRechargeSetting->gift_coins, 2); // 生成充值订单 $playerRechargeRecord = new PlayerRechargeRecord(); $playerRechargeRecord->player_id = $player->id; $playerRechargeRecord->department_id = $player->department_id; $playerRechargeRecord->tradeno = createOrderNo(); $playerRechargeRecord->player_name = $player->name ?? ''; $playerRechargeRecord->money = $channelRechargeSetting->money; $playerRechargeRecord->inmoney = $channelRechargeSetting->money; $playerRechargeRecord->setting_id = $channelRechargeSetting->id; $playerRechargeRecord->coins = $channelRechargeSetting->coins_num; $playerRechargeRecord->gift_coins = $channelRechargeSetting->gift_coins; $playerRechargeRecord->currency = $channelRechargeSetting->channel_recharge_method->currency; $playerRechargeRecord->type = $channelRechargeSetting->type; $playerRechargeRecord->status = PlayerRechargeRecord::STATUS_RECHARGING; $playerRechargeRecord->certificate = $data['certificate'] ?? ''; $playerRechargeRecord->bank_name = $channelRechargeSetting->channel_recharge_method->methodLang[0]['bank_name'] ?? ''; $playerRechargeRecord->sub_bank = $channelRechargeSetting->channel_recharge_method->methodLang[0]['sub_bank'] ?? ''; $playerRechargeRecord->owner = $channelRechargeSetting->channel_recharge_method->methodLang[0]['owner'] ?? ''; $playerRechargeRecord->account = $channelRechargeSetting->channel_recharge_method->account; $playerRechargeRecord->chip_amount = bcmul($allCoins, $channelRechargeSetting->chip_multiple, 2); $playerRechargeRecord->save(); } catch (Exception $e) { return jsonFailResponse($e->getMessage()); } sendSocketMessage('private-admin_group-channel-' . request()->department_id, [ 'msg_type' => 'player_examine_recharge_order', 'id' => $rechargeRecord->id, 'player_id' => $player->id, 'player_name' => $player->name, 'player_phone' => $player->phone, 'money' => $playerRechargeRecord->money, 'status' => $playerRechargeRecord->status, 'tradeno' => $playerRechargeRecord->tradeno, ]); return jsonSuccessResponse('success', [ 'tradeno' => $playerRechargeRecord->tradeno, 'order_id' => $playerRechargeRecord->id, 'money' => $playerRechargeRecord->money, 'coins' => $allCoins, 'currency' => $playerRechargeRecord->currency, 'status' => $playerRechargeRecord->status, 'created_at' => strtotime($playerRechargeRecord->created_at), 'recharge_setting' => $channelRechargeSetting ]); } /** * 提现记录 * @param Request $request * @return Response * @throws PlayerCheckException|GameException */ public function cashOutList(Request $request): Response { $player = checkPlayer(); $data = $request->all(); $validator = v::key('page', v::intVal()->setName(trans('page', [], 'message'))) ->key('size', v::intVal()->setName(trans('size', [], 'message'))); try { $validator->assert($data); } catch (AllOfException $e) { return jsonFailResponse(getValidationMessages($e)); } $size = $data['size'] ?? 10; $totalRecords = PlayerWithdrawRecord::query() ->where('player_id', $player->id) ->count(); return jsonSuccessResponse('success', [ 'list' => PlayerWithdrawRecord::where('player_id', $player->id) ->select(['id', 'coins', 'after_coins', 'created_at', 'status']) ->forPage($data['page'] ?? 1, $data['size'] ?? 10) ->orderBy('created_at', 'desc') ->get() ->toArray(), 'total_page' => ceil($totalRecords / $size) ]); } /** * 玩家提现 * @param Request $request * @return Response * @throws PlayerCheckException * @throws Exception */ public function playerWithdrawal(Request $request): Response { $player = checkPlayer(); $data = $request->all(); $validator = v::key('amount', v::intVal()->notEmpty()->min(100)->setName(trans('withdrawal_amount', [], 'message'))) ->key('bank_id', v::intVal()->setName(trans('withdrawal_bank', [], 'message'))); try { $validator->assert($data); } catch (AllOfException $e) { return jsonFailResponse(getValidationMessages($e)); } /** @var Channel $channel */ $channel = Channel::where('department_id', $player->department_id)->first(); if ($player->status_withdraw != 1) { return jsonFailResponse(trans('player_withdraw_closed', [], 'message')); } if ($player->wallet->money < $data['amount']) { return jsonFailResponse(trans('insufficient_balance', [], 'message')); } if ($channel->withdraw_status == 0) { return jsonFailResponse(trans('self_withdraw_closed', [], 'message')); } if (empty($data['bank_id'])) { return jsonFailResponse(trans('please_select_player_bank', [], 'message')); } /** @var Currency $currency */ $currency = Currency::where('identifying', $channel->currency)->where('status', 1)->whereNull('deleted_at')->first(); if (empty($currency)) { return jsonFailResponse(trans('currency_no_setting', [], 'message')); } /** @var PlayerBank $playerBank */ $playerBank = PlayerBank::where('id', $data['bank_id'])->where('player_id', $player->id)->where('status', 1)->whereNull('deleted_at')->first(); if (empty($playerBank)) { return jsonFailResponse(trans('player_bank_not_found', [], 'message')); } if ($player->must_chip_amount > $player->chip_amount) { return jsonFailResponse(trans('must_chip_amount_incomplete', [], 'message')); } DB::beginTransaction(); try { $money = bcdiv($data['amount'], $currency->ratio, 2); // 生成订单 $playerWithdrawRecord = new PlayerWithdrawRecord(); $beforeGameAmount = $player->wallet->money; // 玩家钱包扣减 $player->wallet->money = bcsub($player->wallet->money, $data['amount'], 2); $playerWithdrawRecord->player_id = $player->id; $playerWithdrawRecord->department_id = $player->department_id; $playerWithdrawRecord->tradeno = createOrderNo(); $playerWithdrawRecord->player_name = $player->name ?? ''; $playerWithdrawRecord->player_phone = $player->phone ?? ''; $playerWithdrawRecord->money = $money; $playerWithdrawRecord->coins = $data['amount']; $playerWithdrawRecord->after_coins = $player->wallet->money; $playerWithdrawRecord->fee = 0; $playerWithdrawRecord->inmoney = bcsub($playerWithdrawRecord->money, $playerWithdrawRecord->fee, 2); // 实际提现金额 $playerWithdrawRecord->currency = $channel->currency; $playerWithdrawRecord->bank_name = $playerBank->bank_name; $playerWithdrawRecord->account = $playerBank->account; $playerWithdrawRecord->account_name = $playerBank->account_name; $playerWithdrawRecord->type = PlayerWithdrawRecord::TYPE_SELF; $playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_WAIT; $playerWithdrawRecord->save(); // 更新玩家统计 $player->player_extend->withdraw_amount = bcadd($player->player_extend->withdraw_amount, $playerWithdrawRecord->coins, 2); $player->push(); //寫入金流明細 $playerDeliveryRecord = new PlayerDeliveryRecord; $playerDeliveryRecord->player_id = $playerWithdrawRecord->player_id; $playerDeliveryRecord->department_id = $playerWithdrawRecord->department_id; $playerDeliveryRecord->target = $playerWithdrawRecord->getTable(); $playerDeliveryRecord->target_id = $playerWithdrawRecord->id; $playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_WITHDRAWAL; $playerDeliveryRecord->source = 'channel_withdrawal'; $playerDeliveryRecord->amount = $playerWithdrawRecord->coins; $playerDeliveryRecord->amount_before = $beforeGameAmount; $playerDeliveryRecord->amount_after = $player->wallet->money; $playerDeliveryRecord->tradeno = $playerWithdrawRecord->tradeno ?? ''; $playerDeliveryRecord->remark = $playerWithdrawRecord->remark ?? ''; $playerDeliveryRecord->save(); DB::commit(); } catch (\Exception $e) { DB::rollBack(); return jsonFailResponse(trans('system_error', [], 'message') . $e->getMessage()); } $notice = new Notice(); $notice->department_id = $playerWithdrawRecord->department_id; $notice->player_id = $playerWithdrawRecord->player_id; $notice->source_id = $playerWithdrawRecord->id; $notice->type = Notice::TYPE_EXAMINE_WITHDRAW; $notice->receiver = Notice::RECEIVER_DEPARTMENT; $notice->is_private = 0; $notice->title = '渠道提现待审核'; $notice->content = '提现订单待审核,玩家' . (empty($playerWithdrawRecord->player_name) ? $playerWithdrawRecord->player_name : $playerWithdrawRecord->player_phone) . ', 提现游戏点: ' . $playerWithdrawRecord->point . ' 提现金额: ' . $playerWithdrawRecord->money; $notice->save(); if ($playerWithdrawRecord->status == PlayerWithdrawRecord::STATUS_FAIL) { return jsonFailResponse(trans('withdraw_fail', [], 'message')); } sendSocketMessage('private-admin_group-channel-' . $channel->department_id, [ 'msg_type' => 'player_create_withdraw_order', 'id' => $playerWithdrawRecord->id, 'player_id' => $player->id, 'player_name' => $player->name, 'player_phone' => $player->phone, 'money' => $playerWithdrawRecord->money, 'status' => $playerWithdrawRecord->status, 'tradeno' => $playerWithdrawRecord->tradeno, ]); return jsonSuccessResponse('success', [ 'tradeno' => $playerWithdrawRecord->tradeno, 'order_id' => $playerWithdrawRecord->id, 'money' => $playerWithdrawRecord->money, 'currency' => $playerWithdrawRecord->currency, 'status' => $playerWithdrawRecord->status, ]); } /** * 首页活动 * @return Response * @throws PlayerCheckException|GameException */ public function homeActivity(): Response { $player = checkPlayer(); $list = Activity::query() ->where('department_id', $player->department_id) ->where('status', 1) ->limit(3) ->orderBy('sort', 'desc') ->get(); $lang = locale(); $lang = Str::replace('_', '-', $lang); $activityList = []; /** @var Activity $activity */ foreach ($list as $activity) { /** @var ActivityContent $activityContent */ $activityContent = $activity->activity_content->where('lang', $lang)->first(); if ($activity->type == Activity::TYPE_CUSTOM) { if (strtotime($activity->start_time) > time() || strtotime($activity->end_time) < time()) { continue; } } if ($activity->type == Activity::TYPE_CYCLE) { if ($activity->cycle_type == 'Week' && $activity->cycle_data != Carbon::now()->dayOfWeek) { continue; } if ($activity->cycle_type == 'Month' && $activity->cycle_data != Carbon::now()->day) { continue; } } $activityList[] = [ 'id' => $activity->id, 'start_time' => $activity->start_time, 'end_time' => $activity->end_time, 'name' => $activityContent->name ?? '', 'lang' => $activityContent->lang, 'picture' => $activityContent->picture ?? '', 'recharge_id' => $activity->recharge_id, 'method_id' => $activity->channelRechargeSetting->method_id, ]; } return jsonSuccessResponse('success', [ 'list' => $activityList, ]); } /** * cash in记录 * @param Request $request * @return Response * @throws PlayerCheckException|GameException */ public function cashInList(Request $request): Response { $player = checkPlayer(); $data = $request->all(); $validator = v::key('page', v::intVal()->setName(trans('page', [], 'message'))) ->key('size', v::intVal()->setName(trans('size', [], 'message'))); try { $validator->assert($data); } catch (AllOfException $e) { return jsonFailResponse(getValidationMessages($e)); } $size = $data['size'] ?? 10; $totalRecords = PlayerRechargeRecord::query() ->where('player_id', $player->id) ->count(); $list = PlayerRechargeRecord::leftJoin('player_delivery_record as pdr',function ($join){ $join->on( 'pdr.target_id', '=', 'player_recharge_record.id') ->where('pdr.type', '=', PlayerDeliveryRecord::TYPE_RECHARGE); })->where('player_recharge_record.player_id', $player->id) ->select(['player_recharge_record.id', 'player_recharge_record.status', 'player_recharge_record.coins', 'pdr.amount_after', 'player_recharge_record.created_at']) ->forPage($data['page'] ?? 1, $data['size'] ?? 10) ->orderBy('player_recharge_record.created_at', 'desc') ->get() ->toArray(); foreach ($list as &$item) { $item['created_at'] = Carbon::parse($item['created_at'])->format('Y/m/d H:i'); $item['amount_after'] = round($item['amount_after'], 2); } return jsonSuccessResponse('success', [ 'list' => $list, 'total_page' => ceil($totalRecords / $size) ]); } /** * 消息列表 * @param Request $request * @return Response * @throws PlayerCheckException|GameException */ public function noticeList(Request $request): Response { $player = checkPlayer(); $data = $request->all(); $validator = v::key('page', v::intVal()->setName(trans('page', [], 'message'))) ->key('size', v::intVal()->setName(trans('size', [], 'message'))); try { $validator->assert($data); } catch (AllOfException $e) { return jsonFailResponse(getValidationMessages($e)); } $noticeList = Notice::query() ->leftJoin('player_withdraw_record', 'player_withdraw_record.id', '=', 'notice.source_id') ->select(['notice.id', 'notice.player_id', 'notice.title', 'notice.type', 'notice.content', 'notice.created_at', 'player_withdraw_record.status', 'player_withdraw_record.money']) ->where('notice.player_id', $player->id) ->where('notice.receiver', Notice::RECEIVER_PLAYER) ->where('notice.is_private', 1) ->whereNull('notice.deleted_at') ->forPage($data['page'], $data['size']) ->orderBy('notice.status', 'asc') ->orderBy('notice.id', 'desc') ->get(); foreach ($noticeList as &$item) { $item['title'] = trans('title.' . $item->type.'.'.$item->status, ['{point}' => $item->money], 'notice'); $item['content'] = trans('content.' . $item->type.'.'.$item->status, ['{point}' => $item->money], 'notice'); } // 更新为已读状态 Notice::where('status', 0) ->where('receiver', Notice::RECEIVER_PLAYER) ->where('is_private', 1) ->where('player_id', $player->id) ->whereNull('deleted_at') ->update([ 'status' => 1 ]); return jsonSuccessResponse('success', [ 'list' => $noticeList ]); } /** * 渠道信息 * @return Response * @throws PlayerCheckException|GameException */ public function channelInfo(): Response { $player = checkPlayer(); return jsonSuccessResponse('success', [ 'channel_info' => Channel::query() ->where('department_id', $player->department_id) ->first(), ]); } /** * 提现记录 * @param Request $request * @return Response * @throws PlayerCheckException|GameException */ public function withdrawList(Request $request): Response { checkPlayer(); $date = date('Y-m-d'); $list = PlayerWithdrawRecord::with('player:id,uuid,phone') ->where('status', 2) ->whereDate('finish_time', $date) ->select(['money', 'player_id', 'updated_at']) ->orderBy('finish_time', 'desc') ->get() ->toArray(); foreach ($list as &$item) { $PlayerWalletTransfer = PlayerWalletTransfer::query()->where('player_id', $item['player_id']) ->where('type', PlayerWalletTransfer::TYPE_IN) ->where('created_at', '<=', $item['updated_at']) ->orderBy('id', 'desc') ->first(); $item['game'] = $PlayerWalletTransfer->gamePlatform->title; } unset($item); $copyList = []; $broadcast = Broadcast::query() ->select('title','num','phone','updated_at') ->where('status', 1) ->where('type', 1) ->wheredate('date', $date) ->get() ->toArray(); foreach ($broadcast as $item) { $copyList[] = [ 'money' => $item['num'], 'player_id' => 0, 'updated_at' => $item['updated_at'], 'player' => [ 'id' => 0, 'uuid' => 0, 'phone' => $item['phone'], ], 'game' => $item['title'] ]; } $data = array_merge($list, $copyList); $key = array_column($data,'updated_at'); array_multisort($key, SORT_DESC, $data); return jsonSuccessResponse('success', [ 'list' => $data, ]); } }