import { w2grid, w2ui, w2popup, w2alert } from 'https://cdn.jsdelivr.net/gh/vitmalina/w2ui@master/dist/w2ui.es6.min.js' import { setUserGridMode, loadData } from './adm_comp.js' export function destroyGrid(name) { if (w2ui[name]) { w2ui[name].destroy() } } /* ---------------------------------------- Super Admin Grid 생성 (상단) ---------------------------------------- */ export function createSuperAdminGrid(boxId) { destroyGrid('superGrid') userGrid const grid = new w2grid({ name: 'superGrid', box: boxId, show: { // toolbar: true, footer: true, // toolbarReload: true, // toolbarColumns: true, // toolbarSearch: true }, // multiSearch: true, // searches: [ // { field: 'member_id', text: 'ID', type: 'text' }, // { field: 'user_nm', text: '회원명', type: 'text' }, // { field: 'co_nm', text: '회사명', type: 'text' }, // { // field: 'stat_bc', // text: '회원상태', // type: 'list', // options: { // items: [ // { id: 'Y', text: '사용' }, // { id: 'N', text: '미사용' } // ] // } // } // ], columns: [ { field: 'recid', text: '#', size: '50px', attr: 'align=center', editable: false, resizable: true, sortable: true }, { field: 'member_id', text: 'ID', size: '90px', editable: false, resizable: true, sortable: true }, { field: 'user_nm', text: '회원명', size: '90px', editable: false, resizable: true, sortable: true }, { field: 'tel_no', text: '연락처', size: '120px', editable: {type : 'text'}, resizable: true, sortable: true }, { field: 'email', text: 'E-mail', size: '180px', editable: {type : 'text'}, resizable: true, sortable: true }, { field: 'co_nm', text: '회사명', size: '120px', editable: {type : 'text'}, resizable: true, sortable: true }, { field: 'bs_no', text: '사업자번호', size: '120px', editable: { type: 'text' }, resizable: true, sortable: true }, { field: 'join_dt', text: '가입일', size: '100px', editable: false, resizable: true, sortable: true }, { field: 'user_y', text: '사용자수', size: '80px', attr: 'align=right', editable: false, resizable: true, sortable: true }, { field: 'buy_area', text: '제공면적', size: '100px', attr: 'align=right', editable: false, resizable: true, sortable: true }, { field: 'use_area', text: '사용면적', size: '100px', attr: 'align=right', editable: false, resizable: true, sortable: true }, { field: 'rem_area', text: '잔여면적', size: '100px', attr: 'align=right', editable: false, resizable: true, sortable: true }, { field: 'stat_bc', text: '회원상태', size: '80px', resizable: true, sortable: true, editable: false, render(record) { switch (record.stat_bc) { case 'SA100100': return '사용중' case 'SA100200': return '탈퇴' default: return record.stat_bc || '' } } }, { field: 'memo', text: '메모', size: '100px', attr: 'align=right', editable: {type : 'text'}, resizable: true, sortable: true }, ], records: [], /* -------------------------------- 상단 회사 클릭 → 하단 사용자 Grid 갱신 -------------------------------- */ onClick(event) { if (!event.detail.recid) return const record = this.get(event.detail.recid) if (!record) return // 하단 영역 표시 document.getElementById('detailCard').style.display = 'block' // 하단 사용자 로드 // fetch(`/admin/api/super?action=user_list&member_id=${record.member_id}`) // .then(res => res.json()) // .then(d => { // if (d.status !== 'success') { // w2alert('사용자 조회 실패') // return // } // const g = w2ui.detailGrid // g.clear() // g.add(d.records || []) // }) import('./adm_comp.js').then(m => { m.loadUsersByMember(record.member_id) }) }, onSelect(event) { event.onComplete = () => { const btn = document.getElementById('btnServiceRegister') if (btn) btn.disabled = false } }, onUnselect(event) { event.onComplete = () => { const btn = document.getElementById('btnServiceRegister') if (btn && !this.getSelection().length) { btn.disabled = true } } }, // onEditField(event) { // if (event.field !== 'bs_no') return // event.onComplete = () => { // const input = event.input // if (!input) return // input.addEventListener('input', () => { // let v = input.value.replace(/\D/g, '').slice(0, 10) // if (v.length >= 6) { // v = `${v.slice(0, 3)}-${v.slice(3, 5)}-${v.slice(5)}` // } else if (v.length >= 4) { // v = `${v.slice(0, 3)}-${v.slice(3)}` // } // input.value = v // }) // } // }, onChange(event) { event.onComplete = function (ev) { let rec = grid.get(ev.recid); if (!rec) return; let field = grid.columns[ev.column].field; let val = ev.value_new; /* =============================== 🔴 사업자번호(bs_no) 전용 처리 =============================== */ if (field === 'bs_no') { // 숫자만 추출 let digits = String(val || '').replace(/\D/g, ''); // 🔥 입력 중에는 아무 것도 안 건드린다 if (digits.length < 10) { return; } // 10자리 초과 방지 digits = digits.slice(0, 10); // 최종 포맷 let formatted = `${digits.slice(0, 3)}-${digits.slice(3, 5)}-${digits.slice(5)}`; // 🔥 여기서만 set grid.set(ev.recid, { bs_no: formatted }); grid.refreshRow(ev.recid); return; } /* =============================== 🔵 기존 공통 로직 =============================== */ if (typeof val === "object" && val !== null) { val = val.text; } grid.set(ev.recid, { [field]: val }); if (field === 'quantity' || field === 'unit_price' || field === 'discount') { let qty = parseInt(rec.quantity) || 0; let unit = parseInt(rec.unit_price) || 0; let dc = parseInt(rec.discount) || 0; let total = Math.max(0, qty * unit - dc); grid.set(ev.recid, { total_amount: total }); } grid.refresh(); }; } // onDblClick(event) { // if (!event.detail.recid) return // const record = this.get(event.detail.recid) // if (!record) return // import('./adm_service.js').then(m => { // m.openServiceRegisterPopup({ // memberId: record.member_id, // memberName: record.user_nm, // company: record.co_nm, // bizNo: record.bs_no // }) // }) // } }) loadCompanies() return grid } //사업자 번호 포맷 function formatBizNo(value) { const digits = String(value || '').replace(/\D/g, ''); if (digits.length !== 10) return null; return `${digits.slice(0, 3)}-${digits.slice(3, 5)}-${digits.slice(5)}`; } /* ---------------------------------------- 상단 회사 목록 로드 ---------------------------------------- */ function loadCompanies() { fetch('/admin/api/super') .then(res => res.json()) .then(json => { if (!json.records) return w2ui.superGrid.clear() w2ui.superGrid.add(json.records) }) .catch(err => { console.error('회사 목록 로드 실패:', err) }) } // ========================= // 서비스등록 버튼 // ========================= document.getElementById('btnServiceRegister') .addEventListener('click', () => { const g = w2ui.superGrid if (!g) return const sel = g.getSelection() if (!sel.length) { w2alert('서비스를 등록할 회원을 선택하세요.') return } const r = g.get(sel[0]) // 신규 행 방지 if (!r.member_id || String(r.member_id).startsWith('new_')) { w2alert('저장된 회원만 서비스 등록이 가능합니다.') return } import('/kngil/js/adm_service.js').then(m => { m.openServiceRegisterPopup({ memberId: r.member_id, memberName: r.user_nm, company: r.co_nm, bizNo: r.bs_no }) }) }) //저장 let isSaveBound = false export function bindSaveButton() { if (isSaveBound) return isSaveBound = true const btn = document.getElementById('btnSave') if (!btn) return btn.addEventListener('click', () => { const g = w2ui.superGrid if (!g) return document.activeElement?.blur() g.finishEditing?.() const changes = g.getChanges() changes.forEach(ch => { // bs_no가 변경 대상이면 if ('bs_no' in ch) { const formatted = formatBizNo(ch.bs_no); if (!formatted) { w2alert('사업자번호는 숫자 10자리여야 합니다.\n예: 123-45-67890'); throw new Error('invalid bs_no'); } // 🔥 changes 객체를 직접 수정 ch.bs_no = formatted; } }); if (!changes.length) { w2alert('변경된 내용이 없습니다.') return } // 🔥 recid 기준으로 원본 record + 변경값 병합 const updates = changes.map(c => { const r = g.get(c.recid) return { ...r, ...c } }) // 🔥 member_id 필수 체크 if (!updates[0]?.member_id) { w2alert('member_id가 없습니다.') return } fetch('/admin/api/super?action=save', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ member_id: updates[0].member_id, // ✅ 핵심 updates }) }) .then(res => res.json()) .then(json => { if (json.status !== 'success') { throw new Error(json.message) } updates.forEach(u => { const r = g.get(u.recid); if (r && u.bs_no) { r.bs_no = u.bs_no; // 하이픈 포함 값 g.refreshRow(u.recid); } }); // g.mergeChanges() // changes 강제 제거 g.changes = []; // 수정 상태 플래그 제거 g.records.forEach(r => { if (r.w2ui) delete r.w2ui.changes; }); // 화면 다시 그리기 g.refresh(); w2alert('저장되었습니다.') }) .catch(err => { console.error(err) w2alert(err.message || '저장 실패') }) }) } export function createDetailGrid(boxId) { if (w2ui.detailGrid) w2ui.detailGrid.destroy() new w2grid({ name: 'detailGrid', box: boxId, show: { footer: true }, columns: [ { field: 'recid', text: '#', size: '50px' }, { field: 'user_id', text: 'ID', size: '120px' }, { field: 'user_nm', text: '이름', size: '120px' }, { field: 'dept_nm', text: '부서', size: '120px' }, { field: 'email', text: 'E-mail', size: '200px' }, { field: 'use_yn', text: '사용', size: '80px' } ], records: [] }) }