orderByDesc('send_at') ->paginate(20); return view('admin.holiday-events.index', compact('events')); } /** * 新建活动表单页。 */ public function create(): View { return view('admin.holiday-events.create'); } /** * 保存新活动。 */ public function store(StoreHolidayEventRequest $request): RedirectResponse { HolidayEvent::create($this->buildPayload($request->validated(), true)); return redirect()->route('admin.holiday-events.index')->with('success', '节日福利活动创建成功!'); } /** * 编辑活动表单页。 */ public function edit(HolidayEvent $holidayEvent): View { return view('admin.holiday-events.edit', ['event' => $holidayEvent]); } /** * 更新活动。 */ public function update(UpdateHolidayEventRequest $request, HolidayEvent $holidayEvent): RedirectResponse { $holidayEvent->update($this->buildPayload($request->validated())); return redirect()->route('admin.holiday-events.index')->with('success', '活动已更新!'); } /** * 切换活动启用/禁用状态。 */ public function toggle(HolidayEvent $holidayEvent): JsonResponse { $holidayEvent->update(['enabled' => ! $holidayEvent->enabled]); return response()->json([ 'ok' => true, 'enabled' => $holidayEvent->enabled, 'message' => $holidayEvent->enabled ? '已启用' : '已禁用', ]); } /** * 手动立即触发活动(管理员操作)。 */ public function triggerNow(HolidayEvent $holidayEvent): RedirectResponse { if (! $holidayEvent->enabled || $holidayEvent->status === 'cancelled') { return back()->with('error', '当前活动未启用或已取消,不能立即触发。'); } // 立即触发只生成临时批次,不覆盖年度锚点或下次计划时间。 TriggerHolidayEventJob::dispatch($holidayEvent, true); return back()->with('success', '活动已触发,请稍后刷新查看状态。'); } /** * 删除活动。 */ public function destroy(HolidayEvent $holidayEvent): RedirectResponse { $holidayEvent->delete(); return redirect()->route('admin.holiday-events.index')->with('success', '活动已删除。'); } /** * 组装节日福利模板的可持久化字段。 * * @param array $data * @return array */ private function buildPayload(array $data, bool $isCreating = false): array { $payload = $data; // 创建与编辑都统一回收无效字段,避免模板状态互相污染。 if (($payload['distribute_type'] ?? 'random') === 'random') { $payload['fixed_amount'] = null; } else { $payload['min_amount'] = 1; $payload['max_amount'] = null; } if (($payload['target_type'] ?? 'all') !== 'level') { $payload['target_value'] = null; } if (($payload['repeat_type'] ?? 'once') !== 'cron') { $payload['cron_expr'] = null; } if (($payload['repeat_type'] ?? 'once') === 'yearly') { $payload['send_at'] = $this->scheduleService ->resolveNextConfiguredSendAt($payload) ->toDateTimeString(); } else { $payload['schedule_month'] = null; $payload['schedule_day'] = null; $payload['schedule_time'] = null; $payload['duration_days'] = 1; $payload['daily_occurrences'] = 1; $payload['occurrence_interval_minutes'] = null; } // 每次保存模板时,都让系统按新配置重新进入待触发状态。 $payload['status'] = 'pending'; $payload['enabled'] = (bool) ($payload['enabled'] ?? true); $payload['triggered_at'] = null; $payload['expires_at'] = null; $payload['claimed_count'] = 0; $payload['claimed_amount'] = 0; return $payload; } }