2026-04-11 12:01:52 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 文件功能:前台会员中心控制器
|
2026-04-11 15:44:30 +08:00
|
|
|
|
* 负责展示会员等级、权益说明、当前会员状态、用户购买记录与会员个性化进退场设置
|
2026-04-11 12:01:52 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
|
2026-04-11 15:44:30 +08:00
|
|
|
|
use App\Http\Requests\UpdateVipPresenceSettingsRequest;
|
2026-04-11 12:01:52 +08:00
|
|
|
|
use App\Models\Sysparam;
|
|
|
|
|
|
use App\Models\VipLevel;
|
|
|
|
|
|
use App\Models\VipPaymentOrder;
|
|
|
|
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
2026-04-11 15:44:30 +08:00
|
|
|
|
use Illuminate\Http\RedirectResponse;
|
2026-04-11 12:01:52 +08:00
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
|
use Illuminate\View\View;
|
|
|
|
|
|
|
|
|
|
|
|
class VipCenterController extends Controller
|
|
|
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 显示会员中心页面
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param Request $request 当前请求对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function index(Request $request): View
|
|
|
|
|
|
{
|
|
|
|
|
|
$user = $request->user();
|
|
|
|
|
|
|
|
|
|
|
|
// 会员等级按后台排序字段展示,方便用户对比不同档位权益。
|
|
|
|
|
|
$vipLevels = VipLevel::query()
|
|
|
|
|
|
->withCount('users')
|
|
|
|
|
|
->orderByDesc('sort_order')
|
|
|
|
|
|
->orderBy('id')
|
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
|
|
// 仅展示当前用户自己的购买记录,避免泄露其他会员订单信息。
|
|
|
|
|
|
$paymentLogs = $this->buildPaymentLogs($user->id);
|
|
|
|
|
|
|
|
|
|
|
|
$paidOrders = VipPaymentOrder::query()
|
|
|
|
|
|
->where('user_id', $user->id)
|
|
|
|
|
|
->where('status', 'paid')
|
|
|
|
|
|
->count();
|
|
|
|
|
|
|
|
|
|
|
|
$totalAmount = (float) VipPaymentOrder::query()
|
|
|
|
|
|
->where('user_id', $user->id)
|
|
|
|
|
|
->where('status', 'paid')
|
|
|
|
|
|
->sum('amount');
|
|
|
|
|
|
|
|
|
|
|
|
return view('vip.center', [
|
|
|
|
|
|
'user' => $user,
|
|
|
|
|
|
'vipLevels' => $vipLevels,
|
|
|
|
|
|
'paymentLogs' => $paymentLogs,
|
|
|
|
|
|
'vipPaymentEnabled' => Sysparam::getValue('vip_payment_enabled', '0') === '1',
|
|
|
|
|
|
'paidOrders' => $paidOrders,
|
|
|
|
|
|
'totalAmount' => $totalAmount,
|
2026-04-11 15:44:30 +08:00
|
|
|
|
'effectOptions' => [
|
|
|
|
|
|
'none' => '无特效',
|
|
|
|
|
|
'fireworks' => '烟花',
|
|
|
|
|
|
'rain' => '下雨',
|
|
|
|
|
|
'lightning' => '闪电',
|
|
|
|
|
|
'snow' => '下雪',
|
|
|
|
|
|
],
|
|
|
|
|
|
'bannerStyleOptions' => [
|
|
|
|
|
|
'aurora' => '鎏光星幕',
|
|
|
|
|
|
'storm' => '雷霆风暴',
|
|
|
|
|
|
'royal' => '王者金辉',
|
|
|
|
|
|
'cosmic' => '星穹幻彩',
|
|
|
|
|
|
'farewell' => '告别暮光',
|
|
|
|
|
|
],
|
2026-04-11 12:01:52 +08:00
|
|
|
|
]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-11 15:44:30 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 保存会员个人自定义欢迎语与离开语。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function updatePresenceSettings(UpdateVipPresenceSettingsRequest $request): RedirectResponse
|
|
|
|
|
|
{
|
|
|
|
|
|
$user = $request->user();
|
|
|
|
|
|
|
|
|
|
|
|
// 只有有效会员且当前等级允许自定义时,才允许保存专属语句。
|
|
|
|
|
|
if (! $user->canCustomizeVipPresence()) {
|
|
|
|
|
|
return redirect()
|
|
|
|
|
|
->route('vip.center')
|
|
|
|
|
|
->with('error', '当前会员等级暂不支持自定义欢迎语和离开语。');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$data = $request->validated();
|
|
|
|
|
|
|
|
|
|
|
|
// 空字符串统一转成 null,避免数据库保存无意义空白值。
|
|
|
|
|
|
$user->update([
|
|
|
|
|
|
'custom_join_message' => $this->sanitizeNullableMessage($data['custom_join_message'] ?? null),
|
|
|
|
|
|
'custom_leave_message' => $this->sanitizeNullableMessage($data['custom_leave_message'] ?? null),
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
return redirect()
|
|
|
|
|
|
->route('vip.center')
|
|
|
|
|
|
->with('success', '会员专属欢迎语和离开语已保存。');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-11 12:01:52 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 构建当前用户的购买记录分页数据
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param int $userId 当前登录用户 ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
private function buildPaymentLogs(int $userId): LengthAwarePaginator
|
|
|
|
|
|
{
|
|
|
|
|
|
return VipPaymentOrder::query()
|
|
|
|
|
|
->with('vipLevel:id,name,color,icon')
|
|
|
|
|
|
->where('user_id', $userId)
|
|
|
|
|
|
->latest('id')
|
|
|
|
|
|
->paginate(10)
|
|
|
|
|
|
->withQueryString();
|
|
|
|
|
|
}
|
2026-04-11 15:44:30 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 将可空文案统一整理为数据库可保存的字符串。
|
|
|
|
|
|
*/
|
|
|
|
|
|
private function sanitizeNullableMessage(?string $message): ?string
|
|
|
|
|
|
{
|
|
|
|
|
|
$message = trim((string) $message);
|
|
|
|
|
|
|
|
|
|
|
|
return $message === '' ? null : $message;
|
|
|
|
|
|
}
|
2026-04-11 12:01:52 +08:00
|
|
|
|
}
|