迁移职务内联保存脚本
This commit is contained in:
@@ -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<void>}
|
||||||
|
*/
|
||||||
|
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;
|
||||||
@@ -8,6 +8,7 @@ import './admin/holiday-event-form.js';
|
|||||||
import { bindAdminHolidayEventsControls } from './admin/holiday-events.js';
|
import { bindAdminHolidayEventsControls } from './admin/holiday-events.js';
|
||||||
import { bindAdminInputSelection } from './admin/input-selection.js';
|
import { bindAdminInputSelection } from './admin/input-selection.js';
|
||||||
import { bindAdminOpsControls } from './admin/ops.js';
|
import { bindAdminOpsControls } from './admin/ops.js';
|
||||||
|
import './admin/positions-inline-patch.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';
|
||||||
|
|
||||||
|
|||||||
@@ -505,50 +505,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- inlinePatch:职务列表内联编辑 Alpine 工厂函数(失焦/回车自动 PATCH 保存) --}}
|
|
||||||
<script>
|
|
||||||
function inlinePatch(positionId, field, initial) {
|
|
||||||
return {
|
|
||||||
val: initial, // null = 显示为空(placeholder "不限")
|
|
||||||
saving: false,
|
|
||||||
saved: false,
|
|
||||||
error: '',
|
|
||||||
|
|
||||||
async save() {
|
|
||||||
if (this.saving) return;
|
|
||||||
this.saving = true;
|
|
||||||
this.saved = false;
|
|
||||||
this.error = '';
|
|
||||||
try {
|
|
||||||
const body = {};
|
|
||||||
// 空字符串/null → 发 null(=不限)
|
|
||||||
body[field] = (this.val === '' || this.val === null) ? null : Number(this.val);
|
|
||||||
|
|
||||||
const res = await fetch(`/admin/positions/${positionId}/patch`, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]')?.content || '',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
});
|
|
||||||
if (res.ok) {
|
|
||||||
this.saved = true;
|
|
||||||
setTimeout(() => this.saved = false, 2000);
|
|
||||||
} else {
|
|
||||||
const d = await res.json().catch(() => ({}));
|
|
||||||
this.error = d.message || '保存失败';
|
|
||||||
setTimeout(() => this.error = '', 3000);
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
this.error = '网络异常';
|
|
||||||
setTimeout(() => this.error = '', 3000);
|
|
||||||
}
|
|
||||||
this.saving = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
Reference in New Issue
Block a user