84 lines
4.8 KiB
PHP
84 lines
4.8 KiB
PHP
@once
|
|
@push('scripts_start')
|
|
<script>
|
|
(() => {
|
|
if (window.caiwuWorkflowReviewers) return;
|
|
window.caiwuWorkflowReviewers = true;
|
|
const people = new Map();
|
|
let pending;
|
|
async function search(form) {
|
|
const input = form.querySelector('[data-reviewer-search]');
|
|
const status = form.querySelector('[data-reviewer-search-status]');
|
|
const results = form.querySelector('[data-reviewer-results]');
|
|
if (!input.value.trim()) { status.textContent = '请输入姓名或花名后查询。'; return; }
|
|
pending?.abort();
|
|
const controller = new AbortController();
|
|
pending = controller;
|
|
status.textContent = '正在查询钉钉花名册…';
|
|
results.replaceChildren();
|
|
const url = new URL(form.dataset.searchUrl);
|
|
url.searchParams.set('q', input.value.trim());
|
|
try {
|
|
const response = await fetch(url, {signal:controller.signal, credentials:'same-origin', headers:{Accept:'application/json'}});
|
|
if (!response.ok) throw new Error('unavailable');
|
|
const data = await response.json();
|
|
people.clear();
|
|
for (const person of data.people) {
|
|
people.set(person.id, person);
|
|
const row = document.createElement('div');
|
|
row.className = 'flex flex-wrap items-center justify-between gap-3 border-b border-gray-200 py-3 text-sm';
|
|
const name = document.createElement('span');
|
|
name.textContent = person.name + (person.account ? ' · 账号:' + person.account : '') + ' · ' + person.reason;
|
|
row.append(name);
|
|
const actions = document.createElement('div');
|
|
actions.className = 'flex gap-3';
|
|
for (const [stage, label] of [['first','加入初审'],['final','加入复审']]) {
|
|
const button = document.createElement('button');
|
|
button.type = 'button'; button.textContent = label;
|
|
button.dataset.reviewerAdd = stage; button.dataset.reviewerId = person.id;
|
|
button.disabled = !person.selectable;
|
|
button.className = person.selectable ? 'settings-accent' : 'text-gray-600 cursor-not-allowed';
|
|
actions.append(button);
|
|
}
|
|
row.append(actions); results.append(row);
|
|
}
|
|
status.textContent = data.people.length ? '最多显示 12 人,重名请核对对应系统账号;可缩小查询范围。' : '未找到人员,请检查姓名或花名后重试。';
|
|
} catch (error) {
|
|
if (error.name !== 'AbortError') status.textContent = '钉钉花名册暂时无法查询,请稍后重新点击查询人员。';
|
|
}
|
|
}
|
|
document.addEventListener('click', event => {
|
|
const button = event.target.closest('[data-reviewer-search-button], [data-reviewer-add], [data-reviewer-remove]');
|
|
const form = button?.closest('[data-reviewers-form]');
|
|
if (!form) return;
|
|
if (button.hasAttribute('data-reviewer-search-button')) { search(form); return; }
|
|
if (button.hasAttribute('data-reviewer-remove')) { button.closest('li').remove(); return; }
|
|
const person = people.get(button.dataset.reviewerId);
|
|
if (!person?.selectable) return;
|
|
const stage = button.dataset.reviewerAdd;
|
|
const list = form.querySelector(`[data-reviewer-selected="${stage}"]`);
|
|
const selected = [...list.querySelectorAll('input')];
|
|
const status = form.querySelector('[data-reviewer-search-status]');
|
|
if (selected.some(input => input.value === person.id)) { status.textContent = '该人员已在此环节名单中。'; return; }
|
|
if (selected.length >= 10) { status.textContent = '每个环节最多选择 10 人。'; return; }
|
|
const row = document.createElement('li');
|
|
row.className = 'flex items-center justify-between gap-3 rounded-lg border border-gray-200 px-3 py-2 text-sm';
|
|
const input = document.createElement('input');
|
|
input.type = 'hidden'; input.name = stage + '[]'; input.value = person.id;
|
|
const name = document.createElement('span'); name.textContent = person.name;
|
|
const remove = document.createElement('button');
|
|
remove.type = 'button'; remove.dataset.reviewerRemove = ''; remove.className = 'settings-accent'; remove.textContent = '移除';
|
|
remove.setAttribute('aria-label', '移除' + person.name);
|
|
row.append(input, name, remove); list.append(row);
|
|
status.textContent = '已加入名单,请保存审核人员。';
|
|
});
|
|
document.addEventListener('keydown', event => {
|
|
if (event.key === 'Enter' && event.target.matches('[data-reviewer-search]')) {
|
|
event.preventDefault(); search(event.target.closest('[data-reviewers-form]'));
|
|
}
|
|
});
|
|
})();
|
|
</script>
|
|
@endpush
|
|
@endonce
|