From 9b6d4dc4c8f10c84d50604239935bd036c3e9d10 Mon Sep 17 00:00:00 2001 From: pjs Date: Sun, 1 Mar 2026 16:35:13 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=A0=EA=B0=9D=ED=9B=84=EA=B8=B0=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rules.md | 94 ++++ .../web/webreview/WebReviewController.java | 117 +++++ .../dao/web/webreview/WebReviewSqlMapDAO.java | 68 +++ .../web/webreview/WebReviewService.java | 9 + .../webreview/impl/WebReviewServiceImpl.java | 81 ++++ .../resources/mappers/WebReviewSqlMap.xml | 68 +++ .../web/webreview/procedureReviewSelect.css | 255 +++++++++++ .../webreview/procedureReviewSelectList.css | 412 ++++++++++++++++++ .../static/image/equip/온다리프팅.jpg | Bin 0 -> 44668 bytes .../static/image/quick_menu/review.png | Bin 0 -> 8344 bytes .../js/web/webreview/procedureReviewSelect.js | 117 +++++ .../webreview/procedureReviewSelectList.js | 259 +++++++++++ .../introductionHospitalSelect.html | 366 ++++++++-------- .../templates/web/layout/layoutHeader.html | 200 +++++---- .../web/webreview/procedureReviewSelect.html | 54 +++ .../webreview/procedureReviewSelectList.html | 44 ++ 16 files changed, 1865 insertions(+), 279 deletions(-) create mode 100644 rules.md create mode 100644 src/main/java/com/madeuhome/controller/web/webreview/WebReviewController.java create mode 100644 src/main/java/com/madeuhome/dao/web/webreview/WebReviewSqlMapDAO.java create mode 100644 src/main/java/com/madeuhome/service/web/webreview/WebReviewService.java create mode 100644 src/main/java/com/madeuhome/service/web/webreview/impl/WebReviewServiceImpl.java create mode 100644 src/main/resources/mappers/WebReviewSqlMap.xml create mode 100644 src/main/resources/static/css/web/webreview/procedureReviewSelect.css create mode 100644 src/main/resources/static/css/web/webreview/procedureReviewSelectList.css create mode 100644 src/main/resources/static/image/equip/온다리프팅.jpg create mode 100644 src/main/resources/static/image/quick_menu/review.png create mode 100644 src/main/resources/static/js/web/webreview/procedureReviewSelect.js create mode 100644 src/main/resources/static/js/web/webreview/procedureReviewSelectList.js create mode 100644 src/main/resources/templates/web/webreview/procedureReviewSelect.html create mode 100644 src/main/resources/templates/web/webreview/procedureReviewSelectList.html diff --git a/rules.md b/rules.md new file mode 100644 index 0000000..98b2bff --- /dev/null +++ b/rules.md @@ -0,0 +1,94 @@ +# 프로젝트 코딩 가이드라인 (Java Backend) + +AI 에디터(Agent)는 다음 규칙을 항상 준수하여 코드를 작성하고 수정해야 합니다. + +## 0. 기본 소통 규칙 (Communication) +- **언어**: 사용자에 대한 모든 답변과 코드 설명은 항상 **한글(Korean)**로만 작성해야 합니다. + +## 1. 패키지 구성 (Package Structure) +- **베이스 패키지**: `com.madeuhome` +- **컨트롤러 (Controller)**: `ctrl` +- **서비스 (Service)**: `svc` +- **DTO (Data Transfer Object)**: `dto` +- **매퍼 (Mapper)**: `mapper` +- **공통 서비스**: `com.madeuhome.common.service` (LogHistoryService 등 시스템 공통 모듈) + +## 2. 파일 명명 규칙 및 구성 (File Naming Conventions) +- **컨트롤러 (Controller)**: `[도메인명]Controller.java` (예: `ABCDController.java`) +- **서비스 (Service)**: `[도메인명]Service.java` (인터페이스와 구현체(impl)를 분리하지 않고 Service 클래스 파일 하나로만 구현, 예: `ABCDService.java`) +- **DTO**: `[도메인명]DTO.java` (예: `ABCDDTO.java`) +- **매퍼 (Mapper)**: `[도메인명]Mapper.java` (예: `ABCDMapper.java`) +- **XML Mapper**: `[도메인명]SqlMap.xml` (namespace는 Mapper 인터페이스의 **FQCN**과 반드시 일치) + +## 3. URL 및 메소드 명명 규칙 (RequestMapping & Method Naming) + +### 1) RequestMapping (URL) 및 컨트롤러 메소드명 +- 페이지 이동하는 url : `moveXXXX.do` +- 팝업 오픈하는 url : `openXXXX.do` +- 조회 url : `getXXXX.do` +- 저장 url : `putXXXX.do` +- 수정 url : `modXXXX.do` +- 삭제 url : `delXXXX.do` +- **단, 컨트롤러 메소드명은 위 url에서 `.do`를 제외한 이름과 동일하게 명명합니다.** + +### 2) 서비스 메소드명 +- 서비스 메소드명은 **컨트롤러 메소드명과 동일**하게 명명합니다. + - 조회: `getXXXX` / 목록 조회: `getXXXXList` + - 저장: `putXXXX` + - 수정: `modXXXX` + - 삭제: `delXXXX` + +### 3) Mapper 인터페이스 메소드명 +- 단일조회 : `selectXXXX` +- 리스트조회 : `selectListXXXX` +- insert : `insertXXXX` +- update : `updateXXXX` +- delete : `deleteXXXX` + +## 4. 데이터베이스 연동 정보 (DB Connection) +- `application-local.yml`의 설정을 기반으로 한 공통 접속 정보입니다. +- **Host**: 183.98.184.84 +- **Port**: 3306 +- **Database**: madeu +- **User**: madeu +- **Password**: apdlemdb12#$ + +## 5. 아키텍처 및 코딩 원칙 (Architecture & Coding Principles) + +### 5-1. 컨트롤러 원칙 (Skinny Controller) +- 컨트롤러에는 비즈니스 로직이나 예외처리 로직을 넣지 않고, **서비스 메서드를 호출하는 1줄로만 작성**합니다. +- 컨트롤러 클래스는 `@Controller` 대신 **`@RestController`**를 사용하며, `@ResponseBody`는 생략합니다. +- 데이터 입출력 메소드의 파라미터는 **단일 DTO 하나만 `@RequestBody`**로 받습니다. +- 파일 업로드가 포함된 경우에만 `@ModelAttribute` + `@RequestParam MultipartFile`을 허용합니다. +- 화면 이동(`move~`) 메소드는 **`ModelAndView`를 리턴**합니다. (`@RestController`에서 String 리턴 시 뷰 이름이 아닌 응답 바디로 해석되므로) +- 화면 이동 메소드의 뷰 경로는 **컨트롤러에서 직접 명시**합니다. (서비스에 위임 금지) + +### 5-2. 서비스 원칙 (Service Layer) +- 에러 처리(try-catch), 응답 메시지(msgCode, msgDesc) 설정은 **서비스 계층에서 전담**합니다. +- `HttpServletRequest`, `HttpSession`은 `@Autowired`로 직접 주입받아 사용합니다. (Spring이 Request-scope 프록시로 제공) +- `session.getAttribute("loginMemberId")`를 통해 로그인 ID를 가져오고, DTO에 설정합니다. + +### 5-3. DTO 원칙 (DTO Communication) +- **HashMap 사용 금지**. 컨트롤러 ↔ 서비스 ↔ 매퍼 간 모든 데이터는 **DTO 객체만 사용**합니다. +- DTO에는 `@Data` (Lombok)을 사용합니다. +- DTO 필드 구성: + - **DB 컬럼 매핑 필드**: `muProcedureReviewId`, `title`, `content` 등 + - **조회 결과 전용 필드**: `rowNum`, `writeDate`, `writeName` 등 + - **검색/UI 변수**: `startDate`, `endDate`, `start`, `limit`, `sort`, `dir` 등 + - **응답 매핑 변수**: `msgCode`, `msgDesc`, `success`, `totalCount`, `rows`(Object 타입), `tId` + +### 5-4. Mapper 원칙 (MyBatis Mapper) +- Mapper는 **`@Mapper` 어노테이션을 사용한 인터페이스**로 작성합니다. (`SqlSessionDaoSupport` 상속 금지) +- XML Mapper의 `namespace`는 Mapper 인터페이스의 **FQCN(Fully Qualified Class Name)**과 일치시킵니다. +- XML의 `resultType`은 `hashmap` 대신 **DTO FQCN**을 사용합니다. + - 예외: 도메인 외부 테이블 조회(카테고리 등)는 `hashmap` 허용 +- XML alias는 **DTO 필드명(camelCase)**과 정확히 일치시킵니다. +- 단건 조회는 `List` 대신 **DTO 단일 객체를 리턴**합니다. + +## 6. 파일 업로드 규칙 (File Upload) +- `MultipartFile.transferTo()` 사용 시 반드시 **절대경로를 명시**합니다: + ```java + File dest = new File(outDir, savedName); + file.transferTo(dest.toPath().toAbsolutePath()); + ``` +- 상대경로 사용 시 Tomcat 임시 디렉토리 기준으로 해석되어 오류가 발생합니다. diff --git a/src/main/java/com/madeuhome/controller/web/webreview/WebReviewController.java b/src/main/java/com/madeuhome/controller/web/webreview/WebReviewController.java new file mode 100644 index 0000000..0b1c10e --- /dev/null +++ b/src/main/java/com/madeuhome/controller/web/webreview/WebReviewController.java @@ -0,0 +1,117 @@ +package com.madeuhome.controller.web.webreview; + +import com.madeuhome.constants.Constants; +import com.madeuhome.init.ManagerDraftAction; +import com.madeuhome.service.web.webreview.WebReviewService; +import com.madeuhome.util.HttpUtil; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +import java.util.HashMap; + +@Slf4j +@Controller +public class WebReviewController extends ManagerDraftAction { + + @Autowired + private WebReviewService webReviewService; + + /** + * 시술후기 리스트 화면으로 이동 + */ + @RequestMapping(value = "/webreview/selectListProcedureReviewIntro.do") + public String selectListProcedureReviewIntro(HttpSession session, HttpServletRequest request) { + log.debug("WebReviewController selectListProcedureReviewIntro START"); + log.debug("WebReviewController selectListProcedureReviewIntro END"); + return "/web/webreview/procedureReviewSelectList"; + } + + /** + * 시술후기 리스트 조회 (AJAX) + */ + @RequestMapping(value = "/webreview/selectListProcedureReview.do") + public ModelAndView selectListProcedureReview(HttpSession session, HttpServletRequest request, + HttpServletResponse response) { + log.debug("WebReviewController selectListProcedureReview START"); + + HashMap paramMap = HttpUtil.getParameterMap(request); + HashMap map = new HashMap(); + StringBuffer errorMsg = new StringBuffer(); + + try { + map = webReviewService.selectListProcedureReview(paramMap); + } catch (Exception e) { + e.printStackTrace(); + errorMsg.append(e); + return null; + } finally { + if (Constants.OK == map.get("msgCode")) { + } else { + if (null == map.get("msgCode") || ("").equals(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("WebReviewController selectListProcedureReview END"); + return HttpUtil.makeHashToJsonModelAndView(map); + } + + /** + * 시술후기 상세 화면으로 이동 + */ + @RequestMapping(value = "/webreview/selectProcedureReviewIntro.do") + public String selectProcedureReviewIntro(HttpSession session, HttpServletRequest request, Model model) { + log.debug("WebReviewController selectProcedureReviewIntro START"); + HashMap paramMap = HttpUtil.getParameterMap(request); + model.addAttribute("muProcedureReviewId", paramMap.get("muProcedureReviewId")); + log.debug("WebReviewController selectProcedureReviewIntro END"); + return "/web/webreview/procedureReviewSelect"; + } + + /** + * 시술후기 상세 조회 (AJAX) + */ + @RequestMapping(value = "/webreview/selectProcedureReview.do") + public ModelAndView selectProcedureReview(HttpSession session, HttpServletRequest request, + HttpServletResponse response) { + log.debug("WebReviewController selectProcedureReview START"); + + HashMap paramMap = HttpUtil.getParameterMap(request); + HashMap map = new HashMap(); + StringBuffer errorMsg = new StringBuffer(); + + try { + map = webReviewService.selectProcedureReview(paramMap); + } catch (Exception e) { + e.printStackTrace(); + errorMsg.append(e); + return null; + } finally { + if (Constants.OK == map.get("msgCode")) { + } else { + if (null == map.get("msgCode") || ("").equals(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("WebReviewController selectProcedureReview END"); + return HttpUtil.makeHashToJsonModelAndView(map); + } +} diff --git a/src/main/java/com/madeuhome/dao/web/webreview/WebReviewSqlMapDAO.java b/src/main/java/com/madeuhome/dao/web/webreview/WebReviewSqlMapDAO.java new file mode 100644 index 0000000..fb401dd --- /dev/null +++ b/src/main/java/com/madeuhome/dao/web/webreview/WebReviewSqlMapDAO.java @@ -0,0 +1,68 @@ +package com.madeuhome.dao.web.webreview; + +import jakarta.annotation.PostConstruct; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.support.SqlSessionDaoSupport; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.stereotype.Repository; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Repository +public class WebReviewSqlMapDAO extends SqlSessionDaoSupport { + + @Autowired + private SqlSessionTemplate sqlSessionTemplate; + + @PostConstruct + void init() { + setSqlSessionTemplate(sqlSessionTemplate); + } + + /** + * 시술후기 전체 건수 조회 + */ + public Map selectTotalProcedureReviewCount(HashMap paramMap) + throws DataAccessException { + logger.debug("WebReviewSqlMapDAO selectTotalProcedureReviewCount START"); + String sqlId = "WebReview.selectTotalProcedureReviewCount"; + logger.debug("WebReviewSqlMapDAO selectTotalProcedureReviewCount END"); + return getSqlSession().selectOne(sqlId, paramMap); + } + + /** + * 시술후기 리스트 조회 + */ + public List> selectListProcedureReview(HashMap paramMap) + throws DataAccessException { + logger.debug("WebReviewSqlMapDAO selectListProcedureReview START"); + String sqlId = "WebReview.selectListProcedureReview"; + logger.debug("WebReviewSqlMapDAO selectListProcedureReview END"); + return getSqlSession().selectList(sqlId, paramMap); + } + + /** + * 시술후기 상세 조회 + */ + public Map selectProcedureReview(HashMap paramMap) + throws DataAccessException { + logger.debug("WebReviewSqlMapDAO selectProcedureReview START"); + String sqlId = "WebReview.selectProcedureReview"; + logger.debug("WebReviewSqlMapDAO selectProcedureReview END"); + return getSqlSession().selectOne(sqlId, paramMap); + } + + /** + * 시술후기 조회수 증가 + */ + public void updateViewCount(HashMap paramMap) + throws DataAccessException { + logger.debug("WebReviewSqlMapDAO updateViewCount START"); + String sqlId = "WebReview.updateViewCount"; + getSqlSession().update(sqlId, paramMap); + logger.debug("WebReviewSqlMapDAO updateViewCount END"); + } +} diff --git a/src/main/java/com/madeuhome/service/web/webreview/WebReviewService.java b/src/main/java/com/madeuhome/service/web/webreview/WebReviewService.java new file mode 100644 index 0000000..160cc9c --- /dev/null +++ b/src/main/java/com/madeuhome/service/web/webreview/WebReviewService.java @@ -0,0 +1,9 @@ +package com.madeuhome.service.web.webreview; + +import java.util.HashMap; + +public interface WebReviewService { + public HashMap selectListProcedureReview(HashMap paramMap) throws Exception; + + public HashMap selectProcedureReview(HashMap paramMap) throws Exception; +} diff --git a/src/main/java/com/madeuhome/service/web/webreview/impl/WebReviewServiceImpl.java b/src/main/java/com/madeuhome/service/web/webreview/impl/WebReviewServiceImpl.java new file mode 100644 index 0000000..eb05f20 --- /dev/null +++ b/src/main/java/com/madeuhome/service/web/webreview/impl/WebReviewServiceImpl.java @@ -0,0 +1,81 @@ +package com.madeuhome.service.web.webreview.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.madeuhome.constants.Constants; +import com.madeuhome.dao.web.webreview.WebReviewSqlMapDAO; +import com.madeuhome.service.web.webreview.WebReviewService; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service("WebReviewService") +public class WebReviewServiceImpl implements WebReviewService { + + @Autowired + private WebReviewSqlMapDAO webReviewSqlMapDAO; + + /** + * 시술후기 리스트 조회 + */ + @Override + public HashMap selectListProcedureReview(HashMap paramMap) throws Exception { + log.debug("WebReviewServiceImpl selectListProcedureReview START"); + + HashMap map = new HashMap(); + + try { + // 전체 건수 조회 + Map totalMap = webReviewSqlMapDAO.selectTotalProcedureReviewCount(paramMap); + map.put("totalCount", totalMap.get("totalCount")); + + // 리스트 조회 + List> listMap = webReviewSqlMapDAO.selectListProcedureReview(paramMap); + map.put("rows", listMap); + + map.put("msgCode", Constants.OK); + map.put("success", "true"); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + + log.debug("WebReviewServiceImpl selectListProcedureReview END"); + return map; + } + + /** + * 시술후기 상세 조회 + */ + @Override + public HashMap selectProcedureReview(HashMap paramMap) throws Exception { + log.debug("WebReviewServiceImpl selectProcedureReview START"); + + HashMap map = new HashMap(); + + try { + // 조회수 증가 + webReviewSqlMapDAO.updateViewCount(paramMap); + + // 상세 조회 + Map detailMap = webReviewSqlMapDAO.selectProcedureReview(paramMap); + map.put("rows", detailMap); + + map.put("msgCode", Constants.OK); + map.put("success", "true"); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + + log.debug("WebReviewServiceImpl selectProcedureReview END"); + return map; + } +} diff --git a/src/main/resources/mappers/WebReviewSqlMap.xml b/src/main/resources/mappers/WebReviewSqlMap.xml new file mode 100644 index 0000000..55b3f0d --- /dev/null +++ b/src/main/resources/mappers/WebReviewSqlMap.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + UPDATE MU_PROCEDURE_REVIEW + SET VIEW_COUNT = IFNULL(VIEW_COUNT, 0) + 1 + WHERE USE_YN = 'Y' + AND MU_PROCEDURE_REVIEW_ID = #{muProcedureReviewId} + + + diff --git a/src/main/resources/static/css/web/webreview/procedureReviewSelect.css b/src/main/resources/static/css/web/webreview/procedureReviewSelect.css new file mode 100644 index 0000000..5dcaa01 --- /dev/null +++ b/src/main/resources/static/css/web/webreview/procedureReviewSelect.css @@ -0,0 +1,255 @@ +* { + box-sizing: border-box; +} + +html, +body { + height: 100vh; + margin: 0; + padding: 0; + font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + background: #f8f9fa; + color: #1a1a1a; + overflow-x: hidden; + font-size: 16px; + line-height: 1.6; +} + +.container { + max-width: 900px; + width: 100%; + margin: 0 auto; + min-height: calc(100vh - 300px); + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +/* 브레드크럼 */ +.breadcrumb { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.875rem; + color: #9ca3af; + padding: 0.5rem 0; +} + +.breadcrumb a { + color: #6b7280; + text-decoration: none; + transition: color 0.2s; +} + +.breadcrumb a:hover { + color: #C60B24; +} + +/* 게시글 */ +.review-article { + background: white; + border-radius: 16px; + box-shadow: 0 2px 16px rgba(0, 0, 0, 0.06); + overflow: hidden; +} + +.review-header { + padding: 2rem 2rem 1.5rem; + border-bottom: 1px solid #f1f5f9; +} + +.review-title { + font-size: clamp(1.375rem, 3vw, 1.75rem); + font-weight: 700; + color: #1a1a1a; + margin: 0 0 1rem; + letter-spacing: -0.025em; + line-height: 1.4; +} + +.review-meta { + display: flex; + gap: 1.5rem; + font-size: 0.875rem; + color: #9ca3af; + margin-bottom: 0.75rem; +} + +.review-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.review-tag { + display: inline-block; + padding: 0.25rem 0.75rem; + background: rgba(198, 11, 36, 0.08); + color: #C60B24; + border-radius: 20px; + font-size: 0.8125rem; + font-weight: 500; +} + +/* Quill 에디터 본문 */ +.review-content { + padding: 2rem; + min-height: 300px; +} + +.review-content img { + max-width: 100%; + height: auto; + border-radius: 8px; + margin: 0.5rem 0; +} + +.review-content p { + margin: 0 0 0.75rem; + line-height: 1.8; +} + +.review-content h1, +.review-content h2, +.review-content h3 { + margin: 1.5rem 0 0.75rem; + font-weight: 700; +} + +.review-content blockquote { + border-left: 4px solid #C60B24; + padding: 0.75rem 1rem; + margin: 1rem 0; + background: #fafafa; + border-radius: 0 8px 8px 0; +} + +.review-content ul, +.review-content ol { + padding-left: 1.5rem; + margin: 0.5rem 0; +} + +.review-content li { + margin: 0.25rem 0; + list-style: inherit; +} + +/* Quill 에디터 특수 클래스 */ +.ql-editor .ql-align-center { + text-align: center; +} + +.ql-editor .ql-align-right { + text-align: right; +} + +.ql-editor .ql-align-justify { + text-align: justify; +} + +.ql-editor .ql-indent-1 { + padding-left: 3em; +} + +.ql-editor .ql-indent-2 { + padding-left: 6em; +} + +.ql-editor .ql-indent-3 { + padding-left: 9em; +} + +.ql-editor .ql-size-small { + font-size: 0.75em; +} + +.ql-editor .ql-size-large { + font-size: 1.5em; +} + +.ql-editor .ql-size-huge { + font-size: 2.5em; +} + +.ql-editor .ql-font-serif { + font-family: Georgia, 'Times New Roman', serif; +} + +.ql-editor .ql-font-monospace { + font-family: 'Monaco', 'Courier New', monospace; +} + +/* 목록 버튼 */ +.btn-area { + display: flex; + justify-content: center; + padding-bottom: 2rem; +} + +.btn-list { + display: inline-flex; + align-items: center; + padding: 0.75rem 2.5rem; + background: white; + color: #1a1a1a; + border: 1px solid #e5e7eb; + border-radius: 10px; + font-size: 0.9375rem; + font-weight: 600; + text-decoration: none; + transition: all 0.2s; +} + +.btn-list:hover { + border-color: #C60B24; + color: #C60B24; + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); +} + +/* 로딩 */ +.loading { + text-align: center; + padding: 3rem; + color: #6b7280; +} + +/* 반응형 */ +@media (max-width: 768px) { + .container { + padding: 1rem; + gap: 1rem; + } + + .review-header { + padding: 1.5rem; + } + + .review-content { + padding: 1.5rem; + } + + .review-title { + font-size: 1.25rem; + } + + .review-meta { + flex-direction: column; + gap: 0.25rem; + } +} + +@media (max-width: 480px) { + .container { + padding: 0.75rem; + } + + .review-header { + padding: 1rem; + } + + .review-content { + padding: 1rem; + } +} \ No newline at end of file diff --git a/src/main/resources/static/css/web/webreview/procedureReviewSelectList.css b/src/main/resources/static/css/web/webreview/procedureReviewSelectList.css new file mode 100644 index 0000000..783f850 --- /dev/null +++ b/src/main/resources/static/css/web/webreview/procedureReviewSelectList.css @@ -0,0 +1,412 @@ +* { + box-sizing: border-box; +} + +html, +body { + height: 100vh; + margin: 0; + padding: 0; + font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + background: #f8f9fa; + color: #1a1a1a; + overflow-x: hidden; + font-size: 16px; + line-height: 1.6; +} + +/* 메인 컨테이너 */ +.container { + max-width: 1280px; + width: 100%; + margin: 0 auto; + min-height: calc(100vh - 300px); + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +/* 상단 헤더 */ +.header { + background: white; + border-radius: 16px; + box-shadow: 0 2px 16px rgba(0, 0, 0, 0.06); + padding: 1.5rem 2rem; + border-bottom: 3px solid #C60B24; +} + +.page-title { + font-size: clamp(1.5rem, 3vw, 1.875rem); + font-weight: 700; + color: #1a1a1a; + margin: 0; + letter-spacing: -0.025em; +} + +.page-subtitle { + font-size: 0.95rem; + color: #6b7280; + margin: 0.25rem 0 0; +} + +/* 검색 영역 */ +.search-area { + display: flex; + justify-content: flex-end; +} + +.search-box { + display: flex; + gap: 0.5rem; +} + +.search-box input { + width: 280px; + padding: 0.625rem 1rem; + border: 1px solid #e5e7eb; + border-radius: 10px; + font-size: 0.9375rem; + outline: none; + transition: border-color 0.2s; +} + +.search-box input:focus { + border-color: #C60B24; +} + +.search-btn { + padding: 0.625rem 1.25rem; + background: #C60B24; + color: white; + border: none; + border-radius: 10px; + font-size: 0.9375rem; + font-weight: 600; + cursor: pointer; + transition: background 0.2s; +} + +.search-btn:hover { + background: #a5091e; +} + +/* 시술후기 그리드 */ +.review-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); + gap: 1.5rem; +} + +/* 카드 */ +.review-card { + background: white; + border-radius: 16px; + box-shadow: 0 2px 16px rgba(0, 0, 0, 0.06); + overflow: hidden; + transition: all 0.3s ease; + border: 1px solid #f1f5f9; + cursor: pointer; + display: flex; + flex-direction: column; +} + +.review-card:hover { + transform: translateY(-4px); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12); + border-color: #C60B24; +} + +/* ===== 이미지 슬라이더 ===== */ +.review-slider { + position: relative; + width: 100%; + aspect-ratio: 4 / 3; + overflow: hidden; + background: #f1f5f9; +} + +.review-slider-track { + display: flex; + width: 100%; + height: 100%; + transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +.review-slider-track img { + min-width: 100%; + max-width: 100%; + height: 100%; + object-fit: cover; + flex-shrink: 0; +} + +/* 슬라이더 화살표 */ +.slider-arrow { + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 32px; + height: 32px; + background: rgba(0, 0, 0, 0.45); + color: white; + border: none; + border-radius: 50%; + font-size: 14px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 0.25s; + z-index: 2; + line-height: 1; +} + +.review-slider:hover .slider-arrow { + opacity: 1; +} + +.slider-arrow.prev { + left: 8px; +} + +.slider-arrow.next { + right: 8px; +} + +.slider-arrow:hover { + background: rgba(0, 0, 0, 0.7); +} + +/* 슬라이더 도트 */ +.slider-dots { + position: absolute; + bottom: 8px; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 5px; + z-index: 2; +} + +.slider-dot { + width: 7px; + height: 7px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.5); + border: none; + cursor: pointer; + padding: 0; + transition: all 0.25s; +} + +.slider-dot.active { + background: white; + transform: scale(1.3); +} + +/* 이미지 카운트 뱃지 */ +.slider-count { + position: absolute; + top: 10px; + right: 10px; + background: rgba(0, 0, 0, 0.55); + color: white; + font-size: 0.75rem; + padding: 2px 8px; + border-radius: 12px; + z-index: 2; +} + +/* 이미지 없을 때 */ +.review-no-image { + width: 100%; + aspect-ratio: 4 / 3; + background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%); + display: flex; + align-items: center; + justify-content: center; + font-size: 2.5rem; + color: #cbd5e1; +} + +/* 카드 바디 */ +.review-card-body { + padding: 1.25rem 1.5rem 1.5rem; + flex: 1; + display: flex; + flex-direction: column; +} + +.review-card-title { + font-size: 1.0625rem; + font-weight: 700; + color: #1a1a1a; + margin-bottom: 0.5rem; + letter-spacing: -0.025em; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.review-card-summary { + color: #6b7280; + font-size: 0.8125rem; + line-height: 1.6; + flex: 1; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + margin-bottom: 0.75rem; +} + +.review-card-tags { + display: flex; + flex-wrap: wrap; + gap: 0.375rem; + margin-bottom: 0.75rem; +} + +.review-tag { + display: inline-block; + padding: 0.2rem 0.5rem; + background: rgba(198, 11, 36, 0.08); + color: #C60B24; + border-radius: 20px; + font-size: 0.6875rem; + font-weight: 500; +} + +.review-card-footer { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 0.8125rem; + color: #9ca3af; +} + +.review-card-footer .views { + display: flex; + align-items: center; + gap: 0.25rem; +} + +/* 페이지네이션 */ +.pagination-area { + display: flex; + justify-content: center; + gap: 0.375rem; + padding: 1rem 0 2rem; +} + +.page-btn { + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + border: 1px solid #e5e7eb; + background: white; + border-radius: 8px; + font-size: 0.875rem; + color: #6b7280; + cursor: pointer; + transition: all 0.2s; +} + +.page-btn:hover { + border-color: #C60B24; + color: #C60B24; +} + +.page-btn.active { + background: #C60B24; + color: white; + border-color: #C60B24; +} + +.page-btn.disabled { + opacity: 0.4; + cursor: default; +} + +/* 로딩 & 빈상태 */ +.loading { + text-align: center; + padding: 3rem; + color: #6b7280; + font-size: 0.9375rem; + grid-column: 1 / -1; +} + +.empty-state { + text-align: center; + padding: 4rem 2rem; + grid-column: 1 / -1; +} + +.empty-state .icon { + font-size: 3rem; + margin-bottom: 1rem; +} + +.empty-state .message { + font-size: 1.125rem; + color: #6b7280; + font-weight: 500; +} + +/* 반응형 */ +@media (max-width: 768px) { + .container { + padding: 1rem; + gap: 1rem; + } + + .header { + padding: 1rem 1.5rem; + border-radius: 12px; + } + + .page-title { + font-size: clamp(1.25rem, 2.5vw, 1.5rem); + } + + .review-grid { + grid-template-columns: 1fr; + gap: 1rem; + } + + .search-area { + justify-content: stretch; + } + + .search-box { + width: 100%; + } + + .search-box input { + flex: 1; + width: auto; + } + + .slider-arrow { + opacity: 0.7; + } +} + +@media (max-width: 480px) { + .container { + padding: 0.75rem; + } + + .header { + padding: 0.875rem 1rem; + } + + .review-card-body { + padding: 1rem; + } +} \ No newline at end of file diff --git a/src/main/resources/static/image/equip/온다리프팅.jpg b/src/main/resources/static/image/equip/온다리프팅.jpg new file mode 100644 index 0000000000000000000000000000000000000000..74d41aada8b04d353d5f5174361f7870e7395cc1 GIT binary patch literal 44668 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�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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/image/quick_menu/review.png b/src/main/resources/static/image/quick_menu/review.png new file mode 100644 index 0000000000000000000000000000000000000000..087b3b3b39f9384ca3331c7ff26f18ee58906fbf GIT binary patch literal 8344 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/js/web/webreview/procedureReviewSelect.js b/src/main/resources/static/js/web/webreview/procedureReviewSelect.js new file mode 100644 index 0000000..3c5cea7 --- /dev/null +++ b/src/main/resources/static/js/web/webreview/procedureReviewSelect.js @@ -0,0 +1,117 @@ +class ReviewDetailManager { + constructor() { + this.quill = null; + this.init(); + } + + async init() { + if (!muProcedureReviewId) { + this.showError('잘못된 접근입니다.'); + return; + } + await this.loadReview(); + } + + async apiRequest(url, data) { + return new Promise((resolve, reject) => { + $.ajax({ + url: encodeURI(url), + data: data, + dataType: 'json', + processData: false, + contentType: false, + type: 'POST', + success: resolve, + error: reject + }); + }); + } + + async loadReview() { + try { + const formData = new FormData(); + formData.append('muProcedureReviewId', muProcedureReviewId); + + const data = await this.apiRequest('/webreview/selectProcedureReview.do', formData); + + if (data.msgCode === '0' && data.rows) { + this.renderReview(data.rows); + } else { + this.showError('게시글을 찾을 수 없습니다.'); + } + } catch (error) { + this.showError('게시글 조회 중 오류가 발생하였습니다.'); + } + } + + renderReview(review) { + // 제목 + document.getElementById('review-title').textContent = review.title || ''; + document.getElementById('breadcrumb-title').textContent = review.title || '상세보기'; + + // 메타 정보 + document.getElementById('review-date').textContent = review.writeDate || ''; + document.getElementById('review-views').textContent = review.viewCount || 0; + + // 해시태그 + const tagsContainer = document.getElementById('review-tags'); + if (review.hashtag) { + const tags = review.hashtag.split(',').map(t => t.trim()).filter(t => t); + tagsContainer.innerHTML = tags.map(tag => + `#${tag}` + ).join(''); + } + + // Quill Delta JSON 본문 렌더링 + const contentDiv = document.getElementById('review-content'); + if (review.content) { + try { + // Base64 디코딩 + const decoded = decodeURIComponent(escape(atob(review.content))); + const delta = JSON.parse(decoded); + + // Quill read-only 모드로 렌더링 + contentDiv.innerHTML = ''; // 로딩 메시지 제거 + this.quill = new Quill(contentDiv, { + readOnly: true, + modules: { toolbar: false }, + theme: 'snow' + }); + this.quill.setContents(delta); + + // 툴바 숨기기 (snow 테마 기본 요소) + const toolbar = contentDiv.parentElement.querySelector('.ql-toolbar'); + if (toolbar) toolbar.style.display = 'none'; + + // 에디터 테두리 제거 + const container = contentDiv.parentElement.querySelector('.ql-container'); + if (container) { + container.style.border = 'none'; + container.style.fontSize = '16px'; + } + + } catch (e) { + // Delta 파싱 실패 시 HTML로 시도 + try { + const html = decodeURIComponent(escape(atob(review.content))); + contentDiv.innerHTML = html; + } catch (e2) { + contentDiv.innerHTML = review.content; + } + } + } else { + contentDiv.innerHTML = '

내용이 없습니다.

'; + } + } + + showError(msg) { + document.getElementById('review-content').innerHTML = ` +
+
😔
+
${msg}
+
+ `; + } +} + +const reviewDetailManager = new ReviewDetailManager(); diff --git a/src/main/resources/static/js/web/webreview/procedureReviewSelectList.js b/src/main/resources/static/js/web/webreview/procedureReviewSelectList.js new file mode 100644 index 0000000..8de052f --- /dev/null +++ b/src/main/resources/static/js/web/webreview/procedureReviewSelectList.js @@ -0,0 +1,259 @@ +class ReviewListManager { + constructor() { + this.reviews = []; + this.currentPage = 1; + this.pageSize = 9; + this.totalCount = 0; + this.categoryDivCd = '07'; // 다이어트센터 + this.sliders = {}; + this.init(); + } + + async init() { + this.bindEvents(); + await this.loadReviews(); + } + + bindEvents() { + document.getElementById('btnSearch').addEventListener('click', () => { + this.currentPage = 1; + this.loadReviews(); + }); + document.getElementById('searchTitle').addEventListener('keypress', (e) => { + if (e.key === 'Enter') { this.currentPage = 1; this.loadReviews(); } + }); + } + + async apiRequest(url, data) { + return new Promise((resolve, reject) => { + $.ajax({ + url: encodeURI(url), data: data, dataType: 'json', + processData: false, contentType: false, type: 'POST', + success: resolve, error: reject + }); + }); + } + + async loadReviews() { + try { + const formData = new FormData(); + formData.append('categoryDivCd', this.categoryDivCd); + formData.append('start', (this.currentPage - 1) * this.pageSize); + formData.append('limit', this.pageSize); + + const searchTitle = document.getElementById('searchTitle').value.trim(); + if (searchTitle) formData.append('title', searchTitle); + + const data = await this.apiRequest('/webreview/selectListProcedureReview.do', formData); + if (data.msgCode === '0') { + this.reviews = data.rows || []; + this.totalCount = parseInt(data.totalCount) || 0; + this.renderReviews(); + this.renderPagination(); + } else { + this.showEmpty('조회 중 오류가 발생하였습니다.'); + } + } catch (error) { + this.showEmpty('조회 중 오류가 발생하였습니다.'); + } + } + + /** Delta JSON에서 이미지 URL 배열 추출 */ + extractImages(content) { + if (!content) return []; + try { + const decoded = decodeURIComponent(escape(atob(content))); + const delta = JSON.parse(decoded); + if (delta.ops) { + return delta.ops + .filter(op => op.insert && typeof op.insert === 'object' && op.insert.image) + .map(op => op.insert.image); + } + return []; + } catch (e) { + return []; + } + } + + /** Delta JSON에서 텍스트 요약 추출 */ + extractSummary(content) { + if (!content) return ''; + try { + const decoded = decodeURIComponent(escape(atob(content))); + const delta = JSON.parse(decoded); + if (delta.ops) { + const text = delta.ops + .filter(op => typeof op.insert === 'string') + .map(op => op.insert).join('').replace(/\n/g, ' ').trim(); + return text.length > 100 ? text.substring(0, 100) + '...' : text; + } + return ''; + } catch (e) { return ''; } + } + + /** 이미지 슬라이더 HTML 생성 */ + buildSliderHtml(images, cardIdx) { + if (images.length === 0) { + return '
📷
'; + } + + const sliderId = `slider-${cardIdx}`; + const imagesHtml = images.map(src => + `고객후기` + ).join(''); + + // 도트 인디케이터 + const dotsHtml = images.length > 1 + ? `
${images.map((_, i) => + `` + ).join('')}
` : ''; + + // 화살표 + const arrowsHtml = images.length > 1 + ? ` + ` : ''; + + // 이미지 카운트 + const countHtml = images.length > 1 + ? `1 / ${images.length}` : ''; + + return ` +
+
${imagesHtml}
+ ${arrowsHtml} + ${dotsHtml} + ${countHtml} +
+ `; + } + + renderReviews() { + const grid = document.getElementById('review-grid'); + + if (this.reviews.length === 0) { + grid.innerHTML = `
📝
등록된 고객후기가 없습니다.
`; + return; + } + + grid.innerHTML = this.reviews.map((review, idx) => { + const images = this.extractImages(review.summary || review.content); + const summaryText = this.extractSummary(review.summary || review.content); + const sliderHtml = this.buildSliderHtml(images, idx); + + let tagsHtml = ''; + if (review.hashtag) { + const tags = review.hashtag.split(',').map(t => t.trim()).filter(t => t); + tagsHtml = `
${tags.slice(0, 3).map(tag => + `#${tag}`).join('')}
`; + } + + return ` +
+ ${sliderHtml} +
+
${this.escapeHtml(review.title)}
+
${summaryText}
+ ${tagsHtml} + +
+
+ `; + }).join(''); + + // 슬라이더 이벤트 바인딩 + this.bindSliderEvents(); + + // 카드 클릭 이벤트 (슬라이더 요소 클릭 제외) + grid.querySelectorAll('.review-card').forEach(card => { + card.addEventListener('click', (e) => { + // 슬라이더 화살표나 도트 클릭 시 이동 방지 + if (e.target.closest('.slider-arrow') || e.target.closest('.slider-dot')) return; + const id = card.dataset.id; + location.href = `/webreview/selectProcedureReviewIntro.do?muProcedureReviewId=${id}`; + }); + }); + } + + /** 슬라이더 이벤트 바인딩 */ + bindSliderEvents() { + document.querySelectorAll('.review-slider').forEach(slider => { + const total = parseInt(slider.dataset.total); + if (total <= 1) return; + + const track = slider.querySelector('.review-slider-track'); + const dots = slider.querySelectorAll('.slider-dot'); + const countEl = slider.querySelector('.slider-count'); + + const goTo = (idx) => { + const current = Math.max(0, Math.min(idx, total - 1)); + slider.dataset.current = current; + track.style.transform = `translateX(-${current * 100}%)`; + + dots.forEach((d, i) => d.classList.toggle('active', i === current)); + if (countEl) countEl.textContent = `${current + 1} / ${total}`; + }; + + // 화살표 클릭 + slider.querySelectorAll('.slider-arrow').forEach(arrow => { + arrow.addEventListener('click', (e) => { + e.stopPropagation(); + const dir = parseInt(arrow.dataset.dir); + let next = parseInt(slider.dataset.current) + dir; + if (next < 0) next = total - 1; + if (next >= total) next = 0; + goTo(next); + }); + }); + + // 도트 클릭 + dots.forEach(dot => { + dot.addEventListener('click', (e) => { + e.stopPropagation(); + goTo(parseInt(dot.dataset.idx)); + }); + }); + }); + } + + renderPagination() { + const area = document.getElementById('pagination-area'); + const totalPages = Math.ceil(this.totalCount / this.pageSize); + if (totalPages <= 1) { area.innerHTML = ''; return; } + + let html = ``; + const startPage = Math.max(1, this.currentPage - 2); + const endPage = Math.min(totalPages, startPage + 4); + for (let i = startPage; i <= endPage; i++) { + html += ``; + } + html += ``; + area.innerHTML = html; + + area.querySelectorAll('.page-btn:not(.disabled)').forEach(btn => { + btn.addEventListener('click', () => { + this.currentPage = parseInt(btn.dataset.page); + this.loadReviews(); + window.scrollTo({ top: 0, behavior: 'smooth' }); + }); + }); + } + + showEmpty(msg) { + document.getElementById('review-grid').innerHTML = ` +
⚠️
${msg}
`; + document.getElementById('pagination-area').innerHTML = ''; + } + + escapeHtml(str) { + if (!str) return ''; + return str.replace(/&/g, '&').replace(//g, '>') + .replace(/"/g, '"').replace(/'/g, '''); + } +} + +const reviewListManager = new ReviewListManager(); diff --git a/src/main/resources/templates/web/introduction/introductionHospitalSelect.html b/src/main/resources/templates/web/introduction/introductionHospitalSelect.html index bc143f5..361e596 100644 --- a/src/main/resources/templates/web/introduction/introductionHospitalSelect.html +++ b/src/main/resources/templates/web/introduction/introductionHospitalSelect.html @@ -1,8 +1,6 @@ - + @@ -10,16 +8,16 @@
- introduction + introduction

#맞춤진료 #만족스러운결과

- MADE U 강남본점
- Total Beauty
One Stop System + MADE U 강남본점
+ Total Beauty
One Stop System

- 한 공간에서 고객 한분 한분께 자연스러운
아름다움과 건강한 다이어트를 위해
- 항상 노력하는 함께하는
조언자가 되어 드릴 것을 약속드립니다. + 한 공간에서 고객 한분 한분께 자연스러운
아름다움과 건강한 다이어트를 위해
+ 항상 노력하는 함께하는
조언자가 되어 드릴 것을 약속드립니다.

@@ -28,47 +26,47 @@

#차별화된 맞춤 플랜

-

Looking Around
MADE U

+

Looking Around
MADE U

- 쾌적하고 안락한 공간을 제공하는
+ 쾌적하고 안락한 공간을 제공하는
메이드유 강남본점

깨끗한 공간, 친절한 상담을 제공하겠습니다.

- content1 + content1
-

쉬운다이어트 방법 없을까?
MADE U 시그니처 프로그램

+

쉬운다이어트 방법 없을까?
MADE U 시그니처 프로그램

  • - content2-1 + content2-1

    One-On-One Customized Counseling

    - MADE U 강남본점만의
    + MADE U 강남본점만의
    1:1 맞춤 상담

    - 고객님의 체형별 그리고 고민
    부위별 맞춤진료로,
    + 고객님의 체형별 그리고 고민
    부위별 맞춤진료로,
    숨겨진 아름다움을 찾아드립니다.

  • - content2-2 + content2-2

    Trademark Application

    - MADE U 강남본점만의
    + MADE U 강남본점만의
    특허상표 출원

    - 메이드유 강남본점에서 자체 개발한
    메쉬다 주사
    - 레시피의 뛰어난
    효과를 바탕으로 다수의
    + 메이드유 강남본점에서 자체 개발한
    메쉬다 주사
    + 레시피의 뛰어난
    효과를 바탕으로 다수의
    특허와 상표를 등록했습니다.

    @@ -77,151 +75,151 @@
-
-

국내 고가명품 최다보유
MADE U 프리미엄 장비 소개

- -
-
-
- 써마지 -
-
-

써마지

-

깊은 탄력과 리프팅을 동시에

-

-
-
- -
-
- 울쎄라 -
-
-

울쎄라

-

깊은 탄력과 리프팅을 동시에

-

-
-
- -
-
- 티타늄리프팅 -
-
-

티타늄리프팅

-

깊은 탄력과 리프팅을 동시에

-

-
-
- -
-
- 튠바디 -
-
-

튠바디

-

깊은 탄력과 리프팅을 동시에

-

-
-
- - -
-
- 튠페이스 -
-
-

튠페이스

-

깊은 탄력과 리프팅을 동시에

-

-
-
- -
-
- 울핏 -
-
-

울핏

-

깊은 탄력과 리프팅을 동시에

-

-
-
- -
-
- 포텐자 -
-
-

포텐자

-

깊은 탄력과 리프팅을 동시에

-

-
-
- -
-
- 인모드 -
-
-

인모드

-

깊은 탄력과 리프팅을 동시에

-

-
-
- - -
-
- 슈링크유니버스 -
-
-

슈링크유니버스

-

깊은 탄력과 리프팅을 동시에

-

-
-
- -
-
- 바디고주파테라피 -
-
-

바디고주파테라피

-

깊은 탄력과 리프팅을 동시에

-

-
-
- -
-
- 리포덤 -
-
-

리포덤

-

깊은 탄력과 리프팅을 동시에

-

-
-
- -
-
- 라비앙 -
-
-

라비앙

-

깊은 탄력과 리프팅을 동시에

-

-
-
-
-
+
+

국내 고가명품 최다보유
MADE U 프리미엄 장비 소개

+ +
+
+
+ 써마지 +
+
+

써마지

+ +

+
+
+ +
+
+ 울쎄라 +
+
+

울쎄라

+ +

+
+
+ +
+
+ 티타늄리프팅 +
+
+

티타늄리프팅

+ +

+
+
+
+
+ 온다리프팅 +
+
+

온다리프팅

+ + +
+
+
+
+ 튠바디 +
+
+

튠바디

+ +

+
+
+ + +
+
+ 튠페이스 +
+
+

튠페이스

+ +

+
+
+ +
+
+ 울핏 +
+
+

울핏

+ +

+
+
+ +
+
+ 포텐자 +
+
+

포텐자

+ +

+
+
+ +
+
+ 인모드 +
+
+

인모드

+ +

+
+
+ + +
+
+ 슈링크유니버스 +
+
+

슈링크유니버스

+ +

+
+
+ +
+
+ 바디고주파테라피 +
+
+

바디고주파테라피

+ +

+
+
+ +
+
+ 리포덤 +
+
+

리포덤

+ +

+
+
+ + +
+

- 한 공간에서 고객 한분 한분께 자연스러운 아름다움과
건강한 다이어트를 위해 항상 노력하는
+ 한 공간에서 고객 한분 한분께 자연스러운 아름다움과
건강한 다이어트를 위해 항상 노력하는
Total Beauty One Stop System

    @@ -229,56 +227,57 @@

    - 자연스러운 아름다움과
    + 자연스러운 아름다움과
    건강한 다이어트

    - 메이드유는 Total Beauty One Stop System으로
    - 한 공간에서 고객 한분
    한분께 자연스러운 아름다움과
    - 건강한 다이어트를 위해 항상 노력하는 함께하는 조언자가
    + 메이드유는 Total Beauty One Stop System으로
    + 한 공간에서 고객 한분
    한분께 자연스러운 아름다움과
    + 건강한 다이어트를 위해 항상 노력하는 함께하는 조언자가
    되어 드릴 것을 약속드립니다.

    - introduction_content4-1 - introduction_content4-1 + introduction_content4-1 + introduction_content4-1
  • - 고객을 가족으로 생각하는 마음으로
    정직한 시술,
    만족할 수 있는 결과,

    - 더 나은 감동을 선사하기 위해
    + 고객을 가족으로 생각하는 마음으로
    정직한 시술,
    만족할 수 있는 + 결과,

    + 더 나은 감동을 선사하기 위해
    끊임없이 노력하겠습니다.

    - 메이드유는 전국, 해외에서 찾아오는 비만센터와
    프리미멈 명품 - 장비 보유 및 장비 최다 보유
    와 엘란쎄,
    스컬트라 콜라겐 볼륨 - 전국 3대 병원인 쁘띠 센터로
    구분되어 고객에 맞춰 운영되고 + 메이드유는 전국, 해외에서 찾아오는 비만센터와
    프리미멈 명품 + 장비 보유 및 장비 최다 보유
    와 엘란쎄,
    스컬트라 콜라겐 볼륨 + 전국 3대 병원인 쁘띠 센터로
    구분되어 고객에 맞춰 운영되고 있습니다.

    - introduction_content4-2 - introduction_content4-2 + introduction_content4-2 + introduction_content4-2
  • - No Pain 통증 없이
    - No Bruise 멍 없이
    - No Swelling 붓기 없이
    + No Pain 통증 없이
    + No Bruise 멍 없이
    + No Swelling 붓기 없이
    3No 의료서비스를 지향

    - 모든 제품은 정품, 정량, 정품 장비 사용을 원칙으로 안전을
    - 최우선으로 하고 있으며, 모든 시술은 No Pain, No Bruise,
    - No Swelling라는 3No 의료서비스를 지향
    합니다.
    - 앞으로도 고품질의 관리와 서비스를 받을 수 있도록 노력하며
    - 사소한 불편까지 읽어주는 세심한 배려, 마음까지 읽는 서비스로
    + 모든 제품은 정품, 정량, 정품 장비 사용을 원칙으로 안전을
    + 최우선으로 하고 있으며, 모든 시술은 No Pain, No Bruise,
    + No Swelling라는 3No 의료서비스를 지향
    합니다.
    + 앞으로도 고품질의 관리와 서비스를 받을 수 있도록 노력하며
    + 사소한 불편까지 읽어주는 세심한 배려, 마음까지 읽는 서비스로
    무한 감동을 드릴 것을 약속합니다.

    - introduction_content4-3 - introduction_content4-3 + introduction_content4-3 + introduction_content4-3
@@ -287,4 +286,5 @@ + \ No newline at end of file diff --git a/src/main/resources/templates/web/layout/layoutHeader.html b/src/main/resources/templates/web/layout/layoutHeader.html index 4e56160..3b97cc1 100644 --- a/src/main/resources/templates/web/layout/layoutHeader.html +++ b/src/main/resources/templates/web/layout/layoutHeader.html @@ -1,106 +1,114 @@ - - - -
-
- - - + // 현재 경로가 /index인지 확인 + function isIndexPage() { + return window.location.pathname === '/index'; // '/index.html'인 경우 조정 필요 + } + + // 퀵메뉴 표시/숨김 함수 + function toggleQuickMenu() { + const quickMenu = document.querySelector('.quick-menu-simple'); + if (!quickMenu) return; // 요소가 없으면 종료 + + if (isMobile()) { + // 모바일: /index일 때만 표시 + quickMenu.style.display = isIndexPage() ? '' : 'none'; + } else { + // 데스크톱: 항상 표시 + quickMenu.style.display = ''; + } + } + + // 페이지 로드와 리사이즈 이벤트 연결 + window.addEventListener('load', toggleQuickMenu); + window.addEventListener('resize', toggleQuickMenu); + +
+
+ + + +
+
+ +
+
+ 고객후기 +
+
+ 이벤트 +
+
+ 쁘띠센터 +
+ +
+ 카카오톡 상담 +
+ + +
+
+ 전화 상담 +
+
+ 전화 상담 +
+
-
- -
-
- 이벤트 -
-
- 쁘띠센터 -
- -
- 카카오톡 상담 -
- - -
-
- 전화 상담 -
-
- 전화 상담 -
-
-
- + + \ No newline at end of file diff --git a/src/main/resources/templates/web/webreview/procedureReviewSelect.html b/src/main/resources/templates/web/webreview/procedureReviewSelect.html new file mode 100644 index 0000000..14e9bda --- /dev/null +++ b/src/main/resources/templates/web/webreview/procedureReviewSelect.html @@ -0,0 +1,54 @@ + + + + + + + + + + + + +
+ + + + +
+
+

+
+ + 조회 0 +
+
+
+ + +
+
게시글을 불러오는 중...
+
+
+ + + +
+
+ + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/web/webreview/procedureReviewSelectList.html b/src/main/resources/templates/web/webreview/procedureReviewSelectList.html new file mode 100644 index 0000000..95d8668 --- /dev/null +++ b/src/main/resources/templates/web/webreview/procedureReviewSelectList.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+ +
+

고객후기

+

실제 고객님들의 생생한 후기를 확인하세요

+
+ + +
+ +
+ + +
+
고객후기를 불러오는 중...
+
+ + +
+
+
+ + + + + + \ No newline at end of file