(function () { 'use strict'; let members = new Map(); let loading = false; let scheduled = false; function token() { const match = document.cookie.match(/(?:^|;\s*)accessToken=([^;]+)/); return match ? decodeURIComponent(match[1]) : ''; } function currentId() { try { return JSON.parse(atob(token().split('.')[1].replace(/-/g, '+').replace(/_/g, '/'))).sub; } catch (_) { return ''; } } function allowed() { return currentId() === 'master' || currentId() === 'chals'; } async function api(path, method) { const response = await fetch(path, { method: method || 'GET', headers: {Authorization: 'Bearer ' + token()}, credentials: 'same-origin' }); if (!response.ok) { let detail = ''; try { const error = await response.json(); detail = error.detail || error.message || ''; } catch (_) {} throw new Error(detail || (response.status === 403 ? '관리 권한이 없거나 보호된 계정입니다. 다시 로그인해 주세요.' : '요청에 실패했습니다.')); } return response.status === 204 ? null : response.json().catch(function () { return null; }); } async function loadMembers() { if (loading || !allowed()) return; loading = true; try { const list = await api('/api/member/list'); members = new Map(list.map(function (member) { return [member.memId, member]; })); schedule(); } catch (error) { console.error('회원 관리 목록을 가져오지 못했습니다.', error); } finally { loading = false; } } function decorate() { if (location.pathname !== '/joinId') return; const title = Array.from(document.querySelectorAll('h6')).find(function (node) { return node.textContent.trim() === '회원 목록'; }); const table = title && title.parentElement.querySelector('table'); if (!table) return; const head = table.querySelector('thead tr'); const rows = table.querySelectorAll('tbody tr'); if (!head) return; const nativeReset = Array.from(head.children).find(function (cell) { return cell.textContent.trim() === '초기화'; }); if (nativeReset) { const index = Array.from(head.children).indexOf(nativeReset); nativeReset.style.display = 'none'; rows.forEach(function (row) { if (row.children[index]) row.children[index].style.display = 'none'; }); } if (!allowed()) return; if (!head.querySelector('[data-doffice-admin-head]')) { const cell = document.createElement('th'); cell.textContent = '관리'; cell.setAttribute('data-doffice-admin-head', ''); cell.className = 'doffice-admin-head'; head.appendChild(cell); } rows.forEach(function (row) { if (row.querySelector('[data-doffice-admin-actions]')) return; const id = row.children[1] && row.children[1].textContent.trim(); if (!id || !members.has(id)) return; const cell = document.createElement('td'); cell.className = 'doffice-admin-actions'; cell.setAttribute('data-doffice-admin-actions', ''); cell.innerHTML = '' + ''; if (id === 'master' || id === 'chals') { cell.querySelectorAll('button').forEach(function (button) { button.disabled = true; }); } row.appendChild(cell); }); } function schedule() { if (scheduled) return; scheduled = true; setTimeout(function () { scheduled = false; decorate(); }, 0); } document.addEventListener('click', async function (event) { const button = event.target.closest('[data-doffice-action]'); if (!button || !allowed()) return; const row = button.closest('tr'); const id = row && row.children[1] && row.children[1].textContent.trim(); let member = members.get(id); if (!member) { await loadMembers(); member = members.get(id); } if (!member) return alert('회원 정보를 다시 불러온 뒤 시도해 주세요.'); const action = button.getAttribute('data-doffice-action'); const question = action === 'delete' ? member.memName + ' (' + id + ') 계정을 삭제하시겠습니까? 기존 업무·이력은 유지됩니다.' : member.memName + ' (' + id + ') 비밀번호를 1234로 초기화하시겠습니까?'; if (!confirm(question)) return; button.disabled = true; try { if (action === 'delete') { await api('/api/admin/deleteMember/' + encodeURIComponent(member.memCode), 'DELETE'); alert('계정이 삭제되었습니다.'); location.reload(); } else { await api('/api/admin/resetPw?memCode=' + encodeURIComponent(member.memCode)); alert('비밀번호가 1234로 초기화되었습니다.'); } } catch (error) { alert(error.message); } finally { button.disabled = false; } }); const observer = new MutationObserver(schedule); observer.observe(document.documentElement, {childList: true, subtree: true}); setInterval(function () { if (location.pathname !== '/joinId' || !allowed()) return; if (!members.size) loadMembers(); else schedule(); }, 1500); document.addEventListener('submit', function () { if (location.pathname === '/joinId') setTimeout(loadMembers, 1200); }, true); })();