commit
This commit is contained in:
406
kngil/js/adm.js
Normal file
406
kngil/js/adm.js
Normal file
@@ -0,0 +1,406 @@
|
||||
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(`/kngil/bbs/adm.php?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('/kngil/bbs/adm.php')
|
||||
.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('/kngil/bbs/adm.php?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: []
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user