Files
kngil_home/kngil/js/adm_product_popup.js
2026-02-04 12:40:02 +09:00

280 lines
11 KiB
JavaScript

import { w2grid, w2ui, w2popup, w2alert } from 'https://cdn.jsdelivr.net/gh/vitmalina/w2ui@master/dist/w2ui.es6.min.js'
/* -------------------------------------------------
공통 유틸
------------------------------------------------- */
function destroyGrid(name) {
if (w2ui[name]) {
w2ui[name].destroy()
}
}
function loadBaseCode(mainCd) {
return fetch(`/admin/api/company?action=base_code&main_cd=${mainCd}`)
.then(res => res.json())
.then(json => {
if (json.status !== 'success') {
throw new Error(json.message || '공통코드 로딩 실패')
}
return json.items
})
}
/* =================================================
상품등록 팝업 (슈퍼관리자 전용)
================================================= */
export function openProductPopup() {
if (w2ui.productGrid) {
w2ui.productGrid.destroy()
}
w2popup.open({
title: '상품등록',
width: 900,
height: 600,
modal: true,
body: `
<div class="product-popup">
<div style="display: flex; justify-content: flex-end; padding: 1S0px; gap: 5px;">
<button id="prodAdd">추가</button>
<button id="prodRemove">삭제</button>
<button id="prodSave" class="btn-product">저장</button>
</div>
<div id="productGrid" style="height:460px;"></div>
</div>
`,
onOpen(event) {
event.onComplete = () => {
// 1. 그리드를 생성합니다.
createProductGrid('#productGrid');
// 1. 추가 버튼
document.getElementById('prodAdd').onclick = () => {
const g = w2ui.productGrid
if (!g) return
// 신규 row용 recid (음수로 충돌 방지)
const newRecid = -Date.now()
g.add({
row_status: 'I',
recid: newRecid,
__isNew: true, // ⭐ 신규 플래그
use_yn: 'Y'
}, true)
g.select(newRecid)
g.scrollIntoView(newRecid)
// commonAdd('productGrid', { use_yn: 'Y', itm_amt: 0, area: 0 });
};
// 삭제 버튼 이벤트 연결
const removeBtn = document.getElementById('prodRemove');
if (removeBtn) {
removeBtn.onclick = () => {
const g = w2ui.productGrid;
if (!g) return;
// 1. 선택된 행 가져오기
const sel = g.getSelection();
if (!sel.length) {
alert('삭제할 상품을 선택하세요.');
return;
}
// 2. 상품코드 추출
const ids = sel
.map(recid => g.get(recid)?.itm_cd)
.filter(Boolean);
if (!ids.length) {
alert('삭제 가능한 항목이 없습니다.');
return;
}
// 3. 브라우저 기본 확인창 사용 (가장 확실함)
if (confirm(`선택한 ${ids.length}개의 상품을 삭제하시겠습니까?`)) {
fetch('/admin/api/product/delete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'delete', ids: ids })
})
.then(res => {
// 서버 응답이 오면 일단 텍스트로 받아서 확인
return res.text();
})
.then(text => {
try {
const json = JSON.parse(text);
if (json.status === 'success') {
alert('삭제 완료');
loadProductData(); // 목록 새로고침
} else {
alert(json.message || '삭제 실패');
}
} catch (e) {
console.error('응답 파싱 에러:', text);
alert('서버 응답 처리 중 오류가 발생했습니다.');
}
})
.catch(err => {
console.error('통신 에러:', err);
alert('서버와 통신할 수 없습니다.');
});
}
};
}
// 3. 저장 버튼
document.getElementById('prodSave').onclick = () => {
// 현재 사용 중인 grid
const g = w2ui.productGrid
if (!g) return
const changes = g.getChanges()
if (!changes.length) {
w2alert('변경된 내용이 없습니다.')
return
}
const inserts = []
const updates = []
changes.forEach(c => {
const rec = g.get(c.recid)
if (!rec) return
// 🔥 핵심: 원본 rec + 변경값 c 병합
const merged = { ...rec, ...c }
if (rec.__isNew) {
// INSERT → 전체 row 필요
inserts.push(merged)
} else {
// UPDATE → PK + 변경 컬럼
updates.push({
itm_cd : merged.itm_cd,
itm_nm : merged.itm_nm,
area : merged.area,
itm_amt: merged.itm_amt,
use_yn : merged.use_yn,
rmks : merged.rmks
})
}
})
console.log('INSERTS', inserts)
console.log('UPDATES', updates)
fetch('/admin/api/product/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'save',
inserts,
updates
})
})
.then(res => {
// 서버가 준 응답이 괜찮은지 확인
if (!res.ok) throw new Error('서버 응답 오류');
return res.json(); // 처음부터 깔끔하게 데이터로 읽기
})
.then(json => {
// 이제 json.status를 바로 쓸 수 있습니다.
if (json.status === 'success') {
w2alert('저장 완료');
w2ui.productGrid.save(); // 빨간 삼각형 없애기
loadProductData(); // 목록 새로고침
} else {
w2alert(json.message || '저장 실패');
}
})
.catch(err => {
console.error('에러 발생:', err);
w2alert('처리 중 오류가 발생했습니다.');
});
};
}
}
})
}
//상품등록 그리드
export async function createProductGrid(boxId) {
if (w2ui.productGrid) w2ui.productGrid.destroy();
destroyGrid('productGrid')
const authItems = await loadBaseCode('BS210')
const grid = new w2grid({
name: 'productGrid',
box: boxId,
show: {
footer: true,
selectColumn: true,
lineNumbers: true // 행 번호를 표시하면 디버깅이 편합니다.
},
columns: [
/*
{ field: 'row_status', text: ' ', size: '30px', attr: 'align=center',
render: function (record) {
// 1. 신규 추가된 행 (recid가 임시값이거나 DB에 없는 경우)
if (record.is_new) return '<span style="color: green;">I</span>';
// 2. 수정된 데이터 (w2ui.changes 객체가 존재하는 경우)
if (record.w2ui && record.w2ui.changes) return '<span style="color: blue;">U</span>';
// 3. 일반 상태
return '<span style="color: gray;"> </span>';
}
},
*/
{ field: 'itm_cd', text: '상품코드', size: '80px',attr: 'align=center',style: 'text-align: center', attr: 'align=center', editable: { type: 'text' } ,sortable: true}, // name 아님!
{ field: 'itm_nm', text: '상품명', size: '120px', attr: 'align=center',style: 'text-align: center', editable: { type: 'text' } ,sortable: true}, // name 아님!
{ field: 'area', text: '제공량', size: '100px', attr: 'align=center',render: 'number:0' , editable: { type: 'float' } ,sortable: true}, // volume 아님!
{ field: 'itm_amt', text: '단가', size: '120px', attr: 'align=center',render: 'number:0', editable: { type: 'int' } ,sortable: true}, //
{ field: 'use_yn', text: '사용여부', size: '80px',attr: 'align=center',style: 'text-align: center', attr: 'align=center',
editable: { type: 'list', items: authItems, filter: false ,showAll: true } ,
render(record) {
const item = authItems.find(i => i.id === record.use_yn)
return item ? item.text : record.use_yn
},sortable: true
},
{ field: 'rmks', text: '비고', size: '200px', attr: 'align=center', editable: { type: 'text' } ,sortable: true} // memo 아님!
],
records: [] // 처음엔 비워둠
});
// 데이터 호출 함수 실행
loadProductData();
return grid;
}
// 데이터를 서버에서 불러오는 함수
async function loadProductData() {
try {
w2ui.productGrid.lock('조회 중...', true);
const response = await fetch('/admin/api/product'); // PHP 파일 호출
const data = await response.json();
w2ui.productGrid.clear();
w2ui.productGrid.add(data);
w2ui.productGrid.unlock();
} catch (e) {
console.error(e);
w2ui.productGrid.unlock();
w2alert('데이터 로드 실패');
}
}