126 lines
4.0 KiB
PHP
126 lines
4.0 KiB
PHP
<?php
|
||
|
||
/**
|
||
* 文件功能:前台会员中心控制器
|
||
* 负责展示会员等级、权益说明、当前会员状态、用户购买记录与会员个性化进退场设置
|
||
*/
|
||
|
||
namespace App\Http\Controllers;
|
||
|
||
use App\Http\Requests\UpdateVipPresenceSettingsRequest;
|
||
use App\Models\Sysparam;
|
||
use App\Models\VipLevel;
|
||
use App\Models\VipPaymentOrder;
|
||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||
use Illuminate\Http\RedirectResponse;
|
||
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,
|
||
'effectOptions' => [
|
||
'none' => '无特效',
|
||
'fireworks' => '烟花',
|
||
'rain' => '下雨',
|
||
'lightning' => '闪电',
|
||
'snow' => '下雪',
|
||
],
|
||
'bannerStyleOptions' => [
|
||
'aurora' => '鎏光星幕',
|
||
'storm' => '雷霆风暴',
|
||
'royal' => '王者金辉',
|
||
'cosmic' => '星穹幻彩',
|
||
'farewell' => '告别暮光',
|
||
],
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 保存会员个人自定义欢迎语与离开语。
|
||
*/
|
||
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', '会员专属欢迎语和离开语已保存。');
|
||
}
|
||
|
||
/**
|
||
* 构建当前用户的购买记录分页数据
|
||
*
|
||
* @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();
|
||
}
|
||
|
||
/**
|
||
* 将可空文案统一整理为数据库可保存的字符串。
|
||
*/
|
||
private function sanitizeNullableMessage(?string $message): ?string
|
||
{
|
||
$message = trim((string) $message);
|
||
|
||
return $message === '' ? null : $message;
|
||
}
|
||
}
|