54 lines
1.6 KiB
JavaScript
54 lines
1.6 KiB
JavaScript
async function api(path, options = {}) {
|
||
const config = {
|
||
method: options.method || 'GET',
|
||
headers: {},
|
||
credentials: 'same-origin'
|
||
};
|
||
if (options.json !== undefined) {
|
||
config.headers['Content-Type'] = 'application/json';
|
||
config.body = JSON.stringify(options.json);
|
||
} else if (options.body) {
|
||
config.body = options.body;
|
||
}
|
||
const response = await fetch(`/api/${path}`, config);
|
||
let data;
|
||
try {
|
||
data = await response.json();
|
||
} catch (_) {
|
||
data = { ok: false, message: '服务器响应异常,请刷新后重试' };
|
||
}
|
||
if (!response.ok && !data.message) data.message = `请求失败(${response.status})`;
|
||
return data;
|
||
}
|
||
|
||
function toast(message, isError = false) {
|
||
let element = document.querySelector('#toast');
|
||
if (!element) {
|
||
element = document.createElement('div');
|
||
element.id = 'toast';
|
||
element.className = 'toast';
|
||
document.body.appendChild(element);
|
||
}
|
||
element.textContent = message;
|
||
element.classList.toggle('error', Boolean(isError));
|
||
element.classList.add('show');
|
||
clearTimeout(element.timer);
|
||
element.timer = setTimeout(() => element.classList.remove('show'), 3800);
|
||
}
|
||
|
||
function text(value) {
|
||
return String(value ?? '').replace(/[&<>"']/g, ch => ({
|
||
'&': '&', '<': '<', '>': '>', '"': '"', "'": '''
|
||
}[ch]));
|
||
}
|
||
|
||
function requireConfirm(message) {
|
||
return window.confirm(message);
|
||
}
|
||
|
||
function setButtonsDisabled(root, disabled) {
|
||
root.querySelectorAll('button[data-working]').forEach(button => {
|
||
button.disabled = disabled || button.dataset.alwaysDisabled === '1';
|
||
});
|
||
}
|