diff --git a/src/main/java/com/madeu/config/MessageConfig.java b/src/main/java/com/madeu/config/MessageConfig.java new file mode 100644 index 0000000..b87be7b --- /dev/null +++ b/src/main/java/com/madeu/config/MessageConfig.java @@ -0,0 +1,24 @@ +package com.madeu.config; + +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Configuration; + +import com.madeu.util.MessageUtils; + +import jakarta.annotation.PostConstruct; + +@Configuration +public class MessageConfig { + + private final MessageSource messageSource; + + public MessageConfig(MessageSource messageSource) { + this.messageSource = messageSource; + } + + @PostConstruct + public void init() { + // 여기서 딱 한 번 MessageUtils의 static 필드에 값을 셋팅합니다. + MessageUtils.setMessageSource(messageSource); + } +} diff --git a/src/main/java/com/madeu/constants/Constants.java b/src/main/java/com/madeu/constants/Constants.java index 1c19a4d..86bc61d 100644 --- a/src/main/java/com/madeu/constants/Constants.java +++ b/src/main/java/com/madeu/constants/Constants.java @@ -39,6 +39,8 @@ public interface Constants { static final public String EBS_ID_UNEQUAL = "410"; // 사용자 정보가 없습니다. static final public String SERVER_ERROR = "서버 오류가 발생했습니다."; //서버 오류가 발생했습니다. + static final public String MSG_0001 = "접수되었습니다! 안내데스크에서 확인 후 바로 안내해 드릴게요. 잠시만 기다려 주세요."; + static final public String MSG_0002 = "오늘 예약은 확인되었습니다만, 현재 방문하신 시간이 예약 시간과 차이가 있어 안내데스크의 확인이 필요합니다. 데스크로 문의해 주시면 친절히 안내해 드리겠습니다."; } diff --git a/src/main/java/com/madeu/crm/kiosk/ctrl/KioskController.java b/src/main/java/com/madeu/crm/kiosk/ctrl/KioskController.java index a3bd068..efefc67 100644 --- a/src/main/java/com/madeu/crm/kiosk/ctrl/KioskController.java +++ b/src/main/java/com/madeu/crm/kiosk/ctrl/KioskController.java @@ -238,11 +238,12 @@ public class KioskController extends ManagerDraftAction { /** * 고객 등록 + * @throws Exception */ @PostMapping("/kiosk/putSubmit.do") - public KioskDTO putSubmit(@RequestBody KioskDTO dto) { - - return null; + public KioskDTO putSubmit(@RequestBody KioskDTO dto) throws Exception { + System.out.println("putSubmit getMuUserId:::: " + dto.getMuUserId()); + return kioskService.putSubmit(dto); } /** diff --git a/src/main/java/com/madeu/crm/kiosk/dto/KioskDTO.java b/src/main/java/com/madeu/crm/kiosk/dto/KioskDTO.java index 3de51ab..d5de403 100644 --- a/src/main/java/com/madeu/crm/kiosk/dto/KioskDTO.java +++ b/src/main/java/com/madeu/crm/kiosk/dto/KioskDTO.java @@ -8,7 +8,8 @@ import lombok.ToString; @Setter @ToString public class KioskDTO { - private String userNumber; // 고객명 + private String muUserId; // 고객ID + private String userNumber; // 고객번호 private String userName; // 고객명 private String birthday; // 생년월일 (YYYYMMDD) private String gender; // 성별 (M/F) diff --git a/src/main/java/com/madeu/crm/kiosk/dto/ReserveDTO.java b/src/main/java/com/madeu/crm/kiosk/dto/ReserveDTO.java new file mode 100644 index 0000000..38a64ba --- /dev/null +++ b/src/main/java/com/madeu/crm/kiosk/dto/ReserveDTO.java @@ -0,0 +1,80 @@ +package com.madeu.crm.kiosk.dto; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.LocalDateTime; + +@Getter +@Setter +@ToString +public class ReserveDTO { + + private String muReserveId; // 식별자 + private String userName; // 고객 이름 + private String muUserId; // 고객 식별자 + private LocalDate reserveDate; // 예약날짜 + private LocalTime reserveTime; // 예약시간 + private String reserveCategoryItemId; // 예약처 카테고리 식별자 + private String reserveCategoryItemName;// 예약처 카테고리 이름 + private String reserveAppYn; // 앱예약 유무 (Y/N) + private String reserveNaverYn; // 네이버 예약 유무 (Y/N) + private String muTreatmentId; // 진료 식별자 + private String treatmentName; // 진료명 + private String muTreatmentProcedureId; // 진료 시술 식별자 + private String treatmentProcedureName; // 진료 시술명 + private String reserveMemberId; // 의사, 상담자 식별자 + private String muMemberId; // 담당자 식별자 + private String etc; // 메모 + private String status; // 상태 (T, TN, R, RW, RN, G, Y) + private String status2; // 수납상태 (N, Y, C, P, R) + private String userCheckYn; // 사용자 확인 여부 + private LocalDate writeDate; // 작성일자 + private LocalTime writeTime; // 작성시간 + private String remark; // 비고 + private String cudFlag; // 작업타입 (C, U, D) + private String useYn; // 사용여부 + private String regId; // 등록자 + private LocalDateTime regDate; // 등록일자 + private String modId; // 수정자 + private LocalDateTime modDate; // 수정일자 + private String tId; // T_ID + private LocalDateTime tDate; // T_DATE + private LocalDateTime receptionDate; // 접수시간 + private String phoneNumber; // 고객 전화번호 + + // 네이버 예약 관련 필드 + private String naverReservationKey; // 네이버 예약 상품 키값 + private String naverBookingKey; // 네이버 예약 키값 + private String naverDateTime; // 네이버 예약 일자 및 시간 + private String naverName; // 네이버 예약 예약자 이름 + private String naverPhone; // 네이버 예약 예약자 전화번호 + private String naverState; // 네이버 예약상태 + private String naverUserId; // 네이버 예약 사용자 아이디 + + // 기존 CRM DB 연동 필드 + private String crmMemberSchedulePid; // 기존 DB 식별자 + private String crmMemberScheduleMbPid; // 기존 DB 고객 식별자 + private String crmMemberScheduleMbHp; // 기존 DB 고객 전화번호 + private String crmMemberScheduleResPid; // 기존 DB 예약종류 식별자 + private String crmMemberScheduleResPid2; // 기존 DB 시술분류 식별자 + private String crmMemberScheduleResPid3; + private String crmMemberScheduleResPid4; + private String crmMemberScheduleResPidName; // 기존 DB 예약종류 이름 + private String crmMemberScheduleResPid2Name; // 기존 DB 시술분류 이름 + private String crmMemberScheduleResPid3Name; + private String crmMemberScheduleResPid4Name; + private String crmMemberScheduleResEtc; // 기존 DB 시술분류 비고 + private String crmMemberScheduleRStaff3; // 기존 DB 시술의사 식별자 + private String crmMemberScheduleRStaff3Icon; + private String crmMemberScheduleRStaff3Name; // 기존 DB 시술의사 이름 + private String crmMemberScheduleResConsult; // 기존 DB 상담자 식별자 + private String crmMemberScheduleResConsultName; + private String crmMemberScheduleResAccept; // 기존 DB 담당자 식별자 + private String crmMemberScheduleResAcceptName; + private String crmMemberScheduleResState; // 기존 DB 예약상태 + private String reserveHomepageYn; // 홈페이지 예약 여부 + + private String id; +} diff --git a/src/main/java/com/madeu/crm/kiosk/map/KioskMAP.java b/src/main/java/com/madeu/crm/kiosk/map/KioskMAP.java index 102fcec..1daca40 100644 --- a/src/main/java/com/madeu/crm/kiosk/map/KioskMAP.java +++ b/src/main/java/com/madeu/crm/kiosk/map/KioskMAP.java @@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Mapper; import com.madeu.crm.kiosk.dto.ConsentFormDTO; import com.madeu.crm.kiosk.dto.KioskDTO; +import com.madeu.crm.kiosk.dto.ReserveDTO; import com.madeu.crm.kiosk.dto.UserDTO; @Mapper @@ -50,4 +51,10 @@ public interface KioskMAP { int insertUser(UserDTO dto); List selectUserByPhoneNumber(KioskDTO dto); + + List selectReserveByMuUserId(KioskDTO dto); + + int updateReserveStatus(ReserveDTO dto); + + int insertReserve(ReserveDTO dto); } \ No newline at end of file diff --git a/src/main/java/com/madeu/crm/kiosk/service/KioskService.java b/src/main/java/com/madeu/crm/kiosk/service/KioskService.java index c15b2f5..ec335ac 100644 --- a/src/main/java/com/madeu/crm/kiosk/service/KioskService.java +++ b/src/main/java/com/madeu/crm/kiosk/service/KioskService.java @@ -1,21 +1,27 @@ package com.madeu.crm.kiosk.service; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; import com.madeu.constants.Constants; import com.madeu.crm.kiosk.dto.ConsentFormDTO; import com.madeu.crm.kiosk.dto.KioskDTO; +import com.madeu.crm.kiosk.dto.ReserveDTO; import com.madeu.crm.kiosk.dto.UserDTO; import com.madeu.crm.kiosk.map.KioskMAP; import com.madeu.dao.web.webuser.WebUserSqlMapDAO; +import com.madeu.util.MessageUtils; import com.madeu.util.ValidationCheckUtil; import lombok.extern.slf4j.Slf4j; @@ -29,6 +35,7 @@ public class KioskService { @Autowired private WebUserSqlMapDAO webUserSqlMapDAO; + /** * 진료 리스트 조회 (option) */ @@ -314,6 +321,13 @@ public class KioskService { return kioskMAP.selectConsentForm(dto); } + + /** + * 폰번호로 사용자정보 조회 + * @param dto + * @return + * @throws Exception + */ public HashMap getUserByPhoneNumber(KioskDTO dto) throws Exception { HashMap map = new HashMap<>(); @@ -333,7 +347,59 @@ public class KioskService { return map; } - + public KioskDTO putSubmit(KioskDTO dto) throws Exception { + LocalTime now = LocalTime.now(); + /** + * 1. 예약된사람인지 확인 - 예약이 여러건일수도 있음. + * 2. 동의서 1년이 경과했는지 확인 + * 3. 예약 > 접수 가능 시간은 예약시간으로 앞뒤 한시간으로 정함 + * 4. + */ + + // 예약시간으로부터 앞뒤 한시간안에 해당 muUserId로 예약한 건이 있는지 조회 + List reserveList = kioskMAP.selectReserveByMuUserId(dto); + + if (ObjectUtils.isEmpty(reserveList)) { + + String muReserveId = ("R").concat(String.valueOf(System.currentTimeMillis())); + ReserveDTO insertDto = new ReserveDTO(); + insertDto.setMuReserveId(muReserveId); + insertDto.setUserName(dto.getUserName()); + insertDto.setMuUserId(dto.getMuUserId()); + insertDto.setStatus("RW"); + insertDto.setRegId("kiosk");; + + kioskMAP.insertReserve(insertDto); + + dto.setMsgCode(Constants.OK); + dto.setMsgDesc(MessageUtils.getMessage("reserve.checkin.success", dto.getUserName())); + } else { + + for (ReserveDTO reserveDTO : reserveList) { + + LocalTime reserveTime = reserveDTO.getReserveTime(); + + // 3. 현재 시간과 예약 시간의 차이 계산 (절댓값) + long minutesBetween = Math.abs(ChronoUnit.MINUTES.between(now, reserveTime)); + if (minutesBetween <= 60) { + reserveDTO.setStatus("R"); //접수 + kioskMAP.updateReserveStatus(reserveDTO); + dto.setMsgCode(Constants.OK); + dto.setMsgDesc(MessageUtils.getMessage("reserve.checkin.welcome", dto.getUserName())); + } else { + dto.setMsgCode(Constants.OK); + dto.setMsgDesc(MessageUtils.getMessage("reserve.checkin.time-mismatch", dto.getUserName())); + return dto; + } + + } + + } + + + + return dto; + } diff --git a/src/main/java/com/madeu/util/MessageUtils.java b/src/main/java/com/madeu/util/MessageUtils.java new file mode 100644 index 0000000..bf9e579 --- /dev/null +++ b/src/main/java/com/madeu/util/MessageUtils.java @@ -0,0 +1,19 @@ +package com.madeu.util; + +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; + +public class MessageUtils { + // static 필드 + private static MessageSource messageSource; + + // 외부(Config)에서 호출하여 주입할 메서드 + public static void setMessageSource(MessageSource messageSource) { + MessageUtils.messageSource = messageSource; + } + + public static String getMessage(String code, Object... args) { + if (messageSource == null) return code; // 초기화 전이라면 키값 그대로 반환 + return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1645c48..40d2b62 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -15,6 +15,19 @@ spring: aop: proxy-target-class: false + + messages: + # 메시지 파일의 경로와 기본 파일명 (src/main/resources 기준) + basename: messages + # 인코딩 설정 (한글 깨짐 방지를 위해 UTF-8 권장) + encoding: UTF-8 + # 메시지 파일을 찾지 못했을 때 시스템 언어를 사용할지 여부 + fallback-to-system-locale: true + # 설정한 로케일에 해당하는 파일이 없어도 에러를 내지 않고 기본 파일을 사용함 + use-code-as-default-message: true + # 메시지 변경 시 새로고침 주기 (초 단위, -1은 캐싱) + cache-duration: 3600 + server: encoding: diff --git a/src/main/resources/mappers/crm/kiosk/KioskMAP.xml b/src/main/resources/mappers/crm/kiosk/KioskMAP.xml index a235be4..d982006 100644 --- a/src/main/resources/mappers/crm/kiosk/KioskMAP.xml +++ b/src/main/resources/mappers/crm/kiosk/KioskMAP.xml @@ -710,4 +710,56 @@ ORDER BY CONSENT_FORM_VERSION DESC LIMIT 1 + + + + + UPDATE MU_RESERVE + SET STATUS = #{status} + WHERE MU_RESERVE_ID = #{muReserveId} -- 찾으려는 예약 ID + AND USE_YN = 'Y' -- 사용 중인 데이터 + AND STATUS = 'T' + + + + + SELECT CONCAT(#{muReserveId},LPAD((SELECT NEXTVAL(MU_RESERVE_SEQ)), 11, 0)) + + INSERT INTO MU_RESERVE ( + MU_RESERVE_ID, + USER_NAME, + MU_USER_ID, + RESERVE_DATE, + RESERVE_TIME, + STATUS, + WRITE_DATE, + WRITE_TIME, + CUD_FLAG, + USE_YN, + REG_ID, + MOD_ID + ) VALUES ( + #{id}, + #{userName}, + #{muUserId}, + CURDATE(), + CURTIME(), + #{status}, + CURDATE(), + CURTIME(), + 'C', + 'Y', + #{regId}, + #{regId} + ) + \ No newline at end of file diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties new file mode 100644 index 0000000..7b5f2f9 --- /dev/null +++ b/src/main/resources/messages.properties @@ -0,0 +1,9 @@ +# 공통 오류 +common.error.server=서버 오류가 발생했습니다. + +# 예약/접수 관련 (Reservation) +reserve.checkin.success=접수되었습니다! 안내데스크에서 확인 후 바로 안내해 드릴게요. 잠시만 기다려 주세요. +reserve.checkin.time-mismatch=오늘 예약은 확인되었습니다만, 방문하신 시간이 예약 시간과 차이가 있어 데스크 확인이 필요합니다. 안내데스크로 문의해 주세요. + +# 만약 파라미터를 쓴다면 (나중을 위해) +reserve.checkin.welcome={0}님, 접수가 완료되었습니다. 잠시만 기다려 주세요. \ No newline at end of file diff --git a/src/main/resources/templates/kiosk/existing-patient.html b/src/main/resources/templates/kiosk/existing-patient.html index 9ffac7b..af47073 100644 --- a/src/main/resources/templates/kiosk/existing-patient.html +++ b/src/main/resources/templates/kiosk/existing-patient.html @@ -251,7 +251,7 @@ let html = ""; if( res.msgCode == 0 ){ const userList = res.list; - + console.log(userList); if (!userList || userList.length === 0) { alert("조회된 정보가 없습니다."); return; @@ -260,7 +260,7 @@ userList.forEach((user, index) => { html += ` - + ${user.userName} ${user.birthday || '-'} ${user.gender === 'M' ? '남' : (user.gender === 'F' ? '여' : '-')} @@ -282,16 +282,44 @@ }); } - function submitBtn() { - const selectedUser = $("input[name='selectedUser']:checked"); - if (selectedUser.length === 0) { - alert("접수할 고객을 선택해 주세요."); - return; - } - const userName = selectedUser.val(); - alert(userName + "님 접수가 완료되었습니다."); - $("#customerDialog").dialog("close"); - } + function submitBtn() { + const selectedUser = $("input[name='selectedUser']:checked"); + + // 1. 선택 여부 확인 + if (selectedUser.length === 0) { + alert("접수할 고객을 선택해 주세요."); + return; + } + + // 2. 선택된 사용자의 식별값 (userNumber) 가져오기 + const muUserId = selectedUser.val(); + const userName = selectedUser.closest('tr').find('.user-name-cell').text(); + + // 3. 서버로 접수 정보 전송 (AJAX) + $.ajax({ + url: '/kiosk/putSubmit.do', // 실제 서버의 접수 처리 URL로 변경하세요 + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({ + muUserId: muUserId, + userName: userName + }), + success: function(res) { + if (res.msgCode == 0) { + alert(res.msgDesc); + $("#customerDialog").dialog("close"); + + // 접수 완료 후 메인 페이지로 이동하거나 초기화 + location.href = "/kiosk"; + } else { + alert(res.msgDesc); + } + }, + error: function() { + alert("서버 통신 중 오류가 발생했습니다."); + } + }); + } function moveKiosk() { window.location.href = "/kiosk";