diff --git a/resources/js/admin/ops.js b/resources/js/admin/ops.js
new file mode 100644
index 0000000..3111ac7
--- /dev/null
+++ b/resources/js/admin/ops.js
@@ -0,0 +1,27 @@
+// 运维工具后台事件代理,替代 Blade 内联确认提交逻辑。
+
+let adminOpsControlsBound = false;
+
+/**
+ * 绑定运维工具确认提交事件。
+ *
+ * @returns {void}
+ */
+export function bindAdminOpsControls() {
+ if (adminOpsControlsBound || typeof document === "undefined") {
+ return;
+ }
+
+ adminOpsControlsBound = true;
+ document.addEventListener("submit", (event) => {
+ if (!(event.target instanceof HTMLFormElement)) {
+ return;
+ }
+
+ // 运维动作不可撤销,提交前统一读取 Blade 声明的确认文案。
+ const confirmMessage = event.target.getAttribute("data-ops-confirm");
+ if (confirmMessage && !window.confirm(confirmMessage)) {
+ event.preventDefault();
+ }
+ });
+}
diff --git a/resources/js/app.js b/resources/js/app.js
index 392637c..ef5e9b4 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -2,6 +2,7 @@ import './bootstrap';
import { bindAdminAutoactControls } from './admin/autoact.js';
import { bindAdminFishingEventsControls } from './admin/fishing-events.js';
import { bindAdminGameConfigControls } from './admin/game-configs.js';
+import { bindAdminOpsControls } from './admin/ops.js';
import { bindAdminRoomControls } from './admin/rooms.js';
import { bindAdminSignInRulesControls } from './admin/sign-in-rules.js';
@@ -9,5 +10,6 @@ import { bindAdminSignInRulesControls } from './admin/sign-in-rules.js';
bindAdminAutoactControls();
bindAdminFishingEventsControls();
bindAdminGameConfigControls();
+bindAdminOpsControls();
bindAdminRoomControls();
bindAdminSignInRulesControls();
diff --git a/resources/views/admin/ops/index.blade.php b/resources/views/admin/ops/index.blade.php
index d4a6e6a..ca475d2 100644
--- a/resources/views/admin/ops/index.blade.php
+++ b/resources/views/admin/ops/index.blade.php
@@ -26,7 +26,7 @@
修改 .env 后、部署新版本后建议执行。