feat: Implement hospital update functionality including operating hours and holiday management.

This commit is contained in:
pjs
2026-02-14 22:16:25 +09:00
parent 1175eb13c5
commit 6287526490
8 changed files with 1659 additions and 596 deletions

View File

@@ -258,4 +258,106 @@ public class WebHospitalController extends ManagerDraftAction {
log.debug("WebHospitalController updateHospital END");
return HttpUtil.makeHashToJsonModelAndView(map);
}
/**
* 병원 스케줄 상세 조회
*/
@RequestMapping(value = "/webhospital/selectHospitalScheduleDetail.do")
public ModelAndView selectHospitalScheduleDetail(HttpSession session, HttpServletRequest request,
HttpServletResponse response) {
log.debug("WebHospitalController selectHospitalScheduleDetail START");
HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
HashMap<String, Object> map = new HashMap<String, Object>();
try {
if (!webCheckLogin(session)) {
return null;
} else {
paramMap.put("loginMemberId", String.valueOf(session.getAttribute("loginMemberId")));
map = webHospitalService.selectHospitalScheduleDetail(paramMap);
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (Constants.OK != map.get("msgCode")) {
map.put("msgCode", Constants.FAIL);
map.put("success", false);
if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
}
}
}
log.debug("WebHospitalController selectHospitalScheduleDetail END");
return HttpUtil.makeHashToJsonModelAndView(map);
}
/**
* 병원 스케줄 저장
*/
@RequestMapping(value = "/webhospital/saveHospitalSchedule.do")
public ModelAndView saveHospitalSchedule(HttpSession session, HttpServletRequest request,
HttpServletResponse response) {
log.debug("WebHospitalController saveHospitalSchedule START");
HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
HashMap<String, Object> map = new HashMap<String, Object>();
try {
if (!webCheckLogin(session)) {
return null;
} else {
paramMap.put("loginMemberId", String.valueOf(session.getAttribute("loginMemberId")));
paramMap.put("regId", String.valueOf(session.getAttribute("loginMemberId")));
paramMap.put("modId", String.valueOf(session.getAttribute("loginMemberId")));
map = webHospitalService.saveHospitalSchedule(paramMap);
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (Constants.OK != map.get("msgCode")) {
map.put("msgCode", Constants.FAIL);
map.put("success", false);
if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
}
}
}
log.debug("WebHospitalController saveHospitalSchedule END");
return HttpUtil.makeHashToJsonModelAndView(map);
}
/**
* 병원 스케줄 삭제
*/
@RequestMapping(value = "/webhospital/deleteHospitalSchedule.do")
public ModelAndView deleteHospitalSchedule(HttpSession session, HttpServletRequest request,
HttpServletResponse response) {
log.debug("WebHospitalController deleteHospitalSchedule START");
HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
HashMap<String, Object> map = new HashMap<String, Object>();
try {
if (!webCheckLogin(session)) {
return null;
} else {
paramMap.put("loginMemberId", String.valueOf(session.getAttribute("loginMemberId")));
paramMap.put("modId", String.valueOf(session.getAttribute("loginMemberId")));
map = webHospitalService.deleteHospitalSchedule(paramMap);
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (Constants.OK != map.get("msgCode")) {
map.put("msgCode", Constants.FAIL);
map.put("success", false);
if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
}
}
}
log.debug("WebHospitalController deleteHospitalSchedule END");
return HttpUtil.makeHashToJsonModelAndView(map);
}
}

View File

@@ -66,6 +66,7 @@ public class WebHospitalSqlMapDAO extends SqlSessionDaoSupport{
logger.debug("WebHospitalSqlMapDAO selectHospitalWeek2 END");
return getSqlSession().selectList(sqlId, paramMap);
}
/**
* 병원 월별 휴일 정보
*
@@ -95,4 +96,49 @@ public class WebHospitalSqlMapDAO extends SqlSessionDaoSupport{
logger.debug("WebHospitalSqlMapDAO updateHospital END");
return getSqlSession().update(sqlId, paramMap);
}
/**
* 병원 스케줄 상세 조회
*/
public Map<String, Object> selectHospitalScheduleDetail(HashMap<String, Object> paramMap)
throws DataAccessException {
return getSqlSession().selectOne("WebHospital.selectHospitalScheduleDetail", paramMap);
}
/**
* 병원 스케줄 존재 여부 확인
*/
public Map<String, Object> selectHospitalScheduleCheck(HashMap<String, Object> paramMap)
throws DataAccessException {
return getSqlSession().selectOne("WebHospital.selectHospitalScheduleCheck", paramMap);
}
/**
* 병원 휴일 여부 확인 (스케줄 등록되지 않은 날짜 기준)
*/
public Map<String, Object> selectHospitalHolidayCheck(HashMap<String, Object> paramMap)
throws DataAccessException {
return getSqlSession().selectOne("WebHospital.selectHospitalHolidayCheck", paramMap);
}
/**
* 병원 스케줄 등록
*/
public int insertHospitalSchedule(HashMap<String, Object> paramMap) throws DataAccessException {
return getSqlSession().insert("WebHospital.insertHospitalSchedule", paramMap);
}
/**
* 병원 스케줄 수정
*/
public int updateHospitalSchedule(HashMap<String, Object> paramMap) throws DataAccessException {
return getSqlSession().update("WebHospital.updateHospitalSchedule", paramMap);
}
/**
* 병원 스케줄 삭제
*/
public int deleteHospitalSchedule(HashMap<String, Object> paramMap) throws DataAccessException {
return getSqlSession().update("WebHospital.deleteHospitalSchedule", paramMap);
}
}

View File

@@ -14,4 +14,9 @@ public interface WebHospitalService {
public HashMap<String, Object> selectHospitalHolidayList(HashMap<String, Object> paramMap) throws Exception;
public HashMap<String, Object> selectHospitalScheduleDetail(HashMap<String, Object> paramMap) throws Exception;
public HashMap<String, Object> saveHospitalSchedule(HashMap<String, Object> paramMap) throws Exception;
public HashMap<String, Object> deleteHospitalSchedule(HashMap<String, Object> paramMap) throws Exception;
}

View File

@@ -758,4 +758,72 @@ public class WebHospitalServiceImpl implements WebHospitalService {
log.debug("WebHospitalServiceImpl updateHospital END");
return map;
}
@Override
public HashMap<String, Object> selectHospitalScheduleDetail(HashMap<String, Object> paramMap) throws Exception {
HashMap<String, Object> map = new HashMap<String, Object>();
try {
Map<String, Object> result = webHospitalSqlMapDAO.selectHospitalScheduleDetail(paramMap);
if (result == null) {
// 스케줄이 없으면 휴일 여부 확인
Map<String, Object> holidayCheck = webHospitalSqlMapDAO.selectHospitalHolidayCheck(paramMap);
if (holidayCheck != null) {
map.put("isHoliday", "Y");
}
}
map.put("msgCode", Constants.OK);
map.put("rows", result);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
return map;
}
@Override
@Transactional(rollbackFor = { Exception.class }, propagation = Propagation.REQUIRES_NEW)
public HashMap<String, Object> saveHospitalSchedule(HashMap<String, Object> paramMap) throws Exception {
HashMap<String, Object> map = new HashMap<String, Object>();
try {
String muHospitalScheduleId = String.valueOf(paramMap.get("muHospitalScheduleId"));
if (muHospitalScheduleId == null || muHospitalScheduleId.isEmpty() || "null".equals(muHospitalScheduleId)) {
// 중복 체크
Map<String, Object> existingSchedule = webHospitalSqlMapDAO.selectHospitalScheduleCheck(paramMap);
if (existingSchedule != null && existingSchedule.get("muHospitalScheduleId") != null) {
// 이미 존재하면 UPDATE 로 전환 (삭제된 데이터 복구 포함)
paramMap.put("muHospitalScheduleId", existingSchedule.get("muHospitalScheduleId"));
webHospitalSqlMapDAO.updateHospitalSchedule(paramMap);
} else {
webHospitalSqlMapDAO.insertHospitalSchedule(paramMap);
}
} else {
webHospitalSqlMapDAO.updateHospitalSchedule(paramMap);
}
map.put("msgCode", Constants.OK);
map.put("msgDesc", "저장되었습니다.");
} catch (Exception e) {
e.printStackTrace();
throw e;
}
return map;
}
@Override
@Transactional(rollbackFor = { Exception.class }, propagation = Propagation.REQUIRES_NEW)
public HashMap<String, Object> deleteHospitalSchedule(HashMap<String, Object> paramMap) throws Exception {
HashMap<String, Object> map = new HashMap<String, Object>();
try {
webHospitalSqlMapDAO.deleteHospitalSchedule(paramMap);
map.put("msgCode", Constants.OK);
map.put("msgDesc", "삭제되었습니다.");
} catch (Exception e) {
e.printStackTrace();
throw e;
}
return map;
}
}

View File

@@ -55,7 +55,10 @@
<select id="selectHospitalWeek" parameterType="hashmap" resultType="hashmap">
SELECT MH.MU_HOSPITAL_ID AS "muHospitalId"
,MH.HOSPITAL_NAME AS "hospitalName"
,CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
,CASE
WHEN MHS.MU_HOSPITAL_SCHEDULE_ID IS NOT NULL THEN MHS.OPEN_YN
ELSE
CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
WHEN '2' THEN MH.MON_OPEN_YN
WHEN '3' THEN MH.TUE_OPEN_YN
WHEN '4' THEN MH.WED_OPEN_YN
@@ -63,6 +66,7 @@
WHEN '6' THEN MH.FRI_OPEN_YN
WHEN '7' THEN MH.SAT_OPEN_YN
WHEN '1' THEN MH.SUN_OPEN_YN
END
END AS "openYn"
,CASE
WHEN EXISTS (
@@ -85,7 +89,10 @@
THEN 'Y'
ELSE 'N'
END AS "holidayYn"
,CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
,CASE
WHEN MHS.MU_HOSPITAL_SCHEDULE_ID IS NOT NULL THEN MHS.OPEN_START_TIME
ELSE
CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
WHEN '2' THEN MH.MON_OPEN_START_TIME
WHEN '3' THEN MH.TUE_OPEN_START_TIME
WHEN '4' THEN MH.WED_OPEN_START_TIME
@@ -93,8 +100,12 @@
WHEN '6' THEN MH.FRI_OPEN_START_TIME
WHEN '7' THEN MH.SAT_OPEN_START_TIME
WHEN '1' THEN MH.SUN_OPEN_START_TIME
END
END AS "openStartTime"
,CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
,CASE
WHEN MHS.MU_HOSPITAL_SCHEDULE_ID IS NOT NULL THEN MHS.OPEN_END_TIME
ELSE
CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
WHEN '2' THEN MH.MON_OPEN_END_TIME
WHEN '3' THEN MH.TUE_OPEN_END_TIME
WHEN '4' THEN MH.WED_OPEN_END_TIME
@@ -102,8 +113,12 @@
WHEN '6' THEN MH.FRI_OPEN_END_TIME
WHEN '7' THEN MH.SAT_OPEN_END_TIME
WHEN '1' THEN MH.SUN_OPEN_END_TIME
END
END AS "openEndTime"
,CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
,CASE
WHEN MHS.MU_HOSPITAL_SCHEDULE_ID IS NOT NULL THEN MHS.BREAK_START_TIME
ELSE
CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
WHEN '2' THEN MH.MON_BREAK_START_TIME
WHEN '3' THEN MH.TUE_BREAK_START_TIME
WHEN '4' THEN MH.WED_BREAK_START_TIME
@@ -111,8 +126,12 @@
WHEN '6' THEN MH.FRI_BREAK_START_TIME
WHEN '7' THEN MH.SAT_BREAK_START_TIME
WHEN '1' THEN MH.SUN_BREAK_START_TIME
END
END AS "breakStartTime"
,CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
,CASE
WHEN MHS.MU_HOSPITAL_SCHEDULE_ID IS NOT NULL THEN MHS.BREAK_END_TIME
ELSE
CASE DAYOFWEEK(DATE_FORMAT(#{searchDate}, '%Y-%m-%d'))
WHEN '2' THEN MH.MON_BREAK_END_TIME
WHEN '3' THEN MH.TUE_BREAK_END_TIME
WHEN '4' THEN MH.WED_BREAK_END_TIME
@@ -120,8 +139,13 @@
WHEN '6' THEN MH.FRI_BREAK_END_TIME
WHEN '7' THEN MH.SAT_BREAK_END_TIME
WHEN '1' THEN MH.SUN_BREAK_END_TIME
END
END AS "breakEndTime"
FROM MU_HOSPITAL AS MH
LEFT JOIN MU_HOSPITAL_SCHEDULE MHS
ON MH.MU_HOSPITAL_ID = MHS.MU_HOSPITAL_ID
AND MHS.SCHEDULE_DATE = #{searchDate}
AND MHS.USE_YN = 'Y'
WHERE MH.USE_YN = 'Y'
LIMIT 0, 1
</select>
@@ -136,7 +160,11 @@
FROM T_TEMP_DATES
WHERE RESULT_DATE &lt; #{endDate}
)
SELECT TTD.OPEN_YN AS "openYn"
SELECT
CASE
WHEN MHS.OPEN_YN IS NOT NULL THEN MHS.OPEN_YN
ELSE TTD.OPEN_YN
END AS "openYn"
,TTD.HOLIDAY_YN AS "holidayYn"
FROM (
SELECT TTD.RESULT_DATE AS RESULT_DATE
@@ -187,6 +215,9 @@
LEFT JOIN MU_HOSPITAL AS MH
ON 1 = 1
) AS TTD
LEFT JOIN MU_HOSPITAL_SCHEDULE MHS
ON MHS.SCHEDULE_DATE = TTD.RESULT_DATE
AND MHS.USE_YN = 'Y'
</select>
<select id="selectHospitalHoliday" parameterType="hashmap" resultType="hashmap">
@@ -213,8 +244,105 @@
WHERE MPH.USE_YN = 'Y'
AND DATE_FORMAT( MPH.LOC_DATE, '%Y' ) >= DATE_FORMAT( CURDATE( ), '%Y' )
)
UNION ALL
(
SELECT 'hospitalSchedule' AS "dateType"
, CASE WHEN OPEN_YN = 'Y' THEN '운영' ELSE '휴무' END AS "hospitalHolidayName"
, DATE_FORMAT(SCHEDULE_DATE, '%Y-%m-%d') AS "locDate"
FROM MU_HOSPITAL_SCHEDULE
WHERE MU_HOSPITAL_ID = #{muHospitalId}
AND USE_YN = 'Y'
AND DATE_FORMAT( SCHEDULE_DATE, '%Y' ) >= DATE_FORMAT( CURDATE( ), '%Y' )
)
</select>
<select id="selectHospitalScheduleDetail" parameterType="hashmap" resultType="hashmap">
SELECT MU_HOSPITAL_SCHEDULE_ID AS "muHospitalScheduleId"
, MU_HOSPITAL_ID AS "muHospitalId"
, DATE_FORMAT(SCHEDULE_DATE, '%Y-%m-%d') AS "scheduleDate"
, OPEN_YN AS "openYn"
, OPEN_START_TIME AS "openStartTime"
, OPEN_END_TIME AS "openEndTime"
, BREAK_START_TIME AS "breakStartTime"
, BREAK_END_TIME AS "breakEndTime"
FROM MU_HOSPITAL_SCHEDULE
WHERE MU_HOSPITAL_ID = #{muHospitalId}
AND SCHEDULE_DATE = #{searchDate}
AND USE_YN = 'Y'
LIMIT 1
</select>
<select id="selectHospitalScheduleCheck" parameterType="hashmap" resultType="hashmap">
SELECT MU_HOSPITAL_SCHEDULE_ID AS "muHospitalScheduleId"
FROM MU_HOSPITAL_SCHEDULE
WHERE MU_HOSPITAL_ID = #{muHospitalId}
AND SCHEDULE_DATE = #{scheduleDate}
LIMIT 1
</select>
<select id="selectHospitalHolidayCheck" parameterType="hashmap" resultType="hashmap">
SELECT 1 AS "isHoliday"
FROM DUAL
WHERE EXISTS (
SELECT 1
FROM MU_HOSPITAL_HOLIDAY
WHERE MU_HOSPITAL_ID = #{muHospitalId}
AND USE_YN = 'Y'
AND (
(REPEAT_YN = 'Y' AND DATE_FORMAT(LOC_DATE, '%m-%d') = DATE_FORMAT(#{searchDate}, '%m-%d'))
OR
(REPEAT_YN = 'N' AND LOC_DATE = #{searchDate})
)
) OR EXISTS (
SELECT 1
FROM MU_PUBLIC_HOLIDAY MPH
JOIN MU_HOSPITAL MH
ON MH.MU_HOSPITAL_ID = #{muHospitalId}
AND MH.PUBLIC_HOLIDAY_USE_YN = 'Y'
WHERE MPH.USE_YN = 'Y'
AND MPH.LOC_DATE = #{searchDate}
)
</select>
<insert id="insertHospitalSchedule" parameterType="hashmap">
INSERT INTO MU_HOSPITAL_SCHEDULE (
MU_HOSPITAL_SCHEDULE_ID, MU_HOSPITAL_ID, SCHEDULE_DATE, OPEN_YN,
OPEN_START_TIME, OPEN_END_TIME, BREAK_START_TIME, BREAK_END_TIME,
WRITE_DATE, WRITE_TIME, CUD_FLAG, USE_YN, REG_ID, MOD_ID,
REG_DATE, MOD_DATE
) VALUES (
(SELECT CONCAT('S', DATE_FORMAT(NOw(), '%y%m%d%H%i%s%f'), LPAD(NEXT_NOT_CACHED_VALUE, 9, '0'))
FROM MU_HOSPITAL_SCHEDULE_SEQ),
#{muHospitalId}, #{scheduleDate}, #{openYn},
#{openStartTime}, #{openEndTime}, #{breakStartTime}, #{breakEndTime},
CURDATE(), CURTIME(), 'C', 'Y', #{regId}, #{modId},
NOW(),NOW()
)
</insert>
<update id="updateHospitalSchedule" parameterType="hashmap">
UPDATE MU_HOSPITAL_SCHEDULE
SET OPEN_YN = #{openYn},
OPEN_START_TIME = #{openStartTime},
OPEN_END_TIME = #{openEndTime},
BREAK_START_TIME = #{breakStartTime},
BREAK_END_TIME = #{breakEndTime},
USE_YN = 'Y',
MOD_ID = #{modId},
MOD_DATE = NOW(),
CUD_FLAG = 'U'
WHERE MU_HOSPITAL_SCHEDULE_ID = #{muHospitalScheduleId}
</update>
<delete id="deleteHospitalSchedule" parameterType="hashmap">
UPDATE MU_HOSPITAL_SCHEDULE
SET USE_YN = 'N',
CUD_FLAG = 'D',
MOD_ID = #{modId},
MOD_DATE = NOW()
WHERE MU_HOSPITAL_SCHEDULE_ID = #{muHospitalScheduleId}
</delete>
<update id="updateHospital" parameterType="hashmap">
UPDATE MU_HOSPITAL
SET MOD_ID = #{modId}

View File

@@ -0,0 +1,36 @@
CREATE TABLE `MU_HOSPITAL_SCHEDULE` (
`MU_HOSPITAL_SCHEDULE_ID` varchar(25) NOT NULL COMMENT '병원 스케줄 식별자',
`MU_HOSPITAL_ID` varchar(25) NOT NULL COMMENT '병원 식별자',
`SCHEDULE_DATE` date NOT NULL COMMENT '스케줄 날짜',
`OPEN_YN` char(1) NOT NULL DEFAULT 'Y' COMMENT '운영여부 (Y/N)',
`OPEN_START_TIME` varchar(5) DEFAULT NULL COMMENT '운영 시작시간 (HH:mm)',
`OPEN_END_TIME` varchar(5) DEFAULT NULL COMMENT '운영 종료시간 (HH:mm)',
`BREAK_START_TIME` varchar(5) DEFAULT NULL COMMENT '휴게 시작시간 (HH:mm)',
`BREAK_END_TIME` varchar(5) DEFAULT NULL COMMENT '휴게 종료시간 (HH:mm)',
`WRITE_DATE` date NOT NULL COMMENT '작성일자',
`WRITE_TIME` time NOT NULL COMMENT '작성시간',
`REMARK` text DEFAULT NULL COMMENT '비고',
`CUD_FLAG` char(1) DEFAULT 'C' COMMENT '작업타입',
`USE_YN` char(1) NOT NULL DEFAULT 'Y' COMMENT '사용여부',
`REG_ID` varchar(25) NOT NULL COMMENT '등록자',
`REG_DATE` timestamp NOT NULL DEFAULT current_timestamp() COMMENT '등록일시',
`MOD_ID` varchar(25) NOT NULL COMMENT '수정자',
`MOD_DATE` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '수정일시',
`T_ID` varchar(13) DEFAULT NULL,
`T_DATE` datetime DEFAULT NULL,
PRIMARY KEY (`MU_HOSPITAL_SCHEDULE_ID`),
UNIQUE KEY `UK_HOSPITAL_DATE` (`MU_HOSPITAL_ID`, `SCHEDULE_DATE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='병원별 날짜별 운영 스케줄 (예외처리)';
CREATE TABLE `MU_HOSPITAL_SCHEDULE_SEQ` (
`next_not_cached_value` bigint(21) NOT NULL,
`minimum_value` bigint(21) NOT NULL,
`maximum_value` bigint(21) NOT NULL,
`start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used',
`increment` bigint(21) NOT NULL COMMENT 'increment value',
`cache_size` bigint(21) unsigned NOT NULL,
`cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed',
`cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
) ENGINE=InnoDB SEQUENCE=1;
INSERT INTO `MU_HOSPITAL_SCHEDULE_SEQ` VALUES (1,1,9999999999,1,1,0,1,0);

View File

@@ -2,7 +2,7 @@
/****************************************************************************
* 병원 정보 상세 조회
****************************************************************************/
function fn_selectHospitalJson() {
function fn_selectHospitalJson(onlyOperatingHours) {
let formData = new FormData();
formData.append("menuClass", menuClass);
@@ -120,17 +120,21 @@ function fn_selectHospitalJson() {
if ('Y' == hospitalRows.publicHolidayUseYn) {
$('#checkPublicHolidayUseYn').prop('checked', true);
} else {
$('#checkPublicHolidayUseYn').prop('checked', false);
}
$("#txt_muMemberId").val(hospitalRows.muMemberId);
$("#txt_memberName").val(hospitalRows.memberName);
if (!onlyOperatingHours) {
// 휴일 상세 정보
fn_addRow2(hospitalRows.holidayRows);
// 달력 조회 (병원 ID 확보 후 실행)
fn_selectHospitalHolidayList();
}
}
else {
modalEvent.danger("조회 오류", data.msgDesc);
}
@@ -147,6 +151,9 @@ function fn_selectHospitalJson() {
});
}
/****************************************************************************
* 조회 row 추가 이벤트
****************************************************************************/
/****************************************************************************
* 조회 row 추가 이벤트
****************************************************************************/
@@ -154,116 +161,137 @@ function fn_addRow2(detailList) {
let addRowHtml = '';
if (0 < detailList.length) {
addRowHtml += '<li class="list_title_li">';
addRowHtml += ' <span class="list_title">휴일명</span>';
addRowHtml += ' <span class="list_title">날짜</span>';
addRowHtml += ' <span class="list_title">일정반복</span>';
addRowHtml += ' <span class="list_title"></span>';
// Rebuild Header (must match HTML exactly)
addRowHtml += '<li class="list_title_li" style="display: flex !important; width: 100% !important; margin: 0 !important; padding: 10px 0 !important; background: #EDF5FF; border-radius: 5px; float: none !important; position: sticky; top: 0; z-index: 10;">';
addRowHtml += ' <span class="list_title" style="width: 40px !important; display: flex; justify-content: center; align-items: center; float: none !important; border: none !important;"><input type="checkbox" id="checkAllHolidays"></span>';
addRowHtml += ' <span class="list_title" style="flex: 1 !important; text-align: center; float: none !important; border: none !important; width: auto !important;">휴일명</span>';
addRowHtml += ' <span class="list_title" style="width: 140px !important; text-align: center; float: none !important; border: none !important;">날짜</span>';
addRowHtml += ' <span class="list_title" style="width: 100px !important; text-align: center; float: none !important; border: none !important;">일정반복</span>';
addRowHtml += ' <span class="list_title" style="width: 70px !important; text-align: center; float: none !important; border: none !important;">저장</span>';
addRowHtml += '</li>';
for (let i = 0; i < detailList.length; i++) {
let hospitalHolidayName = detailList[i].hospitalHolidayName;
let locDate = detailList[i].locDate;
let repeatYn = detailList[i].repeatYn;
let repeatLabel = ('Y' == repeatYn) ? '반복' : '반복 안함';
addRowHtml += '<li>';
addRowHtml += ' <div class="input_box">';
addRowHtml += ' <input type="text" name="hospitalHolidayName" value="' + hospitalHolidayName + '" placeholder="휴일명" maxlength="50">';
addRowHtml += '<li style="display: flex !important; width: 100% !important; float: none !important; align-items: center; border-bottom: 1px solid #eee; padding: 10px 0;">';
// Checkbox
addRowHtml += ' <div class="check_box" style="width: 40px !important; display: flex; justify-content: center; align-items: center; float: none !important;">';
addRowHtml += ' <input type="checkbox" name="checkHolidayRow" value="">';
addRowHtml += ' </div>';
addRowHtml += ' <div class="calendar_box">';
addRowHtml += ' <div class="date_box">';
addRowHtml += ' <img src="/image/web/calendar.svg" alt="calendar"/>';
addRowHtml += ' <input type="date" class="date_picker" name="dateLocDate" value="' + locDate + '">';
// Name
addRowHtml += ' <div class="input_box" style="flex: 1 !important; width: auto !important; float: none !important; border: none !important; padding: 0 5px;">';
addRowHtml += ' <input type="text" name="hospitalHolidayName" value="' + hospitalHolidayName + '" placeholder="휴일명" maxlength="50" style="width: 100%; border: 1px solid #ddd; height: 34px; padding: 0 10px;">';
addRowHtml += ' </div>';
// Date
// Use simpler structure to avoid CSS conflict
addRowHtml += ' <div class="calendar_box" style="width: 140px !important; float: none !important; border: none !important; padding: 0 5px;">';
addRowHtml += ' <div class="date_box" style="width: 100%; position: relative;">';
addRowHtml += ' <img src="/image/web/calendar.svg" alt="calendar" style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); width: 16px;">';
addRowHtml += ' <input type="date" class="date_picker" name="dateLocDate" value="' + locDate + '" style="width: 100%; padding-left: 30px; border: 1px solid #ddd; height: 34px; border-radius: 4px;">';
addRowHtml += ' </div>';
addRowHtml += ' </div>';
addRowHtml += ' <div class="select_list">';
addRowHtml += ' <div class="select_box dropdown">';
if ('Y' == repeatYn) {
addRowHtml += ' <button type="button" class="label" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">반복</button>';
addRowHtml += ' <input type="hidden" name="repeatYn" value="Y"/>';
}
else {
addRowHtml += ' <button type="button" class="label" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">반복 안함</button>';
addRowHtml += ' <input type="hidden" name="repeatYn" value="N"/>';
}
addRowHtml += ' <ul class="select_option_list dropdown-menu">';
addRowHtml += ' <li class="option_list_item first" onclick="fn_clickSelectValue(this, \'Y\', \'반복\');">반복</li>';
addRowHtml += ' <li class="option_list_item" onclick="fn_clickSelectValue(this, \'N\', \'반복 안함\');">반복 안함</li>';
// Repeat
addRowHtml += ' <div class="select_list" style="width: 100px !important; float: none !important; border: none !important; padding: 0 5px;">';
addRowHtml += ' <div class="select_box dropdown" style="width: 100%; height: 34px; border: 1px solid #ddd; border-radius: 4px; position: relative; background: #fff;">';
addRowHtml += ' <button type="button" class="label" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="width: 100%; height: 100%; text-align: left; padding: 0 10px; background: transparent; border: none;">' + repeatLabel + '</button>';
addRowHtml += ' <input type="hidden" name="repeatYn" value="' + repeatYn + '"/>';
addRowHtml += ' <ul class="select_option_list dropdown-menu" style="width: 100%; padding: 0; margin: 0; border: 1px solid #ddd;">';
addRowHtml += ' <li class="option_list_item first" onclick="fn_clickSelectValue(this, \'Y\', \'반복\');" style="padding: 5px; cursor: pointer; text-align: center;">반복</li>';
addRowHtml += ' <li class="option_list_item" onclick="fn_clickSelectValue(this, \'N\', \'반복 안함\');" style="padding: 5px; cursor: pointer; text-align: center;">반복 안함</li>';
addRowHtml += ' </ul>';
addRowHtml += ' </div>';
addRowHtml += ' </div>';
if (i == 0) {
addRowHtml += '<div class="add_box">';
addRowHtml += ' <button onclick="javascript:fn_removeRow2(this);"><img src="/image/web/subtract.svg" alt="삭제"></button>';
// Save Button
addRowHtml += ' <div class="save_box" style="width: 70px !important; text-align: center; float: none !important;">';
// Using 60px width button or so
addRowHtml += ' <button type="button" onclick="fn_saveHospitalHolidayRow(this);" style="background: #4a5568; color: #fff; border: none; padding: 0; width: 60px; height: 34px; border-radius: 4px; cursor: pointer; font-size: 13px;">저장</button>';
addRowHtml += ' </div>';
addRowHtml += '<div class="add_box">';
addRowHtml += ' <button onclick="javascript:fn_addRow(this);"><img src="/image/web/add.svg" alt="추가"/></button>';
addRowHtml += '</div>';
}
else {
addRowHtml += '<div class="add_box" style="display:none;">';
addRowHtml += ' <button onclick="javascript:fn_addRow(this);"><img src="/image/web/add.svg" alt="추가"/></button>';
addRowHtml += '</div>';
addRowHtml += '<div class="subtract_box">';
addRowHtml += ' <button onclick="javascript:fn_removeRow(this);"><img src="/image/web/subtract.svg" alt="삭제"></button>';
addRowHtml += '</div>';
}
addRowHtml += '</li>';
}
$('#hospitalHolidayList').empty().html(addRowHtml).trigger("create");
}
else {
fn_addRow();
// Add Header
let headerHtml = '<li class="list_title_li" style="display: flex !important; width: 100% !important; margin: 0 !important; padding: 10px 0 !important; background: #EDF5FF; border-radius: 5px; float: none !important; position: sticky; top: 0; z-index: 10;">';
headerHtml += ' <span class="list_title" style="width: 40px !important; display: flex; justify-content: center; align-items: center; float: none !important; border: none !important;"><input type="checkbox" id="checkAllHolidays"></span>';
headerHtml += ' <span class="list_title" style="flex: 1 !important; text-align: center; float: none !important; border: none !important; width: auto !important;">휴일명</span>';
headerHtml += ' <span class="list_title" style="width: 140px !important; text-align: center; float: none !important; border: none !important;">날짜</span>';
headerHtml += ' <span class="list_title" style="width: 100px !important; text-align: center; float: none !important; border: none !important;">일정반복</span>';
headerHtml += ' <span class="list_title" style="width: 70px !important; text-align: center; float: none !important; border: none !important;">저장</span>';
headerHtml += '</li>';
$('#hospitalHolidayList').html(headerHtml);
// Show No Data message instead of empty row
$('#hospitalHolidayList').append('<li class="no_data" style="width: 100%; text-align: center; padding: 20px 0;">지정한 휴일이 없습니다.</li>');
}
// 날짜 datepicker
fn_datePicker("#hospitalHolidayList input[type='date']");
let parentTable = $("#hospitalHolidayList");
fn_hospitalRefreshOrderNumber(parentTable);
// fn_hospitalRefreshOrderNumber is no longer needed since we don't have add/sub buttons per row.
// But let's check full context.
}
/****************************************************************************
* row 추가 이벤트
****************************************************************************/
/****************************************************************************
* row 추가 이벤트
****************************************************************************/
/****************************************************************************
* row 추가 이벤트
****************************************************************************/
function fn_addRow(param) {
// Remove No Data message if present
if ($("#hospitalHolidayList .no_data").length > 0) {
$("#hospitalHolidayList .no_data").remove();
}
let addRowHtml = '';
addRowHtml += '<li>';
addRowHtml += ' <div class="input_box">';
addRowHtml += ' <input type="text" name="hospitalHolidayName" value="" placeholder="휴일명" maxlength="50">';
addRowHtml += '<li style="display: flex !important; width: 100% !important; float: none !important; align-items: center; border-bottom: 1px solid #eee; padding: 10px 0;">';
// Checkbox
addRowHtml += ' <div class="check_box" style="width: 40px !important; display: flex; justify-content: center; align-items: center; float: none !important;">';
addRowHtml += ' <input type="checkbox" name="checkHolidayRow" value="">';
addRowHtml += ' </div>';
addRowHtml += ' <div class="calendar_box">';
addRowHtml += ' <div class="date_box">';
addRowHtml += ' <img src="/image/web/calendar.svg" alt="calendar"/>';
addRowHtml += ' <input type="date" class="date_picker" name="dateLocDate">';
// Name
addRowHtml += ' <div class="input_box" style="flex: 1 !important; width: auto !important; float: none !important; border: none !important; padding: 0 5px;">';
addRowHtml += ' <input type="text" name="hospitalHolidayName" value="" placeholder="휴일명" maxlength="50" style="width: 100%; border: 1px solid #ddd; height: 34px; padding: 0 10px;">';
addRowHtml += ' </div>';
// Date
addRowHtml += ' <div class="calendar_box" style="width: 140px !important; float: none !important; border: none !important; padding: 0 5px;">';
addRowHtml += ' <div class="date_box" style="width: 100%; position: relative;">';
addRowHtml += ' <img src="/image/web/calendar.svg" alt="calendar" style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); width: 16px;">';
addRowHtml += ' <input type="date" class="date_picker" name="dateLocDate" style="width: 100%; padding-left: 30px; border: 1px solid #ddd; height: 34px; border-radius: 4px;">';
addRowHtml += ' </div>';
addRowHtml += ' </div>';
addRowHtml += ' <div class="select_list">';
addRowHtml += ' <div class="select_box dropdown">';
addRowHtml += ' <button type="button" class="label" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">반복 안함</button>';
// Repeat
addRowHtml += ' <div class="select_list" style="width: 100px !important; float: none !important; border: none !important; padding: 0 5px;">';
addRowHtml += ' <div class="select_box dropdown" style="width: 100%; height: 34px; border: 1px solid #ddd; border-radius: 4px; position: relative; background: #fff;">';
addRowHtml += ' <button type="button" class="label" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="width: 100%; height: 100%; text-align: left; padding: 0 10px; background: transparent; border: none;">반복 안함</button>';
addRowHtml += ' <input type="hidden" name="repeatYn" value="N"/>';
addRowHtml += ' <ul class="select_option_list dropdown-menu">';
addRowHtml += ' <li class="option_list_item first" onclick="fn_clickSelectValue(this, \'Y\', \'반복\');">반복</li>';
addRowHtml += ' <li class="option_list_item" onclick="fn_clickSelectValue(this, \'N\', \'반복 안함\');">반복 안함</li>';
addRowHtml += ' <ul class="select_option_list dropdown-menu" style="width: 100%; padding: 0; margin: 0; border: 1px solid #ddd;">';
addRowHtml += ' <li class="option_list_item first" onclick="fn_clickSelectValue(this, \'Y\', \'반복\');" style="padding: 5px; cursor: pointer; text-align: center;">반복</li>';
addRowHtml += ' <li class="option_list_item" onclick="fn_clickSelectValue(this, \'N\', \'반복 안함\');" style="padding: 5px; cursor: pointer; text-align: center;">반복 안함</li>';
addRowHtml += ' </ul>';
addRowHtml += ' </div>';
addRowHtml += ' </div>';
addRowHtml += ' <div class="subtract_box" style="display:none;">';
addRowHtml += ' <button onclick="javascript:fn_removeRow(this);"><img src="/image/web/subtract.svg" alt="삭제"></button>';
addRowHtml += ' </div>';
addRowHtml += ' <div class="add_box">';
addRowHtml += ' <button onclick="javascript:fn_addRow(this);"><img src="/image/web/add.svg" alt="추가"/></button>';
// Save Button
addRowHtml += ' <div class="save_box" style="width: 70px !important; text-align: center; float: none !important;">';
addRowHtml += ' <button type="button" onclick="fn_saveHospitalHolidayRow(this);" style="background: #4a5568; color: #fff; border: none; padding: 0; width: 60px; height: 34px; border-radius: 4px; cursor: pointer; font-size: 13px;">저장</button>';
addRowHtml += ' </div>';
addRowHtml += '</li>';
@@ -272,8 +300,7 @@ function fn_addRow(param) {
// 날짜 datepicker
fn_datePicker("#hospitalHolidayList input[type='date']");
let parentTable = $("#hospitalHolidayList");
fn_hospitalRefreshOrderNumber(parentTable);
// fn_hospitalRefreshOrderNumber is removed
}
/****************************************************************************
@@ -714,6 +741,15 @@ function fn_clickSelectValue(target, param, paramText) {
* 페이지 init
****************************************************************************/
function fn_pageInit() {
// 탭 전환 시 캘린더 리사이즈 (풀캘린더 v6)
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
if (e.target.hash === '#schedule') {
if (window.calendar) {
window.calendar.render();
}
}
});
// 병원 상세 조회
fn_selectHospitalJson();
}
@@ -734,20 +770,11 @@ function fn_selectHospitalHolidayList() {
right: 'dayGridMonth,listMonth'
},
locale: 'ko',
dateClick: function (info) {
fn_openSchedulePopup(info.dateStr);
},
events: function (info, successCallback, failureCallback) {
let formData = new FormData();
// 필요한 파라미터가 있다면 추가 (예: 검색 년월 등)
// 여기서는 전체 조회를 하거나, FullCalendar가 주는 start/end 날짜를 활용할 수 있음
// 하지만 현재 API는 파라미터 없이 병원 ID 기준으로 다 가져오거나 날짜 조건이 필요함.
// selectHospitalHoliday 쿼리를 보면 locDate 등의 조건이 있을 수 있음.
// 일단 전체 조회 또는 현재 월 기준 조회가 필요하지만, 쿼리 확인 결과 조건이 없거나 locDate 조건이 있을 수 있음.
// 여기서는 단순히 호출하고 결과 매핑.
// FullCalendar는 startStr, endStr을 쿼리스트링으로 보낼 수 있음 (?start=...&end=...)
// API 컨트롤러에서 이를 paramMap으로 받아서 쿼리에 넘겨줘야 함.
// 현재 selectHospitalHoliday 쿼리(WebHospitalSqlMap.xml)를 확인해보지 않았지만,
// 보통 날짜 조건이 없다면 전체를 가져옴.
formData.append("paramStartDate", info.startStr);
formData.append("paramEndDate", info.endStr);
formData.append("muHospitalId", $("#muHospitalId").val());
@@ -766,16 +793,18 @@ function fn_selectHospitalHolidayList() {
if (rows) {
for (let i = 0; i < rows.length; i++) {
let row = rows[i];
let color = '#3985EA'; // 기본 파란색 (Theme Blue)
let color = '#3985EA'; // 기본
if (row.dateType === 'publicHoliday') {
color = '#FF5252'; // 공휴일 빨간색 (Vibrant Red)
color = '#FF5252'; // 법정공휴일 Red
} else if (row.dateType === 'hospitalHoliday') {
color = '#2ECC71'; // 병원휴일 초록색 (Vibrant Green)
color = '#2ECC71'; // 병원휴일 Green
} else if (row.dateType === 'hospitalSchedule') {
color = '#f39c12'; // 스케줄 Orange
}
events.push({
title: row.hospitalHolidayName || row.publicHolidayName || '휴일',
start: row.locDate, // yyyy.MM.dd 포맷이라면 yyyy-MM-dd로 변환 필요할 수 있음
start: row.locDate,
color: color,
allDay: true
});
@@ -793,6 +822,208 @@ function fn_selectHospitalHolidayList() {
}
});
calendar.render();
window.calendar = calendar; // 전역 변수로 저장
}
/****************************************************************************
* 스케줄 팝업 열기
****************************************************************************/
function fn_openSchedulePopup(date) {
// 시간 옵션 초기화 (최초 1회)
if ($('#popOpenStartTime option').length == 0) {
fn_initTimeSelect();
}
$("#popScheduleDate").val(date);
$("#popMuHospitalScheduleId").val("");
// 상세 조회
let formData = new FormData();
formData.append("muHospitalId", $("#muHospitalId").val());
formData.append("searchDate", date);
$.ajax({
url: encodeURI('/webhospital/selectHospitalScheduleDetail.do'),
data: formData,
dataType: "json",
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
if ('0' == data.msgCode) {
let row = data.rows;
if (row) {
// 수정 모드
$("#popMuHospitalScheduleId").val(row.muHospitalScheduleId);
$("input[name='popOpenYn'][value='" + row.openYn + "']").prop("checked", true);
if (row.openYn == 'Y') {
$("#popOpenStartTime").val(row.openStartTime);
$("#popOpenEndTime").val(row.openEndTime);
$("#popBreakStartTime").val(row.breakStartTime);
$("#popBreakEndTime").val(row.breakEndTime);
$("#popTimeArea").show();
} else {
$("#popTimeArea").hide();
}
$("#btnDeleteSchedule").show();
} else {
// 신규 모드
// 1. 휴일 여부 확인 (서버에서 전달된 isHoliday 값)
if (data.isHoliday == 'Y') {
// 휴일이면 기본값: 휴무
$("input[name='popOpenYn'][value='N']").prop("checked", true);
$("#popTimeArea").hide();
$("#btnDeleteSchedule").hide();
$("#schedulePopup").show();
return;
}
// 2. 휴일이 아니면 요일별 기본 설정 따름
let dayOfWeek = new Date(date).getDay(); // 0:Sun, 1:Mon...
let days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
let dayStr = days[dayOfWeek];
// 메인 화면의 해당 요일 설정 가져오기
let isOpen = $("#check" + dayStr + "OpenYn").is(":checked");
$("input[name='popOpenYn'][value='" + (isOpen ? 'Y' : 'N') + "']").prop("checked", true);
if (isOpen) {
$("#popOpenStartTime").val($("#" + dayStr.toLowerCase() + "OpenStartTime").val());
$("#popOpenEndTime").val($("#" + dayStr.toLowerCase() + "OpenEndTime").val());
$("#popBreakStartTime").val($("#" + dayStr.toLowerCase() + "BreakStartTime").val());
$("#popBreakEndTime").val($("#" + dayStr.toLowerCase() + "BreakEndTime").val());
$("#popTimeArea").show();
} else {
$("#popTimeArea").hide();
}
$("#btnDeleteSchedule").hide();
}
$("#schedulePopup").show();
} else {
modalEvent.danger("오류", data.msgDesc);
}
},
error: function () {
modalEvent.danger("오류", "조회 중 오류가 발생했습니다.");
}
});
}
/****************************************************************************
* 스케줄 팝업 닫기
****************************************************************************/
function fn_closeSchedulePopup() {
$("#schedulePopup").hide();
}
/****************************************************************************
* 스케줄 저장
****************************************************************************/
function fn_saveSchedule() {
let openYn = $("input[name='popOpenYn']:checked").val();
if (openYn == 'Y') {
if (!$("#popOpenStartTime").val() || !$("#popOpenEndTime").val()) {
modalEvent.warning("알림", "운영시간을 선택해주세요.");
return;
}
}
let formData = new FormData();
formData.append("muHospitalId", $("#muHospitalId").val());
formData.append("muHospitalScheduleId", $("#popMuHospitalScheduleId").val());
formData.append("scheduleDate", $("#popScheduleDate").val());
formData.append("openYn", openYn);
if (openYn == 'Y') {
formData.append("openStartTime", $("#popOpenStartTime").val());
formData.append("openEndTime", $("#popOpenEndTime").val());
formData.append("breakStartTime", $("#popBreakStartTime").val());
formData.append("breakEndTime", $("#popBreakEndTime").val());
} else {
// 휴무일 경우 시간 초기화
formData.append("openStartTime", "00:00");
formData.append("openEndTime", "00:00");
formData.append("breakStartTime", "00:00");
formData.append("breakEndTime", "00:00");
}
$.ajax({
url: encodeURI('/webhospital/saveHospitalSchedule.do'),
data: formData,
dataType: "json",
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
if ('0' == data.msgCode) {
fn_closeSchedulePopup();
window.calendar.refetchEvents(); // 달력 갱신
} else {
modalEvent.danger("오류", data.msgDesc);
}
},
error: function () {
modalEvent.danger("오류", "저장 중 오류가 발생했습니다.");
}
});
}
/****************************************************************************
* 스케줄 삭제
****************************************************************************/
function fn_deleteSchedule() {
let formData = new FormData();
formData.append("muHospitalId", $("#muHospitalId").val());
formData.append("muHospitalScheduleId", $("#popMuHospitalScheduleId").val());
$.ajax({
url: encodeURI('/webhospital/deleteHospitalSchedule.do'),
data: formData,
dataType: "json",
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
if ('0' == data.msgCode) {
fn_closeSchedulePopup();
window.calendar.refetchEvents(); // 달력 갱신
} else {
modalEvent.danger("오류", data.msgDesc);
}
},
error: function () {
modalEvent.danger("오류", "삭제 중 오류가 발생했습니다.");
}
});
}
/****************************************************************************
* 팝업 운영여부 변경
****************************************************************************/
function fn_changePopOpenYn(target) {
if ($(target).val() == 'Y') {
$("#popTimeArea").show();
} else {
$("#popTimeArea").hide();
}
}
/****************************************************************************
* 시간 옵션 초기화
****************************************************************************/
function fn_initTimeSelect() {
let html = "";
for (let i = 0; i < 24; i++) {
let hour = i < 10 ? "0" + i : i;
html += '<option value="' + hour + ':00">' + hour + ':00</option>';
html += '<option value="' + hour + ':30">' + hour + ':30</option>';
}
$("#popOpenStartTime, #popOpenEndTime, #popBreakStartTime, #popBreakEndTime").html(html);
}
/****************************************************************************
@@ -838,6 +1069,198 @@ function fn_pageEvent() {
$("#btnUpdateHospital").click(function () {
fn_updateHospital();
});
// [New] 취소 버튼 (운영시간 탭)
$("#btnCancelHospital").click(function () {
modalEvent.info("취소", "수정 중인 내용을 취소하고 초기화하시겠습니까?", function () {
fn_selectHospitalJson(true);
});
});
// 병원 휴일 정보 수정 (신규 버튼 - 하단 일괄저장이 필요할 경우 사용)
$("#btnUpdateHospitalHoliday").click(function () {
fn_updateHospitalHoliday();
});
// [New] Row Add Button
$("#btnAddRow").click(function () {
fn_addRow();
});
// [New] Row Remove Button (Checked items)
$("#btnRemoveRow").click(function () {
let checkedRows = $("#hospitalHolidayList input[name='checkHolidayRow']:checked");
if (checkedRows.length > 0) {
modalEvent.info("삭제", "선택한 " + checkedRows.length + "개의 항목을 삭제하시겠습니까?", function () {
checkedRows.each(function () {
$(this).closest('li').remove();
});
// If no rows left, add one empty row? Or just leave header?
// fn_addRow2 logic adds header if length > 0, else calls fn_addRow.
// If we deleted all data rows, we should check if any data row exists.
// Header is li.list_title_li. Data rows are just li.
if ($("#hospitalHolidayList li").not(".list_title_li").length == 0) {
$('#hospitalHolidayList').append('<li class="no_data" style="width: 100%; text-align: center; padding: 20px 0;">지정한 휴일이 없습니다.</li>');
}
// Trigger DB update immediately (skip confirmation)
fn_updateHospitalHoliday(true);
});
} else {
modalEvent.warning("알림", "삭제할 항목을 선택해주세요.");
}
});
// [New] Check All
$(document).on("click", "#checkAllHolidays", function () {
$("#hospitalHolidayList input[name='checkHolidayRow']").prop("checked", $(this).is(":checked"));
});
}
/****************************************************************************
* 병원 휴일 행별 저장
****************************************************************************/
function fn_saveHospitalHolidayRow(btn) {
// Simply call the bulk update function which gathers all rows and saves them.
// This satisfies the "Save" action while maintaining data integrity with the backend's "Delete All -> Insert All" logic.
fn_updateHospitalHoliday();
}
/****************************************************************************
* 병원 휴일 정보 수정
****************************************************************************/
function fn_updateHospitalHoliday() {
let muHospitalId = $("#muHospitalId").val();
// 법정공휴일 사용 여부
let publicHolidayUseYn = $("#checkPublicHolidayUseYn").is(":checked") ? "Y" : "N";
// 병원 지정 휴일 리스트
let detailArray = new Object();
let holidayLi = $("#hospitalHolidayList li");
let liLength = holidayLi.length;
let tempArray = new Array();
for (let i = 1; i < liLength; i++) {
// Skip 'no_data' row
if (holidayLi.eq(i).hasClass('no_data')) continue;
let hospitalHolidayName = holidayLi.eq(i).find('input[name="hospitalHolidayName"]').val();
// Skip empty names to prevent null insertion
if (!hospitalHolidayName || hospitalHolidayName.trim() === "") continue;
let locDate = holidayLi.eq(i).find('input[name="dateLocDate"]').val();
let repeatYn = holidayLi.eq(i).find('input[name="repeatYn"]').val();
let arr_sub = new Object();
arr_sub.hospitalHolidayName = hospitalHolidayName;
arr_sub.locDate = locDate;
arr_sub.repeatYn = repeatYn;
tempArray.push(arr_sub);
}
detailArray.data = tempArray;
var updateFunc = function () {
let formData = new FormData();
// 기존 병원 정보 수정 로직과 동일한 엔드포인트를 사용하되, 휴일 관련 데이터만 전송
// 단, 서버 로직상 다른 필드가 필수라면 기존 값을 가져오거나, 별도 API가 필요할 수 있음.
// 현재 updateHospital 로직은 전체 필드를 업데이트하는 것으로 보이므로,
// 안전하게는 전체 데이터를 보내거나, 휴일만 업데이트하는 별도 로직이 권장됨.
// 여기서는 사용자의 요청에 따라 '별도로 저장' 기능을 구현하므로,
// 기존 updateHospital을 호출하되 휴일 데이터 위주로 처리하거나,
// 혹은 updateHospital 수정이 필요할 수 있음.
// *중요*: 사용자가 '운영시간' 탭의 내용은 '저장' 버튼으로, '운영스케쥴' 탭의 내용은 '휴일 저장' 버튼으로 저장하길 원함.
// 하지만 백엔드(updateHospital)가 하나 통으로 되어 있다면,
// 여기서도 다른 필드 값들을 다 채워서 보내야 에러가 안 날 수 있음 (MyBatis Query 확인 필요).
// 앞서 본 쿼리상 updateHospital은 모든 칼럼을 업데이트함.
// 따라서 여기서도 화면에 있는 모든 입력값을 다 읽어서 보내는 것이 안전함. (부분 업데이트 쿼리가 없다면)
// 하지만 '운영시간' 탭의 데이터 변경사항이 '휴일 저장' 버튼 누를 때 같이 저장되어도 되는지?
// 사용자 의도는 "별도로 저장할 수 있게" 이므로,
// 이상적으로는 휴일만 업데이트하는 API가 있어야 함.
// 현재 API 구조상 updateHospital을 재사용한다면 모든 데이터를 다 보내야 함.
// 일단 전체 데이터를 다 수집해서 보내되, 성공 메시지 등은 분리 처리.
// --- 전체 데이터 수집 시작 (fn_updateHospital 내용 복사) ---
formData.append("menuClass", menuClass);
formData.append("muHospitalId", muHospitalId);
// 운영시간 데이터도 현재 화면 값 그대로 전송 (null 방지)
formData.append("monOpenYn", $("#checkMonOpenYn").is(":checked") ? "Y" : "N");
formData.append("monOpenStartTime", $("#monOpenStartTime").val());
formData.append("monOpenEndTime", $("#monOpenEndTime").val());
formData.append("monBreakStartTime", $("#monBreakStartTime").val());
formData.append("monBreakEndTime", $("#monBreakEndTime").val());
formData.append("tueOpenYn", $("#checkTueOpenYn").is(":checked") ? "Y" : "N");
formData.append("tueOpenStartTime", $("#tueOpenStartTime").val());
formData.append("tueOpenEndTime", $("#tueOpenEndTime").val());
formData.append("tueBreakStartTime", $("#tueBreakStartTime").val());
formData.append("tueBreakEndTime", $("#tueBreakEndTime").val());
formData.append("wedOpenYn", $("#checkWedOpenYn").is(":checked") ? "Y" : "N");
formData.append("wedOpenStartTime", $("#wedOpenStartTime").val());
formData.append("wedOpenEndTime", $("#wedOpenEndTime").val());
formData.append("wedBreakStartTime", $("#wedBreakStartTime").val());
formData.append("wedBreakEndTime", $("#wedBreakEndTime").val());
formData.append("thuOpenYn", $("#checkThuOpenYn").is(":checked") ? "Y" : "N");
formData.append("thuOpenStartTime", $("#thuOpenStartTime").val());
formData.append("thuOpenEndTime", $("#thuOpenEndTime").val());
formData.append("thuBreakStartTime", $("#thuBreakStartTime").val());
formData.append("thuBreakEndTime", $("#thuBreakEndTime").val());
formData.append("friOpenYn", $("#checkFriOpenYn").is(":checked") ? "Y" : "N");
formData.append("friOpenStartTime", $("#friOpenStartTime").val());
formData.append("friOpenEndTime", $("#friOpenEndTime").val());
formData.append("friBreakStartTime", $("#friBreakStartTime").val());
formData.append("friBreakEndTime", $("#friBreakEndTime").val());
formData.append("satOpenYn", $("#checkSatOpenYn").is(":checked") ? "Y" : "N");
formData.append("satOpenStartTime", $("#satOpenStartTime").val());
formData.append("satOpenEndTime", $("#satOpenEndTime").val());
formData.append("satBreakStartTime", $("#satBreakStartTime").val());
formData.append("satBreakEndTime", $("#satBreakEndTime").val());
formData.append("sunOpenYn", $("#checkSunOpenYn").is(":checked") ? "Y" : "N");
formData.append("sunOpenStartTime", $("#sunOpenStartTime").val());
formData.append("sunOpenEndTime", $("#sunOpenEndTime").val());
formData.append("sunBreakStartTime", $("#sunBreakStartTime").val());
formData.append("sunBreakEndTime", $("#sunBreakEndTime").val());
// 휴일 데이터
formData.append("publicHolidayUseYn", publicHolidayUseYn);
formData.append("holidayRows", JSON.stringify(detailArray));
$.ajax({
url: encodeURI('/webhospital/updateHospital.do'),
data: formData,
dataType: "json",
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
if ('0' == data.msgCode) {
modalEvent.success("성공", "수정되었습니다.", function () {
// 캘린더 리렌더링
if (window.calendar) {
window.calendar.refetchEvents();
}
// 페이지 리로드 대신 필요한 부분만 갱신하거나 유지
// location.reload();
});
} else {
modalEvent.danger("오류", data.msgDesc);
}
},
error: function () {
modalEvent.danger("오류", "수정 중 오류가 발생했습니다.");
}
});
};
if (typeof arguments[0] !== 'undefined' && arguments[0] === true) {
updateFunc();
} else {
modalEvent.info("수정", "병원 휴일 정보를 수정하시겠습니까?", updateFunc);
}
}
$(function () {

View File

@@ -2,8 +2,33 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{/web/layout/homeLayout}">
<th:block layout:fragment="layout_css">
<link rel="stylesheet" href="/css/web/hospital.css?v1.1">
<link rel="stylesheet" href="/css/web/hospital_info.css?v1.1">
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.js'></script>
<style>
.project_wrap .content_section .hospital_wrap .center_box {
box-sizing: border-box;
overflow: hidden !important;
padding-bottom: 0 !important;
/* Ensure padding doesn't add to scroll height */
}
.project_wrap .content_section .hospital_wrap .center_box .tab_panel {
height: 100%;
overflow: hidden;
}
.project_wrap .content_section .hospital_wrap .center_box .tab_panel .tab-content {
height: calc(100% - 42px);
/* 42px is typical nav-tabs height */
overflow: hidden;
}
.project_wrap .content_section .hospital_wrap .center_box .tab_panel .tab-content .tab-pane {
height: 100%;
overflow: hidden;
}
</style>
</th:block>
<th:block layout:fragment="layout_top_script">
@@ -22,48 +47,116 @@
<input type="hidden" id="muHospitalId">
<!-- 센터쪽 -->
<div class="center_box">
<p class="page_title">병원 기본정보</p>
<div class="info_box">
<div class="info_left">
<div class="form_box first">
<div class="hospital_box" style="margin-top: 0;">
<!-- 달력 영역 -->
<div id='calendar' style="margin-bottom: 20px;"></div>
<ul class="hospital_list" id="hospitalHolidayList">
<li class="list_title_li">
<span class="list_title">휴일명</span>
<span class="list_title">날짜</span>
<span class="list_title">일정반복</span>
<span class="list_title"></span>
<!-- 탭 패널 추가 -->
<div class="tab_panel" role="tabpanel">
<!-- Nav tabs -->
<div class="nav_box">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#schedule" aria-controls="schedule" role="tab" data-toggle="tab">
<p>병원 운영스케쥴</p>
</a>
</li>
<li role="presentation">
<a href="#operatingHours" aria-controls="operatingHours" role="tab" data-toggle="tab">
<p>운영시간</p>
</a>
</li>
</ul>
</div>
<div class="holiday_box">
<p class="holiday_title">법정 공휴일</p>
<!-- Tab panes -->
<div class="tab-content">
<!-- 병원 운영스케쥴 탭 -->
<div role="tabpanel" class="tab-pane active" id="schedule">
<div class="info_box" style="display: flex; gap: 20px;">
<div class="check_holiday_box">
<div class="check_box">
<label for="checkPublicHolidayUseYn">
<input class="select_check_hide" type="checkbox" id="checkPublicHolidayUseYn"
name="checkPublicHolidayUseYn" value="Y">
<div class="select_check_show"></div>
</label>
</div>
<span>법정 공휴일 반영</span>
</div>
</div><!--content_box-->
<!-- 좌측: 달력 & 법정공휴일 -->
<div class="info_left" style="width: 50%; min-width: auto;">
<div class="form_box first">
<div class="hospital_box" style="margin-top: 0;">
<p class="title">병원 운영스케쥴</p>
<!-- 달력 영역 -->
<div id='calendar' style="margin-bottom: 20px;"></div>
<div class="calendar_guide"
style="padding: 15px; background: #f8f9fa; border-radius: 5px; font-size: 13px; color: #555;">
<p style="font-weight: bold; margin-bottom: 8px;">※ 달력 사용 가이드</p>
<ul style="list-style: disc; padding-left: 18px; line-height: 1.6;">
<li>날짜를 클릭하여 해당 일자의 운영/휴무 여부 및 시간을 개별 설정할 수 있습니다.</li>
<li>등록된 일정을 클릭하면 내용을 수정하거나 삭제할 수 있습니다.</li>
<li style="margin-top: 5px;">
<span style="margin-right: 10px;"><span style="color:#FF5252"></span>
법정공휴일</span>
<span style="margin-right: 10px;"><span style="color:#2ECC71"></span>
병원지정 휴일</span>
<span><span style="color:#f39c12"></span> 별도 스케줄</span>
</li>
</ul>
</div>
</div>
<div class="info_right">
</div>
</div>
<!-- 우측: 병원지정 휴일 -->
<div class="info_right" style="width: 50%; min-width: auto;">
<div class="form_box first">
<div class="hospital_box" style="margin-top: 0;">
<div class="hospital_title_box"
style="display: flex; justify-content: space-between; align-items: center;">
<p class="title" style="margin-bottom: 0; font-weight: bold; font-size: 16px;">
병원지정 휴일</p>
<div class="btn_group">
<button type="button" id="btnAddRow"
style="border: none; background: transparent; padding: 0; cursor: pointer; margin-right: 10px;">
<img src="/image/web/add.svg" alt="추가"
style="width: 24px; height: 24px; vertical-align: middle;">
</button>
<button type="button" id="btnRemoveRow"
style="border: none; background: transparent; padding: 0; cursor: pointer;">
<img src="/image/web/subtract.svg" alt="삭제"
style="width: 24px; height: 24px; vertical-align: middle;">
</button>
</div>
</div>
<ul class="hospital_list" id="hospitalHolidayList"
style="width: 100% !important; float: none !important; box-sizing: border-box; height: 450px; overflow-y: auto;">
<li class="list_title_li"
style="display: flex !important; width: 100% !important; margin: 0 !important; padding: 10px 0 !important; background: #EDF5FF; border-radius: 5px; float: none !important; position: sticky; top: 0; z-index: 10;">
<span class="list_title"
style="width: 40px !important; display: flex; justify-content: center; align-items: center; float: none !important; border: none !important;">
<input type="checkbox" id="checkAllHolidays">
</span>
<span class="list_title"
style="flex: 1 !important; text-align: center; float: none !important; border: none !important; width: auto !important;">휴일명</span>
<span class="list_title"
style="width: 140px !important; text-align: center; float: none !important; border: none !important;">날짜</span>
<span class="list_title"
style="width: 100px !important; text-align: center; float: none !important; border: none !important;">일정반복</span>
<span class="list_title"
style="width: 70px !important; text-align: center; float: none !important; border: none !important;">저장</span>
</li>
</ul>
<!-- 하단 일괄 저장 버튼은 row별 저장으로 대체되므로 제거하거나 숨김 처리, 일단 제거 -->
</div>
</div>
</div>
</div>
</div>
<!-- 운영시간 탭 -->
<div role="tabpanel" class="tab-pane" id="operatingHours">
<div class="info_box" style="display: flex; gap: 0;">
<div class="info_left"
style="width: 50%; min-width: auto; border-right: 1px solid #ddd; padding-right: 20px;">
<div class="form_box first">
<p class="title">운영시간</p>
<div class="time_box">
<p class="time_title">운영시간</p>
<ul class="time_list">
<li class="list_title_li">
@@ -82,10 +175,12 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="monOpenStartTime">
<ul class="select_option_list dropdown-menu" id="selMonOpenStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selMonOpenStartTime"></ul>
</div><!--select_box-->
</div>
@@ -94,10 +189,12 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="monOpenEndTime">
<ul class="select_option_list dropdown-menu" id="selMonOpenEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selMonOpenEndTime"></ul>
</div><!--select_box-->
</div>
</div>
@@ -106,9 +203,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="monBreakStartTime">
<ul class="select_option_list dropdown-menu" id="selMonBreakStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selMonBreakStartTime"></ul>
</div><!--select_box-->
</div>
@@ -117,16 +216,19 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="monBreakEndTime">
<ul class="select_option_list dropdown-menu" id="selMonBreakEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selMonBreakEndTime"></ul>
</div><!--select_box-->
</div>
</div>
<div class="wrapper_box">
<div class="wrapper">
<input type="checkbox" id="checkMonOpenYn" class="switch_input" value="Y">
<input type="checkbox" id="checkMonOpenYn" class="switch_input"
value="Y">
<label for="checkMonOpenYn" class="switch_label">
<span class="switch_btn"></span>
</label>
@@ -143,9 +245,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="tueOpenStartTime">
<ul class="select_option_list dropdown-menu" id="selTueOpenStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selTueOpenStartTime"></ul>
</div><!--select_box-->
</div>
@@ -154,9 +258,11 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="tueOpenEndTime">
<ul class="select_option_list dropdown-menu" id="selTueOpenEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selTueOpenEndTime"></ul>
</div><!--select_box-->
</div>
</div>
@@ -165,9 +271,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="tueBreakStartTime">
<ul class="select_option_list dropdown-menu" id="selTueBreakStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selTueBreakStartTime"></ul>
</div><!--select_box-->
</div>
@@ -176,16 +284,19 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="tueBreakEndTime">
<ul class="select_option_list dropdown-menu" id="selTueBreakEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selTueBreakEndTime"></ul>
</div><!--select_box-->
</div>
</div>
<div class="wrapper_box">
<div class="wrapper">
<input type="checkbox" id="checkTueOpenYn" class="switch_input" value="Y">
<input type="checkbox" id="checkTueOpenYn" class="switch_input"
value="Y">
<label for="checkTueOpenYn" class="switch_label">
<span class="switch_btn"></span>
</label>
@@ -202,9 +313,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="wedOpenStartTime">
<ul class="select_option_list dropdown-menu" id="selWedOpenStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selWedOpenStartTime"></ul>
</div><!--select_box-->
</div>
@@ -213,9 +326,11 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="wedOpenEndTime">
<ul class="select_option_list dropdown-menu" id="selWedOpenEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selWedOpenEndTime"></ul>
</div><!--select_box-->
</div>
</div>
@@ -224,9 +339,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="wedBreakStartTime">
<ul class="select_option_list dropdown-menu" id="selWedBreakStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selWedBreakStartTime"></ul>
</div><!--select_box-->
</div>
@@ -235,16 +352,19 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="wedBreakEndTime">
<ul class="select_option_list dropdown-menu" id="selWedBreakEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selWedBreakEndTime"></ul>
</div><!--select_box-->
</div>
</div>
<div class="wrapper_box">
<div class="wrapper">
<input type="checkbox" id="checkWedOpenYn" class="switch_input" value="Y">
<input type="checkbox" id="checkWedOpenYn" class="switch_input"
value="Y">
<label for="checkWedOpenYn" class="switch_label">
<span class="switch_btn"></span>
</label>
@@ -261,9 +381,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="thuOpenStartTime">
<ul class="select_option_list dropdown-menu" id="selThuOpenStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selThuOpenStartTime"></ul>
</div><!--select_box-->
</div>
@@ -272,9 +394,11 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="thuOpenEndTime">
<ul class="select_option_list dropdown-menu" id="selThuOpenEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selThuOpenEndTime"></ul>
</div><!--select_box-->
</div>
</div>
@@ -283,9 +407,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="thuBreakStartTime">
<ul class="select_option_list dropdown-menu" id="selThuBreakStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selThuBreakStartTime"></ul>
</div><!--select_box-->
</div>
@@ -294,16 +420,19 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="thuBreakEndTime">
<ul class="select_option_list dropdown-menu" id="selThuBreakEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selThuBreakEndTime"></ul>
</div><!--select_box-->
</div>
</div>
<div class="wrapper_box">
<div class="wrapper">
<input type="checkbox" id="checkThuOpenYn" class="switch_input" value="Y">
<input type="checkbox" id="checkThuOpenYn" class="switch_input"
value="Y">
<label for="checkThuOpenYn" class="switch_label">
<span class="switch_btn"></span>
</label>
@@ -320,9 +449,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="friOpenStartTime">
<ul class="select_option_list dropdown-menu" id="selFriOpenStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selFriOpenStartTime"></ul>
</div><!--select_box-->
</div>
@@ -331,9 +462,11 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="friOpenEndTime">
<ul class="select_option_list dropdown-menu" id="selFriOpenEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selFriOpenEndTime"></ul>
</div><!--select_box-->
</div>
</div>
@@ -342,9 +475,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="friBreakStartTime">
<ul class="select_option_list dropdown-menu" id="selFriBreakStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selFriBreakStartTime"></ul>
</div><!--select_box-->
</div>
@@ -353,16 +488,19 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="friBreakEndTime">
<ul class="select_option_list dropdown-menu" id="selFriBreakEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selFriBreakEndTime"></ul>
</div><!--select_box-->
</div>
</div>
<div class="wrapper_box">
<div class="wrapper">
<input type="checkbox" id="checkFriOpenYn" class="switch_input" value="Y">
<input type="checkbox" id="checkFriOpenYn" class="switch_input"
value="Y">
<label for="checkFriOpenYn" class="switch_label">
<span class="switch_btn"></span>
</label>
@@ -380,9 +518,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="satOpenStartTime">
<ul class="select_option_list dropdown-menu" id="selSatOpenStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selSatOpenStartTime"></ul>
</div><!--select_box-->
</div>
@@ -391,9 +531,11 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="satOpenEndTime">
<ul class="select_option_list dropdown-menu" id="selSatOpenEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selSatOpenEndTime"></ul>
</div><!--select_box-->
</div>
</div>
@@ -402,9 +544,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="satBreakStartTime">
<ul class="select_option_list dropdown-menu" id="selSatBreakStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selSatBreakStartTime"></ul>
</div><!--select_box-->
</div>
@@ -413,16 +557,19 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="satBreakEndTime">
<ul class="select_option_list dropdown-menu" id="selSatBreakEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selSatBreakEndTime"></ul>
</div><!--select_box-->
</div>
</div>
<div class="wrapper_box">
<div class="wrapper">
<input type="checkbox" id="checkSatOpenYn" class="switch_input" value="Y">
<input type="checkbox" id="checkSatOpenYn" class="switch_input"
value="Y">
<label for="checkSatOpenYn" class="switch_label">
<span class="switch_btn"></span>
</label>
@@ -440,9 +587,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="sunOpenStartTime">
<ul class="select_option_list dropdown-menu" id="selSunOpenStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selSunOpenStartTime"></ul>
</div><!--select_box-->
</div>
@@ -451,9 +600,11 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="sunOpenEndTime">
<ul class="select_option_list dropdown-menu" id="selSunOpenEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selSunOpenEndTime"></ul>
</div><!--select_box-->
</div>
</div>
@@ -462,9 +613,11 @@
<div class="select_list first">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="sunBreakStartTime">
<ul class="select_option_list dropdown-menu" id="selSunBreakStartTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selSunBreakStartTime"></ul>
</div><!--select_box-->
</div>
@@ -473,16 +626,19 @@
<div class="select_list">
<div class="select_box dropdown">
<button type="button" class="label" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>00:00</button>
aria-haspopup="true" aria-expanded="false"
disabled>00:00</button>
<input type="hidden" id="sunBreakEndTime">
<ul class="select_option_list dropdown-menu" id="selSunBreakEndTime"></ul>
<ul class="select_option_list dropdown-menu"
id="selSunBreakEndTime"></ul>
</div><!--select_box-->
</div>
</div>
<div class="wrapper_box">
<div class="wrapper">
<input type="checkbox" id="checkSunOpenYn" class="switch_input" value="Y">
<input type="checkbox" id="checkSunOpenYn" class="switch_input"
value="Y">
<label for="checkSunOpenYn" class="switch_label">
<span class="switch_btn"></span>
</label>
@@ -491,14 +647,43 @@
</li>
</ul>
</div>
</div>
<div class="button_box"
style="display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px;">
<button id="btnUpdateHospital" class="btn_blue"
style="width: 100px; height: 36px; background: #3985EA; color: #fff; border: none; border-radius: 5px; font-size: 14px; font-weight: bold; cursor: pointer;">저장</button>
<button id="btnCancelHospital" class="btn_gray"
style="width: 100px; height: 36px; background: #666; color: #fff; border: none; border-radius: 5px; font-size: 14px; font-weight: bold; cursor: pointer;">취소</button>
<div class="button_box">
<button id="btnUpdateHospital">저장</button>
</div>
</div>
</div>
</div>
<div class="info_right" style="width: 50%; min-width: auto; padding-left: 20px;">
<div class="form_box first">
<div class="holiday_box" style="margin-top: 0; border-top: none; padding-top: 0;">
<p class="title" style="margin-bottom: 10px;">법정 공휴일</p>
<div class="check_holiday_box">
<div class="check_box">
<label for="checkPublicHolidayUseYn">
<input class="select_check_hide" type="checkbox"
id="checkPublicHolidayUseYn" name="checkPublicHolidayUseYn"
value="Y">
<div class="select_check_show"></div>
</label>
</div>
<span>법정 공휴일 반영</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div class="form_box">
<p class="title">최고관리자 설정</p>
@@ -522,6 +707,76 @@
<form id="hospitalUpdateForm" onsubmit="return false;"></form>
</th:block>
<th:block layout:fragment="layout_popup">
<div id="schedulePopup" class="modal_layer"
style="display:none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 9999;">
<div class="modal_bg"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5);"></div>
<div class="modal_content"
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #fff; padding: 30px; border-radius: 10px; width: 500px;">
<div class="modal_title"
style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 1px solid #ddd; padding-bottom: 15px;">
<h3 style="font-size: 20px; font-weight: bold;">운영 스케줄 설정</h3>
<button type="button" onclick="fn_closeSchedulePopup();"
style="border: none; background: none; font-size: 20px; cursor: pointer;">X</button>
</div>
<div class="modal_body">
<input type="hidden" id="popMuHospitalScheduleId">
<div class="input_row" style="margin-bottom: 15px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold;">날짜</label>
<input type="text" id="popScheduleDate" readonly
style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 5px; background: #f5f5f5;">
</div>
<div class="input_row" style="margin-bottom: 15px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold;">운영여부</label>
<div style="display: flex; gap: 20px;">
<label style="display: flex; align-items: center; gap: 5px; cursor: pointer;">
<input type="radio" name="popOpenYn" value="Y" onchange="fn_changePopOpenYn(this)"> 운영
</label>
<label style="display: flex; align-items: center; gap: 5px; cursor: pointer;">
<input type="radio" name="popOpenYn" value="N" onchange="fn_changePopOpenYn(this)"> 휴무
</label>
</div>
</div>
<div id="popTimeArea">
<div class="input_row" style="margin-bottom: 15px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold;">운영시간</label>
<div style="display: flex; align-items: center; gap: 10px;">
<select id="popOpenStartTime"
style="width: 140px; padding: 10px; border: 1px solid #ddd; border-radius: 5px;"></select>
<span>~</span>
<select id="popOpenEndTime"
style="width: 140px; padding: 10px; border: 1px solid #ddd; border-radius: 5px;"></select>
</div>
</div>
<div class="input_row" style="margin-bottom: 15px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold;">휴게시간</label>
<div style="display: flex; align-items: center; gap: 10px;">
<select id="popBreakStartTime"
style="width: 140px; padding: 10px; border: 1px solid #ddd; border-radius: 5px;"></select>
<span>~</span>
<select id="popBreakEndTime"
style="width: 140px; padding: 10px; border: 1px solid #ddd; border-radius: 5px;"></select>
</div>
</div>
</div>
</div>
<div class="modal_footer"
style="display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; border-top: 1px solid #ddd; padding-top: 20px;">
<button type="button" onclick="fn_deleteSchedule();" id="btnDeleteSchedule"
style="padding: 5px 20px; background: #FF5252; color: #fff; border: none; border-radius: 5px; cursor: pointer; display: none;">삭제</button>
<button type="button" onclick="fn_closeSchedulePopup();"
style="padding: 5px 20px; background: #ddd; border: none; border-radius: 5px; cursor: pointer;">취소</button>
<button type="button" onclick="fn_saveSchedule();"
style="padding: 5px 20px; background: #3985EA; color: #fff; border: none; border-radius: 5px; cursor: pointer;">저장</button>
</div>
</div>
</div>
</th:block>
<th:block layout:fragment="layout_script">
<script src="/js/web/hospital/hospitalUpdate.js"></script>