| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- <%@ 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 src="/resources/js/common/jquery.tablesorter.min.js"></script>
- <script>
- $( function(){
- $( "select[name='y'], select[name='m']" ).change( function(){
- var ym = $( "select[name='y']" ).val() + "-" + $( "select[name='m']" ).val();
- var sDate = moment( ym+"-01" ).startOf('month').format('YYYY-MM-DD');
- var eDate = moment( ym+"-01" ).endOf('month').format('YYYY-MM-DD');
-
- $( "input[name='startDate']" ).val( sDate );
- $( "input[name='endDate']" ).val( eDate );
- });
-
- $( "input.date-no-req" ).daterangepicker({
- singleDatePicker : true,
- showDropdowns : true,
- locale : {
- format : "YYYY-MM-DD"
- },
- autoUpdateInput: false,
- minDate: moment( $( "select[name='y']" ).val() + "-" + $( "select[name='m']" ).val() + "-01" ).startOf('month').format('YYYY-MM-DD'),
- maxDate: moment( $( "select[name='y']" ).val() + "-" + $( "select[name='m']" ).val() + "-01" ).endOf('month').format('YYYY-MM-DD')
- }).on('apply.daterangepicker', function(ev, picker) {
- $(this).val(picker.startDate.format('YYYY-MM-DD'));
- $(this).trigger( "change" );
- });
- $( "#searchForm" ).validate({
- rules: {
- startDate : {
- date : true
- },
- endDate : {
- date : true
- }
- },
- onkeyup: function( element, event ) {
- $( element ).valid();
- },
- onfocusout: function (element) {
- $( element ).val( $.trim( $( element ).val() ) );
- $( element ).valid();
- },
- submitHandler: function(form) {
- form.submit();
- }
- });
-
- $( document ).on( "click", "span.push-result", function(){
- var $this = $( this );
- var key = $this.attr( "data-access" );
-
- 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 = "";
- var resultMessage = "";
-
- console.log( key );
- if( key == "success" ) {
- title.text( "발송 성공 리스트" );
- resultAddClass = "text-success";
- resultMessage = "성공";
-
- } else if( key == "fail" ) {
- title.text( "발송 실패 리스트" );
- resultAddClass = "text-danger";
- resultMessage = "실패";
-
- } else if( key == "wait" ) {
- title.text( "발송 대기 리스트" );
- resultAddClass = "text-warning";
- resultMessage = "대기";
-
- }
-
- //ajax -> get patientList
- var loadingTr = $( "#loading-tr" ).clone().removeAttr( "id" );
- $( "#patientList" ).empty().append( loadingTr );
-
- var url = "./getPushResultList";
- var vv = "resultType=" + key + "&logIdx=" + logIdx + "&pushIdx=" + pushIdx + "&ym=" + yearMonth;
-
- // $( "#patientList" ).find( "tr" ).not( loadingTr ).remove();
-
- $( "#pushResultTable" ).trigger( "destroy" );
-
- getAjax( url, vv, function( data ){
- $( "#patientList" ).empty();
-
- if( data.total > 0 ) {
- for( var i = 1; i <= data.total; i ++ ) {
- var info = data.result[i - 1];
- var tr = $( "#patient-tr" ).clone().removeAttr( "id" );
-
- tr.find( "td.no" ).text( i );
- tr.find( "td.name" ).text( info.patientName );
- tr.find( "td.ward" ).text( info.wardNumber == "" ? info.roomNumber+"호" : info.wardNumber+"동 " + info.roomNumber+"호" );
- tr.find( "td.gender" ).text( info.gender );
- 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.failCode + "] " + info.note );
-
- if( key == "fail" ) {
- tr.find( "td.failMsg" ).popover({
- container: 'body'
- });
- }
-
-
- $( "#patientList" ).append( tr );
-
- if( i == ( data.total ) ) {
- $( "#pushResultTable" ).tablesorter();
- }
- }
- } else {
- $( "#patientList" ).append( "<tr><td colspan='8'>대상자가 존재하지않습니다</td></tr>" );
- }
- }, null, null );
-
-
- });
-
- // 즉시발송건 존재할경우 5초마다 새로고침
- setInterval(sendDirectCheck, 3000);
-
- // modal hide event
- $('#sendResultList').on('hide.bs.modal', function () {
- $( "div.popover" ).hide();
- });
- });
- function sendDirectCheck(){
- if( $( "div.send-loading" ).length > 0 ) {
- $.ajax({
- type: "GET",
- url : "./list",
- dataType : "text",
- error : function(){
- console.log( "error" );
- },
- success : function( data ){
- var domNodes = $( $.parseHTML( data ) );
- $( "#pushLogTable" ).html( domNodes.find( "#pushLogTable" ).html() );
- }
- })
- };
-
- return false;
- };
- function pushDetail( t ){
- var $this = $( t );
- var targetBox = $( "#defaultModalPrimary_1" );
-
- console.log( $this );
- console.log( $this.parent( "td" ).siblings( "td-target-type" ).text() );
-
- targetBox.find( "td.center-name" ).text( $this.siblings( "input.center-name" ).val() );
- targetBox.find( "td.sender" ).text( $this.siblings( "input.name" ).val() + " (" + $this.siblings( "input.sender" ).val() + ")" );
- targetBox.find( "td.target-type" ).text( $this.parent( "td" ).siblings( "td.td-target-type" ).text() );
- targetBox.find( "td.send-type" ).text( $this.parent( "td" ).siblings( "td.td-send-type" ).text() + " 발송" );
- targetBox.find( "td.start-date" ).text( $this.parent( "td" ).siblings( "td.td-start-date" ).text() );
- targetBox.find( "input.push-title" ).val( $this.text() );
- targetBox.find( "textarea.push-content" ).val( $this.siblings( "input.push-content" ).val() );
- }
- </script>
- <style>
- .pointer{cursor:pointer;}
- .pointer span:hover{text-decoration: underline;}
- </style>
- </head>
- <body>
- <div class="modal fade" id="defaultModalPrimary_1" tabindex="-1" role="dialog" aria-hidden="true">
- <div class="modal-dialog" 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">×</span> </button>
- </div>
- <div class="modal-body m-4">
- <table class="table mobile-table">
- <colgroup>
- <col style="width: 30%">
- <col style="width: 70%">
- </colgroup>
- <tr>
- <th>생활치료센터명</th>
- <td class="center-name"></td>
- </tr>
- <tr>
- <th>발송등록자</th>
- <td class="sender"></td>
- </tr>
-
-
- <tr>
- <th>발송 대상</th>
- <td class="target-type"></td>
- </tr>
-
- <tr>
- <th>발송 구분</th>
- <td class="send-type"></td>
- </tr>
-
- <tr>
- <th>발송일</th>
- <td class="start-date"></td>
- </tr>
-
- <tr>
- <th>푸시 제목</th>
- <td>
- <div class="form-group mb-xl-0">
- <input class="form-control push-title" type="text" value="" readonly>
- </div>
- </td>
- </tr>
- <tr>
- <th>푸시 내용</th>
- <td>
- <div class="form-group mb-xl-0">
- <textarea class="form-control push-content" rows="10" readonly></textarea>
- </div>
- </td>
- </tr>
- </table>
- </div>
- <div class="modal-footer">
- <button type="button" class="btn btn-primary" data-dismiss="modal">확인</button>
- </div>
- </div>
- </div>
- </div>
-
-
- <div class="modal fade" id="sendResultList" 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">×</span> </button>
- </div>
- <div class="modal-body m-4">
- <table class="table mobile-table table-striped text-center" id="pushResultTable">
- <colgroup>
- <col style="width: 8%">
- <col style="width: 12%">
- <col style="width: 15%">
- <col style="width: 10%">
- <col style="width: 16%">
- <col style="width: 16%">
- <col style="width: 10%">
- <col style="width: 19%">
- </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>
- <th style="max-width: 60px;">비고 <i class="fa fa-fw fa-sort"></i></th>
- </tr>
- </thead>
- <tbody id="patientList">
- <!-- 환자리스트 동적 생성 -->
- </tbody>
- </table>
- <table class="d-none" id="hide-table">
- <tr id="loading-tr">
- <td colspan="8">
- <div class="spinner-border text-primary" role="status">
- <span class="sr-only">Loading...</span>
- </div>
- </td>
- </tr>
-
- <tr id="patient-tr">
- <td class="no"></td>
- <td class="name"></td>
- <td class="ward"></td>
- <td class="gender"></td>
- <td class="jumin"></td>
- <td class="updateDate"></td>
- <td class="sendResult"></td>
- <td class="failMsg" style="max-width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;" data-toggle="popover" title="실패 사유" data-content=""></td>
- </tr>
- </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">
- <!-- 의료진 관리 START -->
- <div class="row">
- <div class="col-12 col-lg-6">
- <h1 class="h3 mb-3">월별 푸시 발송 현황 (<c:out value="${y}"/>년 <c:out value="${m}"/>월)</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 action="?" method="get" id="searchForm">
- <input type="hidden" id="ym" value='<c:out value="${ym}"/>' />
- <div class="card-body">
- <table class="table mobile-table">
- <colgroup>
- <col style="width:10%">
- <col style="width:40%">
- <col style="width:10%">
- <col style="width:40%">
- </colgroup>
- <tr>
- <th>발송(연도)</th>
- <td>
- <select class="custom-select form-control" name="y">
- <c:forEach var="i" begin="2020" end="${nowYear}">
- <option value="${i}" <c:if test="${i eq y}">selected="selected"</c:if>>${i} 년</option>
- </c:forEach>
- </select>
- </td>
- <th>발송(월)</th>
- <td>
- <select class="custom-select form-control" name="m">
- <c:forEach var="j" begin="1" end="12">
- <c:if test="${j < 10}">
- <c:set var="j" value="0${j}"/>
- </c:if>
-
- <option value="${j}" <c:if test="${j eq m}">selected="selected"</c:if>>${j} 월</option>
- </c:forEach>
- </select>
- </td>
- </tr>
- <tr>
- <th>발송(일)</th>
- <td>
- <div class="row">
- <div class="col-5">
- <div class="form-group mb-xl-0">
- <input class="form-control date-no-req" type="text" name="startDate" value='<c:out value="${startDate}"/>' onKeyup="inputYMDNumber(this);" autocomplete="off" placeholder="검색 시작일자">
- </div>
- </div>
- <div
- class="col-2 text-center">
- ~</div>
- <div class="col-5">
- <div class="form-group mb-xl-0">
- <input class="form-control date-no-req" type="text" name="endDate" value='<c:out value="${endDate}"/>' onKeyup="inputYMDNumber(this);" autocomplete="off" placeholder="검색 종료일자">
- </div>
- </div>
- </div>
- </td>
-
- <th>수신 대상</th>
- <td>
- <select class="custom-select form-control" name="targetType">
- <option value="">대상자 선택</option>
- <option value="A" <c:if test="${targetType eq 'A'}">selected="selected"</c:if>>전체 환자</option>
- <option value="N" <c:if test="${targetType eq 'N'}">selected="selected"</c:if>>건강정보 미입력자</option>
- <option value="M" <c:if test="${targetType eq 'M'}">selected="selected"</c:if>>본인 관리 환자</option>
- <option value="P" <c:if test="${targetType eq 'P'}">selected="selected"</c:if>>환자 개별선택</option>
- <option value="T" <c:if test="${targetType eq 'T'}">selected="selected"</c:if>>정신건강 자가진단 미입력 환자</option>
- </select>
- </td>
- </tr>
- <tr>
- <th>발송 구분</th>
- <td>
- <select class="custom-select form-control" name="sendType">
- <option value="">전체</option>
- <option value="D" <c:if test="${sendType eq 'D'}">selected="selected"</c:if>>즉시</option>
- <option value="R" <c:if test="${sendType eq 'R'}">selected="selected"</c:if>>예약</option>
- <option value="E" <c:if test="${sendType eq 'E'}">selected="selected"</c:if>>매일</option>
- </select>
- </td>
-
- <th>검색어 조건</th>
- <td>
- <div class="form-row">
- <div class="col-4">
- <select class="custom-select form-control" name="searchType">
- <option value="title" <c:if test="${searchType eq 'title'}">selected="selected"</c:if>>푸시 제목</option>
- <option value="name" <c:if test="${searchType eq 'name'}">selected="selected"</c:if>>발송자 이름</option>
- <option value="id" <c:if test="${searchType eq 'id'}">selected="selected"</c:if>>발송자 아이디</option>
- </select>
- </div>
- <div class="col-6">
- <input type="text" class="form-control" name="q" placeholder="" value="<c:out value='${q}'/>" autocomplete="off">
- </div>
- <div class="col-2">
- <button class="btn btn-primary">검색</button>
- </div>
- </div>
-
- </td>
- </tr>
- </table>
- </div>
- </form>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-12">
- <div class="card">
- <div class="card-body">
- <div class="row mb-3">
- <div class="col-6">전체 :<fmt:formatNumber value="${total}" pattern="#,###" />
- </div>
- <div class="col-6 text-right">
- <button class="btn btn-secondary" onclick="location.href='./schedule/list';">예약 푸시 현황</button>
- <c:if test="${role._CREATE eq 'Y'}">
- <button class="btn btn-primary" onclick="location.href='./send';">신규 푸시 발송</button>
- </c:if>
- </div>
- </div>
- <div class="table-responsive">
- <table class="table table-striped text-center" id="pushLogTable">
- <colgroup>
- <col style=" width: 6%; ">
- <col style=" width: 7%; ">
- <col style=" width: 15%; ">
- <col style=" width: 8%; ">
- <col style=" width: 10%; ">
- <col style=" width: 10%; ">
- <col style=" width: 8%; ">
- <col style=" width: 5%; ">
- <col style=" width: 5%; ">
- <col style=" width: 5%; ">
- <col style=" width: 5%; ">
- <col style=" width: 12%; ">
- </colgroup>
- <thead>
- <tr>
- <th>번호</th>
- <th>발송 구분</th>
- <th>푸시제목</th>
- <th>수신 대상</th>
- <th>최초등록일</th>
- <th>발송시간</th>
- <th>발송상태</th>
- <th>Total</th>
- <th>성공</th>
- <th>실패</th>
- <th>대기</th>
- <th>발송등록자</th>
- </tr>
- </thead>
- <tbody>
- <c:if test="${total eq 0}">
- <tr>
- <td colspan="12">발송 이력이 없습니다</td>
- </tr>
- </c:if>
- <c:forEach var="pl" items="${pushList}" varStatus="lStatus">
- <tr>
- <td>
- <c:set var="pageNum" value="${total - lStatus.index}" />
- <fmt:formatNumber value="${pageNum}" pattern="#,###" />
- </td>
- <td class="td-send-type">
- <c:if test="${pl.sendType eq 'D'}">즉시</c:if>
- <c:if test="${pl.sendType eq 'R'}">예약</c:if>
- <c:if test="${pl.sendType eq 'E'}">매일</c:if>
- </td>
- <td class="td-push-title text-left">
- <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='<c:out value="${pl.idx}"/>' />
- <input type="hidden" class="push-idx" value='<c:out value="${pl.pushIdx}"/>' />
- <input type="hidden" class="center-name" value='<c:out value="${pl.centerName}"/>' />
- <input type="hidden" class="sender" value='<c:out value="${pl.sender}"/>' />
- <input type="hidden" class="name" value='<c:out value="${pl.name}"/>' />
- <input type="hidden" class="push-content" value='<c:out value="${pl.pushContent}"/>' />
- </td>
- <td class="td-target-type">
- <c:if test="${pl.targetType eq 'A'}">전체 환자</c:if>
- <c:if test="${pl.targetType eq 'N'}">건강정보 미입력자</c:if>
- <c:if test="${pl.targetType eq 'M'}">본인 관리 환자</c:if>
- <c:if test="${pl.targetType eq 'P'}">환자 개별선택</c:if>
- <c:if test="${pl.targetType eq 'T'}">정신건강 자가진단 미입력 환자</c:if>
- </td>
- <td class="td-create-date"><c:out value="${pl.createDate}"/></td>
-
- <c:if test="${pl.sendState eq 'W'}">
- <td colspan="6">
- <div class="send-loading align-bottom spinner-border text-primary" role="status">
- <span class="sr-only">Loading...</span>
- </div>
- </td>
- </c:if>
- <c:if test="${pl.sendState ne 'W'}">
- <td class="td-start-date"><c:out value="${pl.startDate}"/></td>
- <td>
- <c:if test="${pl.sendState eq 'W'}">발송 대기</c:if>
- <c:if test="${pl.sendState eq 'C'}">발송 완료</c:if>
- <c:if test="${pl.sendState eq 'I'}">발송중</c:if>
- </td>
- <td class="text-right">
- <fmt:formatNumber value="${pl.totalCount}" pattern="#,###" />
- </td>
- <td class="text-right text-success pointer">
- <span class="text-link push-result" data-access="success" data-toggle="modal" data-target="#sendResultList">
- <fmt:formatNumber value="${pl.successCount}" pattern="#,###" />
- </span>
- </td>
- <td class="text-right text-danger pointer">
- <span class="text-link push-result" data-access="fail" data-toggle="modal" data-target="#sendResultList">
- <fmt:formatNumber value="${pl.failCount}" pattern="#,###" />
- </span>
- </td>
- <td class="text-right text-warning pointer">
- <span class="text-link push-result" data-access="wait" data-toggle="modal" data-target="#sendResultList">
- <fmt:formatNumber value="${pl.waitCount}" pattern="#,###" />
- </span>
- </td>
- </c:if>
- <td>
- <span class="text-info">[<c:out value="${pl.centerName}"/>]</span>
- <br/>
- <c:out value="${pl.name}"/> (<c:out value="${pl.sender}"/>)
- </td>
- </tr>
- </c:forEach>
- </tbody>
- </table>
- </div>
- <div class="row mt-5">
- <div class="col-12 col-lg-6 mb-2">
- <!-- <select class="custom-select form-control col-md-2" id="inputState" name="inputState"> -->
- <!-- <option value="success" selected="">전체</option> -->
- <!-- <option value="info">입소</option> -->
- <!-- <option value="warning">퇴소</option> -->
- <!-- </select> -->
- </div>
- <div class="col-12 col-lg-6 mb-2">
- <jsp:include page="${data._INCLUDE}/paging.jsp" flush="true">
- <jsp:param name="firstPageNo" value="${paging.firstPageNo}" />
- <jsp:param name="prevPageNo" value="${paging.prevPageNo}" />
- <jsp:param name="startPageNo" value="${paging.startPageNo}" />
- <jsp:param name="pageNo" value="${paging.pageNo}" />
- <jsp:param name="endPageNo" value="${paging.endPageNo}" />
- <jsp:param name="nextPageNo" value="${paging.nextPageNo}" />
- <jsp:param name="finalPageNo" value="${paging.finalPageNo}" />
- <jsp:param name="preFix" value="${paging.preFix}" />
- <jsp:param name="url" value="${paging.url}" />
- <jsp:param name="total" value="${paging.totalCount}" />
- </jsp:include>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 의료진 관리 END -->
- </div>
- </main>
- <jsp:include page="${data._INCLUDE}/footer.jsp"></jsp:include>
- </div>
- </div>
- </body>
- </html>
|