*/ private const EFFECT_LABELS = [ 'none' => '无特效', 'fireworks' => '烟花', 'rain' => '下雨', 'lightning' => '闪电', 'snow' => '下雪', ]; /** * 会员主题支持的横幅风格下拉选项。 * * @var array */ private const BANNER_STYLE_LABELS = [ 'aurora' => '鎏光星幕', 'storm' => '雷霆风暴', 'royal' => '王者金辉', 'cosmic' => '星穹幻彩', 'farewell' => '告别暮光', ]; /** * 会员等级管理列表页 */ public function index(): View { $levels = VipLevel::orderBy('sort_order')->get(); return view('admin.vip.index', [ 'levels' => $levels, 'effectOptions' => self::EFFECT_LABELS, 'bannerStyleOptions' => self::BANNER_STYLE_LABELS, ]); } /** * 新增会员等级 */ public function store(Request $request): RedirectResponse { $data = $this->validatedPayload($request); VipLevel::create($data); return redirect()->route('admin.vip.index')->with('success', '会员等级创建成功!'); } /** * 更新会员等级 * * @param VipLevel $vip 路由模型自动注入 */ public function update(Request $request, VipLevel $vip): RedirectResponse { $level = $vip; $data = $this->validatedPayload($request); $level->update($data); return redirect()->route('admin.vip.index')->with('success', '会员等级更新成功!'); } /** * 删除会员等级(关联用户的 vip_level_id 会自动置 null) * * @param VipLevel $vip 路由模型自动注入 */ public function destroy(VipLevel $vip): RedirectResponse { $vip->delete(); return redirect()->route('admin.vip.index')->with('success', '会员等级已删除!'); } /** * 将多行文本转为 JSON 数组字符串 * 每行一个模板,空行忽略 * * @param string $text 多行文本 * @return string|null JSON 字符串 */ private function textToJson(string $text): ?string { $lines = array_filter( array_map('trim', explode("\n", $text)), fn ($line) => $line !== '' ); if (empty($lines)) { return null; } return json_encode(array_values($lines), JSON_UNESCAPED_UNICODE); } /** * 统一整理后台提交的会员等级主题配置数据。 * * @return array */ private function validatedPayload(Request $request): array { $data = $request->validate([ 'name' => 'required|string|max:50', 'icon' => 'required|string|max:20', 'color' => 'required|string|max:10', 'exp_multiplier' => 'required|numeric|min:1|max:99', 'jjb_multiplier' => 'required|numeric|min:1|max:99', 'sort_order' => 'required|integer|min:0', 'price' => 'required|integer|min:0', 'duration_days' => 'required|integer|min:0', 'join_templates' => 'nullable|string', 'leave_templates' => 'nullable|string', 'join_effect' => 'required|in:none,fireworks,rain,lightning,snow', 'leave_effect' => 'required|in:none,fireworks,rain,lightning,snow', 'join_banner_style' => 'required|in:aurora,storm,royal,cosmic,farewell', 'leave_banner_style' => 'required|in:aurora,storm,royal,cosmic,farewell', 'allow_custom_messages' => 'nullable|boolean', ]); // 将多行文本框内容转为 JSON 数组,便于后续随机抽取模板。 $data['join_templates'] = $this->textToJson($data['join_templates'] ?? ''); $data['leave_templates'] = $this->textToJson($data['leave_templates'] ?? ''); $data['allow_custom_messages'] = $request->boolean('allow_custom_messages'); return $data; } }