迁移节日活动后台事件
This commit is contained in:
@@ -0,0 +1,130 @@
|
|||||||
|
// 节日福利后台事件代理,替代 Blade 内联启停、触发和删除确认逻辑。
|
||||||
|
|
||||||
|
let adminHolidayEventsControlsBound = false;
|
||||||
|
|
||||||
|
const enabledButtonClasses =
|
||||||
|
"inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-bold transition bg-emerald-500 text-white hover:bg-emerald-600";
|
||||||
|
const disabledButtonClasses =
|
||||||
|
"inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-bold transition bg-slate-200 text-slate-600 hover:bg-slate-300";
|
||||||
|
const enabledBadgeClasses =
|
||||||
|
"inline-flex rounded-full px-2.5 py-1 text-xs font-bold bg-emerald-100 text-emerald-700";
|
||||||
|
const disabledBadgeClasses =
|
||||||
|
"inline-flex rounded-full px-2.5 py-1 text-xs font-bold bg-slate-100 text-slate-500";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取 CSRF 令牌,供后台 AJAX 状态切换请求使用。
|
||||||
|
*
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getCsrfToken() {
|
||||||
|
return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据启用状态返回按钮文案。
|
||||||
|
*
|
||||||
|
* @param {boolean} enabled
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getToggleButtonLabel(enabled) {
|
||||||
|
return enabled ? "切换为停用" : "重新启用模板";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步当前行的启停按钮、徽标和透明度。
|
||||||
|
*
|
||||||
|
* @param {HTMLButtonElement} button
|
||||||
|
* @param {boolean} enabled
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function renderHolidayEnabledState(button, enabled) {
|
||||||
|
const row = button.closest("tr");
|
||||||
|
const dot = button.querySelector('[data-role="toggle-dot"]');
|
||||||
|
const label = button.querySelector('[data-role="toggle-label"]');
|
||||||
|
const enabledBadge = row?.querySelector('[data-role="enabled-badge"]');
|
||||||
|
|
||||||
|
button.dataset.enabled = enabled ? "1" : "0";
|
||||||
|
button.className = enabled ? enabledButtonClasses : disabledButtonClasses;
|
||||||
|
|
||||||
|
if (dot) {
|
||||||
|
dot.className = enabled ? "h-2 w-2 rounded-full bg-white" : "h-2 w-2 rounded-full bg-slate-500";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (label) {
|
||||||
|
label.textContent = getToggleButtonLabel(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabledBadge) {
|
||||||
|
enabledBadge.className = enabled ? enabledBadgeClasses : disabledBadgeClasses;
|
||||||
|
enabledBadge.textContent = enabled ? "已启用" : "已停用";
|
||||||
|
}
|
||||||
|
|
||||||
|
row?.classList.toggle("opacity-60", !enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换节日活动启用状态,并在成功后刷新当前行状态。
|
||||||
|
*
|
||||||
|
* @param {HTMLButtonElement} button
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async function toggleHolidayEvent(button) {
|
||||||
|
const toggleUrl = button.getAttribute("data-holiday-event-toggle-url");
|
||||||
|
if (!toggleUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(toggleUrl, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"X-CSRF-TOKEN": getCsrfToken(),
|
||||||
|
Accept: "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!data.ok) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderHolidayEnabledState(button, Boolean(data.enabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定节日福利后台页操作。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
export function bindAdminHolidayEventsControls() {
|
||||||
|
if (adminHolidayEventsControlsBound || typeof document === "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
adminHolidayEventsControlsBound = true;
|
||||||
|
|
||||||
|
document.addEventListener("click", (event) => {
|
||||||
|
if (!(event.target instanceof Element)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleButton = event.target.closest("[data-holiday-event-toggle-url]");
|
||||||
|
if (!(toggleButton instanceof HTMLButtonElement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
void toggleHolidayEvent(toggleButton);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("submit", (event) => {
|
||||||
|
if (!(event.target instanceof HTMLFormElement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 立即触发和删除都会改变活动状态,提交前统一读取 Blade 声明的确认文案。
|
||||||
|
const confirmMessage = event.target.getAttribute("data-holiday-event-confirm");
|
||||||
|
if (confirmMessage && !window.confirm(confirmMessage)) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import './bootstrap';
|
|||||||
import { bindAdminAutoactControls } from './admin/autoact.js';
|
import { bindAdminAutoactControls } from './admin/autoact.js';
|
||||||
import { bindAdminFishingEventsControls } from './admin/fishing-events.js';
|
import { bindAdminFishingEventsControls } from './admin/fishing-events.js';
|
||||||
import { bindAdminGameConfigControls } from './admin/game-configs.js';
|
import { bindAdminGameConfigControls } from './admin/game-configs.js';
|
||||||
|
import { bindAdminHolidayEventsControls } from './admin/holiday-events.js';
|
||||||
import { bindAdminOpsControls } from './admin/ops.js';
|
import { bindAdminOpsControls } from './admin/ops.js';
|
||||||
import { bindAdminRoomControls } from './admin/rooms.js';
|
import { bindAdminRoomControls } from './admin/rooms.js';
|
||||||
import { bindAdminSignInRulesControls } from './admin/sign-in-rules.js';
|
import { bindAdminSignInRulesControls } from './admin/sign-in-rules.js';
|
||||||
@@ -10,6 +11,7 @@ import { bindAdminSignInRulesControls } from './admin/sign-in-rules.js';
|
|||||||
bindAdminAutoactControls();
|
bindAdminAutoactControls();
|
||||||
bindAdminFishingEventsControls();
|
bindAdminFishingEventsControls();
|
||||||
bindAdminGameConfigControls();
|
bindAdminGameConfigControls();
|
||||||
|
bindAdminHolidayEventsControls();
|
||||||
bindAdminOpsControls();
|
bindAdminOpsControls();
|
||||||
bindAdminRoomControls();
|
bindAdminRoomControls();
|
||||||
bindAdminSignInRulesControls();
|
bindAdminSignInRulesControls();
|
||||||
|
|||||||
@@ -178,7 +178,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="button"
|
<button type="button"
|
||||||
onclick="toggleHoliday({{ $event->id }}, this)"
|
data-holiday-event-toggle-url="{{ route('admin.holiday-events.toggle', $event) }}"
|
||||||
class="inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-bold transition {{ $event->enabled ? 'bg-emerald-500 text-white hover:bg-emerald-600' : 'bg-slate-200 text-slate-600 hover:bg-slate-300' }}"
|
class="inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-bold transition {{ $event->enabled ? 'bg-emerald-500 text-white hover:bg-emerald-600' : 'bg-slate-200 text-slate-600 hover:bg-slate-300' }}"
|
||||||
data-enabled="{{ $event->enabled ? '1' : '0' }}">
|
data-enabled="{{ $event->enabled ? '1' : '0' }}">
|
||||||
<span data-role="toggle-dot"
|
<span data-role="toggle-dot"
|
||||||
@@ -200,7 +200,7 @@
|
|||||||
<div class="flex flex-wrap justify-end gap-2">
|
<div class="flex flex-wrap justify-end gap-2">
|
||||||
@if ($event->status === 'pending')
|
@if ($event->status === 'pending')
|
||||||
<form action="{{ route('admin.holiday-events.trigger-now', $event) }}"
|
<form action="{{ route('admin.holiday-events.trigger-now', $event) }}"
|
||||||
method="POST" onsubmit="return confirm('确定立即触发此活动吗?')">
|
method="POST" data-holiday-event-confirm="确定立即触发此活动吗?">
|
||||||
@csrf
|
@csrf
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="inline-flex items-center justify-center rounded-lg bg-amber-500 px-3 py-2 text-xs font-bold text-white transition hover:bg-amber-600">
|
class="inline-flex items-center justify-center rounded-lg bg-amber-500 px-3 py-2 text-xs font-bold text-white transition hover:bg-amber-600">
|
||||||
@@ -215,7 +215,7 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<form action="{{ route('admin.holiday-events.destroy', $event) }}" method="POST"
|
<form action="{{ route('admin.holiday-events.destroy', $event) }}" method="POST"
|
||||||
onsubmit="return confirm('确定删除此活动吗?')">
|
data-holiday-event-confirm="确定删除此活动吗?">
|
||||||
@csrf
|
@csrf
|
||||||
@method('DELETE')
|
@method('DELETE')
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
@@ -245,82 +245,4 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
|
||||||
/**
|
|
||||||
* 根据启用状态返回开关按钮类名。
|
|
||||||
*/
|
|
||||||
function holidayToggleButtonClasses(enabled) {
|
|
||||||
return enabled ?
|
|
||||||
'inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-bold transition bg-emerald-500 text-white hover:bg-emerald-600' :
|
|
||||||
'inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-bold transition bg-slate-200 text-slate-600 hover:bg-slate-300';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据启用状态返回开关文案。
|
|
||||||
*/
|
|
||||||
function holidayToggleButtonLabel(enabled) {
|
|
||||||
return enabled ? '切换为停用' : '重新启用模板';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据启用状态返回状态徽标类名。
|
|
||||||
*/
|
|
||||||
function holidayEnabledBadgeClasses(enabled) {
|
|
||||||
return enabled ? 'inline-flex rounded-full px-2.5 py-1 text-xs font-bold bg-emerald-100 text-emerald-700' :
|
|
||||||
'inline-flex rounded-full px-2.5 py-1 text-xs font-bold bg-slate-100 text-slate-500';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据启用状态返回状态徽标文案。
|
|
||||||
*/
|
|
||||||
function holidayEnabledBadgeLabel(enabled) {
|
|
||||||
return enabled ? '已启用' : '已停用';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换节日活动启用/禁用状态,并同步刷新当前行文案与样式。
|
|
||||||
*/
|
|
||||||
function toggleHoliday(id, btn) {
|
|
||||||
fetch(`/admin/holiday-events/${id}/toggle`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(data => {
|
|
||||||
if (!data.ok) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const enabled = Boolean(data.enabled);
|
|
||||||
const row = btn.closest('tr');
|
|
||||||
const dot = btn.querySelector('[data-role="toggle-dot"]');
|
|
||||||
const label = btn.querySelector('[data-role="toggle-label"]');
|
|
||||||
const enabledBadge = row?.querySelector('[data-role="enabled-badge"]');
|
|
||||||
|
|
||||||
btn.dataset.enabled = enabled ? '1' : '0';
|
|
||||||
btn.className = holidayToggleButtonClasses(enabled);
|
|
||||||
|
|
||||||
if (dot) {
|
|
||||||
dot.className = enabled ? 'h-2 w-2 rounded-full bg-white' : 'h-2 w-2 rounded-full bg-slate-500';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (label) {
|
|
||||||
label.textContent = holidayToggleButtonLabel(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enabledBadge) {
|
|
||||||
enabledBadge.className = holidayEnabledBadgeClasses(enabled);
|
|
||||||
enabledBadge.textContent = holidayEnabledBadgeLabel(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row) {
|
|
||||||
row.classList.toggle('opacity-60', !enabled);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
Reference in New Issue
Block a user