瀏覽代碼

푸시 발송 기능 추가

huiwon.seo 4 年之前
父節點
當前提交
9d8974b45c

+ 150 - 14
src/main/java/com/lemon/lifecenter/controller/PushController.java

@@ -136,12 +136,14 @@ public class PushController extends LifeCenterController {
     @ResponseBody
     public String getPushResultList(
             @RequestParam(value="resultType", required=true ) String resultType,
+            @RequestParam(value="logIdx", required=true ) int logIdx,
             @RequestParam(value="pushIdx", required=true ) int pushIdx,
             @RequestParam(value="ym", required=true ) String ym ) {
         
         PushDTO dto = new PushDTO();
         
         dto.setPushIdx( pushIdx );
+        dto.setLogIdx( logIdx );
         dto.setYm( ym );
         
         int total = pushService.selectPushResultTableCount(dto);
@@ -191,11 +193,9 @@ public class PushController extends LifeCenterController {
         dto.setSendState( "W" );
         
         pushService.insertPushData(dto);
-//        System.out.println( "PUSH IDX ::: " + dto.getPushIdx() );
         
         if( dto.getSelectType().equals( "PATIENT" ) && dto.getTargetType().equals( "P" ) ) {
             for( int i = 0; i < patientIdx.length; i ++ ) {
-//                System.out.println( patientIdx[i] );
                 
                 dto.setPatientIdx( Integer.valueOf( patientIdx[i] ) );
                 
@@ -203,37 +203,173 @@ public class PushController extends LifeCenterController {
             }
         }
         
-        return "redirect:/push/list";
+        if( dto.getSendType().equals( "D" ) ) {
+            return "redirect:/push/list";
+        } else {
+            return "redirect:/push/schedule/list";
+        }
     }
     
-    @RequestMapping( "/info" )
-    public ModelAndView info() {
+    
+    @RequestMapping( value="/schedule/update", method=RequestMethod.POST )
+    @Transactional(propagation=Propagation.REQUIRED)
+    public String updatePushData(
+            @ModelAttribute("dto") final PushDTO dto,
+            @RequestParam(value="patientIdx", required=false, defaultValue="") String[] patientIdx,
+            HttpServletRequest request,HttpServletResponse response ) {
+        String sesId = LifeCenterSessionController.getSession( request, "sesId" );
         
-        ModelAndView mv = setMV("push/info");
+        dto.setUpdateBy( sesId );
         
-        return mv;
+        pushService.updatePushData(dto);
+        
+        if( dto.getSelectType().equals( "PATIENT" ) && dto.getTargetType().equals( "P" ) ) {
+            pushService.deletePushTargeTemp(dto);
+            
+            for( int i = 0; i < patientIdx.length; i ++ ) {
+                
+                dto.setPatientIdx( Integer.valueOf( patientIdx[i] ) );
+                
+                pushService.insertPushTargetTemp(dto);
+            }
+        }
+        
+        if( dto.getSendType().equals( "D" ) ) {
+            return "redirect:/push/list";
+        } else {
+            return "redirect:/push/schedule/list";
+        }
     }
     
-    @RequestMapping( "/edit" )
-    public ModelAndView edit() {
+    
+    @RequestMapping( value="/schedule/delete", method=RequestMethod.POST )
+    @Transactional(propagation=Propagation.REQUIRED)
+    public String deletePushData(
+            @ModelAttribute("dto") final PushDTO dto,
+            HttpServletRequest request,HttpServletResponse response ) {
         
-        ModelAndView mv = setMV("push/edit");
+        pushService.deletePushTargeTemp(dto);
+        pushService.deletePushData(dto);
+        
+        return "redirect:/push/schedule/list";
+    }
+    
+    
+    @RequestMapping( "schedule/info" )
+    public ModelAndView info( @RequestParam( value="pushIdx", required=true ) int pushIdx,
+            HttpServletRequest request,HttpServletResponse response ) {
+        
+        PushDTO dto = new PushDTO();
+        dto.setPushIdx( pushIdx );
+        
+        int total = pushService.selectPushScheduleOneCount(dto);
+        int patientTotal = 0;
+        List<PushDTO> patientList = new ArrayList<PushDTO>();
+        
+        if( total > 0 ) {
+            dto = pushService.selectPushScheduleOneData(dto);
+            
+            if( dto.getTargetType().equals( "P" ) ) {
+                patientTotal = pushService.selectPushTargetTempCount(dto);
+                
+                if( patientTotal > 0 ) {
+                    patientList = pushService.selectPushTargetTempList(dto);
+                }
+            }
+        }
+        
+        ModelAndView mv = setMV("push/info");
+        
+        mv.addObject( "total", total );
+        mv.addObject( "result", dto );
+        mv.addObject( "patientTotal", patientTotal );
+        mv.addObject( "patientList", patientList );
         
         return mv;
     }
     
-    @RequestMapping( "/edit/update" )
-    public String updatePushData() {
+    @RequestMapping( value="/schedule/edit", method=RequestMethod.POST )
+    public ModelAndView edit( @RequestParam( value="pushIdx", required=true ) int pushIdx,
+            HttpServletRequest request,HttpServletResponse respons ) {
+        
+        String sesCenterCode  = LifeCenterSessionController.getSession( request, "sesCenterCode" );
+        String sesGroupIdx    = LifeCenterSessionController.getSession( request, "sesGroupIdx" );
+        
+        PatientDTO pdto = new PatientDTO();
+        
+        pdto.setCenterCode( Integer.parseInt( sesCenterCode ) );
+        pdto.setGroupIdx( Integer.valueOf( sesGroupIdx ) );
+        pdto.setState( "H" );
+        
+        int patientAllTotal = patientService.selectPatientCount(pdto);
+        List<PatientDTO> patientAllList = new ArrayList<PatientDTO>();
+
+        if (patientAllTotal > 0) {
+            pdto.setLimit( 0 );
+            pdto.setLimitMax( patientAllTotal );
+            patientAllList = patientService.selectPatientList(pdto);
+        }
+        
+        PushDTO dto = new PushDTO();
+        
+        dto.setPushIdx( pushIdx );
+        
+        int total = pushService.selectPushScheduleOneCount(dto);
+        int patientTotal = 0;
+        List<PushDTO> patientList = new ArrayList<PushDTO>();
+        ArrayList<String> checkList = new ArrayList<String>();
+        
+        if( total > 0 ) {
+            dto = pushService.selectPushScheduleOneData(dto);
+            
+            if( dto.getTargetType().equals( "P" ) ) {
+                patientTotal = pushService.selectPushTargetTempCount(dto);
+                
+                if( patientTotal > 0 ) {
+                    patientList = pushService.selectPushTargetTempList(dto);
+                     
+                    for( PushDTO p : patientList ) {
+                        checkList.add( String.valueOf( p.getPatientIdx() ) );
+                    }
+                }
+            }
+        }
+        
+        ModelAndView mv = setMV("push/edit");
         
+        mv.addObject( "total", total );
+        mv.addObject( "result", dto );
+        
+        mv.addObject( "patientTotal", patientTotal );
+        mv.addObject( "patientList", patientList );
+        
+        mv.addObject( "checkList", checkList );
+        mv.addObject( "patientAllTotal", patientAllTotal );
+        mv.addObject( "patientAllList", patientAllList );
         
-        return "";
+        return mv;
     }
     
     @RequestMapping( "/schedule/list" )
-    public ModelAndView schedule() {
+    public ModelAndView schedule( HttpServletRequest request,HttpServletResponse response ) {
+        int sesCenterCode = Integer.valueOf( LifeCenterSessionController.getSession( request, "sesCenterCode" ) ) ;
+        //String sesId      = LifeCenterSessionController.getSession( request, "sesId" );
+        
+        PushDTO dto = new PushDTO();
+        dto.setCenterCode( sesCenterCode );
+        
+        int total = pushService.selectPushScheduleCount(dto);
+        List<PushDTO> scheduleList = new ArrayList<PushDTO>();
+        
+        if( total > 0 ) {
+            scheduleList = pushService.selectPushScheduleList(dto);
+        }
         
         ModelAndView mv = setMV("push/schedule");
         
+        mv.addObject( "total", total );
+        mv.addObject( "scheduleList", scheduleList );
+        
         return mv;
     }
 }

+ 28 - 0
src/main/java/com/lemon/lifecenter/dto/PushDTO.java

@@ -3,6 +3,7 @@ package com.lemon.lifecenter.dto;
 
 public class PushDTO {
     private int idx;
+    private int logIdx;
     private int pushIdx;
     private int patientIdx;
     private int centerCode;
@@ -42,7 +43,34 @@ public class PushDTO {
     private String state="";
     private String successYn="";
     private String ym;
+    private int age;
+    private String hospitalizationDate="";
+    private String updateBy;
     
+    public String getUpdateBy() {
+        return updateBy;
+    }
+    public void setUpdateBy(String updateBy) {
+        this.updateBy = updateBy;
+    }
+    public int getLogIdx() {
+        return logIdx;
+    }
+    public void setLogIdx(int logIdx) {
+        this.logIdx = logIdx;
+    }
+    public String getHospitalizationDate() {
+        return hospitalizationDate;
+    }
+    public void setHospitalizationDate(String hospitalizationDate) {
+        this.hospitalizationDate = hospitalizationDate;
+    }
+    public int getAge() {
+        return age;
+    }
+    public void setAge(int age) {
+        this.age = age;
+    }
     public String getFailCode() {
         return failCode;
     }

+ 15 - 0
src/main/java/com/lemon/lifecenter/mapper/PushMapper.java

@@ -11,10 +11,25 @@ import com.lemon.lifecenter.dto.PushDTO;
 @Mapper
 public interface PushMapper {
     public void insertPushData( PushDTO dto );
+    public void updatePushData( PushDTO dto );
+    public void deletePushData( PushDTO dto );
+    
     public void insertPushTargetTemp( PushDTO dto );
+    public void deletePushTargetTemp( PushDTO dto );
+    
+    public int selectPushTargetTempCount( PushDTO dto );
+    public List<PushDTO> selectPushTargetTempList( PushDTO dto );
+    
     public int selectPushListTotal( PushDTO dto );
     public List<PushDTO> selectPushListData( PushDTO dto );
+    
     public int selectPushResultTableCount( PushDTO dto );
     public int selectPushResultTotal( PushDTO dto );
     public List<PushDTO> selectPushResultList( PushDTO dto );
+    
+    public int selectPushScheduleCount( PushDTO dto );
+    public List<PushDTO> selectPushScheduleList( PushDTO dto );
+    
+    public int selectPushScheduleOneCount( PushDTO dto );
+    public PushDTO selectPushScheduleOneData( PushDTO dto );
 }

+ 28 - 2
src/main/java/com/lemon/lifecenter/service/PushService.java

@@ -16,11 +16,25 @@ public class PushService {
     public void insertPushData( PushDTO dto ) {
         mapper.insertPushData(dto);
     }
-    
+    public void updatePushData( PushDTO dto ) {
+        mapper.updatePushData(dto);
+    }
+    public void deletePushData( PushDTO dto ) {
+        mapper.deletePushData(dto);
+    }
     public void insertPushTargetTemp( PushDTO dto ) {
         mapper.insertPushTargetTemp(dto);
     }
-    
+    public void deletePushTargeTemp( PushDTO dto ) {
+        mapper.deletePushTargetTemp(dto);
+    }
+    public int selectPushTargetTempCount( PushDTO dto ) {
+        return mapper.selectPushTargetTempCount(dto);
+    }
+    public List<PushDTO> selectPushTargetTempList( PushDTO dto ){
+        return mapper.selectPushTargetTempList(dto);
+    }
+        
     public int selectPushListTotal( PushDTO dto ) {
         return mapper.selectPushListTotal(dto);
     }
@@ -37,4 +51,16 @@ public class PushService {
     public List<PushDTO> selectPushResultList( PushDTO dto ){
         return mapper.selectPushResultList(dto);
     }
+    public int selectPushScheduleCount( PushDTO dto ) {
+        return mapper.selectPushScheduleCount(dto);
+    }
+    public List<PushDTO> selectPushScheduleList( PushDTO dto ){
+        return mapper.selectPushScheduleList(dto);
+    }
+    public int selectPushScheduleOneCount( PushDTO dto ) {
+        return mapper.selectPushScheduleOneCount(dto);
+    }
+    public PushDTO selectPushScheduleOneData( PushDTO dto ) {
+        return mapper.selectPushScheduleOneData(dto);
+    }
 }

+ 147 - 4
src/main/resources/mybatis/mapper/push/push.xml

@@ -71,6 +71,7 @@
                     SELECT COUNT(*) total
                       FROM push_schedule
                      WHERE send_type = 'D'
+                       AND send_state = 'W'
                 ) A
         ]]>
     </select>
@@ -108,7 +109,8 @@
                                  COUNT( IF(success_yn='N', 1, null) ) fail_count,
                                  COUNT( IF(state='W', 1, null) ) wait_count
                             FROM push_result_${ym} A 
-                           WHERE push_idx = PL.push_idx 
+                           WHERE push_idx = PL.push_idx
+                             AND log_idx = PL.idx
                            GROUP BY A.push_idx ) PR
                 ON PR.push_idx = PL.push_idx
              WHERE 1 = 1
@@ -174,7 +176,7 @@
                     push_content AS pushContent,
                     ( SELECT `name` FROM member WHERE id= sender ) AS `name`,
                     DATE_FORMAT( create_date, '%Y-%m-%d %H:%i' )   AS createDate,
-                    null   AS startDate,
+                    DATE_FORMAT( create_date, '%Y-%m-%d %H:%i' )   AS startDate,
                     null   AS endDate,
                     0      AS totalCount,
                     0      AS successCount,
@@ -184,8 +186,9 @@
                     ( SELECT center_name FROM center_info WHERE center_code =  push_schedule.center_code ) AS centerName
                FROM push_schedule
               WHERE send_type = 'D'
-              
-              ORDER BY createDate desc
+                AND send_state = 'W'
+                
+              ORDER BY startDate desc
               LIMIT ${limit}, ${limitMax}
         ]]>
     </select>
@@ -196,6 +199,7 @@
               FROM push_result_${ym} PR
              WHERE 1=1
                AND PR.push_idx = #{pushIdx}
+               AND PR.log_idx = #{logIdx}
         ]]>
                  
         <if test='state != null and state !=""'>
@@ -233,6 +237,7 @@
                 ON PR.patient_idx = PC.patient_idx
              WHERE 1=1
                AND PR.push_idx = #{pushIdx}
+               AND PR.log_idx = #{logIdx}
         ]]>
                  
         <if test='state != null and state !=""'>
@@ -264,6 +269,29 @@
         ]]>
     </insert>
     
+    <update id="updatePushData" parameterType="PushDTO">
+        <![CDATA[
+            UPDATE push_schedule
+               SET send_type    = #{sendType},
+                   target_type  = #{targetType},
+                   push_title   = #{pushTitle},
+                   push_content = #{pushContent},
+                   send_date    = #{sendDate},
+                   send_time    = #{sendTime},
+                   update_date  = NOW(),
+                   update_by    = #{updateBy}
+             WHERE push_idx = #{pushIdx}
+        ]]>
+    </update>
+    
+    <delete id="deletePushData" parameterType="PushDTO">
+        <![CDATA[
+            DELETE 
+              FROM push_schedule 
+             WHERE push_idx = #{pushIdx}
+        ]]>
+    </delete>
+    
     <insert id="insertPushTargetTemp" parameterType="PushDTO">
         <![CDATA[
             INSERT
@@ -272,4 +300,119 @@
             VALUES ( #{pushIdx}, #{patientIdx} )
         ]]>
     </insert>
+    
+    <delete id="deletePushTargetTemp" parameterType="PushDTO">
+        <![CDATA[
+            DELETE
+              FROM push_target_temp
+             WHERE push_idx = #{pushIdx}
+        ]]>
+    </delete>
+    
+    <select id="selectPushTargetTempCount" parameterType="PushDTO" resultType="int">
+        <![CDATA[
+            SELECT COUNT(*) total
+              FROM push_target_temp
+             WHERE push_idx = #{pushIdx}
+        ]]>
+    </select>
+    
+    <select id="selectPushTargetTempList" parameterType="PushDTO" resultType="PushDTO">
+        <![CDATA[
+            SELECT PT.push_idx                                                       AS pushIdx,
+                   PT.patient_idx                                                    AS patientIdx,
+                   PC.patient_name                                                   AS patientName,
+                   CASE WHEN PC.GENDER = 'M' THEN '남'
+                        WHEN PC.GENDER = 'F' THEN '여'
+                        ELSE ''
+                   END                                                               AS gender,
+                   (SELECT TRUNC((SYSDATE-TO_DATE(PC.JUMIN, 'YYYYMMDD'))/365) + 1)   AS age,
+                   PC.ward_number                                                    AS wardNumber,
+                   PC.room_number                                                    AS roomNumber,
+                   DATE_FORMAT(PC.JUMIN, '%Y-%m-%d')                                 AS jumin,
+                   DATE_FORMAT(PC.HOSPITALIZATION_DATE, '%Y-%m-%d')                  AS hospitalizationDate
+              FROM push_target_temp PT
+              LEFT JOIN patient_care PC
+                ON PC.patient_idx = PT.patient_idx
+             WHERE push_idx = #{pushIdx}
+        ]]>
+    </select>
+    
+    <select id="selectPushScheduleCount" parameterType="PushDTO" resultType="int">
+        <![CDATA[
+            SELECT COUNT(*) total
+              FROM push_schedule
+             WHERE send_type != 'D'
+        ]]>
+        
+        <if test='centerCode != null and centerCode !=""'>
+            <![CDATA[
+               AND center_code = #{centerCode}
+            ]]>
+        </if>
+    </select>
+    
+    <select id="selectPushScheduleList" parameterType="PushDTO" resultType="PushDTO">
+        <![CDATA[
+            SELECT PS.push_idx     AS pushIdx,
+                   PS.send_type    AS sendType,
+                   PS.send_state   AS sendState,
+                   PS.target_type  AS targetType,
+                   PS.center_code  AS centerCode,
+                   PS.sender_ip    AS senderIp,
+                   PS.sender       AS sender,
+                   PS.push_title   AS pushTitle,
+                   PS.push_content AS pushContent,
+                   PS.send_date    AS sendDate,
+                   TIME_FORMAT( PS.send_time, '%H:%i' ) AS sendTime,
+                   DATE_FORMAT( PS.create_date, '%Y-%m-%d %H:%i' ) AS createDate,
+                   M.name          AS name
+              FROM push_schedule PS
+              LEFT JOIN member M
+                ON PS.sender = M.id
+             WHERE PS.send_type != 'D'
+        ]]>
+        
+        <if test='centerCode != null and centerCode !=""'>
+            <![CDATA[
+               AND PS.center_code = #{centerCode}
+            ]]>
+        </if>
+        
+        <![CDATA[
+             ORDER BY PS.push_idx DESC
+        ]]>
+    </select>
+    
+    
+    <select id="selectPushScheduleOneCount" parameterType="PushDTO" resultType="int">
+        <![CDATA[
+            SELECT COUNT(*) total
+              FROM push_schedule
+             WHERE push_idx = #{pushIdx}
+        ]]>
+    </select>
+    
+    <select id="selectPushScheduleOneData" parameterType="PushDTO" resultType="PushDTO">
+        <![CDATA[
+            SELECT PS.push_idx     AS pushIdx,
+                   PS.send_type    AS sendType,
+                   PS.send_state   AS sendState,
+                   PS.target_type  AS targetType,
+                   PS.center_code  AS centerCode,
+                   PS.sender_ip    AS senderIp,
+                   PS.sender       AS sender,
+                   PS.push_title   AS pushTitle,
+                   PS.push_content AS pushContent,
+                   PS.send_date    AS sendDate,
+                   TIME_FORMAT( PS.send_time, '%H:%i' ) AS sendTime,
+                   DATE_FORMAT( PS.create_date, '%Y-%m-%d %H:%i' ) AS createDate,
+                   M.name          AS name,
+                   ( SELECT center_name FROM center_info WHERE center_code =  PS.center_code ) AS centerName
+              FROM push_schedule PS
+              LEFT JOIN member M
+                ON PS.sender = M.id
+             WHERE PS.push_idx = #{pushIdx}
+        ]]>
+    </select>
 </mapper>

+ 475 - 0
src/main/webapp/WEB-INF/jsp/push/edit.jsp

@@ -0,0 +1,475 @@
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+    pageEncoding="UTF-8"%>
+<jsp:include page="${data._INCLUDE}/header.jsp"></jsp:include>
+<script type="text/javascript" src="/resources/js/common/jquery.tablesorter.min.js"></script>
+<script>
+var arr = <c:out value='${checkList}'/>;
+
+$( function(){
+    // targetTemp에 등록된 환자 check 처리
+    arr.forEach(function( item ){ 
+        console.log( $( "#patientList" ).find( "input[type='checkbox']:input[value='"+item+"']" ) );
+        $( "#patientList" ).find( "input[type='checkbox']:input[value='"+item+"']" ).prop( "checked", true );
+    });
+    addPatientToTargetTemp();
+    //-------------------------------
+    
+    setEventInit();
+    setTargetSelect();
+    setSendSelect();
+    
+    $( "#sendForm" ).validate({
+        rules: {
+            sendDate : {
+                date : true
+            }
+        },
+        messages : {
+            targetPreview : {
+                required : "대상자를 1명 이상 선택해주세요"
+            }
+        },
+        onfocusout: function (element) {
+            $( element ).val( $.trim( $( element ).val() ) );
+            $( element ).valid();
+        },
+        submitHandler: function(form) {
+            console.log( $( form ).serialize() );
+            
+            alertBox({ 
+                txt: "등록 하시겠습니까?",
+                type : "confirm",
+                callBack : function( result ){
+                    if( result ) {
+                        form.submit();
+                    }
+                }
+            })
+        }
+    });
+    
+    $( "input.date" ).daterangepicker({
+        singleDatePicker : true,
+//         timePicker: true,
+        showDropdowns : true,
+        locale : {
+            format : "YYYY-MM-DD"
+        },
+//         maxDate : ,
+        minDate : new Date()
+    }).on('apply.daterangepicker', function(ev, picker) {
+        
+        // 예약발송 -> 오늘날짜면 minDate 재설정
+        $( "input.date-time-r" ).daterangepicker({
+            singleDatePicker : true,
+            showDropdowns : true,
+            timePicker: true,
+            locale: {
+                format: 'HH:mm'
+            },
+            minDate : new Date()
+        }).on('show.daterangepicker', function(ev, picker) {
+            picker.container.find(".calendar-table").hide();
+        });
+        
+        if( new Date().format( "yyyy-MM-dd" ) < $( this ).val() ) {
+            $( "input.date-time-r" ).data( 'daterangepicker' ).minDate = "";
+        }
+    });
+    
+    // 예약 발송
+    $( "input.date-time-r" ).daterangepicker({
+        singleDatePicker : true,
+        showDropdowns : true,
+        timePicker: true,
+        locale: {
+            format: 'HH:mm'
+        },
+        minDate : new Date()
+    }).on('show.daterangepicker', function(ev, picker) {
+        picker.container.find(".calendar-table").hide();
+    });
+    
+    
+    // 매일 반복 발송
+    $( "input.date-time-e" ).daterangepicker({
+        singleDatePicker : true,
+        showDropdowns : true,
+        timePicker: true,
+        locale: {
+            format: 'HH:mm'
+        }
+    }).on('show.daterangepicker', function(ev, picker) {
+        picker.container.find(".calendar-table").hide();
+    });
+    
+    
+    // checkbox 전체선택, 해제 이벤트 처리
+    $( "#allCheck" ).click( function(){
+        $( "#patientList" ).find( "input[name='patientIdx']" ).prop( "checked", $( this ).prop( "checked" ) );
+    });
+    $( "#patientList" ).find( "input[name='patientIdx']" ).click( function(){
+        if( $( "#patientList" ).find( "input[name='patientIdx']:not(:checked)" ).length > 0 ){
+            $( "#allCheck" ).prop( "checked", false );
+        } else {
+            $( "#allCheck" ).prop( "checked", true );
+        }
+    });
+});
+
+function setEventInit(){
+    // 그룹선택 or 환자개별선택
+    $( "input.target-select" ).click( function(){
+        setTargetSelect();
+    });
+    
+    // 발송방식 선택
+    $( "input.send-select" ).click( function(){
+        setSendSelect();
+    });
+    
+    // 그룹선택이나 환자개별선택시 초기화 해야할부분 처리
+    $( "input[name='selectType']" ).on( "click", function(){
+        var selectType = $( this ).val();
+        
+        if( selectType == "GROUP" ) {
+            // 그룹 선택
+            $('#radio-target-a').click();
+            
+            initPatientSelect();
+        } else if( selectType == "PATIENT" ) {
+            // 환자 개별 선택
+            $('#radio-target-p').click();
+        }
+    });
+    
+    // 환자 개별 선택 팝업창 열때 현재 선택된 환자목록 기준으로 팝업창에서 선택한 환자 동기화
+    $( "#selectPatientList" ).on( "show.bs.modal", function(){
+        var $this               = $( this );
+        var listPushTargetTemp  = $( "#pushTargetTemp" );
+        var savedPushTargetTemp = listPushTargetTemp.find( "input[type='checkbox']:checked" ).serializeArray();
+        
+        $( "#patientList" ).find( "input[type='checkbox']:checked" ).prop( "checked", false );
+        
+        savedPushTargetTemp.forEach( function( item, index, arr2 ){
+//             console.log(item,index,arr2[index+1]);
+            $this.find( "input[type='checkbox']:input[value='"+ item.value +"']" ).prop( "checked", true );
+        });
+    });
+    
+    $( "#sortTable" ).tablesorter();
+}
+
+function setTargetSelect(){
+    $( "tr.target-select" ).hide();
+    $( "#" + $( "input.target-select:checked" ).prop( "accessKey" ) ).fadeIn( 100 );
+};
+
+function setSendSelect(){
+    $( "tr.send-select" ).hide().find( "input" ).prop( "disabled", true );
+    $( "#" + $( "input.send-select:checked" ).prop( "accessKey" ) ).fadeIn( 100 ).find( "input" ).prop( "disabled", false );
+}
+
+function initPatientSelect(){
+    $( "#allCheck" ).prop( "checked", false );
+    $( "#pushTargetTemp" ).empty();
+    $( "#target-preview" ).val( "" );
+    $( "#pushTargetTempTotal" ).text( "" ).hide();
+}
+
+function saveSelectedPatientList(){
+    alertBox({
+        txt : "선택된 환자를 발송 대상자로 적용할까요?",
+        type : "confirm", 
+        callBack : function( result ){
+            
+            if( result ) {
+                addPatientToTargetTemp();
+            } else {
+                console.log( "취소 -> no event" );
+            };
+        }
+    });
+    
+    $( "#selectPatientList" ).find( ".modal-title h3" ).remove();
+}
+
+function addPatientToTargetTemp(){
+    $( "#selectPatientList" ).modal( "hide" );
+    $( "#pushTargetTemp" ).empty();
+    
+    var appendData = $( "#patientList" ).find( "input[type='checkbox']:checked" ).clone();
+    var name = appendData.map( function(){
+        return $( this ).attr( "title" );
+    }).get().join( ", " );
+    
+    console.log( name );
+    
+    appendData.appendTo( "#pushTargetTemp" );
+    
+    if( appendData.length > 0 ){
+        $( "#pushTargetTempTotal" ).text( appendData.length ).show();
+    } else {
+        $( "#pushTargetTempTotal" ).text( "" ).hide();
+    }
+     
+    $( "#target-preview" ).val( name ).valid();
+}
+</script>
+</head>
+<body>
+    <div class="modal fade" id="selectPatientList" tabindex="-1" role="dialog" aria-hidden="true">
+        <div class="modal-dialog modal-xl modal-dialog-scrollable" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">환자 선택</h5>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span> </button>
+                </div>
+                <div class="modal-body m-4">
+                    <table class="table mobile-table table-striped text-center" id="sortTable">
+                        <colgroup>
+                            <col style="width: 5%">
+                            <col style="width: 10%">
+                            <col style="width: 15%">
+                            <col style="width: 20%">
+                            <col style="width: 10%">
+                            <col style="width: 15%">
+                            <col style="width: 10%">
+                            <col style="width: 25%">
+                        </colgroup>
+                        <thead>
+                            <tr>
+                                <th>
+                                    <input type="checkbox" id="allCheck" style="width:20px;height:20px;" >
+                                </th>
+                                <th>번호 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>환자명 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>호실 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>성별 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>생년월일 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>나이 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>입소일자 <i class="fa fa-fw fa-sort"></i></th>
+                            </tr>
+                        </thead>
+                        <tbody id="patientList">
+                            <c:choose>
+                                <c:when test="${patientAllTotal eq 0}">
+                                    <tr>
+                                        <td colspan="8">no data</td>
+                                    </tr>
+                                </c:when>
+                                <c:otherwise>
+                                    <c:forEach var="pl" items="${patientAllList}" varStatus="lStatus">
+                                        <tr>
+                                            <td class="no">
+                                                <input type="checkbox" name="patientIdx" title="[<c:if test="${pl.wardNumber ne '' and pl.wardNumber ne null}">${pl.wardNumber}동</c:if> ${pl.roomNumber}호:${pl.patientName}]" value="${pl.patientIdx}" style="width:20px;height:20px;" >
+                                            </td>
+                                            <td class="no">
+                                                <c:set var="pageNum" value="${patientAllTotal - lStatus.index}" />
+                                                <fmt:formatNumber value="${pageNum}" pattern="#,###" />
+                                            </td>
+                                            <td class="name"><c:out value="${pl.patientName}" /></td>
+                                            <td class="ward"><c:if test="${pl.wardNumber ne '' and pl.wardNumber ne null}">${pl.wardNumber}동</c:if> ${pl.roomNumber}호</td>
+                                            <td class="gender"><c:out value="${pl.gender}" /></td>
+                                            <td class="age"><c:out value="${pl.jumin}" /></td>
+                                            <td class="age"><c:out value="${pl.age}" /></td>
+                                            <td class="hospitalization-date"><c:out value="${pl.hospitalizationDate}" /></td>
+                                        </tr>
+                                    </c:forEach>
+                                </c:otherwise>
+                            </c:choose>
+                        </tbody>
+                    </table>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn border" data-dismiss="modal">취소</button>
+                    <button type="button" class="btn btn-primary" onclick="saveSelectedPatientList();">선택 완료</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    
+    
+    <div class="wrapper">
+        <jsp:include page="${data._INCLUDE}/sidebar.jsp"></jsp:include>
+        
+        <div class="main">
+            <jsp:include page="${data._INCLUDE}/top.jsp"></jsp:include>
+
+            <main class="content">
+                <div class="container-fluid p-0">
+                    <div class="row">
+                        <div class="col-12 col-lg-6">
+                            <h1 class="h3 mb-3">푸시 발송</h1>
+                        </div>
+                        <div class="col-12 col-lg-6  text-right">
+                            <nav aria-label="breadcrumb">
+                                <ol class="breadcrumb">
+                                    <li class="breadcrumb-item"><a href="javscript:;">Home</a></li>
+                                    <li class="breadcrumb-item">푸시서비스 관리</li>
+                                    <li class="breadcrumb-item active">푸시 발송</li>
+                                </ol>
+                            </nav>
+                        </div>
+                    </div>
+                    <div class="row">
+                        <div class="col-12">
+                            <div class="card">
+                                <div class="alert alert-light text-info border p-3">
+                                    <span style="font-size:14px;">· 발송 전체 대상자중 입소자만 푸시 발송 가능<br/>· 그룹선택 발송일 경우 발송시간기준으로 환자 실시간 조회 및 발송되므로 대상자가 현재와 달라질 수 있음</span>
+                                </div>
+                                
+                                <form id="sendForm" action="./update" method="post">
+                                    <input type="hidden" name="pushIdx" value="${result.pushIdx}"/>
+                                    
+                                    <div class="card-body">
+                                        <table class="table mobile-table">
+                                            <colgroup>
+                                                <col style="width:20%">
+                                                <col style="width:80%">
+                                            </colgroup>
+                                            <tr>
+                                                <th>생활치료센터명</th>
+                                                <td><c:out value="${result.centerName}"/></td>
+                                            </tr>
+                                            <tr>
+                                                <th>발송등록자</th>
+                                                <td><c:out value="${result.name}(${result.sender})"/></td>
+                                            </tr>
+                                            <tr>
+                                                <th rowspan="2"><span class="fix">*</span>발송 대상</th>
+                                                <td>
+                                                    <label class="form-check form-check-inline">
+                                                        <input class="form-check-input target-select" accesskey="target-group" type="radio" name="selectType" value="GROUP" <c:if test="${result.targetType ne 'P'}">checked="checked"</c:if>>
+                                                        <span class="form-check-label">그룹 선택</span>
+                                                    </label>
+                                                    <label class="form-check form-check-inline">
+                                                        <input class="form-check-input target-select" accesskey="target-patient" type="radio" name="selectType" value="PATIENT" <c:if test="${result.targetType eq 'P'}">checked="checked"</c:if>>
+                                                        <span class="form-check-label">환자 개별 선택</span>
+                                                    </label>
+                                                </td>
+                                            </tr>
+                                            <tr class="target-select" id="target-group" style="display:none;">
+                                                <td>
+                                                    <label class="form-check form-check-inline">
+                                                        <input class="form-check-input" type="radio" id="radio-target-a" name="targetType" value="A" required <c:if test="${result.targetType eq 'A'}">checked="checked"</c:if>>
+                                                        <span class="form-check-label">전체 환자</span>
+                                                    </label>
+                                                    
+                                                    <label class="form-check form-check-inline">
+                                                        <input class="form-check-input" type="radio" id="radio-target-n" name="targetType" value="N" required <c:if test="${result.targetType eq 'N'}">checked="checked"</c:if>>
+                                                        <span class="form-check-label">건강정보 미입력 환자</span>
+                                                    </label>
+                                                    
+                                                    <label class="form-check form-check-inline">
+                                                        <input class="form-check-input" type="radio" id="radio-target-m" name="targetType" value="M" required <c:if test="${result.targetType eq 'M'}">checked="checked"</c:if>>
+                                                        <span class="form-check-label">본인 관리 환자</span>
+                                                    </label>
+                                                </td>
+                                            </tr>
+                                            <tr class="target-select" id="target-patient" style="display:none;">
+                                                <td>
+                                                    <div class="form-row">
+                                                        <div class="col-7">
+                                                            <input class="form-check-input d-none" id="radio-target-p" type="radio" name="targetType" value="P" <c:if test="${result.targetType eq 'P'}">checked="checked"</c:if>>
+                                                            <input type="text" value="" class="form-control" name="targetPreview" id="target-preview" readonly required>
+                                                            
+                                                            <!-- 발송대상 checkboc동적 추가 hidden 영역 -->
+                                                            <div class="d-none" id="pushTargetTemp"></div>
+                                                        </div>
+                                                        <div class="col-4">
+                                                            <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#selectPatientList">환자 불러오기 <span id="pushTargetTempTotal" class="badge badge-danger" style="display:none;">2</span></button>
+                                                        </div>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            
+                                            <tr>
+                                                <th rowspan="2"><span class="fix">*</span>발송 방식</th>
+                                                <td>
+                                                    <label class="form-check form-check-inline">
+                                                        <input class="form-check-input send-select" accesskey="send-d" type="radio" name="sendType" value="D" required <c:if test="${result.sendType eq 'D'}">checked="checked"</c:if>>
+                                                        <span class="form-check-label">즉시 발송</span>
+                                                    </label>
+                                                    
+                                                    <label class="form-check form-check-inline">
+                                                        <input class="form-check-input send-select" accesskey="send-r" type="radio" name="sendType" value="R" required <c:if test="${result.sendType eq 'R'}">checked="checked"</c:if>>
+                                                        <span class="form-check-label">예약 발송</span>
+                                                    </label>
+                                                    
+                                                    <label class="form-check form-check-inline">
+                                                        <input class="form-check-input send-select" accesskey="send-e" type="radio" name="sendType" value="E" required <c:if test="${result.sendType eq 'E'}">checked="checked"</c:if>>
+                                                        <span class="form-check-label">매일 반복</span>
+                                                    </label>
+                                                </td>
+                                            </tr>
+                                            
+                                            <tr class="send-select" id="send-d">
+                                                <td><span>즉시 발송되며 취소가 불가능 합니다</span></td>
+                                            </tr>
+                                            
+                                            <tr class="send-select" id="send-r">
+                                                <td>
+                                                    <span class="mr-2">예약</span>
+                                                    <div class="form-check-inline calendar-bar mb-xl-0" style="width:120px;">
+                                                        <input type="text" class="form-control date" value="${result.sendDate}" name="sendDate" autocomplete="off" placeholder="예약 일자" required>
+                                                        <i class="align-middle mr-2 fas fa-fw fa-calendar-alt"></i>
+                                                    </div>
+                                                    <div class="form-check-inline calendar-bar mb-xl-0" style="width:80px;">
+                                                        <input type="text" class="form-control date-time-r" value="${result.sendTime}" name="sendTime" autocomplete="off" placeholder="매일 반복 시간" required>
+                                                        <i class="align-middle mr-2 fas fa-fw fa-clock"></i>
+                                                    </div>
+                                                    <span>에 발송됩니다</span>
+                                                </td>
+                                            </tr>
+                                            
+                                            <tr class="send-select" id="send-e">
+                                                <td>
+                                                    <span class="mr-2">매일</span>
+                                                    <div class="form-check-inline calendar-bar mb-xl-0" style="width:80px;">
+                                                        <input type="text" class="form-control date-time-e" value="${result.sendTime}" name="sendTime" autocomplete="off" placeholder="매일 반복 시간" required>
+                                                        <i class="align-middle mr-2 fas fa-fw fa-clock"></i>
+                                                    </div>
+                                                    <span>선택 시간에 반복 발송됩니다</span>
+                                                </td>
+                                            </tr>
+                                            
+                                            <tr>
+                                                <th><span class="fix">*</span>푸시(알림) 제목</th>
+                                                <td>
+                                                    <input type="text" name="pushTitle" value="<c:out value='${result.pushTitle}'/>" class="form-control" placeholder="제목을 입력하세요" maxlength="80" required>
+                                                </td>
+                                            </tr>
+                                            
+                                            <tr>
+                                                <th><span class="fix">*</span>푸시(알림) 내용</th>
+                                                <td>
+                                                    <textarea  class="form-control" rows="10" cols="" name="pushContent" placeholder="내용을 입력하세요" maxlength="1000" required><c:out value='${result.pushContent}'/></textarea>
+                                                </td>
+                                            </tr>
+                                        </table>
+                                        
+                                        <div class="row mt-3">
+                                            <div class="col-12">
+                                                <div class="text-right">
+                                                    <button type="button" class="btn btn-outline-primary w100" onclick="history.back();">취소</button>
+                                                    <button type="submit" class="btn btn-primary w100">수정</button>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </form>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </main>
+
+            <jsp:include page="${data._INCLUDE}/footer.jsp"></jsp:include>
+        </div>
+    </div>
+</body>
+</html>

+ 220 - 0
src/main/webapp/WEB-INF/jsp/push/info.jsp

@@ -0,0 +1,220 @@
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+    pageEncoding="UTF-8"%>
+<jsp:include page="${data._INCLUDE}/header.jsp"></jsp:include>
+<script type="text/javascript" src="/resources/js/common/jquery.tablesorter.min.js"></script>
+<script>
+$( function(){
+    $( "#sortTable" ).tablesorter();
+    if( $( "#total" ).val() == 0 ) {
+        alertBox({ 
+            txt: "이미 발송되었거나 존재하지않는 푸시정보 입니다",
+            callBack : function(){
+                location.href="./list";
+            }
+        });
+    }
+});
+
+function deleteConfirm(){
+    alertBox({ type : "confirm", 
+               txt : "등록된 푸시정보를 정말 삭제할까요?",
+               callBack : function( result ){
+                   if( result ){
+                       $( "#sendForm" ).attr( "action", "./delete" );
+                       $( "#sendForm" ).submit();
+                   }
+               }
+    });
+    return false;
+}
+</script>
+</head>
+<body>
+    <div class="modal fade" id="selectPatientList" tabindex="-1" role="dialog" aria-hidden="true">
+        <div class="modal-dialog modal-xl modal-dialog-scrollable" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">발송 대상자</h5>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span> </button>
+                </div>
+                <div class="modal-body m-4">
+                    <table class="table mobile-table table-striped text-center" id="sortTable">
+                        <colgroup>
+                            <col style="width: 10%">
+                            <col style="width: 15%">
+                            <col style="width: 20%">
+                            <col style="width: 10%">
+                            <col style="width: 15%">
+                            <col style="width: 10%">
+                            <col style="width: 25%">
+                        </colgroup>
+                        <thead>
+                            <tr>
+                                <th>번호 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>환자명 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>호실 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>성별 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>생년월일 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>나이 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>입소일자 <i class="fa fa-fw fa-sort"></i></th>
+                            </tr>
+                        </thead>
+                        <tbody id="patientList">
+                            <c:choose>
+                                <c:when test="${patientTotal eq 0}">
+                                    <tr>
+                                        <td colspan="6">no data</td>
+                                    </tr>
+                                </c:when>
+                                <c:otherwise>
+                                    <c:forEach var="pl" items="${patientList}" varStatus="lStatus">
+                                        <tr>
+                                            <td class="no">
+                                                <c:set var="pageNum" value="${patientTotal - lStatus.index}" />
+                                                <fmt:formatNumber value="${pageNum}" pattern="#,###" />
+                                            </td>
+                                            <td class="name"><c:out value="${pl.patientName}" /></td>
+                                            <td class="ward"><c:if test="${pl.wardNumber ne '' and pl.wardNumber ne null}">${pl.wardNumber}동</c:if> ${pl.roomNumber}호</td>
+                                            <td class="gender"><c:out value="${pl.gender}" /></td>
+                                            <td class="age"><c:out value="${pl.jumin}" /></td>
+                                            <td class="age"><c:out value="${pl.age}" /></td>
+                                            <td class="hospitalization-date"><c:out value="${pl.hospitalizationDate}" /></td>
+                                        </tr>
+                                    </c:forEach>
+                                </c:otherwise>
+                            </c:choose>
+                        </tbody>
+                    </table>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-primary" data-dismiss="modal">확인</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    
+    
+    <div class="wrapper">
+        <jsp:include page="${data._INCLUDE}/sidebar.jsp"></jsp:include>
+        
+        <div class="main">
+            <jsp:include page="${data._INCLUDE}/top.jsp"></jsp:include>
+
+            <main class="content">
+                <div class="container-fluid p-0">
+                    <div class="row">
+                        <div class="col-12 col-lg-6">
+                            <h1 class="h3 mb-3">예약 푸시 상세</h1>
+                        </div>
+                        <div class="col-12 col-lg-6  text-right">
+                            <nav aria-label="breadcrumb">
+                                <ol class="breadcrumb">
+                                    <li class="breadcrumb-item"><a href="javscript:;">Home</a></li>
+                                    <li class="breadcrumb-item">푸시서비스 관리</li>
+                                    <li class="breadcrumb-item active">예약 푸시 상세</li>
+                                </ol>
+                            </nav>
+                        </div>
+                    </div>
+                    <div class="row">
+                        <div class="col-12">
+                            <div class="card">
+                                <form id="sendForm" action="./edit" method="post">
+                                    <input type="hidden" name="pushIdx" value="${result.pushIdx}"/>
+                                    <input type="hidden" id="total" value="${total}"/>
+                                    <div class="card-body">
+                                        <table class="table mobile-table">
+                                            <colgroup>
+                                                <col style="width:20%">
+                                                <col style="width:80%">
+                                            </colgroup>
+                                            
+                                            
+                                            <c:if test="${total eq 0}">
+                                                <tr>
+                                                    <td colspan="2">존재하지않는 푸시 정보입니다.</td>
+                                                </tr>
+                                            </c:if>
+                                            
+                                            <c:if test="${total > 0}">
+                                                <tr>
+                                                    <th>생활치료센터명</th>
+                                                    <td><c:out value="${result.centerName}"/></td>
+                                                </tr>
+                                                <tr>
+                                                    <th>발송등록자</th>
+                                                    <td><c:out value="${result.name}(${result.sender})"/></td>
+                                                </tr>
+                                                <tr>
+                                                    <th rowspan="2">발송 대상</th>
+                                                    <td>
+                                                        <c:if test="${result.targetType ne 'P'}">그룹 선택</c:if>
+                                                        <c:if test="${result.targetType eq 'P'}">환자 개별 선택</c:if>
+                                                    </td>
+                                                </tr>
+                                                
+                                                <tr class="target-select" id="target-group">
+                                                    <td>
+                                                        <c:if test="${result.targetType eq 'A'}">전체 환자</c:if>
+                                                        <c:if test="${result.targetType eq 'N'}">건강정보 미입력 환자</c:if>
+                                                        <c:if test="${result.targetType eq 'M'}">본인 관리 환자</c:if>
+                                                        <c:if test="${result.targetType eq 'P'}">
+                                                            <div class="form-row">
+                                                                <div class="col-12">
+                                                                    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#selectPatientList">발송대상자 확인 <span class="badge badge-danger">${patientTotal}</span></button>
+                                                                </div>
+                                                            </div>
+                                                        </c:if>
+                                                    </td>
+                                                </tr>
+                                                
+                                                <tr>
+                                                    <th>발송 방식</th>
+                                                    <td>
+                                                        <span>
+                                                            <c:if test="${result.sendType eq 'R'}">예약</c:if>
+                                                            <c:if test="${result.sendType eq 'E'}">매일</c:if>
+                                                        </span>
+                                                        <span>/</span>
+                                                        <span><c:out value="${result.sendDate}"/> <c:out value="${result.sendTime}"/></span>
+                                                    </td>
+                                                </tr>
+                                                
+                                                <tr>
+                                                    <th>푸시(알림) 제목</th>
+                                                    <td><c:out value="${result.pushTitle}"/></td>
+                                                </tr>
+                                                
+                                                <tr>
+                                                    <th>푸시(알림) 내용</th>
+                                                    <td style="white-space:pre-line;"><c:out value="${result.pushContent}"/></td>
+                                                </tr>
+                                            </c:if>
+                                        </table>
+                                        
+                                        <div class="row mt-3">
+                                            <div class="col-12">
+                                                <div class="text-right">
+                                                    <button type="button" class="btn btn-outline-primary w100" onclick="location.href='./list'">목록</button>
+                                                    <button type="submit" class="btn btn-primary w100">수정</button>
+                                                    <button type="button" class="btn btn-danger w100" onclick="deleteConfirm();">삭제</button>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </form>
+                            </div>
+                            
+                        </div>
+                    </div>
+                </div>
+            </main>
+
+            <jsp:include page="${data._INCLUDE}/footer.jsp"></jsp:include>
+        </div>
+    </div>
+</body>
+</html>

+ 11 - 11
src/main/webapp/WEB-INF/jsp/push/list.jsp

@@ -56,6 +56,7 @@ $( function(){
         var key   = $this.prop( "accessKey" );
         
         var title     = $( "#sendResultList" ).find( ".modal-title" );
+        var logIdx   = $this.closest( "tr" ).find( "input.log-idx" ).val();
         var pushIdx   = $this.closest( "tr" ).find( "input.push-idx" ).val();
         var yearMonth = $( "#ym" ).val();
         var resultAddClass = "";
@@ -84,7 +85,7 @@ $( function(){
         $( "#patientList" ).empty().append( loadingTr );
         
         var url    = "./getPushResultList";
-        var vv     = "resultType=" + key + "&pushIdx=" + pushIdx + "&ym=" + yearMonth;
+        var vv     = "resultType=" + key + "&logIdx=" + logIdx + "&pushIdx=" + pushIdx + "&ym=" + yearMonth;
         
 //         $( "#patientList" ).find( "tr" ).not( loadingTr ).remove();
         
@@ -105,9 +106,14 @@ $( function(){
                     tr.find( "td.jumin" ).text( info.jumin );
                     tr.find( "td.updateDate" ).text( info.updateDate );
                     tr.find( "td.sendResult" ).text( resultMessage ).addClass( resultAddClass );
-                    tr.find( "td.failMsg" ).text( info.note ).attr( "data-content", info.note ).popover({
-                        container: 'body'
-                    });
+                    tr.find( "td.failMsg" ).text( info.note ).attr( "data-content", "[" + info.failCode + "] " + info.note );
+                    
+                    if( key == "fail" ) {
+                        tr.find( "td.failMsg" ).popover({
+                            container: 'body'
+                        });
+                    }
+                    
                     
                     $( "#patientList" ).append( tr );
                     
@@ -131,13 +137,6 @@ $( function(){
         $( "div.popover" ).hide();
     });
 });
-function getPushResult( type, pidx, ym ){
-	var url = "./getPushResultList";
-	var vv  = "resultType=success&pushIdx=1&ym=202012";
-	getAjax( url, vv, function( result ){
-		console.log( result );
-	}, null, null );
-}
 
 function sendDirectCheck(){
     if( $( "div.send-loading" ).length > 0 ) {
@@ -492,6 +491,7 @@ function pushDetail( t ){
                                                         </td>
                                                         <td class="td-push-title">
                                                             <a href="javascript:;" data-toggle="modal" data-target="#defaultModalPrimary_1" onclick="pushDetail( this );"><c:out value="${pl.pushTitle}"/></a>
+                                                            <input type="hidden" class="log-idx" value="${pl.idx}" />
                                                             <input type="hidden" class="push-idx" value="${pl.pushIdx}" />
                                                             <input type="hidden" class="center-name" value="${pl.centerName}" />
                                                             <input type="hidden" class="sender" value="${pl.sender}" />

+ 44 - 28
src/main/webapp/WEB-INF/jsp/push/schedule.jsp

@@ -166,12 +166,12 @@
                                 <div class="card-body">
                                     <div class="row mb-3">
                                         <div class="col-6">전체 :
-<%--                                             <fmt:formatNumber value="${total}" pattern="#,###" /> --%>
+                                            <fmt:formatNumber value="${total}" pattern="#,###" />
                                         </div>
                                         <div class="col-6 text-right">
 <%--                                             <c:if test="${data._SES_GROUP_IDX ne 1}"> --%>
 <%--                                                 <c:if test="${sesGroupIdx eq '1' or sesGroupIdx eq '2'}"> --%>
-                                                    <button class="btn btn-info" onclick="location.href='./list';">푸시 발송 현황</button>
+                                                    <button class="btn btn-info" onclick="location.href='../list';">푸시 발송 현황</button>
                                                     <button class="btn btn-primary" onclick="location.href='../send';">신규 푸시 발송</button>
 <%--                                                 </c:if> --%>
 <%--                                             </c:if> --%>
@@ -202,32 +202,48 @@
                                                 </tr>
                                             </thead>
                                             <tbody>
-                                                <tr>
-                                                    <td>1</td>
-                                                    <td>매일</td>
-                                                    <td>
-                                                        <a href="./edit">건강 정보를 업데이트 해주세요</a>
-                                                    </td>
-                                                    <td>건강정보 미입력자</td>
-                                                    <td>2020-12-10 15:30</td>
-                                                    <td>매일</td>
-                                                    <td>15:33</td>
-                                                    <td>이은숙수간호사<br/>(admin0005)</td>
-                                                </tr>
-                                                <c:forEach var="i" begin="2" end="10">
-                                                    <tr>
-                                                        <td>${i}</td>
-                                                        <td>즉시</td>
-                                                        <td>
-                                                            <a href="./edit">건강 정보를 업데이트 해주세요</a>
-                                                        </td>
-                                                        <td>건강정보 미입력자</td>
-                                                        <td>2020-12-10 15:30</td>
-                                                        <td>2020-12-10</td>
-                                                        <td>17:12</td>
-                                                        <td>이은숙수간호사<br/>(admin0005)</td>
-                                                    </tr>
-                                                </c:forEach>
+                                                <c:choose>
+                                                    <c:when test="${total eq 0}">
+                                                        <tr>
+                                                            <td colspan="8">등록된 푸시가 없습니다</td>
+                                                        </tr>
+                                                    </c:when>
+                                                    
+                                                    <c:otherwise>
+                                                        <c:forEach var="sl" items="${scheduleList}" varStatus="lStatus">
+                                                            <tr>
+                                                                <td>
+                                                                    <c:set var="pageNum" value="${total - lStatus.index}" />
+                                                                    <fmt:formatNumber value="${pageNum}" pattern="#,###" />
+                                                                </td>
+                                                                <td>
+                                                                    <c:if test="${sl.sendType eq 'E'}">매일</c:if>
+                                                                    <c:if test="${sl.sendType eq 'R'}">예약</c:if>
+                                                                </td>
+                                                                <td>
+                                                                    <a href="./info?pushIdx=${sl.pushIdx}"><c:out value="${sl.pushTitle}"/></a>
+                                                                </td>
+                                                                <td>
+                                                                    <c:if test="${sl.targetType eq 'A'}">전체 환자</c:if>
+                                                                    <c:if test="${sl.targetType eq 'N'}">건강정보 미입력 환자</c:if>
+                                                                    <c:if test="${sl.targetType eq 'M'}">보인 관리 환자</c:if>
+                                                                    <c:if test="${sl.targetType eq 'P'}">환자 개별 선택</c:if>
+                                                                </td>
+                                                                <td><c:out value="${sl.createDate}"/></td>
+                                                                <td>
+                                                                    <c:if test="${sl.sendType eq 'E'}">매일</c:if>
+                                                                    <c:if test="${sl.sendType ne 'E' and sl.sendDate ne null}">
+                                                                        <c:out value="${sl.sendDate}"/>
+                                                                    </c:if>
+                                                                </td>
+                                                                <td>
+                                                                    <c:out value="${sl.sendTime}"/>
+                                                                </td>
+                                                                <td><c:out value="${sl.name}"/><br/>(<c:out value="${sl.sender}"/>)</td>
+                                                            </tr>
+                                                        </c:forEach>
+                                                    </c:otherwise>
+                                                </c:choose>
 <%--                                                 <c:choose> --%>
 <%--                                                     <c:when test="${total > 0}"> --%>
 <%--                                                         <c:forEach var="l" items="${item}"> --%>

+ 42 - 25
src/main/webapp/WEB-INF/jsp/push/send.jsp

@@ -30,7 +30,7 @@ $( function(){
             console.log( $( form ).serialize() );
             
             alertBox({ 
-                txt: "발송하시겠습니까?",
+                txt: "등록 하시겠습니까?",
                 type : "confirm",
                 callBack : function( result ){
                     if( result ) {
@@ -175,28 +175,8 @@ function saveSelectedPatientList(){
         txt : "선택된 환자를 발송 대상자로 적용할까요?",
         type : "confirm", 
         callBack : function( result ){
-            
-            console.log( result );
             if( result ) {
-                $( "#selectPatientList" ).modal( "hide" );
-                $( "#pushTargetTemp" ).empty();
-                
-                var appendData = $( "#patientList" ).find( "input[type='checkbox']:checked" ).clone();
-                var name = appendData.map( function(){
-                    return $( this ).attr( "title" );
-                }).get().join( ", " );
-                
-                console.log( name );
-                
-                appendData.appendTo( "#pushTargetTemp" );
-                
-                if( appendData.length > 0 ){
-                    $( "#pushTargetTempTotal" ).text( appendData.length ).show();
-                } else {
-                    $( "#pushTargetTempTotal" ).text( "" ).hide();
-                }
-                 
-                $( "#target-preview" ).val( name ).valid();
+                addPatientToTargetTemp()
             } else {
                 console.log( "취소 -> no event" );
             };
@@ -205,6 +185,28 @@ function saveSelectedPatientList(){
     
     $( "#selectPatientList" ).find( ".modal-title h3" ).remove();
 }
+
+function addPatientToTargetTemp(){
+    $( "#selectPatientList" ).modal( "hide" );
+    $( "#pushTargetTemp" ).empty();
+    
+    var appendData = $( "#patientList" ).find( "input[type='checkbox']:checked" ).clone();
+    var name = appendData.map( function(){
+        return $( this ).attr( "title" );
+    }).get().join( ", " );
+    
+    console.log( name );
+    
+    appendData.appendTo( "#pushTargetTemp" );
+    
+    if( appendData.length > 0 ){
+        $( "#pushTargetTempTotal" ).text( appendData.length ).show();
+    } else {
+        $( "#pushTargetTempTotal" ).text( "" ).hide();
+    }
+     
+    $( "#target-preview" ).val( name ).valid();
+}
 </script>
 </head>
 <body>
@@ -212,7 +214,7 @@ function saveSelectedPatientList(){
         <div class="modal-dialog modal-xl modal-dialog-scrollable" role="document">
             <div class="modal-content">
                 <div class="modal-header">
-                    <h5 class="modal-title">환자 선택 (레몬생활치료센터)</h5>
+                    <h5 class="modal-title">환자 선택</h5>
                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span> </button>
                 </div>
                 <div class="modal-body m-4">
@@ -221,8 +223,9 @@ function saveSelectedPatientList(){
                             <col style="width: 5%">
                             <col style="width: 10%">
                             <col style="width: 15%">
-                            <col style="width: 25%">
+                            <col style="width: 20%">
                             <col style="width: 10%">
+                            <col style="width: 15%">
                             <col style="width: 10%">
                             <col style="width: 25%">
                         </colgroup>
@@ -235,6 +238,7 @@ function saveSelectedPatientList(){
                                 <th>환자명 <i class="fa fa-fw fa-sort"></i></th>
                                 <th>호실 <i class="fa fa-fw fa-sort"></i></th>
                                 <th>성별 <i class="fa fa-fw fa-sort"></i></th>
+                                <th>생년월일 <i class="fa fa-fw fa-sort"></i></th>
                                 <th>나이 <i class="fa fa-fw fa-sort"></i></th>
                                 <th>입소일자 <i class="fa fa-fw fa-sort"></i></th>
                             </tr>
@@ -259,6 +263,7 @@ function saveSelectedPatientList(){
                                             <td class="name"><c:out value="${pl.patientName}" /></td>
                                             <td class="ward"><c:if test="${pl.wardNumber ne '' and pl.wardNumber ne null}">${pl.wardNumber}동</c:if> ${pl.roomNumber}호</td>
                                             <td class="gender"><c:out value="${pl.gender}" /></td>
+                                            <td class="age"><c:out value="${pl.jumin}" /></td>
                                             <td class="age"><c:out value="${pl.age}" /></td>
                                             <td class="hospitalization-date"><c:out value="${pl.hospitalizationDate}" /></td>
                                         </tr>
@@ -302,6 +307,10 @@ function saveSelectedPatientList(){
                     <div class="row">
                         <div class="col-12">
                             <div class="card">
+                                <div class="alert alert-light text-info border p-3">
+                                    <span style="font-size:14px;">· 발송 전체 대상자중 입소자만 푸시 발송 가능<br/>· 그룹선택 발송일 경우 발송시간기준으로 환자 실시간 조회 및 발송되므로 대상자가 현재와 달라질 수 있음</span>
+                                </div>
+                                
                                 <form id="sendForm" action="./send/insert" method="post">
                                     <div class="card-body">
                                         <table class="table mobile-table">
@@ -309,6 +318,14 @@ function saveSelectedPatientList(){
                                                 <col style="width:20%">
                                                 <col style="width:80%">
                                             </colgroup>
+                                            <tr>
+                                                <th>생활치료센터명</th>
+                                                <td><c:out value="${data._SES_CENTER_NAME}"/></td>
+                                            </tr>
+                                            <tr>
+                                                <th>발송등록자</th>
+                                                <td><c:out value="${data._SES_NAME}(${data._SES_ID})"/></td>
+                                            </tr>
                                             <tr>
                                                 <th rowspan="2"><span class="fix">*</span>발송 대상</th>
                                                 <td>
@@ -378,7 +395,7 @@ function saveSelectedPatientList(){
                                             </tr>
                                             
                                             <tr class="send-select" id="send-d">
-                                                <td><span>즉시 발송니다</span></td>
+                                                <td><span>즉시 발송되며 취소가 불가능 합니다</span></td>
                                             </tr>
                                             
                                             <tr class="send-select" id="send-r">