// 职务列表内联 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;