diff --git a/src/main/java/com/madeu/crm/settings/medicalcategory/ctrl/MedicalCategoryController.java b/src/main/java/com/madeu/crm/settings/medicalcategory/ctrl/MedicalCategoryController.java new file mode 100644 index 0000000..8a11722 --- /dev/null +++ b/src/main/java/com/madeu/crm/settings/medicalcategory/ctrl/MedicalCategoryController.java @@ -0,0 +1,185 @@ +package com.madeu.crm.settings.medicalcategory.ctrl; + +import java.util.HashMap; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.ModelAndView; + +import com.madeu.constants.Constants; +import com.madeu.crm.settings.medicalcategory.dto.MedicalCategoryDTO; +import com.madeu.crm.settings.medicalcategory.service.MedicalCategoryService; +import com.madeu.init.ManagerDraftAction; +import com.madeu.util.HttpUtil; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RestController +@RequestMapping("/settings/medicalCategory") +public class MedicalCategoryController extends ManagerDraftAction { + + @Autowired + private MedicalCategoryService medicalCategoryService; + + // ==================== 뷰 반환 메서드 ==================== + + /** + * 통합 진료유형 관리 메인 화면 이동 + */ + @RequestMapping("/list.do") + public ModelAndView selectList(HttpServletRequest request, HttpServletResponse response) { + log.debug("MedicalCategoryController selectList START"); + log.debug("MedicalCategoryController selectList END"); + + // 프론트 설계 4번 항목 경로 + return new ModelAndView("/web/settings/medicalcategory/medicalCategoryList"); + } + + /** + * 카테고리 상세/등록 팝업 화면 이동 + */ + @RequestMapping("/infoPop.do") + public ModelAndView infoPop(HttpServletRequest request, HttpServletResponse response) { + log.debug("MedicalCategoryController infoPop START"); + log.debug("MedicalCategoryController infoPop END"); + + return new ModelAndView("/web/settings/medicalcategory/popup/medicalCategoryInfoPop"); + } + + // ==================== API 메서드 (JSON 반환) ==================== + + /** + * 진료유형 트리 리스트 조회 + */ + @PostMapping("/getMedicalCategoryTreeList.do") + public HashMap getMedicalCategoryTreeList(HttpServletRequest request, + HttpServletResponse response) { + log.debug("MedicalCategoryController getMedicalCategoryTreeList START"); + + HashMap paramMap = HttpUtil.getParameterMap(request); + HashMap map = new HashMap<>(); + + try { + map = medicalCategoryService.getMedicalCategoryTreeList(paramMap); + } catch (Exception e) { + log.error("getMedicalCategoryTreeList : ", e); + map.put("msgCode", Constants.FAIL); + map.put("msgDesc", "서버 오류가 발생했습니다."); + } finally { + if (Constants.OK != map.get("msgCode")) { + map.put("msgCode", Constants.FAIL); + map.put("success", false); + if (map.get("msgDesc") == null || "".equals(map.get("msgDesc"))) { + map.put("msgDesc", "정보를 불러오는데 실패했습니다. 관리자에게 문의하세요."); + } + } + } + log.debug("MedicalCategoryController getMedicalCategoryTreeList END"); + return map; + } + + /** + * 카테고리 단건 상세 정보 가져오기 + */ + @PostMapping("/getMedicalCategory.do") + public HashMap getMedicalCategory(HttpServletRequest request, HttpServletResponse response) { + log.debug("MedicalCategoryController getMedicalCategory START"); + HashMap paramMap = HttpUtil.getParameterMap(request); + HashMap map = new HashMap<>(); + + try { + map = medicalCategoryService.getMedicalCategory(paramMap); + } catch (Exception e) { + log.error("getMedicalCategory : ", e); + map.put("msgCode", Constants.FAIL); + map.put("msgDesc", "서버 오류가 발생했습니다."); + } + log.debug("MedicalCategoryController getMedicalCategory END"); + return map; + } + + /** + * 거래처 목록 조회 + */ + @PostMapping("/getCustList.do") + public HashMap getCustList(HttpServletRequest request, HttpServletResponse response) { + log.debug("MedicalCategoryController getCustList START"); + HashMap paramMap = HttpUtil.getParameterMap(request); + HashMap map = new HashMap<>(); + + try { + map = medicalCategoryService.getCustList(paramMap); + } catch (Exception e) { + log.error("getCustList : ", e); + map.put("msgCode", Constants.FAIL); + map.put("msgDesc", "서버 오류가 발생했습니다."); + } + log.debug("MedicalCategoryController getCustList END"); + return map; + } + + /** + * 진료유형 등록 + */ + @PostMapping("/putMedicalCategory.do") + public HashMap putMedicalCategory(@RequestBody MedicalCategoryDTO dto, HttpServletRequest request) { + log.debug("MedicalCategoryController putMedicalCategory START"); + HashMap map = new HashMap<>(); + + try { + map = medicalCategoryService.insertMedicalCategory(dto); + } catch (Exception e) { + log.error("putMedicalCategory : ", e); + map.put("msgCode", Constants.FAIL); + map.put("msgDesc", "서버 오류가 발생했습니다."); + } + log.debug("MedicalCategoryController putMedicalCategory END"); + return map; + } + + /** + * 진료유형 수정 + */ + @PostMapping("/modMedicalCategory.do") + public HashMap modMedicalCategory(@RequestBody MedicalCategoryDTO dto, HttpServletRequest request) { + log.debug("MedicalCategoryController modMedicalCategory START"); + HashMap map = new HashMap<>(); + + try { + map = medicalCategoryService.updateMedicalCategory(dto); + } catch (Exception e) { + log.error("modMedicalCategory : ", e); + map.put("msgCode", Constants.FAIL); + map.put("msgDesc", "서버 오류가 발생했습니다."); + } + log.debug("MedicalCategoryController modMedicalCategory END"); + return map; + } + + /** + * 진료유형 삭제 + */ + @PostMapping("/delMedicalCategory.do") + public HashMap delMedicalCategory(HttpServletRequest request, HttpServletResponse response) { + log.debug("MedicalCategoryController delMedicalCategory START"); + HashMap paramMap = HttpUtil.getParameterMap(request); + HashMap map = new HashMap<>(); + + try { + map = medicalCategoryService.deleteMedicalCategory(paramMap); + } catch (Exception e) { + log.error("delMedicalCategory : ", e); + map.put("msgCode", Constants.FAIL); + map.put("msgDesc", "서버 오류가 발생했습니다."); + } + log.debug("MedicalCategoryController delMedicalCategory END"); + return map; + } +} diff --git a/src/main/java/com/madeu/crm/settings/medicalcategory/dto/MedicalCategoryDTO.java b/src/main/java/com/madeu/crm/settings/medicalcategory/dto/MedicalCategoryDTO.java new file mode 100644 index 0000000..cb028cc --- /dev/null +++ b/src/main/java/com/madeu/crm/settings/medicalcategory/dto/MedicalCategoryDTO.java @@ -0,0 +1,95 @@ +package com.madeu.crm.settings.medicalcategory.dto; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class MedicalCategoryDTO { + + // 카테고리 고유 번호 + private Integer pid; + + // 진료유형 명칭 + private String diviName; + + // 현재 항목의 깊이 (예: '1', '2', '3', '4') + private String diviDept; + + // 부모 카테고리의 고유 번호(pid) + private Integer diviParent; + + // 구분(진료) 'y'/'n' + private String clinicUse; + + // 구분(비용) 'y'/'n' + private String expenseUse; + + // 구분(면세) 'y'/'n' + private String taxFree; + + // 색상 코드 + private String diviColor; + + // 정렬 순서 + private Integer diviSort; + + // 거래처 pid + private Integer custListPid; + + // 단가 + private Double kindCost; + + // 제품설명 + private String kindMsg1; + + // 기타설명 + private String kindMsg2; + + // 단위 + private String kindUnit; + + // 단위당 용량 + private Float kindUnitVol; + + // 단위당 용량(단위) + private String kindUnit2; + + // 비율 + private String ccRate; + + // 재고관리품목 'y'/'n' + private String stockUse; + + // 손익계산서 서브보기 'y'/'n' + private String incomeUse; + + // 비과세 'y'/'n' + private String noTax; + + // 비세금 'y'/'n' + private String noTax1; + + // 기타수입 사용 'y'/'n' + private String etcincomeUse; + + // 기타손실 사용 'y'/'n' + private String etclossUse; + + // 데이터 사용/삭제 노출 여부 'y'/'n' + private String listUse; + + // 등록일시 + private String regDate; + + // 수정일시 + private String upDate; + + // 지점(스토어) 고유값 + private String storePid; + + // 미수금관리 보이기 'y'/'n' + private String npayUse; +} diff --git a/src/main/java/com/madeu/crm/settings/medicalcategory/mapper/MedicalCategoryMapper.java b/src/main/java/com/madeu/crm/settings/medicalcategory/mapper/MedicalCategoryMapper.java new file mode 100644 index 0000000..877c2ad --- /dev/null +++ b/src/main/java/com/madeu/crm/settings/medicalcategory/mapper/MedicalCategoryMapper.java @@ -0,0 +1,68 @@ +package com.madeu.crm.settings.medicalcategory.mapper; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.ibatis.annotations.Mapper; + +import com.madeu.crm.settings.medicalcategory.dto.MedicalCategoryDTO; + +@Mapper +public interface MedicalCategoryMapper { + + /** + * 진료유형 리스트 전체 또는 조건 조회 + * + * @param paramMap (store_pid, list_use 등 검색조건) + * @return 카테고리 계층 리스트 + */ + List> getMedicalCategoryList(HashMap paramMap); + + /** + * 특정 카테고리 상세 정보 조회 + * + * @param paramMap (pid) + * @return 카테고리 상세 + */ + Map getMedicalCategory(HashMap paramMap); + + /** + * 카테고리 신규 등록 + * + * @param dto + * @return + */ + int insertMedicalCategory(MedicalCategoryDTO dto); + + /** + * 카테고리 정보 수정 + * + * @param dto + * @return + */ + int updateMedicalCategory(MedicalCategoryDTO dto); + + /** + * 카테고리 삭제 처리 (실제 삭제 or 논리적 삭제(list_use='n')) + * + * @param paramMap (pid) + * @return + */ + int deleteMedicalCategory(HashMap paramMap); + + /** + * 하위 카테고리 목록 존재 여부/수량 확인 (삭제 시 방어 로직 등에 사용) + * + * @param paramMap (divi_parent) + * @return + */ + int getChildCategoryCount(HashMap paramMap); + + /** + * 거래처 목록 조회 (Depth 3 매핑용) + * + * @return 거래처 리스트 + */ + List> getCustList(HashMap paramMap); +} diff --git a/src/main/java/com/madeu/crm/settings/medicalcategory/service/MedicalCategoryService.java b/src/main/java/com/madeu/crm/settings/medicalcategory/service/MedicalCategoryService.java new file mode 100644 index 0000000..2dfd351 --- /dev/null +++ b/src/main/java/com/madeu/crm/settings/medicalcategory/service/MedicalCategoryService.java @@ -0,0 +1,215 @@ +package com.madeu.crm.settings.medicalcategory.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.madeu.constants.Constants; +import com.madeu.crm.settings.medicalcategory.dto.MedicalCategoryDTO; +import com.madeu.crm.settings.medicalcategory.mapper.MedicalCategoryMapper; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class MedicalCategoryService { + + @Autowired + private MedicalCategoryMapper medicalCategoryMapper; + + /** + * 카테고리 트리 리스트 조회 + */ + public HashMap getMedicalCategoryTreeList(HashMap paramMap) throws Exception { + HashMap map = new HashMap<>(); + List> resultList = new ArrayList<>(); + + try { + // DB에서 전체 목록 조회 (list_use='y') - 정렬순은 divi_dept, divi_sort 기준 + List> listMap = medicalCategoryMapper.getMedicalCategoryList(paramMap); + + if (listMap != null && !listMap.isEmpty()) { + // Tabulator 의 dataTree 모드를 사용하기 위해, 평면 구조(Flat)를 받아서 프론트엔드가 자체적으로 Tree로 엮거나 + // 직접 백엔드에서 `_children` 프로퍼티를 만들어서 계층형으로 보내주는 두 가지 방식이 있습니다. + // 여기서는 Tabulator 가 dataTreeChildField: "_children" 속성으로 자동 파싱하기 쉽도록 + // 백엔드에서 부모-자식 트리 구조로 조립해서 보냅니다. + + resultList = buildTree(listMap); + } + + map.put("msgCode", Constants.OK); + map.put("success", true); + map.put("rows", resultList); + + } catch (Exception e) { + log.error("getMedicalCategoryTreeList Error: ", e); + throw e; + } + + return map; + } + + /** + * 평면형(Flat) List를 Tabulator Tree(계층형) 구조로 변환하는 헬퍼 메서드 + */ + private List> buildTree(List> flatList) { + // pid를 키로 하는 Map 구조 생성 (빠른 접근 위함) + Map> nodeMap = new HashMap<>(); + List> roots = new ArrayList<>(); + + for (Map flatNode : flatList) { + // 자식 목록을 담을 공간 초기화 + flatNode.put("_children", new ArrayList>()); + // pid + Integer pid = Integer.parseInt(String.valueOf(flatNode.get("pid"))); + nodeMap.put(pid, flatNode); + } + + for (Map flatNode : flatList) { + Integer diviParent = Integer.parseInt(String.valueOf(flatNode.get("divi_parent"))); + + if (diviParent == 0) { + // 부모가 0이면 최상위(Depth 1) 노드 + roots.add(flatNode); + } else { + // 부모가 있으면 부모 노드를 찾아서 _children 리스트에 추가 + Map parentNode = nodeMap.get(diviParent); + if (parentNode != null) { + @SuppressWarnings("unchecked") + List> children = (List>) parentNode.get("_children"); + children.add(flatNode); + } else { + // 고아 노드일 경우 (부모가 삭제되었거나 매칭오류) 어떻게 처리할지 정책 + // roots.add(flatNode); + } + } + } + return roots; + } + + /** + * 특정 카테고리 상세 정보 조회 + */ + public HashMap getMedicalCategory(HashMap paramMap) throws Exception { + HashMap map = new HashMap<>(); + try { + Map categoryMap = medicalCategoryMapper.getMedicalCategory(paramMap); + map.put("msgCode", Constants.OK); + map.put("success", true); + map.put("data", categoryMap); + } catch (Exception e) { + log.error("getMedicalCategory Error: ", e); + throw e; + } + return map; + } + + /** + * 거래처 목록 조회 + */ + public HashMap getCustList(HashMap paramMap) throws Exception { + HashMap map = new HashMap<>(); + try { + List> list = medicalCategoryMapper.getCustList(paramMap); + map.put("msgCode", Constants.OK); + map.put("success", true); + map.put("data", list); + } catch (Exception e) { + log.error("getCustList Error: ", e); + throw e; + } + return map; + } + + /** + * 카테고리 등록 + * + * @param dto + * @return + * @throws Exception + */ + public HashMap insertMedicalCategory(MedicalCategoryDTO dto) throws Exception { + HashMap map = new HashMap<>(); + try { + int result = medicalCategoryMapper.insertMedicalCategory(dto); + 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("insertMedicalCategory Error: ", e); + throw e; + } + return map; + } + + /** + * 카테고리 수정 + * + * @param dto + * @return + * @throws Exception + */ + public HashMap updateMedicalCategory(MedicalCategoryDTO dto) throws Exception { + HashMap map = new HashMap<>(); + try { + int result = medicalCategoryMapper.updateMedicalCategory(dto); + 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("updateMedicalCategory Error: ", e); + throw e; + } + return map; + } + + /** + * 카테고리 삭제 (논리 삭제 처리) + * + * @param paramMap + * @return + * @throws Exception + */ + public HashMap deleteMedicalCategory(HashMap paramMap) throws Exception { + HashMap map = new HashMap<>(); + try { + // 1. 하위 카테고리가 존재하는지 여부 확인 + int childCount = medicalCategoryMapper.getChildCategoryCount(paramMap); + if (childCount > 0) { + map.put("msgCode", Constants.FAIL); + map.put("msgDesc", "하위 항목이 존재하여 삭제할 수 없습니다. 먼저 하위 항목을 삭제하세요."); + return map; + } + + // 2. 삭제 처리 + int result = medicalCategoryMapper.deleteMedicalCategory(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("deleteMedicalCategory Error: ", e); + throw e; + } + return map; + } + +} diff --git a/src/main/resources/mappers/crm/settings/medicalcategory/MedicalCategoryMapper.xml b/src/main/resources/mappers/crm/settings/medicalcategory/MedicalCategoryMapper.xml new file mode 100644 index 0000000..2f97af4 --- /dev/null +++ b/src/main/resources/mappers/crm/settings/medicalcategory/MedicalCategoryMapper.xml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + INSERT INTO medical_divi_list ( + divi_name, + divi_dept, + divi_parent, + clinic_use, + expense_use, + tax_free, + divi_color, + divi_sort, + cust_list_pid, + kind_cost, + kind_msg1, + kind_msg2, + kind_unit, + kind_unit_vol, + kind_unit2, + cc_rate, + stock_use, + income_use, + no_tax, + no_tax1, + etcIncome_use, + etcLoss_use, + list_use, + reg_date, + up_date, + store_pid, + npay_use + ) VALUES ( + #{diviName}, + #{diviDept}, + #{diviParent}, + IFNULL(#{clinicUse}, 'y'), + IFNULL(#{expenseUse}, 'n'), + IFNULL(#{taxFree}, 'n'), + IFNULL(#{diviColor}, '#000000'), + IFNULL(#{diviSort}, 0), + IFNULL(#{custListPid}, 0), + IFNULL(#{kindCost}, 0), + IFNULL(#{kindMsg1}, ''), + IFNULL(#{kindMsg2}, ''), + IFNULL(#{kindUnit}, ''), + IFNULL(#{kindUnitVol}, 0), + IFNULL(#{kindUnit2}, ''), + IFNULL(#{ccRate}, ''), + IFNULL(#{stockUse}, 'y'), + IFNULL(#{incomeUse}, 'n'), + IFNULL(#{noTax}, 'n'), + IFNULL(#{noTax1}, 'n'), + IFNULL(#{etcincomeUse}, 'n'), + IFNULL(#{etclossUse}, 'n'), + 'y', + NOW(), + NOW(), + #{storePid}, + IFNULL(#{npayUse}, 'n') + ) + + + + + UPDATE medical_divi_list + + + divi_name = #{diviName}, + + + divi_dept = #{diviDept}, + + + divi_parent = #{diviParent}, + + + clinic_use = #{clinicUse}, + + + expense_use = #{expenseUse}, + + + tax_free = #{taxFree}, + + + divi_color = #{diviColor}, + + + divi_sort = #{diviSort}, + + + cust_list_pid = #{custListPid}, + + + kind_cost = #{kindCost}, + + + kind_msg1 = #{kindMsg1}, + + + kind_msg2 = #{kindMsg2}, + + + kind_unit = #{kindUnit}, + + + kind_unit_vol = #{kindUnitVol}, + + + kind_unit2 = #{kindUnit2}, + + + cc_rate = #{ccRate}, + + + stock_use = #{stockUse}, + + + income_use = #{incomeUse}, + + + no_tax = #{noTax}, + + + no_tax1 = #{noTax1}, + + + etcIncome_use = #{etcincomeUse}, + + + etcLoss_use = #{etclossUse}, + + + list_use = #{listUse}, + + + store_pid = #{storePid}, + + + npay_use = #{npayUse}, + + up_date = NOW() + + WHERE pid = #{pid} + + + + + UPDATE medical_divi_list + SET list_use = 'n', up_date = NOW() + WHERE pid = #{pid} + + + + + + diff --git a/src/main/resources/static/css/web/categoryTree.css b/src/main/resources/static/css/web/categoryTree.css index 61ad169..e2ab4b1 100644 --- a/src/main/resources/static/css/web/categoryTree.css +++ b/src/main/resources/static/css/web/categoryTree.css @@ -2,6 +2,17 @@ 카테고리 트리 레이아웃 스타일 =================================================================== */ +/* 추가 버튼을 셀렉트 바로 옆에 배치 */ +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box { + display: flex !important; + align-items: center; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box { + float: none !important; + margin-left: 10px; +} + /* 트리 + 상세 패널 레이아웃 */ .category-tree-layout { display: flex; @@ -26,10 +37,11 @@ display: flex; align-items: center; justify-content: space-between; - padding: 12px 16px; + height: 50px; + padding: 0 16px; border-bottom: 1px solid #E9ECF0; background: #fff; - /* 밝게 변경 */ + box-sizing: border-box; } .tree-panel-title { @@ -396,4 +408,98 @@ .category-detail-panel { height: 300px; } +} + +/* =================================================================== + Grid Link Buttons (수정/등록) + =================================================================== */ +.grid-link-btn { + display: inline-block; + font-size: 12px; + cursor: pointer; + letter-spacing: -0.3px; + transition: all 0.15s; + user-select: none; +} + +.grid-link-edit { + color: #888; +} + +.grid-link-edit:hover { + color: #333; + text-decoration: underline; +} + +.grid-link-add { + color: #3985EA; + font-weight: 600; +} + +.grid-link-add:hover { + color: #2c6fd1; + text-decoration: underline; +} + +/* Compact row height for category grids */ +.category-tree-container .tabulator .tabulator-cell { + padding: 4px 6px; +} + +.category-tree-container .tabulator .tabulator-header .tabulator-col-content { + padding: 6px 6px; +} + +/* 작은 컬럼 (순번, 순서) */ +.tabulator .tabulator-cell.col-sm { + font-size: 11px; + padding: 4px 2px; +} + +.tabulator .tabulator-header .tabulator-col.col-sm .tabulator-col-content { + font-size: 11px; + padding: 6px 2px; +} + +/* ======= 커스텀 컨텍스트 메뉴 ======= */ +.custom-context-menu { + position: absolute; + z-index: 10000; + background-color: #ffffff; + border: 1px solid #ddd; + box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15); + border-radius: 4px; + padding: 5px 0; + min-width: 120px; + display: none; +} + +.custom-context-menu ul { + list-style: none; + margin: 0; + padding: 0; +} + +.custom-context-menu li { + padding: 8px 15px; + cursor: pointer; + font-size: 13px; + color: #333; + transition: background 0.2s; +} + +.custom-context-menu li:hover { + background-color: #f5f5f5; +} + +.custom-context-menu li.delete { + color: #FF5252; +} + +.custom-context-menu li img { + width: 14px; + vertical-align: middle; + margin-right: 6px; + position: relative; + top: -1px; } \ No newline at end of file diff --git a/src/main/resources/static/css/web/webCategorySelectList.css b/src/main/resources/static/css/web/webCategorySelectList.css index 87d08d5..9d7bf93 100644 --- a/src/main/resources/static/css/web/webCategorySelectList.css +++ b/src/main/resources/static/css/web/webCategorySelectList.css @@ -1,69 +1,418 @@ -.project_wrap {width:100%; min-width:1080px; margin:0 auto;} +.project_wrap { + width: 100%; + min-width: 1080px; + margin: 0 auto; +} /*오른쪽영역*/ -.project_wrap .content_section {margin-top:50px; width:100%; min-width:1080px; display:table;} -.project_wrap .content_section .hospital_wrap {width: calc(100% - 72px); min-width:calc(1080px - 72px); height:calc(100vh - 50px); float:left; position:relative;} +.project_wrap .content_section { + margin-top: 50px; + width: 100%; + min-width: 1080px; + display: table; +} + +.project_wrap .content_section .hospital_wrap { + width: calc(100% - 72px); + min-width: calc(1080px - 72px); + height: calc(100vh - 50px); + float: left; + position: relative; +} /* 왼쪽_메뉴 영역 */ -.project_wrap .content_section .hospital_wrap .left_box {position:absolute; width:240px; height:calc(100vh - 50px); overflow:auto; padding:10px 20px;} -.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list {width:100%;} -.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list .title_menu {width:100%; height:auto; margin:20px 0 10px 0; padding:0; font-size:14px; font-weight:700;} -.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list .title_menu.first {margin-top:0;} -.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list a {width:100%; height:100%; display:block; margin-bottom:8px; padding:8px; font-size:14px; text-align:left; border-radius:5px;} -.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list a.on {background:#3985EA; border:none;} -.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list li {width:100%; height:36px; margin-bottom:8px;} -.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list li a.on {color:#fff;} +.project_wrap .content_section .hospital_wrap .left_box { + position: absolute; + width: 240px; + height: calc(100vh - 50px); + overflow: auto; + padding: 10px 20px; +} + +.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list { + width: 100%; +} + +.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list .title_menu { + width: 100%; + height: auto; + margin: 20px 0 10px 0; + padding: 0; + font-size: 14px; + font-weight: 700; +} + +.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list .title_menu.first { + margin-top: 0; +} + +.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list a { + width: 100%; + height: 100%; + display: block; + margin-bottom: 8px; + padding: 8px; + font-size: 14px; + text-align: left; + border-radius: 5px; +} + +.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list a.on { + background: #3985EA; + border: none; +} + +.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list li { + width: 100%; + height: 36px; + margin-bottom: 8px; +} + +.project_wrap .content_section .hospital_wrap .left_box .sub_menu_list li a.on { + color: #fff; +} /* 센터쪽 */ -.project_wrap .content_section .hospital_wrap .center_box {width:calc(100% - 240px); height:calc(100vh - 50px); position:absolute; left:240px; padding:10px 10px 10px 0;} -.project_wrap .content_section .hospital_wrap .center_box .page_title {min-width:90px; padding-left:10px; font-size:18px; font-weight:700; line-height:50px; float:left;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box {display:table; width:100%; padding:20px 0;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box {width:140px; height:36px; margin-left:10px; border:1px solid #E9ECF0; border-radius:5px; background:url(/image/web/select_arrow.svg) no-repeat 95% 55%/20px auto #fff;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box.first { width:100px; margin-left:0; float:left; } -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .slash {width:6px; font-size:14px; font-weight:400; color:#000; line-height:36px; margin:0 12px; display:block; float:left;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list_box { margin-left:10px; } -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box.active {z-index:10;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .label {width:100%; height:100%; padding:0 10px; outline:none; font-size:14px; font-weight:400; text-align:left; color: #494E53; cursor:pointer; background:none;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .select_option_list {min-width:100%; border-radius:5px; transition:.4s ease-in; border:Solid 1px #E9ECF0; padding:10px; } -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .select_option_list .option_list_item {width:100%; line-height:30px; transition:.1s; position:relative; display:table; font-size:14px; color:#494E53;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .select_option_list .option_list_item label {width:100%; line-height:30px; margin-bottom:0px; clear:both; font-weight:400;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box {border-radius:8px; float:left; position:relative;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box {position:relative; width:140px; height:36px; float:left; margin-left:10px;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box.last {margin-left:0;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box img {position:absolute; top:50%; transform:translateY(-50%); left:10px; z-index:1; width:22px;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box .date_picker {line-height:34px; display:block; margin-right:20px; width:100%; font-size:14px; padding:0 12px; padding-left:40px; outline:none; border:1px solid #E9ECF0; border-radius:5px;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box input[type="date"]::-webkit-calendar-picker-indicator {display:none;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box .date_picker {-webkit-appearance:none; -moz-appearance:none; appearance:none; position:absolute; cursor:pointer;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .slash {color:#000; font-size:14px; font-weight:400; line-height:36px; margin:0 5px; width:6px; display:block; float:left;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list {float:left; position:relative; margin-left:10px;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box {width:180px; float:left; height:36px; position:relative;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box img {position:absolute; top:50%; transform:translateY(-50%); left:5px; z-index:1;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box input {width:100%; height:36px; border:1px solid #E9ECF0; border-radius:5px; background:none; position:absolute; left:0; padding:0 10px 0 30px; font-size:14px; background:#fff;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box input::placeholder {color:#B5BDC4;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box .search_list {position:absolute; top:40px; left:0; width:150px; background:#fff; color:#fff; border-radius:5px; transition:.4s ease-in; z-index:1; border:solid 1px #E9ECF0; display:none; margin:0; padding:10px;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_btn {background:#3985EA; border-radius:5px; color:#fff; margin-left:5px;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box {float:right;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box .put_btn {background:#3985EA; color:#fff; border-radius:5px; float:left;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box .put_btn img {position:relative; top:-2px; width:20px; margin-right:5px;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box .delete_btn {background:#FF2222; color:#fff; border-radius:5px; margin-left:10px;} -.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box .delete_btn img {position:relative; top:-2px; width:20px; margin-right:5px;} +.project_wrap .content_section .hospital_wrap .center_box { + width: calc(100% - 240px); + height: calc(100vh - 50px); + position: absolute; + left: 240px; + padding: 10px 10px 10px 0; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_title { + min-width: 90px; + padding-left: 10px; + font-size: 18px; + font-weight: 700; + line-height: 50px; + float: left; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box { + display: table; + width: 100%; + padding: 20px 0; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box { + width: 140px; + height: 36px; + margin-left: 10px; + border: 1px solid #E9ECF0; + border-radius: 5px; + background: url(/image/web/select_arrow.svg) no-repeat 95% 55%/20px auto #fff; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box.first { + width: 100px; + margin-left: 0; + float: left; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .slash { + width: 6px; + font-size: 14px; + font-weight: 400; + color: #000; + line-height: 36px; + margin: 0 12px; + display: block; + float: left; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list_box { + margin-left: 10px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box.active { + z-index: 10; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .label { + width: 100%; + height: 100%; + padding: 0 10px; + outline: none; + font-size: 14px; + font-weight: 400; + text-align: left; + color: #494E53; + cursor: pointer; + background: none; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .select_option_list { + min-width: 100%; + max-height: 300px; + overflow-y: auto; + border-radius: 5px; + transition: .4s ease-in; + border: Solid 1px #E9ECF0; + padding: 10px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .select_option_list .option_list_item { + width: 100%; + line-height: 30px; + transition: .1s; + position: relative; + display: table; + font-size: 14px; + color: #494E53; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .select_option_list .option_list_item label { + width: 100%; + line-height: 30px; + margin-bottom: 0px; + clear: both; + font-weight: 400; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box { + border-radius: 8px; + float: left; + position: relative; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box { + position: relative; + width: 140px; + height: 36px; + float: left; + margin-left: 10px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box.last { + margin-left: 0; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box img { + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 10px; + z-index: 1; + width: 22px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box .date_picker { + line-height: 34px; + display: block; + margin-right: 20px; + width: 100%; + font-size: 14px; + padding: 0 12px; + padding-left: 40px; + outline: none; + border: 1px solid #E9ECF0; + border-radius: 5px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box input[type="date"]::-webkit-calendar-picker-indicator { + display: none; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box .date_picker { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: absolute; + cursor: pointer; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .slash { + color: #000; + font-size: 14px; + font-weight: 400; + line-height: 36px; + margin: 0 5px; + width: 6px; + display: block; + float: left; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list { + float: left; + position: relative; + margin-left: 10px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box { + width: 180px; + float: left; + height: 36px; + position: relative; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box img { + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 5px; + z-index: 1; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box input { + width: 100%; + height: 36px; + border: 1px solid #E9ECF0; + border-radius: 5px; + background: none; + position: absolute; + left: 0; + padding: 0 10px 0 30px; + font-size: 14px; + background: #fff; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box input::placeholder { + color: #B5BDC4; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box .search_list { + position: absolute; + top: 40px; + left: 0; + width: 150px; + background: #fff; + color: #fff; + border-radius: 5px; + transition: .4s ease-in; + z-index: 1; + border: solid 1px #E9ECF0; + display: none; + margin: 0; + padding: 10px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_btn { + background: #3985EA; + border-radius: 5px; + color: #fff; + margin-left: 5px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box { + float: right; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box .put_btn { + background: #3985EA; + color: #fff; + border-radius: 5px; + float: left; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box .put_btn img { + position: relative; + top: -2px; + width: 20px; + margin-right: 5px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box .delete_btn { + background: #FF2222; + color: #fff; + border-radius: 5px; + margin-left: 10px; +} + +.project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .right_btn_box .delete_btn img { + position: relative; + top: -2px; + width: 20px; + margin-right: 5px; +} /* table_box */ -.project_wrap .content_section .hospital_wrap .center_box .table_box {width:100%; height:calc(100% - 180px); overflow:auto; background:#fff; border:solid 1px #E9ECF0; border-radius:5px;} +.project_wrap .content_section .hospital_wrap .center_box .table_box { + width: 100%; + height: calc(100% - 180px); + overflow: auto; + background: #fff; + border: solid 1px #E9ECF0; + border-radius: 5px; +} /* 페이지게이션 */ -.project_wrap .content_section .hospital_wrap .center_box .page_box {position:absolute; bottom:20px; width:100%; height:24px;} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation {height:24px;} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination {margin:0 auto; display:table;} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li {display:inline-block; padding:0} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:first-child a, .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a {position:relative; width:24px; height:24px; background:none;} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:first-child a:hover, .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a:hover {background:none;} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:first-child a img {position:absolute; top:50%; left:50%; transform:translate3d(-50%, -50%, 0); width:10px;} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a img {position:absolute; top:50%; left:50%; transform:translate3d(-50%, -50%, 0) rotate(180deg); width:10px;} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li a {width:24px; height:24px; padding:0; border:none; text-align:center; line-height:22px; font-size:14px; font-weight:500; background:#FFF; font-size:14px;} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li a:hover, .project_wrap .content_section .hospital_wrap .center_box .right_note .page_box .navigation .pagination li a:focus {background:#3985EA; color:#fff; font-weight:700;} -.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li.active a {background:#3985EA; color:#fff;} +.project_wrap .content_section .hospital_wrap .center_box .page_box { + position: absolute; + bottom: 20px; + width: 100%; + height: 24px; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation { + height: 24px; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination { + margin: 0 auto; + display: table; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li { + display: inline-block; + padding: 0 +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:first-child a, +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a { + position: relative; + width: 24px; + height: 24px; + background: none; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:first-child a:hover, +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a:hover { + background: none; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:first-child a img { + position: absolute; + top: 50%; + left: 50%; + transform: translate3d(-50%, -50%, 0); + width: 10px; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a img { + position: absolute; + top: 50%; + left: 50%; + transform: translate3d(-50%, -50%, 0) rotate(180deg); + width: 10px; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li a { + width: 24px; + height: 24px; + padding: 0; + border: none; + text-align: center; + line-height: 22px; + font-size: 14px; + font-weight: 500; + background: #FFF; + font-size: 14px; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li a:hover, +.project_wrap .content_section .hospital_wrap .center_box .right_note .page_box .navigation .pagination li a:focus { + background: #3985EA; + color: #fff; + font-weight: 700; +} + +.project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li.active a { + background: #3985EA; + color: #fff; +} /* Style for select boxes in the search area */ .search_box select { @@ -89,43 +438,152 @@ color: #333; font-size: 14px; } + /*반응형 View*/ @media only screen and (max-width:1500px) { - .project_wrap .content_section .hospital_wrap .left_box { width:160px; padding:10px 15px; } - .project_wrap .content_section .hospital_wrap .center_box { width:calc(100% - 160px); left:160px; } + .project_wrap .content_section .hospital_wrap .left_box { + width: 160px; + padding: 10px 15px; + } + + .project_wrap .content_section .hospital_wrap .center_box { + width: calc(100% - 160px); + left: 160px; + } } @media only screen and (max-width:1280px) { - .project_wrap .content_section .hospital_wrap { width:calc(100% - 60px); } - .project_wrap .content_section .hospital_wrap .left_box .sub_menu_list .title_menu { font-size:12px; } - .project_wrap .content_section .hospital_wrap .left_box .sub_menu_list li { height:32px; margin-bottom:5px; } - .project_wrap .content_section .hospital_wrap .left_box .sub_menu_list li a { font-size:12px; } - .project_wrap .content_section .hospital_wrap .center_box .page_title { min-width:80px; height:40px; font-size:16px; line-height:40px; } - .project_wrap .content_section .hospital_wrap .center_box .total { font-size:12px; line-height:40px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box { padding:15px 0; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box { width:120px; height:32px; background-size:18px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .label { padding:0 10px; font-size:12px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .select_option_list .option_list_item { font-size:12px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box { width:120px; height:32px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box img { width:20px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box .date_picker { height:32px; padding-left:35px; font-size:12px; line-height:32px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .slash { line-height:32px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box { width:120px; height:32px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box img { width:22px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box input { height:32px; padding-left:35px; font-size:12px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .right_btn_box .download_btn { margin-left:5px; padding-left:10px; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .right_btn_box .download_btn p { display:none; } - .project_wrap .content_section .hospital_wrap .center_box .filter_box .right_btn_box .download_btn img { width:12px; margin-top:-3px; position:static; transform:none; } - .project_wrap .content_section .hospital_wrap .center_box .page_box { height:23px; } - .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation { height:23px; } - .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li a { width:23px; height:23px; font-size:12px; } + .project_wrap .content_section .hospital_wrap { + width: calc(100% - 60px); + } + + .project_wrap .content_section .hospital_wrap .left_box .sub_menu_list .title_menu { + font-size: 12px; + } + + .project_wrap .content_section .hospital_wrap .left_box .sub_menu_list li { + height: 32px; + margin-bottom: 5px; + } + + .project_wrap .content_section .hospital_wrap .left_box .sub_menu_list li a { + font-size: 12px; + } + + .project_wrap .content_section .hospital_wrap .center_box .page_title { + min-width: 80px; + height: 40px; + font-size: 16px; + line-height: 40px; + } + + .project_wrap .content_section .hospital_wrap .center_box .total { + font-size: 12px; + line-height: 40px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box { + padding: 15px 0; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box { + width: 120px; + height: 32px; + background-size: 18px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .label { + padding: 0 10px; + font-size: 12px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .select_box .select_option_list .option_list_item { + font-size: 12px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box { + width: 120px; + height: 32px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box img { + width: 20px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .date_box .date_picker { + height: 32px; + padding-left: 35px; + font-size: 12px; + line-height: 32px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .calendar_box .slash { + line-height: 32px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box { + width: 120px; + height: 32px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box img { + width: 22px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .form_box .search_list .search_box input { + height: 32px; + padding-left: 35px; + font-size: 12px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .right_btn_box .download_btn { + margin-left: 5px; + padding-left: 10px; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .right_btn_box .download_btn p { + display: none; + } + + .project_wrap .content_section .hospital_wrap .center_box .filter_box .right_btn_box .download_btn img { + width: 12px; + margin-top: -3px; + position: static; + transform: none; + } + + .project_wrap .content_section .hospital_wrap .center_box .page_box { + height: 23px; + } + + .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation { + height: 23px; + } + + .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li a { + width: 23px; + height: 23px; + font-size: 12px; + } + .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:first-child a, - .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a { width:23px; height:23px; } + .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a { + width: 23px; + height: 23px; + } + .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:first-child a img, - .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a img { width:9px; } - .project_wrap .content_section .hospital_wrap .center_box .table_box { height:calc(100% - 155px); } + .project_wrap .content_section .hospital_wrap .center_box .page_box .navigation .pagination li:last-child a img { + width: 9px; + } + + .project_wrap .content_section .hospital_wrap .center_box .table_box { + height: calc(100% - 155px); + } } @media only screen and (max-width:1080px) { - .project_wrap .content_section .hospital_wrap { width:calc(100% - 50px); } + .project_wrap .content_section .hospital_wrap { + width: calc(100% - 50px); + } } \ No newline at end of file diff --git a/src/main/resources/static/js/web/settings/medicalcategory/medicalCategoryList.js b/src/main/resources/static/js/web/settings/medicalcategory/medicalCategoryList.js new file mode 100644 index 0000000..73a0e94 --- /dev/null +++ b/src/main/resources/static/js/web/settings/medicalcategory/medicalCategoryList.js @@ -0,0 +1,544 @@ +/** + * 통합 진료유형 관리 (medicalCategoryList.js) + * - medical_divi_list 테이블 기반 + * - Depth 1(진료과목 select) → Depth 2/3/4 (Tabulator 그리드) + */ +$(document).ready(function () { + let globalTreeData = []; + let nodeMap = {}; + let table2 = null; + let table3 = null; + let table4 = null; + let tableOverview = null; + let overviewInitialized = false; + + function initGrid() { + // 커스텀 컨텍스트 메뉴 요소 생성 및 이벤트 바인딩 + if ($('#customContextMenu').length === 0) { + $('body').append( + '
' + + '
    ' + + '
  • 삭제
  • ' + + '
' + + '
' + ); + + // 메뉴 밖 클릭 시 커스텀 메뉴 닫기 + $(document).on('click', function (e) { + if (!$(e.target).closest('#customContextMenu').length) { + $('#customContextMenu').hide(); + } + }); + + // 메뉴 [삭제] 클릭 이벤트 + $(document).on('click', '#customContextMenu .delete', function () { + var menu = $('#customContextMenu'); + var pid = menu.data('pid'); + var name = menu.data('name'); + menu.hide(); + + if (!pid) return; + if (!confirm("'" + name + "' 항목을 삭제하시겠습니까?\n하위 항목이 있을 경우 삭제되지 않습니다.")) return; + + $.ajax({ + url: '/settings/medicalCategory/delMedicalCategory.do', + type: 'POST', + data: { pid: pid }, + success: function (res) { + alert(res.msgDesc); + if (res.msgCode === '0' && window.currentContextRow) { + var tableId = window.currentContextRow.getTable().element.id; + var isSelected = window.currentContextRow.isSelected(); + + // 1. 그리드에서 행 삭제 + window.currentContextRow.delete(); + + // 2. 만약 선택된 행이었다면, 우측 하위 패널 초기화 + if (isSelected) { + if (tableId === 'gridDepth2') { + table3.setData([]); + table4.setData([]); + $("#btnArea3").empty(); + $("#btnArea4").empty(); + } else if (tableId === 'gridDepth3') { + table4.setData([]); + $("#btnArea4").empty(); + } + } + } + }, + error: function () { + alert("삭제 중 오류가 발생했습니다."); + } + }); + }); + } + + // Tabulator rowContext 이벤트(우클릭) 공통 핸들러 + function onRowContextMenu(e, row) { + e.preventDefault(); + var data = row.getData(); + window.currentContextRow = row; // 행 삭제를 위해 캐싱 + + $('#customContextMenu') + .data('pid', data.pid) + .data('name', data.divi_name) + .css({ + top: e.pageY + 'px', + left: e.pageX + 'px' + }) + .show(); + } + + let commonOpts = { + index: "pid", + layout: "fitColumns", + placeholder: "상위 항목을 선택하세요.", + selectable: 1, + height: "100%", + columnDefaults: { + headerTooltip: true, + headerHozAlign: "center" + } + }; + + // Depth 2 Grid - 순번, 명칭, 순서, 관리, 하위 + table2 = new Tabulator("#gridDepth2", Object.assign({}, commonOpts, { + columns: [ + { title: "순번", formatter: "rownum", width: 38, hozAlign: "center", headerSort: false, cssClass: "col-sm" }, + { title: "명칭", field: "divi_name", formatter: categoryNameFormatter, tooltip: true }, + { title: "순서", field: "divi_sort", width: 38, hozAlign: "center", cssClass: "col-sm" }, + { title: "관리", width: 50, hozAlign: "center", headerSort: false, formatter: editFormatter, cellClick: function (e, cell) { e.stopPropagation(); editCategory(cell.getRow().getData().pid); } }, + { title: "하위", width: 50, hozAlign: "center", headerSort: false, formatter: function (c) { return addDescendantFormatter(c, 2); }, cellClick: function (e, cell) { e.stopPropagation(); var d = cell.getRow().getData(); addChildCategory(d.pid, 3, d.divi_name); } } + ] + })); + + // Depth 3 Grid - 순번, 명칭, 거래처, 담당자(연락처), 단가, 순서, 관리, 하위 + table3 = new Tabulator("#gridDepth3", Object.assign({}, commonOpts, { + columns: [ + { title: "순번", formatter: "rownum", width: 38, hozAlign: "center", headerSort: false, cssClass: "col-sm" }, + { 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: "관리", width: 50, hozAlign: "center", headerSort: false, formatter: editFormatter, cellClick: function (e, cell) { e.stopPropagation(); editCategory(cell.getRow().getData().pid); } }, + { 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); } } + ] + })); + + // Depth 4 Grid - 순번, 명칭, 순서, 관리 (하위 없음) + table4 = new Tabulator("#gridDepth4", Object.assign({}, commonOpts, { + columns: [ + { title: "순번", formatter: "rownum", width: 38, hozAlign: "center", headerSort: false, cssClass: "col-sm" }, + { title: "명칭", field: "divi_name", formatter: categoryNameFormatter, tooltip: true }, + { title: "순서", field: "divi_sort", width: 38, hozAlign: "center", cssClass: "col-sm" }, + { title: "관리", width: 50, hozAlign: "center", headerSort: false, formatter: editFormatter, cellClick: function (e, cell) { e.stopPropagation(); editCategory(cell.getRow().getData().pid); } } + ] + })); + + table2.on("rowClick", function (e, row) { clickRow(row, 2); }); + table3.on("rowClick", function (e, row) { clickRow(row, 3); }); + table4.on("rowClick", function (e, row) { clickRow(row, 4); }); + + table2.on("rowContext", onRowContextMenu); + table3.on("rowContext", onRowContextMenu); + table4.on("rowContext", onRowContextMenu); + + window.loadData(); + } + + /* ====== 포맷터 영역 ====== */ + + function categoryNameFormatter(cell) { + var data = cell.getRow().getData(); + var nameStyle = data.list_use === 'y' ? 'font-weight:600;' : 'text-decoration:line-through; color:#aaa;'; + var color = data.divi_color || '#333'; + if (data.list_use !== 'y') color = '#aaa'; + + var html = '' + cell.getValue() + ''; + + // 면세 표시 + if (data.tax_free === 'y') { + html += ' [면세]'; + } + return html; + } + + function costFormatter(cell) { + var val = cell.getValue(); + if (val && Number(val) > 0) { + return Number(val).toLocaleString(); + } + return ''; + } + + function ynFormatter(cell) { + var val = cell.getValue(); + if (val === 'y') { + return 'Y'; + } + return 'N'; + } + + function editFormatter(cell) { + return '수정'; + } + + function addDescendantFormatter(cell, depth) { + return '등록'; + } + + /* ====== 행 클릭 ====== */ + + function clickRow(row, depth, currentState) { + var data = row.getData(); + var children = data._children || []; + + row.getTable().deselectRow(); + row.select(); + + if (depth === 2) { + table3.setData(children).then(function () { + if (currentState && currentState.depth3) { + table3.selectRow(currentState.depth3); + let selectedRows = table3.getSelectedRows(); + if (selectedRows && selectedRows.length > 0) { + clickRow(selectedRows[0], 3, currentState); + } + } + }); + table4.setData([]); + $("#btnArea3").html(''); + $("#btnArea4").empty(); + } else if (depth === 3) { + table4.setData(children).then(function () { + if (currentState && currentState.depth4) { + table4.selectRow(currentState.depth4); + } + }); + $("#btnArea4").html(''); + } + } + + /* ====== 트리 구성 ====== */ + + function buildNodeMap(nodes) { + nodes.forEach(node => { + nodeMap[node.pid] = node; + if (node._children && node._children.length > 0) { + buildNodeMap(node._children); + } else if (node._children && node._children.length === 0) { + delete node._children; // 하위 뎁스가 없어 최하위 node일 경우 트리 확정버튼(+/-)을 숨기기 위해 빈 배열 삭제 + } + }); + } + + /* ====== 데이터 로드 ====== */ + + window.loadData = function (preserveState) { + let currentState = {}; + if (preserveState) { + currentState.depth1 = $("#depth1Select").val(); + currentState.depth1Overview = $("#depth1SelectOverview").val(); + let selected2 = table2.getSelectedData()[0]; + let selected3 = table3.getSelectedData()[0]; + let selected4 = table4.getSelectedData()[0]; + + if (selected2) currentState.depth2 = selected2.pid; + if (selected3) currentState.depth3 = selected3.pid; + if (selected4) currentState.depth4 = selected4.pid; + } + + $.ajax({ + url: "/settings/medicalCategory/getMedicalCategoryTreeList.do", + type: "POST", + data: { storePid: '1' }, + success: function (res) { + if (res.msgCode === '0') { + globalTreeData = res.rows || []; + nodeMap = {}; + buildNodeMap(globalTreeData); + renderDepth1Select(globalTreeData, currentState); + } else { + alert(res.msgDesc); + } + }, + error: function () { + alert("데이터 목록을 불러오는데 실패했습니다."); + } + }); + }; + + function renderDepth1Select(nodes, currentState) { + let filteredNodes = []; + if (nodes && nodes.length > 0) { + const seenNames = new Set(); + for (const node of nodes) { + const name = node.divi_name ? node.divi_name.trim() : ''; + if (!seenNames.has(name)) { + seenNames.add(name); + filteredNodes.push(node); + } + } + } + + const optionList = $("#depth1OptionList"); + const labelBtn = $("#depth1SelectBox .label"); + const hiddenInput = $("#depth1Select"); + optionList.empty(); + + const optListOverview = $("#depth1OptionListOverview"); + const lblBtnOverview = $("#depth1SelectBoxOverview .label"); + const hdInputOverview = $("#depth1SelectOverview"); + optListOverview.empty(); + + if (filteredNodes.length === 0) { + labelBtn.text('항목 없음'); + hiddenInput.val(''); + lblBtnOverview.text('항목 없음'); + hdInputOverview.val(''); + + table2.setData([]); + table3.setData([]); + table4.setData([]); + $("#btnArea2").empty(); + $("#btnArea3").empty(); + $("#btnArea4").empty(); + + if (tableOverview) tableOverview.setData([]); + return; + } + + filteredNodes.forEach(function (node) { + var li = $('
  • '); + var label = $('').text(node.divi_name); + li.append(label); + li.data('value', node.pid); + li.on('click', function () { + hiddenInput.val(node.pid); + labelBtn.text(node.divi_name); + window.onChangeDepth1(); + }); + optionList.append(li); + + var liOver = $('
  • '); + var labelOver = $('').text(node.divi_name); + liOver.append(labelOver); + liOver.data('value', node.pid); + liOver.on('click', function () { + hdInputOverview.val(node.pid); + lblBtnOverview.text(node.divi_name); + window.onChangeDepth1Overview(); + }); + optListOverview.append(liOver); + }); + + // 선택 상태 복원 + let targetPid = filteredNodes[0].pid; + let targetName = filteredNodes[0].divi_name; + + let targetPidOverview = filteredNodes[0].pid; + let targetNameOverview = filteredNodes[0].divi_name; + + if (currentState && currentState.depth1) { + let matched = filteredNodes.find(n => n.pid == currentState.depth1); + if (matched) { + targetPid = matched.pid; + targetName = matched.divi_name; + } + } + + if (currentState && currentState.depth1Overview) { + let matched = filteredNodes.find(n => n.pid == currentState.depth1Overview); + if (matched) { + targetPidOverview = matched.pid; + targetNameOverview = matched.divi_name; + } + } + + hiddenInput.val(targetPid); + labelBtn.text(targetName); + window.onChangeDepth1(currentState); + + hdInputOverview.val(targetPidOverview); + lblBtnOverview.text(targetNameOverview); + + if (overviewInitialized) { + window.onChangeDepth1Overview(); + } + } + + window.onChangeDepth1Overview = function () { + const selectedPid = $("#depth1SelectOverview").val(); + if (!selectedPid) { + if (tableOverview) tableOverview.setData([]); + return; + } + + const pid = parseInt(selectedPid); + const node = nodeMap[pid]; + + if (tableOverview && node) { + tableOverview.setData([node]); + } else if (tableOverview) { + tableOverview.setData([]); + } + }; + + window.onChangeDepth1 = function (currentState) { + const selectedPid = $("#depth1Select").val(); + if (!selectedPid) { + table2.setData([]); + table3.setData([]); + table4.setData([]); + $("#btnArea2").empty(); + $("#btnArea3").empty(); + $("#btnArea4").empty(); + return; + } + + const pid = parseInt(selectedPid); + const node = nodeMap[pid]; + + table3.setData([]); + table4.setData([]); + $("#btnArea3").empty(); + $("#btnArea4").empty(); + + if (node && node._children) { + table2.setData(node._children).then(function () { + if (currentState && currentState.depth2) { + table2.selectRow(currentState.depth2); + let selectedRows = table2.getSelectedRows(); + if (selectedRows && selectedRows.length > 0) { + clickRow(selectedRows[0], 2, currentState); + } + } + }); + $("#btnArea2").html(''); + } else { + table2.setData([]); + $("#btnArea2").empty(); + } + }; + + /* ====== 팝업 관련 ====== */ + + window.editCategory = function (pid) { + openInfoPopup('edit', pid); + }; + + window.addChildCategory = function (diviParent, diviDept, parentName) { + openInfoPopup('add', '', diviDept, diviParent, (parentName || '').replace(/'/g, "\\'")); + }; + + window.delCategory = function (pid) { + if (!confirm("해당 카테고리를 삭제하시겠습니까?\n하위 항목이 있을 경우 삭제되지 않습니다.")) return; + + $.ajax({ + url: "/settings/medicalCategory/delMedicalCategory.do", + type: "POST", + data: { pid: pid }, + success: function (res) { + alert(res.msgDesc); + if (res.msgCode === '0') { + loadData(true); + } + }, + error: function () { + alert("삭제 통신 중 오류가 발생했습니다."); + } + }); + }; + + function openInfoPopup(mode, pid, diviDept, diviParent, parentName) { + pid = pid || ''; + diviDept = diviDept || ''; + diviParent = diviParent || ''; + parentName = parentName || ''; + const url = '/settings/medicalCategory/infoPop.do?mode=' + mode + '&pid=' + pid + '&diviDept=' + diviDept + '&diviParent=' + diviParent + '&parentName=' + encodeURIComponent(parentName); + + let width = 650; + let height = 750; + let left = (screen.width - width) / 2; + let top = (screen.height - height) / 2; + + window.open(url, "MedicalCategoryInfoPopup", "width=" + width + ",height=" + height + ",left=" + left + ",top=" + top + ",scrollbars=yes,resizable=yes"); + } + + initGrid(); + + /* ====== 전체보기 탭 ====== */ + + // 탭 전환 이벤트 + $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { + var target = $(e.target).attr('href'); + if (target === '#tabOverview') { + if (!overviewInitialized) { + initOverviewGrid(function () { + window.onChangeDepth1Overview(); + }); + overviewInitialized = true; + } else { + window.onChangeDepth1Overview(); + } + } + }); + + function initOverviewGrid(callback) { + tableOverview = new Tabulator("#gridOverview", { + dataTree: true, + dataTreeStartExpanded: true, + layout: "fitColumns", + placeholder: "데이터를 불러오는 중...", + height: "100%", + columnDefaults: { + headerTooltip: true, + headerHozAlign: "center", + tooltip: true + }, + columns: [ + { title: "1depth", field: "divi_name", width: "15%", hozAlign: "left", formatter: overviewDepthFormatter(1) }, + { title: "2depth", field: "divi_name2", width: "12%", hozAlign: "left", formatter: overviewDepthFormatter(2) }, + { title: "3depth", field: "divi_name3", width: "18%", hozAlign: "left", formatter: overviewDepthFormatter(3) }, + { title: "4depth", field: "divi_name4", width: "12%", hozAlign: "left", formatter: overviewDepthFormatter(4) }, + { title: "단가", field: "kind_cost", width: "10%", formatter: costFormatter, hozAlign: "right" }, + { title: "단위", field: "kind_unit", width: "10%", hozAlign: "center" }, + { title: "사용여부", field: "list_use", width: "10%", formatter: ynFormatter, hozAlign: "center" }, + { title: "면세여부", field: "tax_free", width: "8%", formatter: ynFormatter, hozAlign: "center" } + ] + }); + + tableOverview.on("tableBuilt", function () { + if (typeof callback === 'function') callback(); + }); + } + + function overviewDepthFormatter(targetDepth) { + return function (cell) { + var data = cell.getRow().getData(); + if (parseInt(data.divi_dept, 10) !== targetDepth) return ''; + + var nameStyle = data.list_use === 'y' ? 'font-weight:600;' : 'text-decoration:line-through; color:#aaa;'; + var color = data.divi_color || '#333'; + if (data.list_use !== 'y') color = '#aaa'; + + var html = '' + (data.divi_name || '') + ''; + + if (data.tax_free === 'y') { + html += ' [면세]'; + } + return html; + }; + } + + function loadOverviewData() { + if (globalTreeData.length === 0) { + window.loadData(); + } else { + window.onChangeDepth1Overview(); + } + } + +}); diff --git a/src/main/resources/static/js/web/settings/medicalcategory/popup/medicalCategoryInfoPop.js b/src/main/resources/static/js/web/settings/medicalcategory/popup/medicalCategoryInfoPop.js new file mode 100644 index 0000000..3e5d4ba --- /dev/null +++ b/src/main/resources/static/js/web/settings/medicalcategory/popup/medicalCategoryInfoPop.js @@ -0,0 +1,265 @@ +/** + * 진료유형 상세/추가 팝업 스크립트 + * - medical_divi_list DDL 전체 컬럼 반영 + */ +$(document).ready(function () { + + // 1. URL 파라미터 파싱 + const params = new URLSearchParams(window.location.search); + const mode = params.get('mode'); // 'add' or 'edit' + const pid = params.get('pid'); + const diviDept = params.get('diviDept'); + const diviParent = params.get('diviParent'); + const parentName = params.get('parentName'); + + bindEvents(); + + // 뎁스3이면 거래처 목록을 로드한 뒤 폼 초기화를 진행 + if (diviDept === '3' || mode === 'edit') { + loadCustList().then(function () { + initForm(); + applyDepthUI(); + }); + } else { + initForm(); + applyDepthUI(); + } + + function applyDepthUI() { + const currentDept = $("#diviDept").val() || diviDept; + if (currentDept == '1') { + $("#trNoTax").show(); + $("#trNoTax1").show(); + } else { + $("#trNoTax").hide(); + $("#trNoTax1").hide(); + } + + if (currentDept == '3') { + $("#productInfoTitle").show(); + $("#productInfoTable").show(); + } else { + $("#productInfoTitle").hide(); + $("#productInfoTable").hide(); + } + } + + // 거래처 셀렉트 박스 세팅 + function loadCustList() { + return new Promise(function (resolve) { + $.ajax({ + url: '/settings/medicalCategory/getCustList.do', + type: 'POST', + success: function (res) { + if (res.msgCode === '0' && res.data) { + const $select = $("#custListPid"); + $select.empty().append(''); + res.data.forEach(function (cust) { + $select.append(``); + }); + } + resolve(); + }, + error: function () { + console.error("거래처 목록 로드 실패"); + resolve(); + } + }); + }); + } + + function initForm() { + if (mode === 'add') { + $("#popTitle").text((diviDept == '1' ? '최상위 ' : '') + '진료유형 신규 등록'); + $("#pid").val(''); + $("#diviDept").val(diviDept); + $("#diviParent").val(diviParent); + $("#btn_delete").hide(); + + if (diviParent !== '0' && parentName) { + $("#parentNameRow").show(); + $("#parentNameTxt").text(parentName); + } + } else if (mode === 'edit') { + $("#popTitle").text('진료유형 정보 수정'); + $("#pid").val(pid); + $("#btn_delete").show(); + loadDetail(pid); + } + } + + function loadDetail(id) { + $.ajax({ + url: '/settings/medicalCategory/getMedicalCategory.do', + type: 'POST', + data: { pid: id }, + success: function (res) { + if (res.msgCode === '0') { + const data = res.data; + $("#diviDept").val(data.divi_dept); + $("#diviParent").val(data.divi_parent); + $("#diviName").val(data.divi_name); + $("#diviSort").val(data.divi_sort); + $("#diviColor").val(data.divi_color || '#000000'); + + // 단가/제품 정보 + if (data.cust_list_pid && data.cust_list_pid !== 0) { + $("#custListPid").val(data.cust_list_pid); + } + $("#kindCost").val(data.kind_cost || 0); + $("#kindUnit").val(data.kind_unit || ''); + $("#kindUnitVol").val(data.kind_unit_vol || 0); + $("#kindUnit2").val(data.kind_unit2 || ''); + $("#kindMsg1").val(data.kind_msg1 || ''); + $("#kindMsg2").val(data.kind_msg2 || ''); + $("#ccRate").val(data.cc_rate || ''); + + // 설정 버튼들 + setRadio('listUse', data.list_use); + setCheckbox('clinicUse', data.clinic_use); + setCheckbox('expenseUse', data.expense_use); + setCheckbox('taxFree', data.tax_free); + setCheckbox('etcincomeUse', data.etcincome_use); + setCheckbox('etclossUse', data.etcloss_use); + setCheckbox('stockUse', data.stock_use); + setCheckbox('noTax', data.no_tax); + setCheckbox('noTax1', data.no_tax1); + setCheckbox('npayUse', data.npay_use); + + applyDepthUI(); + } else { + alert("정보를 불러올 수 없습니다."); + window.close(); + } + }, + error: function () { + alert("상세 정보 조회 통신 오류"); + window.close(); + } + }); + } + + function setRadio(name, value) { + if (value) { + $("input:radio[name='" + name + "'][value='" + value + "']").prop('checked', true); + } + } + + function getRadio(name) { + return $("input:radio[name='" + name + "']:checked").val(); + } + + function setCheckbox(name, value) { + if (value === 'y') { + $("input:checkbox[name='" + name + "']").prop('checked', true); + } else { + $("input:checkbox[name='" + name + "']").prop('checked', false); + } + } + + function getCheckbox(name) { + return $("input:checkbox[name='" + name + "']").is(":checked") ? 'y' : 'n'; + } + + function bindEvents() { + $("#btn_close").on("click", function () { + window.close(); + }); + + $("#btn_save").on("click", function () { + saveCategory(); + }); + + $("#btn_delete").on("click", function () { + deleteCategory(); + }); + } + + function saveCategory() { + const dName = $("#diviName").val().trim(); + if (!dName) { + alert("진료유형 명칭을 입력하세요."); + $("#diviName").focus(); + return; + } + + const submitObj = { + pid: $("#pid").val() || null, + storePid: $("#storePid").val(), + diviName: dName, + diviDept: $("#diviDept").val(), + diviParent: $("#diviParent").val(), + diviSort: parseInt($("#diviSort").val() || "0", 10), + diviColor: $("#diviColor").val(), + + // 구분 설정 + listUse: getRadio('listUse') || 'n', + clinicUse: getCheckbox('clinicUse'), + expenseUse: getCheckbox('expenseUse'), + taxFree: getCheckbox('taxFree'), + etcincomeUse: getCheckbox('etcincomeUse'), + etclossUse: getCheckbox('etclossUse'), + stockUse: getCheckbox('stockUse'), + noTax: getCheckbox('noTax'), + noTax1: getCheckbox('noTax1'), + npayUse: getCheckbox('npayUse'), + + // 단가/제품 정보 + custListPid: parseInt($("#custListPid").val() || "0", 10), + kindCost: parseFloat($("#kindCost").val() || "0"), + kindUnit: $("#kindUnit").val(), + kindUnitVol: parseFloat($("#kindUnitVol").val() || "0"), + kindUnit2: $("#kindUnit2").val(), + kindMsg1: $("#kindMsg1").val(), + kindMsg2: $("#kindMsg2").val(), + ccRate: $("#ccRate").val() + }; + + const targetUrl = mode === 'edit' ? '/settings/medicalCategory/modMedicalCategory.do' : '/settings/medicalCategory/putMedicalCategory.do'; + + $.ajax({ + url: targetUrl, + type: 'POST', + contentType: 'application/json', + data: JSON.stringify(submitObj), + success: function (res) { + alert(res.msgDesc); + if (res.msgCode === '0') { + if (window.opener && typeof window.opener.loadData === 'function') { + window.opener.loadData(true); + } + window.close(); + } + }, + error: function () { + alert("저장 중 시스템 오류가 발생했습니다."); + } + }); + } + + function deleteCategory() { + const pidVal = $("#pid").val(); + if (!pidVal) return; + + if (!confirm("해당 카테고리를 삭제하시겠습니까?\n하위 항목이 있을 경우 삭제되지 않습니다.")) return; + + $.ajax({ + url: '/settings/medicalCategory/delMedicalCategory.do', + type: 'POST', + data: { pid: pidVal }, + success: function (res) { + alert(res.msgDesc); + if (res.msgCode === '0') { + if (window.opener && typeof window.opener.loadData === 'function') { + window.opener.loadData(true); + } + window.close(); + } + }, + error: function () { + alert("삭제 중 시스템 오류가 발생했습니다."); + } + }); + } + +}); diff --git a/src/main/resources/templates/web/settings/medicalcategory/medicalCategoryList.html b/src/main/resources/templates/web/settings/medicalcategory/medicalCategoryList.html new file mode 100644 index 0000000..9c9b6e1 --- /dev/null +++ b/src/main/resources/templates/web/settings/medicalcategory/medicalCategoryList.html @@ -0,0 +1,148 @@ + + + + + 통합 진료유형 관리 + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    + + +
    + +
    +
    + 진료유형 +
    +
    +
    +
    + + +
    +
    + 제품/시술 +
    +
    +
    +
    + + +
    +
    + 부위 +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/web/settings/medicalcategory/popup/medicalCategoryInfoPop.html b/src/main/resources/templates/web/settings/medicalcategory/popup/medicalCategoryInfoPop.html new file mode 100644 index 0000000..24cabb6 --- /dev/null +++ b/src/main/resources/templates/web/settings/medicalcategory/popup/medicalCategoryInfoPop.html @@ -0,0 +1,282 @@ + + + + + 진료유형 정보 + + + + + + +
    +

    진료유형 등록

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 항목 명칭
    정렬 순서 숫자가 낮을수록 먼저 + 표시됩니다.
    색상 코드
    + + +
    구분 설정
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    노출 여부 + + +
    구분 +   +   +   +   + +
    재고관리품목 +      + +
    비과세 + +
    비세금 + +
    + + +
    단가/제품 정보
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    거래처 + +
    단가
    단위 + + 용량: + + +
    제품설명
    기타설명
    비율
    + +
    + + + +
    +
    + + + + + \ No newline at end of file