diff --git a/resources/js/admin/positions-inline-patch.js b/resources/js/admin/positions-inline-patch.js new file mode 100644 index 0000000..46a36c8 --- /dev/null +++ b/resources/js/admin/positions-inline-patch.js @@ -0,0 +1,80 @@ +// 职务列表内联 PATCH 工厂,负责人数和奖励额度字段的失焦自动保存。 + +/** + * 读取 CSRF 令牌,供内联 PATCH 请求使用。 + * + * @returns {string} + */ +function getCsrfToken() { + return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") ?? ""; +} + +/** + * 创建职务字段内联编辑状态对象。 + * + * @param {number} positionId + * @param {string} field + * @param {number|null} initial + * @returns {object} + */ +function createInlinePatch(positionId, field, initial) { + return { + val: initial, + saving: false, + saved: false, + error: "", + + /** + * 保存当前字段值,空值会转换为 null 表示不限。 + * + * @returns {Promise} + */ + async save() { + if (this.saving) { + return; + } + + this.saving = true; + this.saved = false; + this.error = ""; + + try { + const body = {}; + body[field] = this.val === "" || this.val === null ? null : Number(this.val); + + const response = await fetch(`/admin/positions/${positionId}/patch`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + "X-CSRF-TOKEN": getCsrfToken(), + Accept: "application/json", + }, + body: JSON.stringify(body), + }); + + if (response.ok) { + this.saved = true; + window.setTimeout(() => { + this.saved = false; + }, 2000); + return; + } + + const data = await response.json().catch(() => ({})); + this.error = data.message || "保存失败"; + window.setTimeout(() => { + this.error = ""; + }, 3000); + } catch { + this.error = "网络异常"; + window.setTimeout(() => { + this.error = ""; + }, 3000); + } finally { + this.saving = false; + } + }, + }; +} + +window.inlinePatch = createInlinePatch; diff --git a/resources/js/app.js b/resources/js/app.js index 6122509..5334389 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -8,6 +8,7 @@ import './admin/holiday-event-form.js'; import { bindAdminHolidayEventsControls } from './admin/holiday-events.js'; import { bindAdminInputSelection } from './admin/input-selection.js'; import { bindAdminOpsControls } from './admin/ops.js'; +import './admin/positions-inline-patch.js'; import { bindAdminRoomControls } from './admin/rooms.js'; import { bindAdminSignInRulesControls } from './admin/sign-in-rules.js'; diff --git a/resources/views/admin/positions/index.blade.php b/resources/views/admin/positions/index.blade.php index 2a526d1..17eb75a 100644 --- a/resources/views/admin/positions/index.blade.php +++ b/resources/views/admin/positions/index.blade.php @@ -505,50 +505,5 @@ - {{-- inlinePatch:职务列表内联编辑 Alpine 工厂函数(失焦/回车自动 PATCH 保存) --}} - @endsection