진료유형 설정(전체보기 탭) 수정
This commit is contained in:
@@ -209,4 +209,44 @@ public class MedicalCategoryController extends ManagerDraftAction {
|
|||||||
log.debug("MedicalCategoryController delMultiMedicalCategory END");
|
log.debug("MedicalCategoryController delMultiMedicalCategory END");
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 진료유형 인라인(부분) 수정
|
||||||
|
*/
|
||||||
|
@PostMapping("/updatePartialMedicalCategory.do")
|
||||||
|
public HashMap<String, Object> updatePartialMedicalCategory(@RequestBody HashMap<String, Object> paramMap,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
log.debug("MedicalCategoryController updatePartialMedicalCategory START");
|
||||||
|
HashMap<String, Object> map = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
map = medicalCategoryService.updatePartialMedicalCategory(paramMap);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("updatePartialMedicalCategory : ", e);
|
||||||
|
map.put("msgCode", Constants.FAIL);
|
||||||
|
map.put("msgDesc", "서버 오류가 발생했습니다.");
|
||||||
|
}
|
||||||
|
log.debug("MedicalCategoryController updatePartialMedicalCategory END");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 진료유형 인라인(부분) 여러건 일괄 수정 (전체보기 저장)
|
||||||
|
*/
|
||||||
|
@PostMapping("/updateBatchMedicalCategory.do")
|
||||||
|
public HashMap<String, Object> updateBatchMedicalCategory(@RequestBody List<MedicalCategoryDTO> list,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
log.debug("MedicalCategoryController updateBatchMedicalCategory START");
|
||||||
|
HashMap<String, Object> map = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
map = medicalCategoryService.updateBatchMedicalCategory(list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("updateBatchMedicalCategory : ", e);
|
||||||
|
map.put("msgCode", Constants.FAIL);
|
||||||
|
map.put("msgDesc", "서버 오류가 발생했습니다.");
|
||||||
|
}
|
||||||
|
log.debug("MedicalCategoryController updateBatchMedicalCategory END");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,14 @@ public interface MedicalCategoryMapper {
|
|||||||
*/
|
*/
|
||||||
int getChildCategoryCount(HashMap<String, Object> paramMap);
|
int getChildCategoryCount(HashMap<String, Object> paramMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 카테고리 정보 부분 수정 (인라인 에디팅)
|
||||||
|
*
|
||||||
|
* @param paramMap
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int updatePartialMedicalCategory(HashMap<String, Object> paramMap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 거래처 목록 조회 (Depth 3 매핑용)
|
* 거래처 목록 조회 (Depth 3 매핑용)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -91,6 +91,36 @@ public class MedicalCategoryService {
|
|||||||
return roots;
|
return roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 카테고리 정보 부분 다건 일괄 수정 (전체보기 저장)
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public HashMap<String, Object> updateBatchMedicalCategory(List<MedicalCategoryDTO> list) throws Exception {
|
||||||
|
HashMap<String, Object> map = new HashMap<>();
|
||||||
|
try {
|
||||||
|
int successCount = 0;
|
||||||
|
for (MedicalCategoryDTO dto : list) {
|
||||||
|
// dto의 빈 값은 쿼리의 <if> 조건을 통과하지 않아 업데이트 되지 않음
|
||||||
|
successCount += medicalCategoryMapper.updateMedicalCategory(dto);
|
||||||
|
}
|
||||||
|
if (successCount > 0) {
|
||||||
|
map.put("msgCode", Constants.OK);
|
||||||
|
map.put("success", true);
|
||||||
|
map.put("msgDesc", successCount + "건이 수정되었습니다.");
|
||||||
|
} else {
|
||||||
|
map.put("msgCode", Constants.FAIL);
|
||||||
|
map.put("msgDesc", "수정 사항이 없거나 실패했습니다.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("updateBatchMedicalCategory Error: ", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 특정 카테고리 상세 정보 조회
|
* 특정 카테고리 상세 정보 조회
|
||||||
*/
|
*/
|
||||||
@@ -282,4 +312,30 @@ public class MedicalCategoryService {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 카테고리 정보 부분 수정 (인라인 에디팅)
|
||||||
|
*
|
||||||
|
* @param paramMap
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public HashMap<String, Object> updatePartialMedicalCategory(HashMap<String, Object> paramMap) throws Exception {
|
||||||
|
HashMap<String, Object> map = new HashMap<>();
|
||||||
|
try {
|
||||||
|
int result = medicalCategoryMapper.updatePartialMedicalCategory(paramMap);
|
||||||
|
if (result > 0) {
|
||||||
|
map.put("msgCode", Constants.OK);
|
||||||
|
map.put("success", true);
|
||||||
|
map.put("msgDesc", "수정되었습니다.");
|
||||||
|
} else {
|
||||||
|
map.put("msgCode", Constants.FAIL);
|
||||||
|
map.put("msgDesc", "수정 실패했습니다.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("updatePartialMedicalCategory Error: ", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,7 +248,31 @@
|
|||||||
WHERE pid = #{pid}
|
WHERE pid = #{pid}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
<!-- 7. 거래처 목록 조회 (Depth 3 전용) -->
|
<!-- 7. 정보 부분 수정 Update -->
|
||||||
|
<update id="updatePartialMedicalCategory" parameterType="java.util.HashMap">
|
||||||
|
UPDATE medical_divi_list
|
||||||
|
<set>
|
||||||
|
<if test='updateField == "divi_name"'>
|
||||||
|
divi_name = #{updateValue},
|
||||||
|
</if>
|
||||||
|
<if test='updateField == "kind_cost"'>
|
||||||
|
kind_cost = #{updateValue},
|
||||||
|
</if>
|
||||||
|
<if test='updateField == "kind_unit"'>
|
||||||
|
kind_unit = #{updateValue},
|
||||||
|
</if>
|
||||||
|
<if test='updateField == "list_use"'>
|
||||||
|
list_use = #{updateValue},
|
||||||
|
</if>
|
||||||
|
<if test='updateField == "tax_free"'>
|
||||||
|
tax_free = #{updateValue},
|
||||||
|
</if>
|
||||||
|
up_date = NOW()
|
||||||
|
</set>
|
||||||
|
WHERE pid = #{pid}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!-- 8. 거래처 목록 조회 (Depth 3 전용) -->
|
||||||
<select id="getCustList" parameterType="java.util.HashMap" resultType="java.util.HashMap">
|
<select id="getCustList" parameterType="java.util.HashMap" resultType="java.util.HashMap">
|
||||||
SELECT pid,
|
SELECT pid,
|
||||||
cust_name,
|
cust_name,
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ $(document).ready(function () {
|
|||||||
index: "pid",
|
index: "pid",
|
||||||
layout: "fitColumns",
|
layout: "fitColumns",
|
||||||
placeholder: "상위 항목을 선택하세요.",
|
placeholder: "상위 항목을 선택하세요.",
|
||||||
selectable: true,
|
selectableRows: true,
|
||||||
height: "100%",
|
height: "100%",
|
||||||
columnDefaults: {
|
columnDefaults: {
|
||||||
headerTooltip: true,
|
headerTooltip: true,
|
||||||
@@ -149,9 +149,6 @@ $(document).ready(function () {
|
|||||||
columns: [
|
columns: [
|
||||||
{ title: "순번", formatter: "rownum", width: 38, hozAlign: "center", headerSort: false, cssClass: "col-sm" },
|
{ title: "순번", formatter: "rownum", width: 38, hozAlign: "center", headerSort: false, cssClass: "col-sm" },
|
||||||
{ title: "명칭", field: "divi_name", formatter: categoryNameFormatter, tooltip: true },
|
{ title: "명칭", field: "divi_name", formatter: categoryNameFormatter, tooltip: true },
|
||||||
// { title: "거래처", field: "cust_name", width: 90, hozAlign: "center", tooltip: true },
|
|
||||||
// { title: "담당자(연락처)", field: "cust_contact", width: 110, hozAlign: "center", tooltip: true },
|
|
||||||
// { title: "단가", field: "kind_cost", width: 80, hozAlign: "right", formatter: costFormatter },
|
|
||||||
{ title: "순서", field: "divi_sort", width: 38, hozAlign: "center", cssClass: "col-sm" },
|
{ title: "순서", field: "divi_sort", width: 38, hozAlign: "center", cssClass: "col-sm" },
|
||||||
{ title: "하위", width: 50, hozAlign: "center", headerSort: false, formatter: function (c) { return addDescendantFormatter(c, 3); }, cellClick: function (e, cell) { e.stopPropagation(); var d = cell.getRow().getData(); addChildCategory(d.pid, 4, d.divi_name); } }
|
{ title: "하위", width: 50, hozAlign: "center", headerSort: false, formatter: function (c) { return addDescendantFormatter(c, 3); }, cellClick: function (e, cell) { e.stopPropagation(); var d = cell.getRow().getData(); addChildCategory(d.pid, 4, d.divi_name); } }
|
||||||
],
|
],
|
||||||
@@ -329,6 +326,14 @@ $(document).ready(function () {
|
|||||||
function buildNodeMap(nodes) {
|
function buildNodeMap(nodes) {
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
nodeMap[node.pid] = node;
|
nodeMap[node.pid] = node;
|
||||||
|
|
||||||
|
// 편집 모드 진입 시 입력창(Input)에 기존 값이 제대로 표시되게 하기 위해
|
||||||
|
// 공통 피쳐인 divi_name 값을 각 뎁스별 전용 열 필드에 복사해 둡니다.
|
||||||
|
if (node.divi_dept == 2) node.divi_name2 = node.divi_name;
|
||||||
|
else if (node.divi_dept == 3) node.divi_name3 = node.divi_name;
|
||||||
|
else if (node.divi_dept == 4) node.divi_name4 = node.divi_name;
|
||||||
|
else if (node.divi_dept == 5) node.divi_name5 = node.divi_name;
|
||||||
|
|
||||||
if (node._children && node._children.length > 0) {
|
if (node._children && node._children.length > 0) {
|
||||||
buildNodeMap(node._children);
|
buildNodeMap(node._children);
|
||||||
} else if (node._children && node._children.length === 0) {
|
} else if (node._children && node._children.length === 0) {
|
||||||
@@ -599,43 +604,172 @@ $(document).ready(function () {
|
|||||||
|
|
||||||
function initOverviewGrid(callback) {
|
function initOverviewGrid(callback) {
|
||||||
tableOverview = new Tabulator("#gridOverview", {
|
tableOverview = new Tabulator("#gridOverview", {
|
||||||
|
editTriggerEvent: "dblclick",
|
||||||
dataTree: true,
|
dataTree: true,
|
||||||
|
dataTreeElementColumn: "divi_name",
|
||||||
dataTreeStartExpanded: true,
|
dataTreeStartExpanded: true,
|
||||||
|
dataTreeChildIndent: 0,
|
||||||
layout: "fitColumns",
|
layout: "fitColumns",
|
||||||
placeholder: "데이터를 불러오는 중...",
|
placeholder: "데이터를 불러오는 중...",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
columnDefaults: {
|
columnDefaults: {
|
||||||
headerTooltip: true,
|
headerTooltip: true,
|
||||||
headerHozAlign: "center",
|
headerHozAlign: "center",
|
||||||
tooltip: true
|
tooltip: true,
|
||||||
|
headerSort: false
|
||||||
},
|
},
|
||||||
columns: [
|
columns: [
|
||||||
{ title: "1depth", field: "divi_name", width: "15%", hozAlign: "left", formatter: overviewDepthFormatter(1) },
|
{ title: "진료과목", field: "divi_name", width: "6%", hozAlign: "left", formatter: overviewDepthFormatter(1), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 1; }, cellClick: handleTreeToggleClick },
|
||||||
{ title: "2depth", field: "divi_name2", width: "12%", hozAlign: "left", formatter: overviewDepthFormatter(2) },
|
{ title: "진료유형", field: "divi_name2", width: "16.25%", hozAlign: "left", formatter: overviewDepthFormatter(2), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 2; }, cellClick: handleTreeToggleClick },
|
||||||
{ title: "3depth", field: "divi_name3", width: "18%", hozAlign: "left", formatter: overviewDepthFormatter(3) },
|
{ title: "제품/시술", field: "divi_name3", width: "17.75%", hozAlign: "left", formatter: overviewDepthFormatter(3), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 3; }, cellClick: handleTreeToggleClick },
|
||||||
{ title: "4depth", field: "divi_name4", width: "12%", hozAlign: "left", formatter: overviewDepthFormatter(4) },
|
{ title: "용량/출력", field: "divi_name4", width: "14.75%", hozAlign: "left", formatter: overviewDepthFormatter(4), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 4; }, cellClick: handleTreeToggleClick },
|
||||||
{ title: "단가", field: "kind_cost", width: "10%", formatter: costFormatter, hozAlign: "right" },
|
{ title: "부위", field: "divi_name5", width: "14.75%", hozAlign: "left", formatter: overviewDepthFormatter(5), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 5; }, cellClick: handleTreeToggleClick },
|
||||||
{ title: "단위", field: "kind_unit", width: "10%", hozAlign: "center" },
|
{ title: "깊이", field: "divi_dept", width: "4%", hozAlign: "center", editor: "number", editorParams: { min: 1, max: 5, step: 1 } },
|
||||||
{ title: "사용여부", field: "list_use", width: "10%", formatter: ynFormatter, hozAlign: "center" },
|
{ title: "단가", field: "kind_cost", width: "10%", formatter: costFormatter, hozAlign: "right", editor: "number" },
|
||||||
{ title: "면세여부", field: "tax_free", width: "8%", formatter: ynFormatter, hozAlign: "center" }
|
{ title: "할인가", field: "dc_cost", width: "10%", formatter: costFormatter, hozAlign: "right", editor: "number" },
|
||||||
|
{ title: "단위", field: "kind_unit", width: "8%", hozAlign: "center", editor: "input" },
|
||||||
|
{ title: "사용여부", field: "list_use", width: "6%", formatter: ynFormatter, hozAlign: "center", editor: "list", editorParams: { values: { "y": "Y", "n": "N" } } },
|
||||||
|
{ title: "면세여부", field: "tax_free", width: "6%", formatter: ynFormatter, hozAlign: "center", editor: "list", editorParams: { values: { "y": "Y", "n": "N" } } }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function handleTreeToggleClick(e, cell) {
|
||||||
|
if ($(e.target).closest('.custom-tree-toggle').length > 0 || $(e.target).closest('.tabulator-data-tree-control').length > 0) {
|
||||||
|
cell.getRow().treeToggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tableOverview.on("tableBuilt", function () {
|
tableOverview.on("tableBuilt", function () {
|
||||||
if (typeof callback === 'function') callback();
|
if (typeof callback === 'function') callback();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 인라인 편집 후 임시 저장 처리 (일괄 저장)
|
||||||
|
tableOverview.on("cellEdited", function (cell) {
|
||||||
|
var field = cell.getField();
|
||||||
|
var val = (cell.getValue() || "").toString().trim();
|
||||||
|
var oldVal = (cell.getOldValue() || "").toString().trim();
|
||||||
|
|
||||||
|
if (val === oldVal) return;
|
||||||
|
|
||||||
|
// 진료과목~부위 빈값 검증
|
||||||
|
if (field.startsWith("divi_name")) {
|
||||||
|
if (val === "") {
|
||||||
|
alert("항목명은 비워둘 수 없습니다.");
|
||||||
|
cell.restoreOldValue();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 수정 발생 시 저장/취소 버튼 활성화
|
||||||
|
$("#btnSaveOverview, #btnCancelOverview").show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 전체보기 일괄 저장 / 취소 이벤트 바인딩
|
||||||
|
$(document).on("click", "#btnSaveOverview", function () {
|
||||||
|
var editedCells = tableOverview.getEditedCells();
|
||||||
|
if (editedCells.length === 0) {
|
||||||
|
alert("수정된 항목이 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateMap = {};
|
||||||
|
editedCells.forEach(function (cell) {
|
||||||
|
var data = cell.getRow().getData();
|
||||||
|
var pid = data.pid;
|
||||||
|
var field = cell.getField();
|
||||||
|
var val = (cell.getValue() || "").toString().trim();
|
||||||
|
|
||||||
|
if (!updateMap[pid]) {
|
||||||
|
updateMap[pid] = { pid: pid };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field.startsWith("divi_name")) {
|
||||||
|
updateMap[pid].diviName = val;
|
||||||
|
} else if (field === "divi_dept") {
|
||||||
|
updateMap[pid].diviDept = val;
|
||||||
|
} else if (field === "kind_cost") {
|
||||||
|
updateMap[pid].kindCost = parseFloat(val || 0);
|
||||||
|
} else if (field === "kind_sale_cost") {
|
||||||
|
updateMap[pid].kindSaleCost = parseFloat(val || 0);
|
||||||
|
} else if (field === "kind_unit") {
|
||||||
|
updateMap[pid].kindUnit = val;
|
||||||
|
} else if (field === "list_use") {
|
||||||
|
updateMap[pid].listUse = val;
|
||||||
|
} else if (field === "tax_free") {
|
||||||
|
updateMap[pid].taxFree = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var updateList = Object.values(updateMap);
|
||||||
|
|
||||||
|
if (!confirm("수정된 " + updateList.length + "건의 항목을 저장하시겠습니까?")) return;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: '/settings/medicalCategory/updateBatchMedicalCategory.do',
|
||||||
|
type: 'POST',
|
||||||
|
contentType: 'application/json',
|
||||||
|
data: JSON.stringify(updateList),
|
||||||
|
success: function (res) {
|
||||||
|
if (res.msgCode === '0') {
|
||||||
|
alert(res.msgDesc || "저장되었습니다.");
|
||||||
|
$("#btnSaveOverview, #btnCancelOverview").hide();
|
||||||
|
window.onChangeDepth1Overview();
|
||||||
|
} else {
|
||||||
|
alert(res.msgDesc);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
alert("저장 중 오류가 발생했습니다.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("click", "#btnCancelOverview", function () {
|
||||||
|
if (confirm("수정 중인 내용을 취소하시겠습니까? (원래 데이터로 복귀합니다)")) {
|
||||||
|
$("#btnSaveOverview, #btnCancelOverview").hide();
|
||||||
|
window.loadData(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 도움말 버튼 토글 (전체보기)
|
||||||
|
$(document).on("click", "#btnHelpOverview", function () {
|
||||||
|
$("#overviewGuideBox").slideToggle(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 도움말 버튼 토글 (진료유형 관리)
|
||||||
|
$(document).on("click", "#btnHelpManage", function () {
|
||||||
|
$("#manageGuideBox").slideToggle(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("click", "#btnExpandAll", function () {
|
||||||
|
if (tableOverview) {
|
||||||
|
tableOverview.getRows().forEach(function (row) {
|
||||||
|
row.treeExpand();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("click", "#btnCollapseAll", function () {
|
||||||
|
if (tableOverview) {
|
||||||
|
tableOverview.getRows().forEach(function (row) {
|
||||||
|
row.treeCollapse();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function overviewDepthFormatter(targetDepth) {
|
function overviewDepthFormatter(targetDepth) {
|
||||||
return function (cell) {
|
return function (cell) {
|
||||||
var data = cell.getRow().getData();
|
var data = cell.getRow().getData();
|
||||||
if (parseInt(data.divi_dept, 10) !== targetDepth) return '';
|
if (parseInt(data.divi_dept, 10) !== targetDepth) return '';
|
||||||
|
|
||||||
|
var row = cell.getRow();
|
||||||
var nameStyle = data.list_use === 'y' ? 'font-weight:600;' : 'text-decoration:line-through; color:#aaa;';
|
var nameStyle = data.list_use === 'y' ? 'font-weight:600;' : 'text-decoration:line-through; color:#aaa;';
|
||||||
var color = data.divi_color || '#333';
|
var color = data.divi_color || '#333';
|
||||||
if (data.list_use !== 'y') color = '#aaa';
|
if (data.list_use !== 'y') color = '#aaa';
|
||||||
|
|
||||||
var html = '<span style="' + nameStyle + ' color:' + color + '">' + (data.divi_name || '') + '</span>';
|
var val = cell.getValue() || data.divi_name || '';
|
||||||
|
var html = '<span style="' + nameStyle + ' color:' + color + '">' + val + '</span>';
|
||||||
|
|
||||||
if (data.tax_free === 'y') {
|
if (data.tax_free === 'y') {
|
||||||
html += ' <span style="color:#ff0000; font-size:11px; margin-left: 5px;">[면세]</span>';
|
html += ' <span style="color:#ff0000; font-size:11px; margin-left: 5px;">[면세]</span>';
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
<link rel="stylesheet" href="/css/web/grid.css?v1.1">
|
<link rel="stylesheet" href="/css/web/grid.css?v1.1">
|
||||||
<link rel="stylesheet" href="https://unpkg.com/tabulator-tables@5.6.1/dist/css/tabulator.min.css">
|
<link rel="stylesheet" href="https://unpkg.com/tabulator-tables@5.6.1/dist/css/tabulator.min.css">
|
||||||
<link rel="stylesheet" href="/css/web/categoryTree.css?v1.2">
|
<link rel="stylesheet" href="/css/web/categoryTree.css?v1.2">
|
||||||
|
<link rel="stylesheet" href="/css/web/hospital_info.css?v1.1">
|
||||||
<style>
|
<style>
|
||||||
.project_wrap .content_section .hospital_wrap .center_box .tab_panel {
|
.project_wrap .content_section .hospital_wrap .center_box .tab_panel {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -23,6 +24,16 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 탭 내 그리드 헤더 배경색 변경 및 고정 */
|
||||||
|
#gridOverview .tabulator-header {
|
||||||
|
background-color: #EDF5FF !important;
|
||||||
|
border-bottom: 1px solid #ddd !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gridOverview .tabulator-header .tabulator-col {
|
||||||
|
background-color: #EDF5FF !important;
|
||||||
|
}
|
||||||
|
|
||||||
.project_wrap .content_section .hospital_wrap .center_box .tab_panel .tab-content .tab-pane {
|
.project_wrap .content_section .hospital_wrap .center_box .tab_panel .tab-content .tab-pane {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -32,6 +43,36 @@
|
|||||||
.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box {
|
.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 그리드 폭이 좁아질 때 Tabulator 공식 트리 아이콘(SVG)이 찌그러지는 현상 방지 */
|
||||||
|
#gridOverview .tabulator-row .tabulator-cell .tabulator-data-tree-branch,
|
||||||
|
#gridOverview .tabulator-row .tabulator-cell .tabulator-data-tree-control {
|
||||||
|
flex-shrink: 0 !important;
|
||||||
|
/* 공간이 부족해도 아이콘 원형 유지 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#gridOverview .tabulator-row .tabulator-cell .tabulator-data-tree-control svg {
|
||||||
|
width: 14px !important;
|
||||||
|
min-width: 14px !important;
|
||||||
|
height: 14px !important;
|
||||||
|
min-height: 14px !important;
|
||||||
|
flex-shrink: 0 !important;
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dataTreeChildIndent: 0 에 추가로, 모든 트리 컨트롤의 고정 마진 제거 및 1뎁스 여백 완전 밀착 */
|
||||||
|
#gridOverview .tabulator-row .tabulator-cell .tabulator-data-tree-control {
|
||||||
|
margin-right: 4px !important;
|
||||||
|
/* 기호와 텍스트 사이 간격만 유지 */
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1뎁스(진료과목)의 들여쓰기 공간 완전 제거 */
|
||||||
|
#gridOverview .tabulator-row .tabulator-cell[tabulator-field="divi_name"] .tabulator-data-tree-control,
|
||||||
|
#gridOverview .tabulator-row .tabulator-cell[tabulator-field="divi_name"] .tabulator-data-tree-branch {
|
||||||
|
margin-left: 0 !important;
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
@@ -66,8 +107,10 @@
|
|||||||
<!-- ===== 탭1: 진료유형 관리 ===== -->
|
<!-- ===== 탭1: 진료유형 관리 ===== -->
|
||||||
<div role="tabpanel" class="tab-pane active" id="tabManage">
|
<div role="tabpanel" class="tab-pane active" id="tabManage">
|
||||||
<div class="filter_box">
|
<div class="filter_box">
|
||||||
<div class="form_box">
|
<div class="form_box"
|
||||||
<div class="select_list first">
|
style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<div style="display: flex; align-items: center; gap: 10px;">
|
||||||
|
<div class="select_list first" style="margin: 0;">
|
||||||
<div class="select_box dropdown" id="depth1SelectBox">
|
<div class="select_box dropdown" id="depth1SelectBox">
|
||||||
<button type="button" class="label dropdown-toggle" data-toggle="dropdown"
|
<button type="button" class="label dropdown-toggle" data-toggle="dropdown"
|
||||||
aria-haspopup="true" aria-expanded="false">진료과목 전체</button>
|
aria-haspopup="true" aria-expanded="false">진료과목 전체</button>
|
||||||
@@ -75,13 +118,34 @@
|
|||||||
<ul class="select_option_list dropdown-menu" id="depth1OptionList"></ul>
|
<ul class="select_option_list dropdown-menu" id="depth1OptionList"></ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="right_btn_box" style="margin: 0;">
|
||||||
<div class="right_btn_box">
|
|
||||||
<button class="put_btn" onclick="addChildCategory('0', '1', '최상위 항목')">
|
<button class="put_btn" onclick="addChildCategory('0', '1', '최상위 항목')">
|
||||||
<img src="/image/web/notice_btn_icon.svg" alt="추가">추가
|
<img src="/image/web/notice_btn_icon.svg" alt="추가">추가
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<button type="button" id="btnHelpManage" class="grid-link-btn grid-link-add"
|
||||||
|
style="border: 1px solid #ccc; padding: 2px 8px; border-radius: 3px; font-size: 13px; height: 32px; line-height: 26px; color: #555; background: #fff; font-weight: 600;">도움말</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 진료유형 관리 사용 가이드 (기본 숨김) -->
|
||||||
|
<div id="manageGuideBox"
|
||||||
|
style="display: none; margin-top: 15px; padding: 15px; background-color: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 5px; font-size: 13px; color: #333; line-height: 1.6;">
|
||||||
|
<h5
|
||||||
|
style="margin-top: 0; margin-bottom: 10px; font-size: 15px; font-weight: 600; color: #1a73e8;">
|
||||||
|
💡 진료유형 관리 탭 사용 가이드</h5>
|
||||||
|
<ul style="padding-left: 20px; margin-bottom: 0;">
|
||||||
|
<li><b>조회 및 이동:</b> 좌측 표에서 항목을 <b>클릭</b>하면 우측 표에 해당 항목의 하위 데이터가 로드됩니다.</li>
|
||||||
|
<li><b>항목 추가:</b> 각 패널 우측 상단이나 그리드 안의 <b>[추가/등록]</b> 버튼을 눌러 새 하위 항목을 손쉽게 생성할 수 있습니다.
|
||||||
|
</li>
|
||||||
|
<li><b>상세 수정:</b> 표 안의 데이터를 <b>더블클릭</b>하면 상세 정보를 수정할 수 있는 팝업창이 열립니다.
|
||||||
|
</li>
|
||||||
|
<li><b>항목 삭제 (우클릭):</b> 삭제할 항목 위에서 <b>마우스 우클릭</b>을 하면 [삭제] 메뉴가 나타납니다. 하위 항목이 딸려있으면 삭제되지
|
||||||
|
않으므로 주의하세요.</li>
|
||||||
|
<li><b>다중 선택 (Shift / Ctrl):</b> <b>Shift + 클릭</b>으로 여러 범위를 한 번에 연속 선택하거나, <b>Ctrl +
|
||||||
|
클릭</b>으로 띄엄띄엄 다중 선택한 뒤 <b>우클릭 삭제</b>할 수 있습니다.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 2depth | 3depth | 4depth | 5depth 가로 배치 -->
|
<!-- 2depth | 3depth | 4depth | 5depth 가로 배치 -->
|
||||||
@@ -96,7 +160,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Depth 3: 제품 -->
|
<!-- Depth 3: 제품 -->
|
||||||
<div class="category-tree-panel" style="flex:20; width:auto; min-width:0;">
|
<div class="category-tree-panel" style="flex:30; width:auto; min-width:0;">
|
||||||
<div class="tree-panel-header">
|
<div class="tree-panel-header">
|
||||||
<span class="tree-panel-title">제품/시술</span>
|
<span class="tree-panel-title">제품/시술</span>
|
||||||
<div class="tree-panel-actions" id="btnArea3"></div>
|
<div class="tree-panel-actions" id="btnArea3"></div>
|
||||||
@@ -114,7 +178,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Depth 5: 부위 -->
|
<!-- Depth 5: 부위 -->
|
||||||
<div class="category-tree-panel" style="flex:25; width:auto; min-width:0;">
|
<div class="category-tree-panel" style="flex:15; width:auto; min-width:0;">
|
||||||
<div class="tree-panel-header">
|
<div class="tree-panel-header">
|
||||||
<span class="tree-panel-title">부위</span>
|
<span class="tree-panel-title">부위</span>
|
||||||
<div class="tree-panel-actions" id="btnArea5"></div>
|
<div class="tree-panel-actions" id="btnArea5"></div>
|
||||||
@@ -127,8 +191,9 @@
|
|||||||
<!-- ===== 탭2: 전체보기 ===== -->
|
<!-- ===== 탭2: 전체보기 ===== -->
|
||||||
<div role="tabpanel" class="tab-pane" id="tabOverview">
|
<div role="tabpanel" class="tab-pane" id="tabOverview">
|
||||||
<div class="filter_box">
|
<div class="filter_box">
|
||||||
<div class="form_box">
|
<div class="form_box"
|
||||||
<div class="select_list first">
|
style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<div class="select_list first" style="display: flex; align-items: center; gap: 10px;">
|
||||||
<div class="select_box dropdown" id="depth1SelectBoxOverview">
|
<div class="select_box dropdown" id="depth1SelectBoxOverview">
|
||||||
<button type="button" class="label dropdown-toggle" data-toggle="dropdown"
|
<button type="button" class="label dropdown-toggle" data-toggle="dropdown"
|
||||||
aria-haspopup="true" aria-expanded="false">진료과목 전체</button>
|
aria-haspopup="true" aria-expanded="false">진료과목 전체</button>
|
||||||
@@ -136,10 +201,53 @@
|
|||||||
<ul class="select_option_list dropdown-menu" id="depth1OptionListOverview"></ul>
|
<ul class="select_option_list dropdown-menu" id="depth1OptionListOverview"></ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<button type="button" id="btnHelpOverview" class="grid-link-btn grid-link-add"
|
||||||
|
style="border: 1px solid #ccc; padding: 2px 8px; border-radius: 3px; font-size: 13px; height: 32px; line-height: 26px; color: #555; background: #fff; font-weight: 600;">도움말</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 전체보기 사용 가이드 (기본 숨김) -->
|
||||||
|
<div id="overviewGuideBox"
|
||||||
|
style="display: none; margin-top: 15px; padding: 15px; background-color: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 5px; font-size: 13px; color: #333; line-height: 1.6;">
|
||||||
|
<h5
|
||||||
|
style="margin-top: 0; margin-bottom: 10px; font-size: 15px; font-weight: 600; color: #1a73e8;">
|
||||||
|
💡 전체보기 탭 사용 가이드</h5>
|
||||||
|
<ul style="padding-left: 20px; margin-bottom: 0;">
|
||||||
|
<li><b>데이터 수정 (더블클릭):</b> 수정하고자 하는 항목(명칭, 단가, 할인가 등)의 셀 위에서 <b>더블클릭</b>하면 즉시 입력창이 표시되어
|
||||||
|
데이터를 수정할 수 있습니다.</li>
|
||||||
|
<li><b>트리 작동 (+/-버튼):</b> 좌측의 <b>+ / - 버튼</b>을 클릭하면 하위 진료유형, 제품/시술, 용량/출력, 부위가 단계별로
|
||||||
|
펼쳐지거나 접힙니다.</li>
|
||||||
|
<li><b>일괄 저장:</b> 항목을 하나라도 수정하면 표 우측 상단에 <b>[일괄저장]</b> 및 <b>[일괄취소]</b> 버튼이 나타납니다. 여러 항목을
|
||||||
|
연속해서 수정한 뒤 마지막에 한 번만 저장하시면 됩니다.</li>
|
||||||
|
<li><b>취소:</b> 저장 전 <b>[일괄취소]</b>를 누르면 모든 수정 내역이 원래 상태로 되돌아갑니다.</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="gridOverview" style="width:100%; height:calc(100vh - 270px);"></div>
|
<div class="form_box first"
|
||||||
|
style="margin-top: 20px; height: calc(100vh - 290px); display: flex; flex-direction: column;">
|
||||||
|
<div class="hospital_box"
|
||||||
|
style="margin-top: 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; height: 100%; display: flex; flex-direction: column; overflow: hidden; background-color: #fff;">
|
||||||
|
<div
|
||||||
|
style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; flex-shrink: 0; min-height: 26px;">
|
||||||
|
<div style="display: flex; align-items: center; gap: 8px;">
|
||||||
|
<span class="tree-panel-title" style="font-size: 17px; margin: 0;">전체 진료유형</span>
|
||||||
|
<button type="button" id="btnExpandAll" class="grid-link-btn grid-link-add"
|
||||||
|
style="border: 1px solid #ccc; padding: 2px 8px; border-radius: 3px; font-size: 12px; height: 24px; line-height: 18px; color: #555; background: #fff;">전체펼치기</button>
|
||||||
|
<button type="button" id="btnCollapseAll" class="grid-link-btn grid-link-edit"
|
||||||
|
style="border: 1px solid #ccc; padding: 2px 8px; border-radius: 3px; font-size: 12px; height: 24px; line-height: 18px; color: #555; background: #fff;">전체접기</button>
|
||||||
|
</div>
|
||||||
|
<div class="tree-panel-actions" style="min-height: 26px; display: flex;">
|
||||||
|
<button type="button" id="btnSaveOverview" class="put_btn"
|
||||||
|
style="display: none;"><img src="/image/web/check.svg" alt="일괄저장"
|
||||||
|
style="filter: brightness(0) invert(1);">일괄저장</button>
|
||||||
|
<button type="button" id="btnCancelOverview" class="delete_btn"
|
||||||
|
style="display: none;"><img src="/image/web/close.svg" alt="일괄취소"
|
||||||
|
style="filter: brightness(0) invert(1);">일괄취소</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="gridOverview" style="width: 100%; flex-grow: 1; border: 1px solid #e0e0e0;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -151,7 +259,8 @@
|
|||||||
|
|
||||||
<th:block layout:fragment="layout_script">
|
<th:block layout:fragment="layout_script">
|
||||||
<script src="https://unpkg.com/tabulator-tables@5.6.1/dist/js/tabulator.min.js"></script>
|
<script src="https://unpkg.com/tabulator-tables@5.6.1/dist/js/tabulator.min.js"></script>
|
||||||
<script th:src="@{/js/web/settings/medicalcategory/medicalCategoryList.js(v=202602223)}"></script>
|
<script th:src="@{/js/web/settings/medicalcategory/medicalCategoryList.js(v=202602296)}"></script>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user