코드 관리 및 진료유형설정 수정

This commit is contained in:
2026-02-25 11:20:10 +09:00
parent 93e9bd9b15
commit da3e497e9c
27 changed files with 3162 additions and 421 deletions

View File

@@ -0,0 +1,188 @@
package com.madeu.crm.settings.code.ctrl;
import com.madeu.constants.Constants;
import com.madeu.util.HttpUtil;
import com.madeu.crm.settings.code.service.CodeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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 jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.HashMap;
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/settings/code")
public class CodeController {
private final CodeService codeService;
/**
* 코드 관리 메인 화면 이동
*/
@RequestMapping("/codeList.do")
public ModelAndView codeList(HttpServletRequest request, HttpServletResponse response) {
log.debug("CodeController codeList START");
log.debug("CodeController codeList END");
return new ModelAndView("/web/settings/code/codeList");
}
/**
* 코드 그룹 리스트 조회
*/
@PostMapping("/getCodeGroupList.do")
public HashMap<String, Object> getCodeGroupList(HttpServletRequest request, HttpServletResponse response) {
log.debug("CodeController getCodeGroupList START");
HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
HashMap<String, Object> map = new HashMap<>();
try {
map = codeService.getCodeGroupList(paramMap);
} catch (Exception e) {
log.error("getCodeGroupList : ", e);
map.put("msgCode", Constants.FAIL);
map.put("msgDesc", "서버 오류가 발생했습니다.");
}
return map;
}
/**
* 코드 그룹 상세 조회
*/
@PostMapping("/getCodeGroup.do")
public HashMap<String, Object> getCodeGroup(HttpServletRequest request, HttpServletResponse response) {
log.debug("CodeController getCodeGroup START");
HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
return codeService.getCodeGroup(paramMap);
}
/**
* 코드 그룹 저장 (신규/수정)
*/
@PostMapping("/saveCodeGroup.do")
public HashMap<String, Object> saveCodeGroup(@RequestBody HashMap<String, Object> paramMap,
HttpServletRequest request, HttpServletResponse response) {
log.debug("CodeController saveCodeGroup START");
HashMap<String, Object> map = new HashMap<>();
try {
map = codeService.saveCodeGroup(paramMap);
} catch (Exception e) {
log.error("saveCodeGroup : ", e);
map.put("msgCode", Constants.FAIL);
map.put("msgDesc", "서버 오류가 발생했습니다.");
}
return map;
}
/**
* 코드 그룹 삭제
*/
@PostMapping("/deleteCodeGroup.do")
public HashMap<String, Object> deleteCodeGroup(HttpServletRequest request, HttpServletResponse response) {
log.debug("CodeController deleteCodeGroup START");
HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
HashMap<String, Object> map = new HashMap<>();
try {
map = codeService.deleteCodeGroup(paramMap);
} catch (Exception e) {
log.error("deleteCodeGroup : ", e);
map.put("msgCode", Constants.FAIL);
map.put("msgDesc", "서버 오류가 발생했습니다.");
}
return map;
}
// ===================================
// 상세 코드 관련
// ===================================
/**
* 상세 코드 리스트 조회
*/
@PostMapping("/getCodeList.do")
public HashMap<String, Object> getCodeList(HttpServletRequest request, HttpServletResponse response) {
log.debug("CodeController getCodeList START");
HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
HashMap<String, Object> map = new HashMap<>();
try {
map = codeService.getCodeList(paramMap);
} catch (Exception e) {
log.error("getCodeList : ", e);
map.put("msgCode", Constants.FAIL);
map.put("msgDesc", "서버 오류가 발생했습니다.");
}
return map;
}
/**
* 상세 코드 상세 조회
*/
@PostMapping("/getCode.do")
public HashMap<String, Object> getCode(HttpServletRequest request, HttpServletResponse response) {
log.debug("CodeController getCode START");
HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
return codeService.getCode(paramMap);
}
/**
* 상세 코드 저장 (신규/수정)
*/
@PostMapping("/saveCode.do")
public HashMap<String, Object> saveCode(@RequestBody HashMap<String, Object> paramMap, HttpServletRequest request,
HttpServletResponse response) {
log.debug("CodeController saveCode START");
HashMap<String, Object> map = new HashMap<>();
try {
map = codeService.saveCode(paramMap);
} catch (Exception e) {
log.error("saveCode : ", e);
map.put("msgCode", Constants.FAIL);
map.put("msgDesc", "서버 오류가 발생했습니다.");
}
return map;
}
/**
* 상세 코드 삭제
*/
@PostMapping("/deleteCode.do")
public HashMap<String, Object> deleteCode(HttpServletRequest request, HttpServletResponse response) {
log.debug("CodeController deleteCode START");
HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
HashMap<String, Object> map = new HashMap<>();
try {
map = codeService.deleteCode(paramMap);
} catch (Exception e) {
log.error("deleteCode : ", e);
map.put("msgCode", Constants.FAIL);
map.put("msgDesc", "서버 오류가 발생했습니다.");
}
return map;
}
// ===================================
// 팝업 화면 라우팅
// ===================================
@RequestMapping("/codeGroupPop.do")
public ModelAndView codeGroupPop(HttpServletRequest request, HttpServletResponse response) {
return new ModelAndView("/web/settings/code/popup/codeGroupPop");
}
@RequestMapping("/codePop.do")
public ModelAndView codePop(HttpServletRequest request, HttpServletResponse response) {
return new ModelAndView("/web/settings/code/popup/codePop");
}
}

View File

@@ -0,0 +1,18 @@
package com.madeu.crm.settings.code.dto;
import lombok.Data;
@Data
public class CodeDTO {
private Integer pid;
private Integer storePid;
private String grpCd;
private String codeCd;
private String codeNm;
private String codeVal;
private String codeDesc;
private Integer codeSort;
private String listUse;
private String regDate;
private String upDate;
}

View File

@@ -0,0 +1,15 @@
package com.madeu.crm.settings.code.dto;
import lombok.Data;
@Data
public class CodeGroupDTO {
private Integer pid;
private Integer storePid;
private String grpCd;
private String grpNm;
private String grpDesc;
private String listUse;
private String regDate;
private String upDate;
}

View File

@@ -0,0 +1,44 @@
package com.madeu.crm.settings.code.mapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.HashMap;
import java.util.List;
@Mapper
public interface CodeMapper {
// 1. 코드 그룹 리스트
List<HashMap<String, Object>> getCodeGroupList(HashMap<String, Object> paramMap);
// 2. 코드 그룹 상세 단건
HashMap<String, Object> getCodeGroup(HashMap<String, Object> paramMap);
// 3. 코드 그룹 확인용 (중복검사)
int checkGrpCd(HashMap<String, Object> paramMap);
// 4. 코드 그룹 등록
int insertCodeGroup(HashMap<String, Object> paramMap);
// 5. 코드 그룹 수정
int updateCodeGroup(HashMap<String, Object> paramMap);
// 6. 코드 그룹 삭제 (논리 삭제)
int deleteCodeGroup(HashMap<String, Object> paramMap);
// 7. 상세 코드 리스트
List<HashMap<String, Object>> getCodeList(HashMap<String, Object> paramMap);
// 8. 상세 코드 단건
HashMap<String, Object> getCode(HashMap<String, Object> paramMap);
// 9. 상세 코드 확인용 (중복검사)
int checkCodeCd(HashMap<String, Object> paramMap);
// 10. 상세 코드 등록
int insertCode(HashMap<String, Object> paramMap);
// 11. 상세 코드 수정
int updateCode(HashMap<String, Object> paramMap);
// 12. 상세 코드 삭제 (논리 삭제)
int deleteCode(HashMap<String, Object> paramMap);
}

View File

@@ -0,0 +1,141 @@
package com.madeu.crm.settings.code.service;
import com.madeu.crm.settings.code.mapper.CodeMapper;
import com.madeu.constants.Constants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class CodeService {
private final CodeMapper codeMapper;
// ==========================================
// 1. 코드 그룹 (Code Group)
// ==========================================
public HashMap<String, Object> getCodeGroupList(HashMap<String, Object> paramMap) {
HashMap<String, Object> returnMap = new HashMap<>();
List<HashMap<String, Object>> rows = codeMapper.getCodeGroupList(paramMap);
returnMap.put("msgCode", Constants.OK);
returnMap.put("rows", rows);
return returnMap;
}
public HashMap<String, Object> getCodeGroup(HashMap<String, Object> paramMap) {
HashMap<String, Object> returnMap = new HashMap<>();
HashMap<String, Object> data = codeMapper.getCodeGroup(paramMap);
returnMap.put("msgCode", Constants.OK);
returnMap.put("data", data);
return returnMap;
}
@Transactional(rollbackFor = Exception.class)
public HashMap<String, Object> saveCodeGroup(HashMap<String, Object> paramMap) {
HashMap<String, Object> returnMap = new HashMap<>();
String pid = paramMap.get("pid") == null ? "" : String.valueOf(paramMap.get("pid"));
// 중복 검사
int dupCnt = codeMapper.checkGrpCd(paramMap);
if (dupCnt > 0) {
returnMap.put("msgCode", Constants.FAIL);
returnMap.put("msgDesc", "이미 사용중인 코드그룹 ID입니다.");
return returnMap;
}
if ("".equals(pid)) {
// 신규 등록
codeMapper.insertCodeGroup(paramMap);
returnMap.put("msgDesc", "코드그룹이 등록되었습니다.");
} else {
// 수정
codeMapper.updateCodeGroup(paramMap);
returnMap.put("msgDesc", "코드그룹이 수정되었습니다.");
}
returnMap.put("msgCode", Constants.OK);
return returnMap;
}
@Transactional(rollbackFor = Exception.class)
public HashMap<String, Object> deleteCodeGroup(HashMap<String, Object> paramMap) {
HashMap<String, Object> returnMap = new HashMap<>();
codeMapper.deleteCodeGroup(paramMap);
returnMap.put("msgCode", Constants.OK);
returnMap.put("msgDesc", "코드그룹이 삭제되었습니다.");
return returnMap;
}
// ==========================================
// 2. 상세 코드 (Code List)
// ==========================================
public HashMap<String, Object> getCodeList(HashMap<String, Object> paramMap) {
HashMap<String, Object> returnMap = new HashMap<>();
List<HashMap<String, Object>> rows = codeMapper.getCodeList(paramMap);
returnMap.put("msgCode", Constants.OK);
returnMap.put("rows", rows);
return returnMap;
}
public HashMap<String, Object> getCode(HashMap<String, Object> paramMap) {
HashMap<String, Object> returnMap = new HashMap<>();
HashMap<String, Object> data = codeMapper.getCode(paramMap);
returnMap.put("msgCode", Constants.OK);
returnMap.put("data", data);
return returnMap;
}
@Transactional(rollbackFor = Exception.class)
public HashMap<String, Object> saveCode(HashMap<String, Object> paramMap) {
HashMap<String, Object> returnMap = new HashMap<>();
String pid = paramMap.get("pid") == null ? "" : String.valueOf(paramMap.get("pid"));
// 중복 검사
int dupCnt = codeMapper.checkCodeCd(paramMap);
if (dupCnt > 0) {
returnMap.put("msgCode", Constants.FAIL);
returnMap.put("msgDesc", "이미 사용중인 상세 코드 ID입니다.");
return returnMap;
}
if ("".equals(pid)) {
// 신규 등록
codeMapper.insertCode(paramMap);
returnMap.put("msgDesc", "상세 코드가 등록되었습니다.");
} else {
// 수정
codeMapper.updateCode(paramMap);
returnMap.put("msgDesc", "상세 코드가 수정되었습니다.");
}
returnMap.put("msgCode", Constants.OK);
return returnMap;
}
@Transactional(rollbackFor = Exception.class)
public HashMap<String, Object> deleteCode(HashMap<String, Object> paramMap) {
HashMap<String, Object> returnMap = new HashMap<>();
codeMapper.deleteCode(paramMap);
returnMap.put("msgCode", Constants.OK);
returnMap.put("msgDesc", "상세 코드가 삭제되었습니다.");
return returnMap;
}
}

View File

@@ -45,14 +45,53 @@ public class MedicalCategoryController extends ManagerDraftAction {
} }
/** /**
* 카테고리 상세/등록 팝업 화면 이동 * 카테고리 1뎁스 팝업 화면 이동 (진료과목)
*/ */
@RequestMapping("/infoPop.do") @RequestMapping("/infoPopDept1.do")
public ModelAndView infoPop(HttpServletRequest request, HttpServletResponse response) { public ModelAndView infoPopDept1(HttpServletRequest request, HttpServletResponse response) {
log.debug("MedicalCategoryController infoPop START"); log.debug("MedicalCategoryController infoPopDept1 START");
log.debug("MedicalCategoryController infoPop END"); log.debug("MedicalCategoryController infoPopDept1 END");
return new ModelAndView("/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept1");
}
return new ModelAndView("/web/settings/medicalcategory/popup/medicalCategoryInfoPop"); /**
* 카테고리 2뎁스 팝업 화면 이동 (진료유형)
*/
@RequestMapping("/infoPopDept2.do")
public ModelAndView infoPopDept2(HttpServletRequest request, HttpServletResponse response) {
log.debug("MedicalCategoryController infoPopDept2 START");
log.debug("MedicalCategoryController infoPopDept2 END");
return new ModelAndView("/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept2");
}
/**
* 카테고리 3뎁스 팝업 화면 이동 (제품/시술)
*/
@RequestMapping("/infoPopDept3.do")
public ModelAndView infoPopDept3(HttpServletRequest request, HttpServletResponse response) {
log.debug("MedicalCategoryController infoPopDept3 START");
log.debug("MedicalCategoryController infoPopDept3 END");
return new ModelAndView("/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept3");
}
/**
* 카테고리 4뎁스 팝업 화면 이동 (용량/출력)
*/
@RequestMapping("/infoPopDept4.do")
public ModelAndView infoPopDept4(HttpServletRequest request, HttpServletResponse response) {
log.debug("MedicalCategoryController infoPopDept4 START");
log.debug("MedicalCategoryController infoPopDept4 END");
return new ModelAndView("/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept4");
}
/**
* 카테고리 5뎁스 팝업 화면 이동 (부위)
*/
@RequestMapping("/infoPopDept5.do")
public ModelAndView infoPopDept5(HttpServletRequest request, HttpServletResponse response) {
log.debug("MedicalCategoryController infoPopDept5 START");
log.debug("MedicalCategoryController infoPopDept5 END");
return new ModelAndView("/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept5");
} }
// ==================== API 메서드 (JSON 반환) ==================== // ==================== API 메서드 (JSON 반환) ====================

View File

@@ -0,0 +1,216 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.madeu.crm.settings.code.mapper.CodeMapper">
<!-- 1. 코드 그룹 리스트 -->
<select id="getCodeGroupList" parameterType="java.util.HashMap" resultType="java.util.HashMap">
SELECT pid,
store_pid,
grp_cd,
grp_nm,
grp_desc,
list_use,
DATE_FORMAT(reg_date, '%Y-%m-%d %H:%i:%s') AS reg_date,
DATE_FORMAT(up_date, '%Y-%m-%d %H:%i:%s') AS up_date
FROM crm_code_group
WHERE list_use = 'y'
<if test='storePid != null and storePid != ""'>
AND store_pid = #{storePid}
</if>
<if test='searchWd != null and searchWd != ""'>
AND (grp_cd LIKE CONCAT('%',#{searchWd},'%') OR grp_nm LIKE CONCAT('%',#{searchWd},'%'))
</if>
ORDER BY grp_cd ASC
</select>
<!-- 2. 코드 그룹 상세 단건 -->
<select id="getCodeGroup" parameterType="java.util.HashMap" resultType="java.util.HashMap">
SELECT pid,
store_pid,
grp_cd,
grp_nm,
grp_desc,
list_use,
DATE_FORMAT(reg_date, '%Y-%m-%d %H:%i:%s') AS reg_date,
DATE_FORMAT(up_date, '%Y-%m-%d %H:%i:%s') AS up_date
FROM crm_code_group
WHERE pid = #{pid}
</select>
<!-- 3. 코드 그룹 중복 검사 -->
<select id="checkGrpCd" parameterType="java.util.HashMap" resultType="int">
SELECT COUNT(pid)
FROM crm_code_group
WHERE grp_cd = #{grpCd}
<if test='storePid != null and storePid != ""'>
AND store_pid = #{storePid}
</if>
<if test='pid != null and pid != ""'>
AND pid != #{pid}
</if>
</select>
<!-- 4. 코드 그룹 등록 -->
<insert id="insertCodeGroup" parameterType="java.util.HashMap" useGeneratedKeys="true" keyProperty="pid">
INSERT INTO crm_code_group (
store_pid,
grp_cd,
grp_nm,
grp_desc,
list_use,
reg_date,
up_date
) VALUES (
#{storePid},
#{grpCd},
#{grpNm},
#{grpDesc, jdbcType=VARCHAR},
'y',
NOW(),
NOW()
)
</insert>
<!-- 5. 코드 그룹 수정 -->
<update id="updateCodeGroup" parameterType="java.util.HashMap">
UPDATE crm_code_group
<set>
<if test='grpNm != null and grpNm != ""'>
grp_nm = #{grpNm},
</if>
<if test='grpDesc != null'>
grp_desc = #{grpDesc},
</if>
<if test='listUse != null and listUse != ""'>
list_use = #{listUse},
</if>
up_date = NOW()
</set>
WHERE pid = #{pid}
</update>
<!-- 6. 코드 그룹 삭제 (논리 삭제) -->
<update id="deleteCodeGroup" parameterType="java.util.HashMap">
UPDATE crm_code_group
SET list_use = 'n', up_date = NOW()
WHERE pid = #{pid}
</update>
<!-- ========================================== -->
<!-- 7. 상세 코드 리스트 -->
<select id="getCodeList" parameterType="java.util.HashMap" resultType="java.util.HashMap">
SELECT pid,
store_pid,
grp_cd,
code_cd,
code_nm,
code_val,
code_desc,
code_sort,
list_use,
DATE_FORMAT(reg_date, '%Y-%m-%d %H:%i:%s') AS reg_date,
DATE_FORMAT(up_date, '%Y-%m-%d %H:%i:%s') AS up_date
FROM crm_code_list
WHERE list_use = 'y'
AND grp_cd = #{grpCd}
<if test='storePid != null and storePid != ""'>
AND store_pid = #{storePid}
</if>
<if test='searchWd != null and searchWd != ""'>
AND (code_cd LIKE CONCAT('%',#{searchWd},'%') OR code_nm LIKE CONCAT('%',#{searchWd},'%'))
</if>
ORDER BY code_sort ASC, code_cd ASC
</select>
<!-- 8. 상세 코드 단건 -->
<select id="getCode" parameterType="java.util.HashMap" resultType="java.util.HashMap">
SELECT pid,
store_pid,
grp_cd,
code_cd,
code_nm,
code_val,
code_desc,
code_sort,
list_use,
DATE_FORMAT(reg_date, '%Y-%m-%d %H:%i:%s') AS reg_date,
DATE_FORMAT(up_date, '%Y-%m-%d %H:%i:%s') AS up_date
FROM crm_code_list
WHERE pid = #{pid}
</select>
<!-- 9. 상세 코드 중복 검사 -->
<select id="checkCodeCd" parameterType="java.util.HashMap" resultType="int">
SELECT COUNT(pid)
FROM crm_code_list
WHERE grp_cd = #{grpCd}
AND code_cd = #{codeCd}
<if test='storePid != null and storePid != ""'>
AND store_pid = #{storePid}
</if>
<if test='pid != null and pid != ""'>
AND pid != #{pid}
</if>
</select>
<!-- 10. 상세 코드 등록 -->
<insert id="insertCode" parameterType="java.util.HashMap" useGeneratedKeys="true" keyProperty="pid">
INSERT INTO crm_code_list (
store_pid,
grp_cd,
code_cd,
code_nm,
code_val,
code_desc,
code_sort,
list_use,
reg_date,
up_date
) VALUES (
#{storePid},
#{grpCd},
#{codeCd},
#{codeNm},
#{codeVal, jdbcType=VARCHAR},
#{codeDesc, jdbcType=VARCHAR},
IFNULL(#{codeSort}, 0),
'y',
NOW(),
NOW()
)
</insert>
<!-- 11. 상세 코드 수정 -->
<update id="updateCode" parameterType="java.util.HashMap">
UPDATE crm_code_list
<set>
<if test='codeNm != null and codeNm != ""'>
code_nm = #{codeNm},
</if>
<if test='codeVal != null'>
code_val = #{codeVal},
</if>
<if test='codeDesc != null'>
code_desc = #{codeDesc},
</if>
<if test='codeSort != null'>
code_sort = #{codeSort},
</if>
<if test='listUse != null and listUse != ""'>
list_use = #{listUse},
</if>
up_date = NOW()
</set>
WHERE pid = #{pid}
</update>
<!-- 12. 상세 코드 삭제 (논리 삭제) -->
<update id="deleteCode" parameterType="java.util.HashMap">
UPDATE crm_code_list
SET list_use = 'n', up_date = NOW()
WHERE pid = #{pid}
</update>
</mapper>

View File

@@ -78,8 +78,10 @@
DATE_FORMAT(a.reg_date, '%Y-%m-%d %H:%i:%s') AS reg_date, DATE_FORMAT(a.reg_date, '%Y-%m-%d %H:%i:%s') AS reg_date,
DATE_FORMAT(a.up_date, '%Y-%m-%d %H:%i:%s') AS up_date, DATE_FORMAT(a.up_date, '%Y-%m-%d %H:%i:%s') AS up_date,
a.store_pid, a.store_pid,
a.npay_use a.npay_use,
p.divi_name AS parent_name
FROM medical_divi_list a FROM medical_divi_list a
LEFT JOIN medical_divi_list p ON a.divi_parent = p.pid
WHERE a.pid = #{pid} WHERE a.pid = #{pid}
</select> </select>

View File

@@ -0,0 +1,178 @@
/**
* 공통코드 관리 화면 스크립트
*/
let tableGroup;
let tableCode;
let currentSelectedGroup = null;
$(document).ready(function () {
initGrid();
bindEvents();
loadGroupData();
});
function initGrid() {
let commonOpts = {
layout: "fitColumns",
selectableRows: 1, // 단일 선택
selectableRowsRangeMode: "click",
height: "100%",
columnDefaults: {
headerTooltip: true,
headerHozAlign: "center",
hozAlign: "center"
}
};
// 1. 좌측 그룹 그리드
tableGroup = new Tabulator("#gridGroup", Object.assign({}, commonOpts, {
columns: [
{ title: "No", field: "no", width: 60, formatter: "rownum", headerSort: false },
{ title: "그룹 ID", field: "grp_cd", width: 120 },
{ title: "그룹 명칭", field: "grp_nm", width: 150 },
{ title: "사용여부", field: "list_use", width: 80, formatter: ynFormatter },
{
title: "수정", width: 60, headerSort: false, formatter: editFormatter, cellClick: function (e, cell) {
editGroup(cell.getRow().getData().pid);
}
},
],
}));
tableGroup.on("rowClick", function (e, row) {
let data = row.getData();
currentSelectedGroup = data;
// 우측 패널 UI 활성화
$("#codePanelTitle").html(`상세 코드 <span style="font-size: 14px; color: #1a73e8; margin-left:10px; font-weight:normal;">[${data.grp_nm} (${data.grp_cd})]</span>`);
$("#codeSearchInput").prop("disabled", false);
$("#btnAddCode").prop("disabled", false).css({
"background": "#3985EA",
"color": "#fff",
"border-color": "#3985EA"
});
loadCodeData(data.grp_cd);
});
// 2. 우측 상세 코드 그리드
tableCode = new Tabulator("#gridCode", Object.assign({}, commonOpts, {
columns: [
{ title: "정렬", field: "code_sort", width: 60 },
{ title: "코드 ID", field: "code_cd", width: 120 },
{ title: "코드 명칭", field: "code_nm", width: 150 },
{ title: "추가값", field: "code_val", width: 120 },
{ title: "사용여부", field: "list_use", width: 80, formatter: ynFormatter },
{
title: "수정", width: 60, headerSort: false, formatter: editFormatter, cellClick: function (e, cell) {
editCode(cell.getRow().getData().pid);
}
},
],
}));
}
function ynFormatter(cell) {
return cell.getValue() === 'y' ? '<span style="color:#3985EA; font-weight:600;">Y</span>' : '<span style="color:#ccc;">N</span>';
}
function editFormatter(cell) {
return '<span class="grid-link-btn grid-link-edit" style="cursor:pointer; display:inline-block; border:1px solid #ccc; padding:2px 6px; border-radius:3px; font-size:12px; background:#fff;">수정</span>';
}
function bindEvents() {
// 그룹 검색
$("#groupSearchInput").on("keyup", function (e) {
if (e.keyCode === 13) loadGroupData();
});
// 상세 코드 검색
$("#codeSearchInput").on("keyup", function (e) {
if (e.keyCode === 13 && currentSelectedGroup) {
loadCodeData(currentSelectedGroup.grp_cd);
}
});
// 창 닫힐 때 리로드용
window.addEventListener("message", function (event) {
if (event.data === 'reloadGroup') {
loadGroupData();
} else if (event.data === 'reloadCode' && currentSelectedGroup) {
loadCodeData(currentSelectedGroup.grp_cd);
}
}, false);
}
// ==========================================
// API 로드
// ==========================================
window.loadGroupData = function () {
let searchWd = $("#groupSearchInput").val();
$.ajax({
url: "/settings/code/getCodeGroupList.do",
type: "POST",
data: { searchWd: searchWd },
success: function (res) {
if (res.msgCode === '0') {
tableGroup.setData(res.rows || []);
if (!currentSelectedGroup) {
tableCode.setData([]);
}
} else {
alert(res.msgDesc);
}
},
error: function (e) {
console.error(e);
alert("그룹 조회 실패");
}
});
};
window.loadCodeData = function (grpCd) {
let searchWd = $("#codeSearchInput").val();
$.ajax({
url: "/settings/code/getCodeList.do",
type: "POST",
data: { grpCd: grpCd, searchWd: searchWd },
success: function (res) {
if (res.msgCode === '0') {
tableCode.setData(res.rows || []);
} else {
alert(res.msgDesc);
}
},
error: function (e) {
console.error(e);
alert("상세 코드 조회 실패");
}
});
};
// ==========================================
// 팝업 호출
// ==========================================
window.addGroup = function () {
let url = "/settings/code/codeGroupPop.do?mode=add";
window.open(url, "codeGroupPop", "width=500, height=450, resizable=no, scrollbars=no, status=no;");
};
window.editGroup = function (pid) {
let url = `/settings/code/codeGroupPop.do?mode=edit&pid=${pid}`;
window.open(url, "codeGroupPop", "width=500, height=450, resizable=no, scrollbars=no, status=no;");
};
window.addCode = function () {
if (!currentSelectedGroup) return;
let url = `/settings/code/codePop.do?mode=add&grpCd=${currentSelectedGroup.grp_cd}&grpNm=${encodeURIComponent(currentSelectedGroup.grp_nm)}`;
window.open(url, "codePop", "width=500, height=550, resizable=no, scrollbars=no, status=no;");
};
window.editCode = function (pid) {
if (!currentSelectedGroup) return;
let url = `/settings/code/codePop.do?mode=edit&pid=${pid}&grpCd=${currentSelectedGroup.grp_cd}&grpNm=${encodeURIComponent(currentSelectedGroup.grp_nm)}`;
window.open(url, "codePop", "width=500, height=550, resizable=no, scrollbars=no, status=no;");
};

View File

@@ -0,0 +1,131 @@
/**
* 코드 그룹 팝업 스크립트
*/
$(document).ready(function () {
const params = new URLSearchParams(window.location.search);
const mode = params.get('mode');
const pid = params.get('pid');
initForm();
bindEvents();
function initForm() {
if (mode === 'add') {
$("#popTitle").text('코드 그룹 신규 등록');
$("#pid").val('');
$("#btn_delete").hide();
} else if (mode === 'edit') {
$("#popTitle").text('코드 그룹 정보 수정');
$("#pid").val(pid);
$("#grpCd").prop("readonly", true).css("background-color", "#f9f9f9");
$("#btn_delete").show();
loadDetail(pid);
}
}
function loadDetail(id) {
$.ajax({
url: '/settings/code/getCodeGroup.do',
type: 'POST',
data: { pid: id },
success: function (res) {
if (res.msgCode === '0') {
const data = res.data;
$("#grpCd").val(data.grp_cd);
$("#grpNm").val(data.grp_nm);
$("#grpDesc").val(data.grp_desc);
$("#listUse").val(data.list_use);
} else {
alert("정보를 불러올 수 없습니다.");
window.close();
}
},
error: function () {
alert("상세 정보 조회 통신 오류");
window.close();
}
});
}
function bindEvents() {
$("#btn_close").on("click", function () {
window.close();
});
$("#btn_save").on("click", function () {
saveGroup();
});
$("#btn_delete").on("click", function () {
deleteGroup();
});
}
function saveGroup() {
const cd = $("#grpCd").val().trim();
const nm = $("#grpNm").val().trim();
if (!cd) {
alert("그룹 ID를 입력하세요.");
$("#grpCd").focus();
return;
}
if (!nm) {
alert("그룹 명칭을 입력하세요.");
$("#grpNm").focus();
return;
}
const submitObj = {
pid: $("#pid").val() || null,
storePid: $("#storePid").val(),
grpCd: cd,
grpNm: nm,
grpDesc: $("#grpDesc").val(),
listUse: $("#listUse").val()
};
$.ajax({
url: '/settings/code/saveCodeGroup.do',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(submitObj),
success: function (res) {
alert(res.msgDesc);
if (res.msgCode === '0') {
if (window.opener) {
window.opener.postMessage('reloadGroup', '*');
}
window.close();
}
},
error: function () {
alert("저장 중 시스템 오류가 발생했습니다.");
}
});
}
function deleteGroup() {
const pidVal = $("#pid").val();
if (!pidVal) return;
if (!confirm("해당 코드 그룹을 삭제하시겠습니까?\n하위 상세 코드들도 모두 사용할 수 없게 됩니다.")) return;
$.ajax({
url: '/settings/code/deleteCodeGroup.do',
type: 'POST',
data: { pid: pidVal },
success: function (res) {
alert(res.msgDesc);
if (res.msgCode === '0') {
if (window.opener) {
window.opener.postMessage('reloadGroup', '*');
}
window.close();
}
},
error: function () {
alert("삭제 중 시스템 오류가 발생했습니다.");
}
});
}
});

View File

@@ -0,0 +1,141 @@
/**
* 상세 코드 팝업 스크립트
*/
$(document).ready(function () {
const params = new URLSearchParams(window.location.search);
const mode = params.get('mode');
const pid = params.get('pid');
const grpCd = params.get('grpCd');
const grpNm = decodeURIComponent(params.get('grpNm') || '');
initForm();
bindEvents();
function initForm() {
$("#grpCd").val(grpCd);
$("#groupInfoText").text(`[그룹: ${grpNm} (${grpCd})]`);
if (mode === 'add') {
$("#popTitle").text('상세 코드 신규 등록');
$("#pid").val('');
$("#btn_delete").hide();
} else if (mode === 'edit') {
$("#popTitle").text('상세 코드 정보 수정');
$("#pid").val(pid);
$("#codeCd").prop("readonly", true).css("background-color", "#f9f9f9");
$("#btn_delete").show();
loadDetail(pid);
}
}
function loadDetail(id) {
$.ajax({
url: '/settings/code/getCode.do',
type: 'POST',
data: { pid: id },
success: function (res) {
if (res.msgCode === '0') {
const data = res.data;
$("#codeCd").val(data.code_cd);
$("#codeNm").val(data.code_nm);
$("#codeVal").val(data.code_val);
$("#codeDesc").val(data.code_desc);
$("#codeSort").val(data.code_sort);
$("#listUse").val(data.list_use);
} else {
alert("정보를 불러올 수 없습니다.");
window.close();
}
},
error: function () {
alert("상세 정보 조회 통신 오류");
window.close();
}
});
}
function bindEvents() {
$("#btn_close").on("click", function () {
window.close();
});
$("#btn_save").on("click", function () {
saveCode();
});
$("#btn_delete").on("click", function () {
deleteCode();
});
}
function saveCode() {
const cd = $("#codeCd").val().trim();
const nm = $("#codeNm").val().trim();
if (!cd) {
alert("코드 ID를 입력하세요.");
$("#codeCd").focus();
return;
}
if (!nm) {
alert("코드 명칭을 입력하세요.");
$("#codeNm").focus();
return;
}
const submitObj = {
pid: $("#pid").val() || null,
storePid: $("#storePid").val(),
grpCd: $("#grpCd").val(),
codeCd: cd,
codeNm: nm,
codeVal: $("#codeVal").val(),
codeDesc: $("#codeDesc").val(),
codeSort: $("#codeSort").val() || 0,
listUse: $("#listUse").val()
};
$.ajax({
url: '/settings/code/saveCode.do',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(submitObj),
success: function (res) {
alert(res.msgDesc);
if (res.msgCode === '0') {
if (window.opener) {
window.opener.postMessage('reloadCode', '*');
}
window.close();
}
},
error: function () {
alert("저장 중 시스템 오류가 발생했습니다.");
}
});
}
function deleteCode() {
const pidVal = $("#pid").val();
if (!pidVal) return;
if (!confirm("해당 상세 코드를 정말 삭제하시겠습니까?")) return;
$.ajax({
url: '/settings/code/deleteCode.do',
type: 'POST',
data: { pid: pidVal },
success: function (res) {
alert(res.msgDesc);
if (res.msgCode === '0') {
if (window.opener) {
window.opener.postMessage('reloadCode', '*');
}
window.close();
}
},
error: function () {
alert("삭제 중 시스템 오류가 발생했습니다.");
}
});
}
});

View File

@@ -125,7 +125,8 @@ $(document).ready(function () {
index: "pid", index: "pid",
layout: "fitColumns", layout: "fitColumns",
placeholder: "상위 항목을 선택하세요.", placeholder: "상위 항목을 선택하세요.",
selectableRows: true, selectableRows: true, // 5.x 에서 선택 기능 활성화
selectableRowsRangeMode: "click", // 브라우저/그리드 자체 단축키 동작을 막고 순수 클릭 이벤트로 동작하게 함
height: "100%", height: "100%",
columnDefaults: { columnDefaults: {
headerTooltip: true, headerTooltip: true,
@@ -184,30 +185,29 @@ $(document).ready(function () {
function handleRowClick(e, row, table, depth) { function handleRowClick(e, row, table, depth) {
var tableId = table.element.id; var tableId = table.element.id;
if (e.shiftKey && lastClickedRow[tableId]) { if (e.shiftKey || e.ctrlKey || e.metaKey) {
// Shift+Click: 범위 선택 // [MULTI-SELECT MODE]
var allRows = table.getRows(); // Shift+Click 또는 Ctrl+Click:
var startIdx = allRows.indexOf(lastClickedRow[tableId]); // Tabulator 자체 옵션(selectableRows: true)에 의해 다중 선택/토글이 자동으로 처리됩니다.
var endIdx = allRows.indexOf(row); // 여러 줄이 동시 선택되어도 하위 뎁스 표(자식 그리드)에 여러 부모의 데이터를 보여줄 구조가 아니므로,
if (startIdx === -1) startIdx = 0; // 하위 표를 갱신하는 clickRow()를 호출하지 않고 여기서 함수를 완전히 종료합니다.
lastClickedRow[tableId] = row;
var from = Math.min(startIdx, endIdx); return;
var to = Math.max(startIdx, endIdx);
table.deselectRow();
for (var i = from; i <= to; i++) {
allRows[i].select();
}
} else if (e.ctrlKey || e.metaKey) {
// Ctrl+Click: 토글 선택
row.toggleSelect();
} else {
// 일반 클릭: 단일 선택
table.deselectRow();
row.select();
} }
// [SINGLE-SELECT / NAVIGATION MODE]
// 일반 클릭: 해당 항목으로 "내비게이션(이동)"하려는 의도.
// 1) 내가 클릭한 행이 이미 선택되어 있는 상태라면 Tabulator가 클릭하면서 선택을 해제(토글)해버리는 것을 방지.
// 2) 다른 행들의 선택을 모두 해제하고, 내가 누른 행 1개만 확실히 선택되도록 강제합니다.
table.deselectRow();
window.setTimeout(function () {
row.select();
}, 0);
// 3) 마지막 활성 행 갱신
lastClickedRow[tableId] = row; lastClickedRow[tableId] = row;
// 4) 자식 항목들을 불러와 다음 뎁스의 표에 뿌려줍니다.
clickRow(row, depth); clickRow(row, depth);
} }
@@ -219,7 +219,8 @@ $(document).ready(function () {
function onCellDblClick(e, cell) { function onCellDblClick(e, cell) {
if (cell.getField() === "divi_name") { if (cell.getField() === "divi_name") {
editCategory(cell.getRow().getData().pid); var data = cell.getRow().getData();
editCategory(data.pid, data.divi_dept);
} }
} }
table2.on("cellDblClick", onCellDblClick); table2.on("cellDblClick", onCellDblClick);
@@ -541,8 +542,17 @@ $(document).ready(function () {
/* ====== 팝업 관련 ====== */ /* ====== 팝업 관련 ====== */
window.editCategory = function (pid) { window.editDepth1 = function () {
openInfoPopup('edit', pid); const pid = $("#depth1Select").val();
if (!pid) {
alert("수정할 진료과목을 선택하세요.");
return;
}
editCategory(pid, 1);
};
window.editCategory = function (pid, diviDept) {
openInfoPopup('edit', pid, diviDept);
}; };
window.addChildCategory = function (diviParent, diviDept, parentName) { window.addChildCategory = function (diviParent, diviDept, parentName) {
@@ -573,14 +583,28 @@ $(document).ready(function () {
diviDept = diviDept || ''; diviDept = diviDept || '';
diviParent = diviParent || ''; diviParent = diviParent || '';
parentName = parentName || ''; parentName = parentName || '';
const url = '/settings/medicalCategory/infoPop.do?mode=' + mode + '&pid=' + pid + '&diviDept=' + diviDept + '&diviParent=' + diviParent + '&parentName=' + encodeURIComponent(parentName);
let width = 650; // 뎁스별 분리된 URL 호출
let height = 750; let endpoint = 'infoPopDept' + diviDept + '.do';
if (!diviDept) {
// 예외 적인 fallback
endpoint = 'infoPopDept2.do';
diviDept = 2;
}
const url = '/settings/medicalCategory/' + endpoint + '?mode=' + mode + '&pid=' + pid + '&diviDept=' + diviDept + '&diviParent=' + diviParent + '&parentName=' + encodeURIComponent(parentName);
let width = 600;
let height = 300; // Depth 2, 3, 5는 기본 300px
if (diviDept == 4) {
height = 500; // Depth 4 (용량/출력)는 입력 필드가 많아 500px
}
let left = (screen.width - width) / 2; let left = (screen.width - width) / 2;
let top = (screen.height - height) / 2; let top = (screen.height - height) / 2;
window.open(url, "MedicalCategoryInfoPopup", "width=" + width + ",height=" + height + ",left=" + left + ",top=" + top + ",scrollbars=yes,resizable=yes"); window.open(url, "MedicalCategoryInfoPopup_" + diviDept, "width=" + width + ",height=" + height + ",left=" + left + ",top=" + top + ",scrollbars=yes,resizable=yes");
} }
initGrid(); initGrid();

View File

@@ -1,290 +0,0 @@
/**
* 진료유형 상세/추가 팝업 스크립트
* - 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 또는 4이면 거래처 목록을 로드한 뒤 폼 초기화를 진행
if (diviDept === '3' || diviDept === '4' || 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();
}
// Depth 3: 제품/시술 정보 (거래처, 제품설명, 기타설명)
if (currentDept == '3') {
$("#productInfoTitle").show();
$("#productInfoTable").show();
} else {
$("#productInfoTitle").hide();
$("#productInfoTable").hide();
}
// Depth 4: 용량/출력 정보 (단가, 할인가, 단위, 비율)
if (currentDept == '4') {
$("#volumeInfoTitle").show();
$("#volumeInfoTable").show();
} else {
$("#volumeInfoTitle").hide();
$("#volumeInfoTable").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('<option value="">선택</option>');
res.data.forEach(function (cust) {
$select.append(`<option value="${cust.pid}">${cust.cust_name}</option>`);
});
}
resolve();
},
error: function () {
console.error("거래처 목록 로드 실패");
resolve();
}
});
});
}
// Depth별 타이틀 매핑
var depthTitleMap = {
'1': '진료과목',
'2': '진료유형',
'3': '제품/시술',
'4': '용량/출력',
'5': '부위'
};
function getDepthTitle(dept) {
return depthTitleMap[dept] || '진료유형';
}
function initForm() {
if (mode === 'add') {
$("#popTitle").text(getDepthTitle(diviDept) + ' 신규 등록');
$("#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(getDepthTitle(diviDept) + ' 정보 수정');
$("#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);
$("#dcCost").val(data.dc_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"),
dcCost: parseFloat($("#dcCost").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("삭제 중 시스템 오류가 발생했습니다.");
}
});
}
});

View File

@@ -0,0 +1,135 @@
/**
* 카테고리 Depth 1 팝업 스크립트
*/
$(document).ready(function () {
const params = new URLSearchParams(window.location.search);
const mode = params.get('mode');
const pid = params.get('pid');
const diviDept = params.get('diviDept') || '1';
const diviParent = params.get('diviParent') || '0';
const parentName = params.get('parentName');
initForm();
bindEvents();
function initForm() {
if (mode === 'add') {
$("#popTitle").text('진료과목 신규 등록');
$("#pid").val('');
$("#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;
$("#diviParent").val(data.divi_parent || '0');
$("#diviName").val(data.divi_name);
$("#diviSort").val(data.divi_sort);
$("#diviColor").val(data.divi_color || '#000000');
} else {
alert("정보를 불러올 수 없습니다.");
window.close();
}
},
error: function () {
alert("상세 정보 조회 통신 오류");
window.close();
}
});
}
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()
};
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("삭제 중 시스템 오류가 발생했습니다.");
}
});
}
});

View File

@@ -0,0 +1,144 @@
/**
* 카테고리 Depth 2 팝업 스크립트
*/
$(document).ready(function () {
const params = new URLSearchParams(window.location.search);
const mode = params.get('mode');
const pid = params.get('pid');
const diviDept = params.get('diviDept');
const diviParent = params.get('diviParent');
const parentName = params.get('parentName');
initForm();
bindEvents();
function initForm() {
if (mode === 'add') {
$("#popTitle").text('진료유형 신규 등록');
$("#pid").val('');
$("#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;
$("#diviParent").val(data.divi_parent);
$("#diviName").val(data.divi_name);
$("#diviSort").val(data.divi_sort);
$("#diviColor").val(data.divi_color || '#000000');
// 상위 카테고리 명칭 표시 (Edit 모드)
if (data.parent_name) {
$("#parentNameRow").show();
$("#parentNameTxt").text(data.parent_name);
} else if (parentName) {
$("#parentNameRow").show();
$("#parentNameTxt").text(parentName);
}
} else {
alert("정보를 불러올 수 없습니다.");
window.close();
}
},
error: function () {
alert("상세 정보 조회 통신 오류");
window.close();
}
});
}
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()
};
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("삭제 중 시스템 오류가 발생했습니다.");
}
});
}
});

View File

@@ -0,0 +1,144 @@
/**
* 카테고리 Depth 3 팝업 스크립트
*/
$(document).ready(function () {
const params = new URLSearchParams(window.location.search);
const mode = params.get('mode');
const pid = params.get('pid');
const diviDept = params.get('diviDept');
const diviParent = params.get('diviParent');
const parentName = params.get('parentName');
initForm();
bindEvents();
function initForm() {
if (mode === 'add') {
$("#popTitle").text('제품/시술 신규 등록');
$("#pid").val('');
$("#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;
$("#diviParent").val(data.divi_parent);
$("#diviName").val(data.divi_name);
$("#diviSort").val(data.divi_sort);
$("#diviColor").val(data.divi_color || '#000000');
// 상위 카테고리 명칭 표시 (Edit 모드)
if (data.parent_name) {
$("#parentNameRow").show();
$("#parentNameTxt").text(data.parent_name);
} else if (parentName) {
$("#parentNameRow").show();
$("#parentNameTxt").text(parentName);
}
} else {
alert("정보를 불러올 수 없습니다.");
window.close();
}
},
error: function () {
alert("상세 정보 조회 통신 오류");
window.close();
}
});
}
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(), // hidden = 3
diviParent: $("#diviParent").val(),
diviSort: parseInt($("#diviSort").val() || "0", 10),
diviColor: $("#diviColor").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("삭제 중 시스템 오류가 발생했습니다.");
}
});
}
});

View File

@@ -0,0 +1,172 @@
/**
* 카테고리 Depth 4 팝업 스크립트
*/
$(document).ready(function () {
const params = new URLSearchParams(window.location.search);
const mode = params.get('mode');
const pid = params.get('pid');
const diviDept = params.get('diviDept');
const diviParent = params.get('diviParent');
const parentName = params.get('parentName');
initForm();
bindEvents();
// 금액 포맷팅 함수
function formatNumber(num) {
if (!num) return '0';
return num.toString().replace(/[^0-9]/g, '').replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function unformatNumber(str) {
if (!str) return 0;
return parseFloat(str.toString().replace(/,/g, '')) || 0;
}
function initForm() {
if (mode === 'add') {
$("#popTitle").text('용량/출력 신규 등록');
$("#pid").val('');
$("#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;
$("#diviParent").val(data.divi_parent);
$("#diviName").val(data.divi_name);
$("#diviSort").val(data.divi_sort);
$("#diviColor").val(data.divi_color || '#000000');
// 단가/제품 정보 (복구)
$("#kindCost").val(formatNumber(data.kind_cost));
$("#dcCost").val(formatNumber(data.dc_cost));
$("#kindUnit").val(data.kind_unit || '');
$("#kindUnitVol").val(data.kind_unit_vol || 0);
// 상위 카테고리 명칭 표시 (Edit 모드)
if (data.parent_name) {
$("#parentNameRow").show();
$("#parentNameTxt").text(data.parent_name);
} else if (parentName) {
$("#parentNameRow").show();
$("#parentNameTxt").text(parentName);
}
} else {
alert("정보를 불러올 수 없습니다.");
window.close();
}
},
error: function () {
alert("상세 정보 조회 통신 오류");
window.close();
}
});
}
function bindEvents() {
$("#btn_close").on("click", function () {
window.close();
});
$("#btn_save").on("click", function () {
saveCategory();
});
$("#btn_delete").on("click", function () {
deleteCategory();
});
// 금액 콤마 자동 입력 이벤트
$("#kindCost, #dcCost").on("keyup", function () {
$(this).val(formatNumber($(this).val()));
});
}
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(), // hidden = 4
diviParent: $("#diviParent").val(),
diviSort: parseInt($("#diviSort").val() || "0", 10),
diviColor: $("#diviColor").val(),
// 단가/제품 정보 (복구 및 포맷팅 처리)
kindCost: unformatNumber($("#kindCost").val()),
dcCost: unformatNumber($("#dcCost").val()),
kindUnit: $("#kindUnit").val(),
kindUnitVol: parseFloat($("#kindUnitVol").val() || "0")
};
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("삭제 중 시스템 오류가 발생했습니다.");
}
});
}
});

View File

@@ -0,0 +1,144 @@
/**
* 카테고리 Depth 5 팝업 스크립트
*/
$(document).ready(function () {
const params = new URLSearchParams(window.location.search);
const mode = params.get('mode');
const pid = params.get('pid');
const diviDept = params.get('diviDept');
const diviParent = params.get('diviParent');
const parentName = params.get('parentName');
initForm();
bindEvents();
function initForm() {
if (mode === 'add') {
$("#popTitle").text('부위 신규 등록');
$("#pid").val('');
$("#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;
$("#diviParent").val(data.divi_parent);
$("#diviName").val(data.divi_name);
$("#diviSort").val(data.divi_sort);
$("#diviColor").val(data.divi_color || '#000000');
// 상위 카테고리 명칭 표시 (Edit 모드)
if (data.parent_name) {
$("#parentNameRow").show();
$("#parentNameTxt").text(data.parent_name);
} else if (parentName) {
$("#parentNameRow").show();
$("#parentNameTxt").text(parentName);
}
} else {
alert("정보를 불러올 수 없습니다.");
window.close();
}
},
error: function () {
alert("상세 정보 조회 통신 오류");
window.close();
}
});
}
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(), // hidden = 5
diviParent: $("#diviParent").val(),
diviSort: parseInt($("#diviSort").val() || "0", 10),
diviColor: $("#diviColor").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("삭제 중 시스템 오류가 발생했습니다.");
}
});
}
});

View File

@@ -0,0 +1,132 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{/web/layout/homeLayout}">
<head>
<title>코드 관리</title>
</head>
<th:block layout:fragment="layout_css">
<link rel="stylesheet" href="/css/web/webCategorySelectList.css?v2.1">
<link rel="stylesheet" href="/css/web/hospital_work.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="/css/web/hospital_info.css?v1.1">
<style>
.split-layout {
display: flex;
height: calc(100vh - 180px);
gap: 20px;
}
.left-panel {
flex: 4;
display: flex;
flex-direction: column;
background: #fff;
border: 1px solid #ddd;
border-radius: 5px;
padding: 15px;
}
.right-panel {
flex: 6;
display: flex;
flex-direction: column;
background: #fff;
border: 1px solid #ddd;
border-radius: 5px;
padding: 15px;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.panel-title {
font-size: 16px;
font-weight: 600;
color: #333;
}
.tabulator-container {
flex-grow: 1;
width: 100%;
}
/* 탭 내 그리드 헤더 배경색 변경 및 고정 */
.tabulator-header {
background-color: #EDF5FF !important;
border-bottom: 1px solid #ddd !important;
}
.tabulator-header .tabulator-col {
background-color: #EDF5FF !important;
}
</style>
</th:block>
<th:block layout:fragment="layout_top_script">
<script>
let menuClass = "[[${param.menuClass}]]" == "" ? "" : "[[${param.menuClass}]]";
</script>
</th:block>
<th:block layout:fragment="layout_content">
<div class="center_box" style="padding: 20px;">
<div class="filter_box" style="margin-bottom: 20px;">
<div class="form_box" style="display: flex; align-items: center; justify-content: space-between;">
<div style="font-size: 20px; font-weight: bold; color: #1a73e8;">공통코드 관리</div>
</div>
</div>
<div class="split-layout">
<!-- Left: Code Group -->
<div class="left-panel">
<div class="panel-header">
<span class="panel-title">코드 그룹</span>
<div class="right_btn_box" style="margin: 0; display: flex; gap: 5px;">
<input type="text" id="groupSearchInput" class="custom-input" placeholder="그룹코드/명칭 검색"
style="width: 150px; height: 32px;">
<button type="button" class="grid-link-btn grid-link-add" onclick="addGroup()"
style="border: 1px solid #3985EA; padding: 2px 8px; border-radius: 3px; font-size: 13px; height: 32px; line-height: 26px; color: #fff; background: #3985EA; font-weight: 600;">
추가
</button>
</div>
</div>
<div id="gridGroup" class="tabulator-container"></div>
</div>
<!-- Right: Code Detail -->
<div class="right-panel">
<div class="panel-header">
<span class="panel-title" id="codePanelTitle">상세 코드 <span
style="font-size: 13px; color: #888; margin-left:10px;">(좌측에서 그룹을 선택하세요)</span></span>
<div class="right_btn_box" style="margin: 0; display: flex; gap: 5px;" id="codeBtnArea">
<input type="text" id="codeSearchInput" class="custom-input" placeholder="코드/명칭 검색"
style="width: 150px; height: 32px;" disabled>
<button type="button" class="grid-link-btn grid-link-add" onclick="addCode()" id="btnAddCode"
style="border: 1px solid #ccc; padding: 2px 8px; border-radius: 3px; font-size: 13px; height: 32px; line-height: 26px; color: #999; background: #f5f5f5; font-weight: 600;"
disabled>
추가
</button>
</div>
</div>
<div id="gridCode" class="tabulator-container"></div>
</div>
</div>
</div>
</th:block>
<th:block layout:fragment="layout_popup">
</th:block>
<th:block layout:fragment="layout_script">
<script src="https://unpkg.com/tabulator-tables@5.6.1/dist/js/tabulator.min.js"></script>
<script th:src="@{/js/web/settings/code/codeList.js}"></script>
</th:block>
</html>

View File

@@ -0,0 +1,175 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<title>코드 그룹 정보</title>
<link rel="stylesheet" th:href="@{/css/common.css}">
<script th:src="@{/js/web/jquery.min.js}"></script>
<style>
.pop_wrap {
max-width: 500px;
margin: 0 auto;
}
.pop_wrap h3 {
font-size: 16px;
margin-bottom: 16px;
padding-bottom: 10px;
border-bottom: 2px solid #3985EA;
color: #333;
}
.board_write {
width: 100%;
border-collapse: collapse;
}
.board_write th {
background: #f8f9fb;
padding: 10px 12px;
text-align: left;
font-size: 13px;
font-weight: 600;
color: #555;
border: 1px solid #e9ecf0;
white-space: nowrap;
}
.board_write td {
padding: 8px 12px;
border: 1px solid #e9ecf0;
}
.board_write input[type="text"] {
width: 100%;
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
box-sizing: border-box;
}
.ess {
color: #ff0000;
}
.pop_btn_area {
text-align: center;
margin-top: 20px;
}
.btn_blue {
padding: 8px 24px;
background: #3985EA;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
.btn_blue:hover {
background: #2c6fd1;
}
.btn_gray {
padding: 8px 24px;
background: #fff;
color: #666;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
cursor: pointer;
margin-left: 6px;
}
.btn_gray:hover {
background: #f5f5f5;
}
.btn_red {
padding: 8px 24px;
background: #ff4444;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
}
.btn_red:hover {
background: #cc0000;
}
textarea {
width: 100%;
height: 60px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 8px;
font-size: 13px;
box-sizing: border-box;
resize: none;
}
select {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
</style>
</head>
<body style="padding: 20px;">
<div class="pop_wrap">
<h3 id="popTitle">코드 그룹 등록</h3>
<input type="hidden" id="pid" value="">
<input type="hidden" id="storePid" value="1">
<table class="board_write">
<colgroup>
<col width="120px">
<col width="*">
</colgroup>
<tbody>
<tr>
<th><span class="ess">*</span> 그룹 ID</th>
<td><input type="text" id="grpCd" placeholder="영문/숫자 고유 ID (예: DEPTH_CD)"></td>
</tr>
<tr>
<th><span class="ess">*</span> 그룹 명칭</th>
<td><input type="text" id="grpNm" placeholder="예: 시술부위 분류"></td>
</tr>
<tr>
<th>설명</th>
<td><textarea id="grpDesc" placeholder="설명을 입력하세요"></textarea></td>
</tr>
<tr>
<th>사용 여부</th>
<td>
<select id="listUse">
<option value="y">사용 (Y)</option>
<option value="n">미사용 (N)</option>
</select>
</td>
</tr>
</tbody>
</table>
<div class="pop_btn_area">
<button type="button" class="btn_blue" id="btn_save">저장</button>
<button type="button" class="btn_red" id="btn_delete" style="display:none;">삭제</button>
<button type="button" class="btn_gray" id="btn_close">닫기</button>
</div>
</div>
<script th:src="@{/js/web/settings/code/popup/codeGroupPop.js}"></script>
</body>
</html>

View File

@@ -0,0 +1,195 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<title>상세 코드 정보</title>
<link rel="stylesheet" th:href="@{/css/common.css}">
<script th:src="@{/js/web/jquery.min.js}"></script>
<style>
.pop_wrap {
max-width: 500px;
margin: 0 auto;
}
.pop_wrap h3 {
font-size: 16px;
margin-bottom: 5px;
padding-bottom: 10px;
border-bottom: 2px solid #3985EA;
color: #333;
}
.group_info {
font-size: 13px;
color: #1a73e8;
margin-bottom: 15px;
font-weight: 600;
text-align: right;
}
.board_write {
width: 100%;
border-collapse: collapse;
}
.board_write th {
background: #f8f9fb;
padding: 10px 12px;
text-align: left;
font-size: 13px;
font-weight: 600;
color: #555;
border: 1px solid #e9ecf0;
white-space: nowrap;
}
.board_write td {
padding: 8px 12px;
border: 1px solid #e9ecf0;
}
.board_write input[type="text"],
.board_write input[type="number"] {
width: 100%;
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
box-sizing: border-box;
}
.ess {
color: #ff0000;
}
.pop_btn_area {
text-align: center;
margin-top: 20px;
}
.btn_blue {
padding: 8px 24px;
background: #3985EA;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
.btn_blue:hover {
background: #2c6fd1;
}
.btn_gray {
padding: 8px 24px;
background: #fff;
color: #666;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
cursor: pointer;
margin-left: 6px;
}
.btn_gray:hover {
background: #f5f5f5;
}
.btn_red {
padding: 8px 24px;
background: #ff4444;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
}
.btn_red:hover {
background: #cc0000;
}
textarea {
width: 100%;
height: 60px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 8px;
font-size: 13px;
box-sizing: border-box;
resize: none;
}
select {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
</style>
</head>
<body style="padding: 20px;">
<div class="pop_wrap">
<h3 id="popTitle">상세 코드 등록</h3>
<div class="group_info" id="groupInfoText"></div>
<input type="hidden" id="pid" value="">
<input type="hidden" id="storePid" value="1">
<input type="hidden" id="grpCd" value="">
<table class="board_write">
<colgroup>
<col width="120px">
<col width="*">
</colgroup>
<tbody>
<tr>
<th><span class="ess">*</span> 코드 ID</th>
<td><input type="text" id="codeCd" placeholder="영문/숫자 코드 고유 ID"></td>
</tr>
<tr>
<th><span class="ess">*</span> 코드 명칭</th>
<td><input type="text" id="codeNm" placeholder="코드 이름 입력"></td>
</tr>
<tr>
<th>추가 값 (Val)</th>
<td><input type="text" id="codeVal" placeholder="코드에 종속된 추가 데이터 (선택 사항)"></td>
</tr>
<tr>
<th>설명</th>
<td><textarea id="codeDesc" placeholder="설명을 입력하세요"></textarea></td>
</tr>
<tr>
<th>정렬 순서</th>
<td><input type="number" id="codeSort" value="0"></td>
</tr>
<tr>
<th>사용 여부</th>
<td>
<select id="listUse">
<option value="y">사용 (Y)</option>
<option value="n">미사용 (N)</option>
</select>
</td>
</tr>
</tbody>
</table>
<div class="pop_btn_area">
<button type="button" class="btn_blue" id="btn_save">저장</button>
<button type="button" class="btn_red" id="btn_delete" style="display:none;">삭제</button>
<button type="button" class="btn_gray" id="btn_close">닫기</button>
</div>
</div>
<script th:src="@{/js/web/settings/code/popup/codePop.js}"></script>
</body>
</html>

View File

@@ -118,9 +118,15 @@
<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" style="margin: 0; display: flex; gap: 5px;">
<button class="put_btn" onclick="addChildCategory('0', '1', '최상위 항목')"> <button type="button" class="grid-link-btn grid-link-edit" onclick="editDepth1()"
<img src="/image/web/notice_btn_icon.svg" alt="추가">추가 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>
<button type="button" class="grid-link-btn grid-link-add"
onclick="addChildCategory('0', '1', '최상위 항목')"
style="border: 1px solid #3985EA; padding: 2px 8px; border-radius: 3px; font-size: 13px; height: 32px; line-height: 26px; color: #fff; background: #3985EA; font-weight: 600;">
추가
</button> </button>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,179 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<title>진료과목 정보</title>
<link rel="stylesheet" th:href="@{/css/common.css}">
<script th:src="@{/js/web/jquery.min.js}"></script>
<style>
.pop_wrap {
max-width: 600px;
margin: 0 auto;
}
.pop_wrap h3 {
font-size: 16px;
margin-bottom: 16px;
padding-bottom: 10px;
border-bottom: 2px solid #3985EA;
color: #333;
}
.board_write {
width: 100%;
border-collapse: collapse;
}
.board_write th {
background: #f8f9fb;
padding: 10px 12px;
text-align: left;
font-size: 13px;
font-weight: 600;
color: #555;
border: 1px solid #e9ecf0;
white-space: nowrap;
}
.board_write td {
padding: 8px 12px;
border: 1px solid #e9ecf0;
}
.board_write input[type="text"],
.board_write input[type="number"] {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
.board_write select {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
.w100p {
width: 100%;
box-sizing: border-box;
}
.w80 {
width: 80px;
}
.w120 {
width: 120px;
}
.ess {
color: #ff0000;
}
.txt_info {
font-size: 11px;
color: #999;
}
.pop_btn_area {
text-align: center;
margin-top: 20px;
}
.btn_blue {
padding: 8px 24px;
background: #3985EA;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
.btn_blue:hover {
background: #2c6fd1;
}
.btn_gray {
padding: 8px 24px;
background: #fff;
color: #666;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
cursor: pointer;
margin-left: 6px;
}
.btn_gray:hover {
background: #f5f5f5;
}
.btn_red {
padding: 8px 24px;
background: #ff4444;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
}
.btn_red:hover {
background: #cc0000;
}
</style>
</head>
<body style="padding: 20px;">
<div class="pop_wrap">
<h3 id="popTitle">진료과목(Depth 1) 등록</h3>
<input type="hidden" id="pid" value="">
<input type="hidden" id="diviDept" value="1">
<input type="hidden" id="diviParent" value="0">
<input type="hidden" id="storePid" value="1">
<table class="board_write">
<colgroup>
<col width="120px">
<col width="*">
</colgroup>
<tbody>
<tr id="parentNameRow" style="display:none;">
<th>상위 카테고리</th>
<td><span id="parentNameTxt"></span></td>
</tr>
<tr>
<th><span class="ess">*</span> 항목 명칭</th>
<td><input type="text" id="diviName" class="w100p" placeholder="예: 시술일반, 장비시술 등"></td>
</tr>
<tr>
<th>정렬 순서</th>
<td><input type="number" id="diviSort" class="w80" value="0"> <span class="txt_info">숫자가 낮을수록 먼저
표시됩니다.</span></td>
</tr>
<tr>
<th>색상 코드</th>
<td><input type="color" id="diviColor" value="#000000"></td>
</tr>
</tbody>
</table>
<div class="pop_btn_area">
<button type="button" class="btn_blue" id="btn_save">저장</button>
<button type="button" class="btn_red" id="btn_delete" style="display:none;">삭제</button>
<button type="button" class="btn_gray" id="btn_close">닫기</button>
</div>
</div>
<script th:src="@{/js/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept1.js}"></script>
</body>
</html>

View File

@@ -0,0 +1,179 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<title>진료유형 정보</title>
<link rel="stylesheet" th:href="@{/css/common.css}">
<script th:src="@{/js/web/jquery.min.js}"></script>
<style>
.pop_wrap {
max-width: 600px;
margin: 0 auto;
}
.pop_wrap h3 {
font-size: 16px;
margin-bottom: 16px;
padding-bottom: 10px;
border-bottom: 2px solid #3985EA;
color: #333;
}
.board_write {
width: 100%;
border-collapse: collapse;
}
.board_write th {
background: #f8f9fb;
padding: 10px 12px;
text-align: left;
font-size: 13px;
font-weight: 600;
color: #555;
border: 1px solid #e9ecf0;
white-space: nowrap;
}
.board_write td {
padding: 8px 12px;
border: 1px solid #e9ecf0;
}
.board_write input[type="text"],
.board_write input[type="number"] {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
.board_write select {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
.w100p {
width: 100%;
box-sizing: border-box;
}
.w80 {
width: 80px;
}
.w120 {
width: 120px;
}
.ess {
color: #ff0000;
}
.txt_info {
font-size: 11px;
color: #999;
}
.pop_btn_area {
text-align: center;
margin-top: 20px;
}
.btn_blue {
padding: 8px 24px;
background: #3985EA;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
.btn_blue:hover {
background: #2c6fd1;
}
.btn_gray {
padding: 8px 24px;
background: #fff;
color: #666;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
cursor: pointer;
margin-left: 6px;
}
.btn_gray:hover {
background: #f5f5f5;
}
.btn_red {
padding: 8px 24px;
background: #ff4444;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
}
.btn_red:hover {
background: #cc0000;
}
</style>
</head>
<body style="padding: 20px;">
<div class="pop_wrap">
<h3 id="popTitle">진료유형(Depth 2) 등록</h3>
<input type="hidden" id="pid" value="">
<input type="hidden" id="diviDept" value="2">
<input type="hidden" id="diviParent" value="">
<input type="hidden" id="storePid" value="1">
<table class="board_write">
<colgroup>
<col width="120px">
<col width="*">
</colgroup>
<tbody>
<tr id="parentNameRow" style="display:none;">
<th>상위 카테고리</th>
<td><span id="parentNameTxt"></span></td>
</tr>
<tr>
<th><span class="ess">*</span> 항목 명칭</th>
<td><input type="text" id="diviName" class="w100p" placeholder="예: 피부, 보톡스, 제모 등"></td>
</tr>
<tr>
<th>정렬 순서</th>
<td><input type="number" id="diviSort" class="w80" value="0"> <span class="txt_info">숫자가 낮을수록 먼저
표시됩니다.</span></td>
</tr>
<tr>
<th>색상 코드</th>
<td><input type="color" id="diviColor" value="#000000"></td>
</tr>
</tbody>
</table>
<div class="pop_btn_area">
<button type="button" class="btn_blue" id="btn_save">저장</button>
<button type="button" class="btn_red" id="btn_delete" style="display:none;">삭제</button>
<button type="button" class="btn_gray" id="btn_close">닫기</button>
</div>
</div>
<script th:src="@{/js/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept2.js}"></script>
</body>
</html>

View File

@@ -0,0 +1,179 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<title>진료유형 정보</title>
<link rel="stylesheet" th:href="@{/css/common.css}">
<script th:src="@{/js/web/jquery.min.js}"></script>
<style>
.pop_wrap {
max-width: 600px;
margin: 0 auto;
}
.pop_wrap h3 {
font-size: 16px;
margin-bottom: 16px;
padding-bottom: 10px;
border-bottom: 2px solid #3985EA;
color: #333;
}
.board_write {
width: 100%;
border-collapse: collapse;
}
.board_write th {
background: #f8f9fb;
padding: 10px 12px;
text-align: left;
font-size: 13px;
font-weight: 600;
color: #555;
border: 1px solid #e9ecf0;
white-space: nowrap;
}
.board_write td {
padding: 8px 12px;
border: 1px solid #e9ecf0;
}
.board_write input[type="text"],
.board_write input[type="number"] {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
.board_write select {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
.w100p {
width: 100%;
box-sizing: border-box;
}
.w80 {
width: 80px;
}
.w120 {
width: 120px;
}
.ess {
color: #ff0000;
}
.txt_info {
font-size: 11px;
color: #999;
}
.pop_btn_area {
text-align: center;
margin-top: 20px;
}
.btn_blue {
padding: 8px 24px;
background: #3985EA;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
.btn_blue:hover {
background: #2c6fd1;
}
.btn_gray {
padding: 8px 24px;
background: #fff;
color: #666;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
cursor: pointer;
margin-left: 6px;
}
.btn_gray:hover {
background: #f5f5f5;
}
.btn_red {
padding: 8px 24px;
background: #ff4444;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
}
.btn_red:hover {
background: #cc0000;
}
</style>
</head>
<body style="padding: 20px;">
<div class="pop_wrap">
<h3 id="popTitle">제품/시술(Depth 3) 등록</h3>
<input type="hidden" id="pid" value="">
<input type="hidden" id="diviDept" value="3">
<input type="hidden" id="diviParent" value="">
<input type="hidden" id="storePid" value="1">
<table class="board_write">
<colgroup>
<col width="120px">
<col width="*">
</colgroup>
<tbody>
<tr id="parentNameRow" style="display:none;">
<th>상위 카테고리</th>
<td><span id="parentNameTxt"></span></td>
</tr>
<tr>
<th><span class="ess">*</span> 항목 명칭</th>
<td><input type="text" id="diviName" class="w100p" placeholder="예: 피부, 보톡스, 제모 등"></td>
</tr>
<tr>
<th>정렬 순서</th>
<td><input type="number" id="diviSort" class="w80" value="0"> <span class="txt_info">숫자가 낮을수록 먼저
표시됩니다.</span></td>
</tr>
<tr>
<th>색상 코드</th>
<td><input type="color" id="diviColor" value="#000000"></td>
</tr>
</tbody>
</table>
<div class="pop_btn_area">
<button type="button" class="btn_blue" id="btn_save">저장</button>
<button type="button" class="btn_red" id="btn_delete" style="display:none;">삭제</button>
<button type="button" class="btn_gray" id="btn_close">닫기</button>
</div>
</div>
<script th:src="@{/js/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept3.js}"></script>
</body>
</html>

View File

@@ -143,11 +143,10 @@
<body style="padding: 20px;"> <body style="padding: 20px;">
<div class="pop_wrap"> <div class="pop_wrap">
<h3 id="popTitle">진료유형 등록</h3> <h3 id="popTitle">용량/출력(Depth 4) 등록</h3>
<input type="hidden" id="pid" value=""> <input type="hidden" id="pid" value="">
<input type="hidden" id="diviDept" value=""> <input type="hidden" id="diviDept" value="4">
<input type="hidden" id="diviParent" value=""> <input type="hidden" id="diviParent" value="">
<!-- 현재 하드코딩된 스토어 ID(지점), 추후엔 로그인세션 등에서 가져옴 -->
<input type="hidden" id="storePid" value="1"> <input type="hidden" id="storePid" value="1">
<!-- 기본 정보 --> <!-- 기본 정보 -->
@@ -177,84 +176,9 @@
</tbody> </tbody>
</table> </table>
<!--분 설정 --> <!-- 용량/출력 정보 (Depth 4 전용) 복-->
<div class="section-title">구분 설정</div> <div class="section-title">용량/출력 정보</div>
<table class="board_write"> <table class="board_write">
<colgroup>
<col width="120px">
<col width="*">
</colgroup>
<tbody>
<tr>
<th>노출 여부</th>
<td>
<label><input type="radio" name="listUse" value="y" checked> Y</label>
<label><input type="radio" name="listUse" value="n"> N</label>
</td>
</tr>
<tr>
<th>구분</th>
<td>
<label><input type="checkbox" name="clinicUse" value="y" checked> 진료</label>&nbsp;
<label><input type="checkbox" name="expenseUse" value="y"> 비용(판관비)</label>&nbsp;
<label><input type="checkbox" name="taxFree" value="y"> 면세</label>&nbsp;
<label><input type="checkbox" name="etcincomeUse" value="y"> 영업외 수익</label>&nbsp;
<label><input type="checkbox" name="etclossUse" value="y"> 영업외 손실</label>
</td>
</tr>
<tr>
<th>재고관리품목</th>
<td>
<label><input type="checkbox" name="stockUse" value="y" checked></label>&nbsp;&nbsp;&nbsp;&nbsp;
<label>재고관리 없이 미수금만 관리하실경우 체크하세요 <input type="checkbox" name="npayUse" value="y"></label>
</td>
</tr>
<tr id="trNoTax">
<th>비과세</th>
<td>
<label><input type="checkbox" name="noTax" value="y"></label>
</td>
</tr>
<tr id="trNoTax1">
<th>비세금</th>
<td>
<label><input type="checkbox" name="noTax1" value="y"></label>
</td>
</tr>
</tbody>
</table>
<!-- 제품/시술 정보 (Depth 3 전용) -->
<div class="section-title" id="productInfoTitle">제품/시술 정보</div>
<table class="board_write" id="productInfoTable">
<colgroup>
<col width="120px">
<col width="*">
</colgroup>
<tbody>
<tr>
<th>거래처</th>
<td>
<select id="custListPid" class="w100p"
style="height:30px; border:1px solid #ddd; border-radius:4px;">
<option value="">선택</option>
</select>
</td>
</tr>
<tr>
<th>제품설명</th>
<td><input type="text" id="kindMsg1" class="w100p" placeholder="제품설명을 입력하세요"></td>
</tr>
<tr>
<th>기타설명</th>
<td><input type="text" id="kindMsg2" class="w100p" placeholder="기타설명을 입력하세요"></td>
</tr>
</tbody>
</table>
<!-- 용량/출력 정보 (Depth 4 전용) -->
<div class="section-title" id="volumeInfoTitle">용량/출력 정보</div>
<table class="board_write" id="volumeInfoTable">
<colgroup> <colgroup>
<col width="120px"> <col width="120px">
<col width="*"> <col width="*">
@@ -262,24 +186,31 @@
<tbody> <tbody>
<tr> <tr>
<th>단가</th> <th>단가</th>
<td><input type="number" id="kindCost" class="w120" value="0"></td> <td>
<input type="text" id="kindCost" class="w120" value="0" style="text-align: right;">
</td>
</tr> </tr>
<tr> <tr>
<th>할인가</th> <th>할인가</th>
<td><input type="number" id="dcCost" class="w120" value="0"></td>
</tr>
<tr>
<th>단위</th>
<td> <td>
<input type="text" id="kindUnit" class="w120" placeholder="예: cc, ml"> <input type="text" id="dcCost" class="w120" value="0" style="text-align: right;">
<span class="txt_info" style="margin-left:8px;">용량:</span>
<input type="number" id="kindUnitVol" class="w80" value="0" step="0.1">
<input type="text" id="kindUnit2" style="width:60px;" placeholder="단위">
</td> </td>
</tr> </tr>
<tr> <tr>
<th>비율</th> <th>사용량</th>
<td><input type="text" id="ccRate" class="w120" placeholder="비율"></td> <td>
<input type="number" id="kindUnitVol" class="w120" value="0" step="0.1" placeholder="용량">
<select id="kindUnit" style="width: 100px; margin-left: 5px;">
<option value="">선택</option>
<!-- 추후 공통코드 연동을 통해 데이터 바인딩 -->
<option value="CC">CC</option>
<option value="ML">ML</option>
<option value="샷"></option>
<option value="회"></option>
<option value="V">V</option>
<option value="줄"></option>
</select>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -291,7 +222,7 @@
</div> </div>
</div> </div>
<script th:src="@{/js/web/settings/medicalcategory/popup/medicalCategoryInfoPop.js}"></script> <script th:src="@{/js/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept4.js}"></script>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,179 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<title>진료유형 정보</title>
<link rel="stylesheet" th:href="@{/css/common.css}">
<script th:src="@{/js/web/jquery.min.js}"></script>
<style>
.pop_wrap {
max-width: 600px;
margin: 0 auto;
}
.pop_wrap h3 {
font-size: 16px;
margin-bottom: 16px;
padding-bottom: 10px;
border-bottom: 2px solid #3985EA;
color: #333;
}
.board_write {
width: 100%;
border-collapse: collapse;
}
.board_write th {
background: #f8f9fb;
padding: 10px 12px;
text-align: left;
font-size: 13px;
font-weight: 600;
color: #555;
border: 1px solid #e9ecf0;
white-space: nowrap;
}
.board_write td {
padding: 8px 12px;
border: 1px solid #e9ecf0;
}
.board_write input[type="text"],
.board_write input[type="number"] {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
.board_write select {
height: 30px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 13px;
}
.w100p {
width: 100%;
box-sizing: border-box;
}
.w80 {
width: 80px;
}
.w120 {
width: 120px;
}
.ess {
color: #ff0000;
}
.txt_info {
font-size: 11px;
color: #999;
}
.pop_btn_area {
text-align: center;
margin-top: 20px;
}
.btn_blue {
padding: 8px 24px;
background: #3985EA;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
.btn_blue:hover {
background: #2c6fd1;
}
.btn_gray {
padding: 8px 24px;
background: #fff;
color: #666;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
cursor: pointer;
margin-left: 6px;
}
.btn_gray:hover {
background: #f5f5f5;
}
.btn_red {
padding: 8px 24px;
background: #ff4444;
color: #fff;
border: none;
border-radius: 5px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
margin-left: 6px;
}
.btn_red:hover {
background: #cc0000;
}
</style>
</head>
<body style="padding: 20px;">
<div class="pop_wrap">
<h3 id="popTitle">부위(Depth 5) 등록</h3>
<input type="hidden" id="pid" value="">
<input type="hidden" id="diviDept" value="5">
<input type="hidden" id="diviParent" value="">
<input type="hidden" id="storePid" value="1">
<table class="board_write">
<colgroup>
<col width="120px">
<col width="*">
</colgroup>
<tbody>
<tr id="parentNameRow" style="display:none;">
<th>상위 카테고리</th>
<td><span id="parentNameTxt"></span></td>
</tr>
<tr>
<th><span class="ess">*</span> 항목 명칭</th>
<td><input type="text" id="diviName" class="w100p" placeholder="예: 얼굴, 턱, 종아리 등"></td>
</tr>
<tr>
<th>정렬 순서</th>
<td><input type="number" id="diviSort" class="w80" value="0"> <span class="txt_info">숫자가 낮을수록 먼저
표시됩니다.</span></td>
</tr>
<tr>
<th>색상 코드</th>
<td><input type="color" id="diviColor" value="#000000"></td>
</tr>
</tbody>
</table>
<div class="pop_btn_area">
<button type="button" class="btn_blue" id="btn_save">저장</button>
<button type="button" class="btn_red" id="btn_delete" style="display:none;">삭제</button>
<button type="button" class="btn_gray" id="btn_close">닫기</button>
</div>
</div>
<script th:src="@{/js/web/settings/medicalcategory/popup/medicalCategoryInfoPopDept5.js}"></script>
</body>
</html>