Browse Source

update 2024-03-15

junggilpark 1 year ago
parent
commit
2c88b4ddd4
23 changed files with 259 additions and 175 deletions
  1. 1 2
      src/main/java/com/its/web/controller/admin/AdminController.java
  2. 3 7
      src/main/java/com/its/web/dto/common/ConnStatisticsDto.java
  3. 3 3
      src/main/java/com/its/web/dto/traffic/VmsDsplPhaseDto.java
  4. 2 3
      src/main/java/com/its/web/interceptor/ConnectHistory.java
  5. 1 1
      src/main/java/com/its/web/mapper/its/traffic/TrafficMapper.java
  6. 1 1
      src/main/java/com/its/web/pagination/Pagination.java
  7. 2 2
      src/main/java/com/its/web/security/WebPasswordEncoder.java
  8. 3 1
      src/main/java/com/its/web/security/WebSecurityConfig.java
  9. 0 3
      src/main/java/com/its/web/service/admin/LoginService.java
  10. 16 3
      src/main/java/com/its/web/service/common/CommonService.java
  11. 19 2
      src/main/java/com/its/web/service/notice/NoticeService.java
  12. 3 13
      src/main/java/com/its/web/service/traffic/TrafficService.java
  13. 0 1
      src/main/resources/application.yml
  14. 1 1
      src/main/resources/mybatis/mapper/its/traffic/TrafficMapper.xml
  15. 13 5
      src/main/resources/static/css/common.css
  16. 5 4
      src/main/resources/static/css/main.css
  17. 23 0
      src/main/resources/static/css/statistics.css
  18. 15 19
      src/main/resources/static/js/common/common.js
  19. 28 28
      src/main/resources/static/js/traffic/traffic.js
  20. 33 20
      src/main/resources/templates/admin/notice-view.html
  21. 20 11
      src/main/resources/templates/admin/notice-write.html
  22. 42 31
      src/main/resources/templates/admin/popup-view.html
  23. 25 14
      src/main/resources/templates/admin/popup-write.html

+ 1 - 2
src/main/java/com/its/web/controller/admin/AdminController.java

@@ -49,10 +49,9 @@ public class AdminController {
         HttpSession session = req.getSession();
         try {
             session.invalidate();
-
             res.sendRedirect("/phits");
         } catch (IOException e) {
-            e.printStackTrace();
+            log.error("Cause IOException - Path : /logout, redirectPath : /phits");
         }
     }
 

+ 3 - 7
src/main/java/com/its/web/dto/common/ConnStatisticsDto.java

@@ -5,8 +5,6 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.*;
 
-import javax.validation.constraints.NotNull;
-
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
@@ -27,18 +25,16 @@ public class ConnStatisticsDto {
     @ToString
     @NoArgsConstructor
     public static class ConnStatisticsDtoReq {
-        @ApiModelProperty("검색 시작 일시, Nullable = N")
+        @ApiModelProperty(value = "검색 시작 일시", example = "20240202000000", required = true)
         @JsonProperty("from_date")
         private String fromDate;
 
-        @ApiModelProperty("검색 종료 일시, Nullable = N")
+        @ApiModelProperty(value = "검색 종료 일시",example = "20240202235959", required = true)
         @JsonProperty("to_date")
-        @NotNull
         private String toDate;
 
-        @ApiModelProperty("유형, Nullable = N")
+        @ApiModelProperty(value = "유형", example = "dd", required = true)
         @JsonProperty("type")
-        @NotNull
         private String type;
     }
 }

+ 3 - 3
src/main/java/com/its/web/dto/traffic/VmsDsplPhaseDto.java

@@ -21,9 +21,9 @@ public class VmsDsplPhaseDto {
     @JsonProperty("phase")
     private Integer phase;
 
-//    @ApiModelProperty("VMS 표출 메세지 이미지")
-//    @JsonProperty("vms_dspl_msg_imag")
-//    private byte[] vms_dspl_msg_imag;
+    @ApiModelProperty("VMS 표출 메세지 이미지")
+    @JsonProperty("vms_dspl_msg_imag")
+    private byte[] vmsDsplMsgImag;
 
     @ApiModelProperty("VMS 표출 메세지 텍스트")
     @JsonProperty("vms_dspl_msg_txt")

+ 2 - 3
src/main/java/com/its/web/interceptor/ConnectHistory.java

@@ -12,6 +12,7 @@ import org.springframework.web.servlet.HandlerInterceptor;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import java.io.IOException;
 import java.util.Arrays;
 
 @Slf4j
@@ -21,9 +22,7 @@ public class ConnectHistory implements HandlerInterceptor {
     private final CommonService service;
 
     @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-//        InetAddress ipAddress = InetAddress.getLocalHost();
-//        String hostIp = ipAddress.getHostAddress();
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
         String uri = request.getRequestURI();
         String[] ipAddressArr = new String[]{"127.0.0.1", "localhost", "192.168.20.46"};
         HttpSession session = request.getSession();

+ 1 - 1
src/main/java/com/its/web/mapper/its/traffic/TrafficMapper.java

@@ -17,7 +17,7 @@ public interface TrafficMapper {
 
     List<VmsDsplPhaseDto> findVmsDsplPhaseInfo(String vmsCtlrNmbr);
 
-    Map<String, Object> findVmsDsplImage(Map<String, String> paramMap);
+    VmsDsplPhaseDto findVmsDsplImage(Map<String, String> paramMap);
 
     List<TbIncdOcrrDto> findAllIncident();
 

+ 1 - 1
src/main/java/com/its/web/pagination/Pagination.java

@@ -43,7 +43,7 @@ public class Pagination {
             }
         }
         catch (NumberFormatException e) {
-
+            throw new NumberFormatException("This Page Value Is Invalid. Page : "+ page);
         }
 
         if (totalCount > PAGE_PER_NUM){

+ 2 - 2
src/main/java/com/its/web/security/WebPasswordEncoder.java

@@ -10,7 +10,7 @@ import java.nio.charset.StandardCharsets;
 @Slf4j
 public class WebPasswordEncoder implements PasswordEncoder {
     @Override
-    public String encode(CharSequence charSequence) {
+    public String encode(CharSequence charSequence) throws IllegalArgumentException {
         if (charSequence == null) {
             throw new IllegalArgumentException("Encode Password Cannot be null");
         }
@@ -19,7 +19,7 @@ public class WebPasswordEncoder implements PasswordEncoder {
     }
 
     @Override
-    public boolean matches(CharSequence charSequence, String s) {
+    public boolean matches(CharSequence charSequence, String s) throws IllegalArgumentException{
         if (charSequence == null) {
             throw new IllegalArgumentException("rawPassword cannot be null");
         }

+ 3 - 1
src/main/java/com/its/web/security/WebSecurityConfig.java

@@ -17,6 +17,8 @@ import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
+import java.io.IOException;
+
 @Slf4j
 @Configuration
 @EnableWebSecurity
@@ -29,7 +31,7 @@ public class WebSecurityConfig implements WebMvcConfigurer {
     private final CommonService commonService;
 
     @Bean
-    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+    public SecurityFilterChain filterChain(HttpSecurity http) throws IOException, Exception {
         http.headers().frameOptions().sameOrigin();
         http.headers().defaultsDisabled().cacheControl();
         http.headers().xssProtection().block(false);

+ 0 - 3
src/main/java/com/its/web/service/admin/LoginService.java

@@ -54,9 +54,6 @@ public class LoginService implements UserDetailsService {
     }
 
     public ResultDto loginCheck(String id, String pwd) {
-//        String id = req.getId();
-//        String pwd = req.getPwd();
-//        Map<String, String> resultMap = new HashMap<>();
         String message = "";
         String success = "S";
         Map<String, String> paramMap = new HashMap<>();

+ 16 - 3
src/main/java/com/its/web/service/common/CommonService.java

@@ -85,6 +85,9 @@ public class CommonService {
         File file = new File(filePath);
         boolean isMkdirs = true;
         if (!file.exists()) {
+            file.setExecutable(false, true); /*파일 실행 권한 설정 (파라미터 - 일반, 소유자)*/
+            file.setReadable(true); /*파일 읽기 권한 설정*/
+            file.setWritable(false, true);
             isMkdirs = file.mkdirs();
         }
 
@@ -92,11 +95,11 @@ public class CommonService {
             String realFileNm;
             realFileNm = UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));
             String rlFileNm = filePath + File.separator + realFileNm;
-
+            OutputStream os = null;
             try (
-                    InputStream is = req.getInputStream();
-                    OutputStream os = new FileOutputStream(rlFileNm);
+                    InputStream is = req.getInputStream()
             ) {
+                os = new FileOutputStream(rlFileNm);
                 int numRead;
                 byte[] byteArray = new byte[Integer.parseInt(req.getHeader("file-size"))];
                 if (is != null) {
@@ -110,6 +113,16 @@ public class CommonService {
             } catch (Exception e1) {
                 log.error("noticeImgupload() Exception");
             }
+            finally {
+                if(os != null) {
+                    try{
+                        os.close();
+                    }
+                    catch (IOException e) {
+                        log.error("Cause IOException...");
+                    }
+                }
+            }
             uploadImageInfo += "&bNewLine=true";
             uploadImageInfo += "&sFileName=" + fileName;
             uploadImageInfo += "&sFileURL=" + "/api/common/upload/" + realFileNm;

+ 19 - 2
src/main/java/com/its/web/service/notice/NoticeService.java

@@ -198,6 +198,9 @@ public class NoticeService {
         File file = new File(boardLocation);
         boolean isMkFile = true;
         if (!file.exists()) {
+            file.setExecutable(false, true); /*파일 실행 권한 설정 (파라미터 - 일반, 소유자)*/
+            file.setReadable(true); /*파일 읽기 권한 설정*/
+            file.setWritable(false, true);
             isMkFile = file.mkdirs();
         }
         if (isMkFile) {
@@ -207,7 +210,7 @@ public class NoticeService {
                 attachFile.transferTo(transFile);
             }
             catch (IOException e) {
-                log.error("파일 생성 중 오류가 발생하였습니다. {}", e.getMessage());
+                log.error("IOException - 첨부 파일 파일 생성 중 오류가 발생하였습니다.");
                 isMkFile = false;
             }
         }
@@ -235,6 +238,9 @@ public class NoticeService {
         File file = new File(filePath);
         boolean isMkdirs = true;
         if (!file.exists()) {
+            file.setExecutable(false, true); /*파일 실행 권한 설정 (파라미터 - 일반, 소유자)*/
+            file.setReadable(true); /*파일 읽기 권한 설정*/
+            file.setWritable(false, true);
             isMkdirs = file.mkdirs();
         }
 
@@ -243,10 +249,11 @@ public class NoticeService {
             realFileNm = UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));
             String rlFileNm = filePath + File.separator + realFileNm;
 
+            OutputStream os = null;
             try (
                     InputStream is = req.getInputStream();
-                    OutputStream os = new FileOutputStream(rlFileNm);
             ) {
+                os = new FileOutputStream(rlFileNm);
                 int numRead;
                 byte[] byteArray = new byte[Integer.parseInt(req.getHeader("file-size"))];
                 if (is != null) {
@@ -260,6 +267,16 @@ public class NoticeService {
             } catch (Exception e1) {
                 log.error("noticeImgupload() Exception");
             }
+            finally {
+                if(os != null) {
+                    try{
+                        os.close();
+                    }
+                    catch (IOException e) {
+                        log.error("Cause IOException...");
+                    }
+                }
+            }
             uploadImageInfo += "&bNewLine=true";
             uploadImageInfo += "&sFileName=" + fileName;
             uploadImageInfo += "&sFileURL=" + "/api/notice/upload/" + realFileNm;

+ 3 - 13
src/main/java/com/its/web/service/traffic/TrafficService.java

@@ -9,8 +9,6 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
-import java.sql.Blob;
-import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -67,18 +65,10 @@ public class TrafficService {
         paramMap.put("vmsCtlrNmbr", vmsCtlrNmbr);
         paramMap.put("phase", phase);
 
-        Map<String, Object> resultMap = this.mapper.findVmsDsplImage(paramMap);
+        VmsDsplPhaseDto dto = this.mapper.findVmsDsplImage(paramMap);
 
-        if (resultMap != null && resultMap.get("VMS_DSPL_MSG_IMAG") != null) {
-            Blob blob = (Blob) resultMap.get("VMS_DSPL_MSG_IMAG");
-            try {
-                if ((int)blob.length() > 0) {
-                    return blob.getBytes(1, (int) blob.length());
-                }
-            }
-            catch (SQLException e) {
-                log.error("Please Check the Sql Exception :{}",  e.getStackTrace());
-            }
+        if (dto != null && dto.getVmsDsplMsgImag() != null) {
+            return dto.getVmsDsplMsgImag();
         }
         return null;
     }

+ 0 - 1
src/main/resources/application.yml

@@ -64,7 +64,6 @@ logging:
           descriptor:
             sql:
               BasicBinder: ERROR
-
 #jasypt:
 #  encryptor:
 #    bean: jasyptStringEncryptor

+ 1 - 1
src/main/resources/mybatis/mapper/its/traffic/TrafficMapper.xml

@@ -187,7 +187,7 @@
         ORDER BY A.VMS_CTLR_NMBR, A.PHASE
     </select>
 
-    <select id="findVmsDsplImage" parameterType="java.util.HashMap" resultType="java.util.HashMap">
+    <select id="findVmsDsplImage" parameterType="java.util.HashMap" resultType="com.its.web.dto.traffic.VmsDsplPhaseDto">
         SELECT VMS_DSPL_MSG_IMAG
           FROM TB_VMS_DSPL_PRST
          WHERE VMS_CTLR_NMBR = #{vmsCtlrNmbr}

+ 13 - 5
src/main/resources/static/css/common.css

@@ -415,7 +415,8 @@ footer .mobile-footer {
 .copyright_modal > div > div {
     box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 6px 0px;
     background-color: rgb(255, 255, 255);
-    width: 65%;
+    width: 90%;
+    height: 100%;
     margin: auto;
     transition: all 0.5s ease 0s;
     padding: 1rem;
@@ -434,8 +435,9 @@ footer .mobile-footer {
     margin-bottom: 1rem;
     padding: 10px;
     border: 1px solid #d1d1d1;
-    height: 730px;
-    min-height: 730px;
+    height: calc(100% - 80px);
+    /*height: 730px;*/
+    /*min-height: 730px;*/
     overflow: auto;
     padding: 20px
 }
@@ -445,8 +447,9 @@ footer .mobile-footer {
     text-align: center;
     padding: 10px;
     border: 1px solid #d1d1d1;
-    height: 730px;
-    min-height: 730px;
+    /*height: 730px;*/
+    /*min-height: 730px;*/
+    height: calc(100% - 80px);
     overflow: auto;
     padding: 20px
 }
@@ -882,6 +885,11 @@ i {
         font-size: 14px;
     }
 
+    .video_proc_modal > div > div,
+    .copyright_modal > div > div {
+        width: 65%;
+    }
+
 }
 
 @media (min-width: 920px) {

+ 5 - 4
src/main/resources/static/css/main.css

@@ -433,13 +433,14 @@ body {
     }
 
     .mainWrap {
-        padding: 0;
-        height: calc(100% - 149.19px);
+        /*padding: 0;*/
+        /*height: calc(100% - 149.19px);*/
+        padding-bottom: 78px;
     }
 
     .mainWrap .main {
         width: 100%;
-        height: 100%;
+        /*height: 100%;*/
         padding: 0;
         justify-content: unset;
 
@@ -487,7 +488,7 @@ body {
 
     .mainWrap .main-menu {
         padding: 0;
-        height: 100%;
+        /*height: 100%;*/
     }
 
     .mainWrap .notice,

+ 23 - 0
src/main/resources/static/css/statistics.css

@@ -228,6 +228,10 @@
     width: auto;
     min-width: 50px;
 }
+
+.search-content.congest .table-box table th {
+    min-width: 120px;
+}
 .table-box table th {
     position: sticky;
     top: 0px;
@@ -247,6 +251,7 @@
     z-index: 99;
     min-width: 300px;
     text-align: left;
+    padding-left: 10px;
 }
 
 .table-box table td span {
@@ -294,6 +299,10 @@
     .statisticWrap {
         height: calc(100% - 253.19px);
     }
+    .table-box table th,
+    .table-box table td{
+        font-size: 14px;
+    }
 }
 
 @media (max-height: 765px) {
@@ -318,6 +327,20 @@
     .statisticWrap {
         height: calc(100% - 237.19px);;
     }
+    .table-box table th,
+    .table-box table td{
+        font-size: 12px;
+    }
+    .search-content .table-box table td:first-child,
+    .search-content .table-box table th:first-child {
+        max-width: 250px;
+        min-width: 250px;
+    }
+    .search-content.congest .table-box table td:first-child,
+    .search-content.congest .table-box table th:first-child {
+        max-width: 180px;
+        min-width: 180px;
+    }
 }
 
 @media (max-width: 547px) {

+ 15 - 19
src/main/resources/static/js/common/common.js

@@ -63,24 +63,9 @@ function alertError(AMessage, ATitle, id) {
     return alertMessage("red", AMessage, ATitle, id);
 }
 
-function alertWarning(AMessage, ATitle, id) {
-    //return alertMessage("fa fa-asterisk", "blue", "btn-blue", AMessage, ATitle, id);
-    return alertMessage("fa fa-warning", "red", "red", "btn-red", AMessage, ATitle, id);
-}
 
-function alertConfirm(AMessage, ATitle, id) {
-    return alertMessage(
-        "fa fa-info-circle dx-theme-accent-as-text-color",
-        "blue dx-theme-accent-as-border-color",
-        "dx-theme-accent-as-text-color",
-        "btn-blue dx-theme-accent-as-background-color",
-        AMessage,
-        ATitle,
-        id
-    );
-}
 
-function alertMessage(type, AMessage, ATitle, id, confirmMethod) {
+function alertMessage(type, AMessage, ATitle, id, confirmMethod, isConfirm) {
 
     const alertModal = $('.modal.alert');
     if (alertModal[0]) {
@@ -91,14 +76,14 @@ function alertMessage(type, AMessage, ATitle, id, confirmMethod) {
                         <div class="title">
                             <div></div>
                             <div>${ATitle}</div>
-                            <div onclick="closeModal('.modal.alert')"></div>
+                            <div class="alert-x"></div>
                         </div>
                         <div class="content">
                             ${AMessage}
                         </div>
                         <div class="button-box">
                             <input type="button" id="confirm-button" value="확인" class="button ${type}">`;
-                 if(confirmMethod) {
+                 if (confirmMethod && !isConfirm) {
                      str+= `<input type="button" id="cancel-button" class="button" value="취소" onclick="closeModal('.modal.alert')">`;
                  }
                  str +=`</div>
@@ -108,9 +93,10 @@ function alertMessage(type, AMessage, ATitle, id, confirmMethod) {
     $('body').append(modal);
     modal.css('display', 'flex');
     const confirmBtn = $('#confirm-button');
+    const alertX = $('.alert-x');
     confirmBtn.focus();
     confirmBtn.on('click', ()=>{
-        closeModal('.modal.alert')
+        closeModal('.modal.alert');
         if (confirmMethod) {
             confirmMethod();
         }
@@ -118,6 +104,16 @@ function alertMessage(type, AMessage, ATitle, id, confirmMethod) {
             id.focus();
         }
     });
+
+    alertX.on('click', ()=>{
+        closeModal('.modal.alert');
+        if (isConfirm) {
+            confirmMethod();
+        }
+        else {
+            closeModal('.modal.alert');
+        }
+    })
 }
 function confirmMessage(AMessage, ATitle) {
     const title = ATitle ?? document.title;

+ 28 - 28
src/main/resources/static/js/traffic/traffic.js

@@ -769,7 +769,7 @@ function drawAtrdMakrer(src, lng, lat, name) {
         position: markerPosition,
         image: markerImage,
         zIndex: 5,
-        // title: name,
+        title: name,
     });
     return atrdSideMarker;
 }
@@ -907,33 +907,33 @@ class TbAtrdObj {
         const name = this.NAME + " [" + this.obj.drct_nm + "]";
         this.marker = drawAtrdMakrer(this.obj.drct_cd, this.Y_CRDN, this.X_CRDN, name);
         this.click();
-        let _self = this;
-        new kakao.maps.event.addListener(this.marker, 'mouseover', function (event) {
-            let position = getKakaoPosition(_self.Y_CRDN, _self.X_CRDN);
-            const iwContent =
-                `<div class="trafficPop">
-                    <div>
-                        <span class="traffic-name">${_self.NAME}</span>
-                        <span>[${_self.obj.drct_nm}]</span>
-                    </div>
-                    <div class="traffic-info">
-                        <span>평균속도 : ${Math.round(_self.sped/_self.cnt)} km/h</span><br>
-                        <span>통행시간 : ${textFormat(Math.round(_self.trvl_hh/_self.trvl_hh))}분 </span>
-                    </div>
-                 </div>`;
-            _self.infoWindow = new kakao.maps.CustomOverlay({
-                map: _MapHandler.map,
-                clickable: true,
-                position: position,
-                content: iwContent,
-                xAnchor: -0.1,
-                yAnchor: 1.1,
-                zIndex: 4
-            });
-        });
-        new kakao.maps.event.addListener(this.marker, 'mouseout', function (event) {
-            _self.infoWindow.setMap(null);
-        })
+        // let _self = this;
+        // new kakao.maps.event.addListener(this.marker, 'mouseover', function (event) {
+        //     let position = getKakaoPosition(_self.Y_CRDN, _self.X_CRDN);
+        //     const iwContent =
+        //         `<div class="trafficPop">
+        //             <div>
+        //                 <span class="traffic-name">${_self.NAME}</span>
+        //                 <span>[${_self.obj.drct_nm}]</span>
+        //             </div>
+        //             <div class="traffic-info">
+        //                 <span>평균속도 : ${Math.round(_self.sped/_self.cnt)} km/h</span><br>
+        //                 <span>통행시간 : ${textFormat(Math.round(_self.trvl_hh/_self.trvl_hh))}분 </span>
+        //             </div>
+        //          </div>`;
+        //     _self.infoWindow = new kakao.maps.CustomOverlay({
+        //         map: _MapHandler.map,
+        //         clickable: true,
+        //         position: position,
+        //         content: iwContent,
+        //         xAnchor: -0.1,
+        //         yAnchor: 1.1,
+        //         zIndex: 4
+        //     });
+        // });
+        // new kakao.maps.event.addListener(this.marker, 'mouseout', function (event) {
+        //     _self.infoWindow.setMap(null);
+        // })
     }
 
     click() {

+ 33 - 20
src/main/resources/templates/admin/notice-view.html

@@ -170,18 +170,18 @@
     function delEvent() {
         const boardNo    = [[${notice.getBoardNo()}]];
         const bSubject   = [[${notice.getBSubject()}]];
-        if (confirm( "번호 : " + boardNo + "\n제목 : " + bSubject + '\n게시물을 삭제하시겠습니까?')) {
+        const message = '번호 : ' + boardNo + '<br>제목 : ' + bSubject + '<br>게시물을 삭제하시겠습니까?';
+        alertMessage('red', message, '공지사항', null, ()=>{
             getDataAsync('/api/notice/deleteNotice', 'DELETE', {boardNo : boardNo}, null, (jsonData)=>{
                 if (jsonData) {
-                    alert(jsonData.message);
-                    if (jsonData.success === "S") {
-                        window.location.href = '/phits/notice-list';
-                    }
+                    alertMessage('blue', jsonData.message, '공지사항', null, ()=>{
+                        if (jsonData.success === "S") {
+                            window.location.href = '/phits/notice-list';
+                        }
+                    }, true)
                 }
-            }, (error)=>{
-                console.log(error);
-            });
-        }
+            }, null);
+        });
     }
 
     function save() {
@@ -191,27 +191,39 @@
         const attachNm = notice.attach_file.split("|")[0];
         let content    = $content.val();
 
+        if (content && content.length >= 13) {
+            let trimContent = content.replaceAll("<p>&nbsp;</p>", "");
+            if (trimContent === "") {
+                content = "";
+            }
+            else {
+                let spaceGap = content.length - 13;
+                let spaceEl = content.substring(spaceGap);
+                if (spaceEl === '<p>&nbsp;</p>') {
+                    content = content.substring(0, spaceGap);
+                }
+            }
+        }
+
         if (notice.b_subject === title && notice.b_content === content) {
             if (file) {
                if (file.name === attachNm) {
-                   return alert("수정하신 내용이 없습니다. 내용을 확인 해 주세요");
+                   return alertError('수정하신 내용이 없습니다. 내용을 확인해주세요.', '공지사항');
                }
             }
             else {
                 const attachFileName = $attach.children().eq(0).text();
                 if ( (attachFileName === "첨부파일 없음" && attachNm === "") || attachFileName === attachNm) {
-                    return alert("수정하신 내용이 없습니다. 내용을 확인 해 주세요");
+                    return alertError('수정하신 내용이 없습니다. 내용을 확인해주세요.', '공지사항');
                 }
             }
         }
         if (isNull(title)) {
-            $title.focus();
-            return alert("공지사항 제목을 입력해주세요.");
+            return alertError('공지사항 제목을 입력해주세요', '공지사항', $title);
         }
 
         if (isNull(content)) {
-            $content.focus();
-            return alert("공지사항 내용을 입력해주세요.");
+            return alertError('공지사항 내용을 입력해주세요', '공지사항', $content);
         }
 
         const formData = new FormData();
@@ -227,14 +239,15 @@
             type: 'POST',
             success: function(jsonData) {
                 if (jsonData) {
-                    alert(jsonData.message);
-                    if (jsonData.success === "S") {
-                        window.location.href = "/phits/notice-view/" + notice.board_no;
-                    }
+                    alertMessage('blue', jsonData.message, '공지사항', null, ()=>{
+                        if (jsonData.success === "S") {
+                            window.location.href = "/phits/notice-view/" + notice.board_no;
+                        }
+                    }, true);
                 }
             },
             error: function(error) {
-                alert(error.responseJSON.message);
+                sendErrorMsg(error);
             }
         });
 

+ 20 - 11
src/main/resources/templates/admin/notice-write.html

@@ -87,7 +87,6 @@
     function deleteAttach() {
         $attachFile.val("");
         $attach.html("<div>첨부파일 없음</div>")
-        console.log($attachFile[0].files[0]);
     }
 
     function save() {
@@ -97,17 +96,26 @@
         const file    = $attachFile[0].files[0];
         const formData = new FormData();
         let content = $content.val();
-        if (content.includes('target="_self"')) {
-            content.replaceAll('target="_self"', 'target="_blank" rel="noreperer nooopenner"')
+        if (content && content.length >= 13) {
+            let trimContent = content.replaceAll("<p>&nbsp;</p>", "");
+            if (trimContent === "") {
+                content = "";
+            }
+            else {
+                let spaceGap = content.length - 13;
+                let spaceEl = content.substring(spaceGap);
+                if (spaceEl === '<p>&nbsp;</p>') {
+                    content = content.substring(0, spaceGap);
+                }
+            }
         }
+
         if (isNull(title)) {
-            $title.focus();
-            return alert("공지사항 제목을 입력해주세요.");
+            return alertError('공지사항 제목을 입력해주세요', '공지사항', $title);
         }
 
         if (isNull(content)) {
-            $content.focus();
-            return alert("공지사항 내용을 입력해주세요.");
+            return alertError('공지사항 내용을 입력해주세요', '공지사항', $content);
         }
 
         formData.append("bsubject", title);
@@ -125,10 +133,11 @@
             type: 'POST',
             success: function(jsonData) {
                 if (jsonData) {
-                    alert(jsonData.message);
-                    if (jsonData.success === "S") {
-                        window.location.href = "/phits/notice-list";
-                    }
+                    alertMessage('blue', jsonData.message, '공지사항', null, ()=>{
+                        if (jsonData.success === "S") {
+                            window.location.href = "/phits/notice-list";
+                        }
+                    }, true);
                 }
             },
             error: function(error) {

+ 42 - 31
src/main/resources/templates/admin/popup-view.html

@@ -45,6 +45,7 @@
 </body>
 </html>
 <script th:inline="javascript">
+
     const $delete     = $('.del-btn');
     const $save       = $('.save-btn');
     const $edit       = $('.edit-btn');
@@ -187,18 +188,19 @@
      * 삭제 이벤트
      */
     function delEvent() {
-        if (confirm( "번호 : " + popupId + "\n제목 : " + popupTitle + '\n게시물을 삭제하시겠습니까?')) {
+        let message = "번호 : " + popupId + "<br>제목 : " + popupTitle + '<br>게시물을 삭제하시겠습니까?';
+        alertMessage('red', message, '팝업공지', null, ()=>{
             getDataAsync('/api/popup/deletePopup', 'POST', {popupId : popupId}, null, (jsonData)=>{
                 if (jsonData) {
-                    alert(jsonData.message);
-                    if (jsonData.success === "S") {
-                        window.location.href = '/phits/popup-list';
-                    }
+                    // alert();
+                    alertMessage('blue', jsonData.message, '팝업공지', null, ()=>{
+                        if (jsonData.success === "S") {
+                            window.location.href = '/phits/popup-list';
+                        }
+                    }, true)
                 }
-            }, (error)=>{
-                console.log(error);
-            });
-        }
+            }, null);
+        });
     }
 
     /**
@@ -206,13 +208,32 @@
      */
     function save() {
         object.getById["content"].exec("UPDATE_CONTENTS_FIELD", []);
-        // const file     = $attachFile[0].files[0];
         const title    = $title.val();
-        const pcontent = $content.val();
-        // const attachNm = popup.img_name;
+        let pcontent = $content.val();
         const postVal  = $post.val();
         let postFrom   = "";
         let postTo     = "";
+        if (pcontent && pcontent.length >= 13) {
+            let trimContent = pcontent.replaceAll("<p>&nbsp;</p>", "");
+            if (trimContent === "") {
+                pcontent = "";
+            }
+            else {
+                let spaceGap = pcontent.length - 13;
+                let spaceEl = pcontent.substring(spaceGap);
+                if (spaceEl === '<p>&nbsp;</p>') {
+                    pcontent = pcontent.substring(0, spaceGap);
+                }
+            }
+        }
+
+        if (isNull(title)) {
+            return alertError('팝업 공지 제목을 입력해주세요', '팝업공지', $title);
+        }
+
+        if (isNull(pcontent)) {
+            return alertError('팝업 공지 내용을 입력해주세요', '팝업공지', $content);
+        }
 
         //첨부파일 기간값 유효성 체크
         if (!isNull(postVal)) {
@@ -222,23 +243,12 @@
                 postTo   = postArray[1];
             }
             else {
-                $post.focus();
-                return alert('공지기간 값을 입력해주세요');
+                return alertError('공지기간 값을 입력해주세요', '팝업공지', $post);
             }
         }
 
-        if (popup.title === title && popup.pcontent === pcontent && $post.post_from === postFrom && $post.post_to === postTo) {
-            // if (file) {
-            //    if (file.name === attachNm) {
-            //        return alert("수정하신 내용이 없습니다. 내용을 확인 해 주세요");
-            //    }
-            // }
-            // else {
-            //     const attachFileName = $attach.children().eq(0).text();
-            //     if ( (attachFileName === "첨부파일 없음" && attachNm === "") || attachFileName === attachNm) {
-            return alert("수정하신 내용이 없습니다. 내용을 확인 해 주세요");
-                // }
-            // }
+        if (popup.title === title && popup.pcontent === pcontent && popup.post_from === postFrom && popup.post_to === postTo) {
+            return alertError("수정하신 내용이 없습니다. 내용을 확인 해 주세요", '팝업공지');
         }
 
         const formData = new FormData();
@@ -257,14 +267,15 @@
             type: 'POST',
             success: function(jsonData) {
                 if (jsonData) {
-                    alert(jsonData.message);
-                    if (jsonData.success === "S") {
-                        window.location.href = "/phits/popup-view/" + popupId;
-                    }
+                    alertMessage('blue', jsonData.message, '팝업공지', null, ()=>{
+                        if (jsonData.success === "S") {
+                            window.location.href = "/phits/popup-view/" + popupId;
+                        }
+                    }, true);
                 }
             },
             error: function(error) {
-                alert(error.responseJSON.message);
+                sendErrorMsg(error)
             }
         });
 

+ 25 - 14
src/main/resources/templates/admin/popup-write.html

@@ -104,7 +104,7 @@
     function save() {
         object.getById["content"].exec("UPDATE_CONTENTS_FIELD", []);
         const title    = $title.val();
-        const pcontent = $content.val();
+        let pcontent = $content.val();
         // const file    = $attachFile[0].files[0];
         const postVal  = $post.val();
 
@@ -120,27 +120,37 @@
             }
         }
 
+        if (pcontent && pcontent.length >= 13) {
+            let trimContent = pcontent.replaceAll("<p>&nbsp;</p>", "");
+            if (trimContent === "") {
+                pcontent = "";
+            }
+            else {
+                let spaceGap = pcontent.length - 13;
+                let spaceEl = pcontent.substring(spaceGap);
+                if (spaceEl === '<p>&nbsp;</p>') {
+                    pcontent = pcontent.substring(0, spaceGap);
+                }
+            }
+        }
+
         const formData = new FormData();
 
         // 유효성 체크
         if (isNull(title)) {
-            $title.focus();
-            return alert("팝업 공지 제목을 입력해주세요.");
+            return alertError('팝업 공지 제목을 입력해주세요', '팝업공지', $title);
         }
 
         if (isNull(pcontent)) {
-            $content.focus();
-            return alert("팝업 공지 내용을 입력해주세요.");
+            return alertError('팝업 공지 내용을 입력해주세요', '팝업공지', $content);
         }
 
         if (isNull(postFrom)) {
-            $post.focus();
-            return alert("팝업 공지 기간 시작일을 입력해주세요.");
+            return alertError('팝업 공지 기간 시작일을 입력해주세요.', '팝업공지', $post);
         }
 
         if (isNull(postTo)) {
-            $post.focus();
-            return alert("팝업 공지 기간 종료일을 입력해주세요.");
+            return alertError('팝업 공지 기간 종료일을 입력해주세요.', '팝업공지', $post);
         }
 
         // if (!file) {
@@ -160,14 +170,15 @@
             type: 'POST',
             success: function(jsonData) {
                 if (jsonData) {
-                    alert(jsonData.message);
-                    if (jsonData.success === "S") {
-                        window.location.href = "/phits/popup-list";
-                    }
+                    alertMessage('blue', jsonData.message, '팝업공지', null, ()=>{
+                        if (jsonData.success === "S") {
+                            window.location.href = "/phits/popup-list";
+                        }
+                    }, true);
                 }
             },
             error: function(error) {
-                alert(error.responseJSON.message);
+                sendErrorMsg(error);
             }
         });
     }