2 次代碼提交 f1333f5dfe ... 026c7e3f21

作者 SHA1 備註 提交日期
  huiwonseo 026c7e3f21 Merge branch 'databank' of http://wcollector.idatabank.com:5230/dbs289/LifeCenter into databank 3 年之前
  huiwonseo 3e01d33dc9 21.10.28일 배포 전 수정사항 적용 1차 3 年之前

+ 25 - 0
src/main/java/com/lemon/lifecenter/controller/PatientController.java

@@ -673,6 +673,31 @@ public class PatientController extends LifeCenterController {
             dto.setSymptomStartDate( null );
         }
         
+        System.err.println( "dto.getResidentNumberFront(): " + dto.getResidentNumberFront() );
+        System.err.println( "dto.getResidentNumberLast(): " + dto.getResidentNumberLast() );
+
+        
+        try {
+          // base64 decode 주민뒷자리
+          if (!dto.getResidentNumberLast().equals("")) {
+            byte[] decoded = Base64.getDecoder().decode(dto.getResidentNumberLast());
+            dto.setResidentNumberLast(new String(decoded, StandardCharsets.UTF_8));
+          }
+          // base64 decode 외국인등록번호 뒷자리
+          if (!dto.getForeignNumberLast().equals("")) {
+            byte[] decoded = Base64.getDecoder().decode(dto.getForeignNumberLast());
+            dto.setForeignNumberLast(new String(decoded, StandardCharsets.UTF_8));
+          }
+          // base64 decode 여권번호
+          if (!dto.getPassportNumber().equals("")) {
+            byte[] decoded = Base64.getDecoder().decode(dto.getPassportNumber());
+            dto.setPassportNumber(new String(decoded, StandardCharsets.UTF_8));
+          }
+        } catch (Exception e) {
+          //TODO: handle exception
+          logger.error("개인식별정보 base64 복호화 error -- > " + e);
+        }
+        
         logger.error("getPw -- > " + dto.getPw());
         
         patientService.updatePatientCare( dto );  // 환지 기본정보

+ 19 - 0
src/main/java/com/lemon/lifecenter/dto/PatientDTO.java

@@ -172,6 +172,25 @@ public class PatientDTO {
 
     private String centerType="";
 
+    private String residentNumberChange="";
+    private String foreignNumberChange="";
+
+    public String getResidentNumberChange() {
+      return this.residentNumberChange;
+    }
+
+    public void setResidentNumberChange(String residentNumberChange) {
+      this.residentNumberChange = residentNumberChange;
+    }
+
+    public String getForeignNumberChange() {
+      return this.foreignNumberChange;
+    }
+
+    public void setForeignNumberChange(String foreignNumberChange) {
+      this.foreignNumberChange = foreignNumberChange;
+    }
+
     public int getStressTotal() {
       return this.stressTotal;
     }

+ 1 - 1
src/main/resources/messages/message.properties

@@ -12,7 +12,7 @@ login.select.all = 전체
 login.select.center = 치료센터 선택
 login.btn.login = 로그인
 login.required.location = 지역을 선택해주세요
-login.required.center = 생활치료센터를 선택해주세요
+login.required.center = 치료센터를 선택해주세요
 login.required.id = 동호실번호를 입력해주세요(동+호실)
 login.required.jumin = 생년월일 8자리를 입력해주세요
 login.required.jumin2 = 생년월일을 입력해주세요

+ 1 - 1
src/main/resources/messages/message_ko.properties

@@ -12,7 +12,7 @@ login.select.all = 전체
 login.select.center = 치료센터 선택
 login.btn.login = 로그인
 login.required.location = 지역을 선택해주세요
-login.required.center = 생활치료센터를 선택해주세요
+login.required.center = 치료센터를 선택해주세요
 login.required.id = 동호실번호를 입력해주세요(동+호실)
 login.required.jumin = 생년월일 8자리를 입력해주세요
 login.required.jumin2 = 생년월일을 입력해주세요

+ 31 - 1
src/main/resources/mybatis/mapper/patient/patient.xml

@@ -749,7 +749,37 @@
                    foreigner_yn = #{foreignerYn},
                    manager_id = #{managerId},
                    patient_etc = #{patientEtc}
-                   ]]>
+        ]]>
+        <if test='residentNumberChange != null and residentNumberChange == "Y"'>
+          <![CDATA[
+                 , resident_number_front = sfxdb_enc( 'normal', #{residentNumberFront} )
+                 , resident_number_last = sfxdb_enc( 'normal', #{residentNumberLast} )
+          ]]>
+        </if>
+        
+        <if test='foreignNumberChange != null and foreignNumberChange == "Y"'>
+          <![CDATA[
+                , foreign_number_front = sfxdb_enc( 'normal', #{foreignNumberFront} )
+                , foreign_number_last = sfxdb_enc( 'normal', #{foreignNumberLast} )
+                , passport_number = sfxdb_enc( 'normal', #{passportNumber} )
+              ]]>
+        </if>
+
+        <if test='foreignerYn != null and foreignerYn == "N"'>
+          <![CDATA[
+                 , foreign_number_front = ''
+                 , foreign_number_last = ''
+                 , passport_number = ''
+          ]]>
+        </if>
+
+        <if test='foreignerYn != null and foreignerYn == "Y"'>
+          <![CDATA[
+                 , resident_number_front = ''
+                 , resident_number_last = ''
+          ]]>
+        </if>
+
         
         <if test='expectedDischargeDate != null and expectedDischargeDate != ""'>
             <![CDATA[

+ 1 - 1
src/main/webapp/WEB-INF/jsp/include/patientInfo.jsp

@@ -51,7 +51,7 @@
             </c:if>
 
             <c:if test="${info.residentNumberFront eq ''}">
-              (주민등록번호 미등록 환자)
+              <!-- 주민등록번호 미등록 -->
             </c:if>
           </c:if>
         </td>

+ 24 - 11
src/main/webapp/WEB-INF/jsp/mobile/login/login.jsp

@@ -32,28 +32,36 @@ $( function(){
                 selectcheck : true
             }
         },
+        focusInvalid:false,
+        onkeyup:false,
+        onclick:false,
+        onfocusout:false,
         errorPlacement: function( error, element ){
-            if (element.attr("name") == "locationCode") {
-                $( "#errMsg" ).text( '<spring:message code="login.required.location" />' );
-            } else if( element.attr( "name" ) == "centerCode" ) {
-                $( "#errMsg" ).text( '<spring:message code="login.required.center" />' );
-            } else if( element.attr( "name" ) == "id"  ||  element.attr( "name" ) == "pw" ) {
+            if( element.attr( "name" ) == "id"  ||  element.attr( "name" ) == "pw" ) {
                 if( $( "#id" ).val().length == 0 ) { 
 
                     var centerType = $("input[name='centerType']:checked").val();
 
                     if( centerType == 'C' ) {
                       $( "#errMsg" ).text( '<spring:message code="login.required.id" />' );
+
                     } else if( centerType == 'S' ){
                       $( "#errMsg" ).text( '<spring:message code="login.required.residence" />' );
                     }
+                    if( $( "#centerList" ).val() == 0 ) {
+                      $( "#errMsg" ).text( '<spring:message code="login.required.center" />' );
+                    }
                     // $( "#id" ).focus();
                     return;
                 } else if( $( "#pw" ).val().length == 0 ){
                     $( "#errMsg" ).text( '<spring:message code="login.required.jumin" />' );
                     $( "#pw" ).focus();
                 }
-            }
+            } else if (element.attr("name") == "locationCode") {
+                $( "#errMsg" ).text( '<spring:message code="login.required.location" />' );
+            } else if( element.attr( "name" ) == "centerCode" ) {
+                $( "#errMsg" ).text( '<spring:message code="login.required.center" />' );
+            } 
         },
         submitHandler: function(form) {
             getAjax( "./check", $("#loginForm").serialize(), function( data ){
@@ -103,7 +111,11 @@ $( function(){
     } else {
       // $( "#startLoading" ).fadeOut( 500 );
     }
-
+    $( "#centerList" ).on( "change", function(){
+      if( $( "#centerList" ).val() != 0 ) {
+        $( "#errMsg" ).empty();
+      } 
+    });
 
     $( "#locationList" ).on( "change", function(){
         setCenterType( $("input[name='centerType']:checked").val() );
@@ -115,18 +127,18 @@ $( function(){
             $( "#centerList option:not([value='0'])" ).appendTo( "#hideList" );
             
             if ($( "#hideList option[data-center-type='" + type +"'][accessKey='"+$('#locationList').val()+"']" ).length == 0) {
-                $("#centerLabel").text('<spring:message code="login.required.noCenter" />');
+                // $("#centerLabel").text('<spring:message code="login.required.noCenter" />');
 //               var option = "<option value='99' selected>등록된 생활치료센터가 없습니다.</option>";
 //               $('#centerList').append(option);
             } else {
-                $("#centerLabel").text('<spring:message code="login.required.selectCenter" />');
+                // $("#centerLabel").text('<spring:message code="login.required.selectCenter" />');
                 $( "#hideList option[data-center-type='" + type +"'][accessKey='"+$('#locationList').val()+"']" ).appendTo( "#centerList" );
                 $("#centerList").val("0").prop("selected", true);
             }
         } else {
             $( "#centerList option:not([value='0'])" ).appendTo( "#hideList" );
             $( "#hideList option[data-center-type='" + type +"']" ).appendTo( "#centerList" );
-            $("#centerLabel").text('<spring:message code="login.required.selectCenter" />');
+            // $("#centerLabel").text('<spring:message code="login.required.selectCenter" />');
         }
     });
 
@@ -171,8 +183,9 @@ function setCenterType( type ){
     $( "#id" ).attr( "placeholder", '<spring:message code="login.placeholder.residence" />' );
   }
   if( $( "#errMsg" ).text() != "" ) {
-    $( "#loginForm" ).valid();
+    // $( "#loginForm" ).valid();
   }
+  $( "#errMsg" ).empty();
 }
 
 function getToken(token, deviceType, macAddress) {

+ 351 - 20
src/main/webapp/WEB-INF/jsp/patient/edit.jsp

@@ -206,22 +206,248 @@ $( function(){
                 }
             },
             submitHandler: function(form) {
+
+                if( $( "input[name='foreignerYn']" ).is(":checked") ) {
+                  if( $( "#foreignNumberCheck" ).val() == "false" ) {
+                    // alertBox({ txt : '외국인인 경우 고유식별정보를 입력해주세요' });
+                      var ff = $( "#foreignNumberFront" ).val();
+                      var fl = $( "#foreignNumberLast" ).val();
+                      var pn = $( "#passportNumber" ).val();
+
+                      if( $.trim( ff||fl||pn ) != '' ) {
+                        $( "#fModal" ).modal('show');
+                        fModalCheck();
+
+                        return false;
+                      }
+                  }
+                } else {
+                  var rf = $('input[name="residentNumberFront"]').val();
+                  var rl = $('input[name="residentNumberLast"]').val();
+
+                  if( $.trim( rf || rl ) != '' ) {
+                    var fVal = $('input[name="residentNumberLast"]').val().substr(0,1);
+      
+                    if( fVal >= 5 && fVal <= 8 ) {
+                      alertBox({ txt : '올바른 주민등록번호를 입력해주세요' });
+                      return false;
+                    }
+                    
+                    if( validRegistrationNumber( rf, rl ) != true ) {
+                      alertBox({ txt : '올바른 주민등록번호를 입력해주세요' });
+                      return false;
+                    }
+                  }
+                }
+
+
+                if( $( "#residentNumberLast" ).val() != "" ) {
+                  $( "#residentNumberLast" ).val( btoa( $( "#residentNumberLast" ).val() ) );
+                }
+
+                if( $( "#foreignNumberLast" ).val() != "" ) {
+                  $( "#foreignNumberLast" ).val( btoa( $( "#foreignNumberLast" ).val() ) );
+                }
+
+                if( $( "#passportNumber" ).val() != "" ) {
+                  $( "#passportNumber" ).val( btoa( $( "#passportNumber" ).val() ) ); 
+                }
+
+                // console.log( $(form).serialize() );
                 form.submit();
             }
         });
     }
     
-    $(document).on('click','input[name="foreignerYn"]',function(){
+    // $(document).on('click','input[name="foreignerYn"]',function(){
+    //     var foreigner = $(this).prop('checked');
+        
+    //     if(foreigner){
+    //       $('input[name="patientPhone"]').val('010-0000-0000').prop('readonly',true);
+    //     } else {
+    //       $('input[name="patientPhone"]').val('').prop('readonly',false);
+    //     }
+    // });
+
+
+    
+    // 외국인 체크버튼 클릭 이벤트
+    $(document).on('click','input.check-foreigner',function(){
         var foreigner = $(this).prop('checked');
         
         if(foreigner){
+          $( ".k-input" ).hide();
+          $( ".f-input" ).show();
+
+          $('#fModal').modal('show');
+          $( "div.f-input .f-txt" ).show();
+          $( "div.f-input .f-val" ).show().text("");
+          $('input[name="residentNumberFront"]').val("");
+          $('input[name="residentNumberLast"]').val("");
+          $('input.check-foreigner').not(this).prop('checked', true);
           $('input[name="patientPhone"]').val('010-0000-0000').prop('readonly',true);
+
+          $( "div.resident-number-change" ).hide();
         } else {
+          $( ".k-input" ).show();
+          $( ".f-input" ).hide();
+          $('input[name="residentNumberFront"]').val("");
+          $('input[name="residentNumberLast"]').val("");
+          $('input.check-foreigner').not(this).prop('checked', false);
           $('input[name="patientPhone"]').val('').prop('readonly',false);
+
+          $( "div.resident-number-change" ).show();
+        }
+
+        fModalReset();
+    });
+
+    // $("#fModal").on('hidden.bs.modal', function () {
+    //   $( "#foreignNumberFront, #foreignNumberLast, #passportNumber" ).val("").prop( "disabled", false );
+    // });
+    
+    
+    $( "#foreignNumberFront, #foreignNumberLast" ).on( "keyup", function() {
+      if( $("#foreignNumberFront").val().length >= 6 ) {
+         $("#foreignNumberLast").focus();
+      }
+
+      if( $( this ).val() != "" ){
+        $( "#passportNumber" ).prop("disabled", true);
+      } else {
+        if( $( "#foreignNumberFront" ).val() == "" && $( "#foreignNumberFront" ).val() == $( "#foreignNumberLast" ).val() ) {
+          $( "#passportNumber" ).prop("disabled", false);
+        }
+      }
+    });
+
+
+    $( "#passportNumber" ).on( "keyup", function() {
+      if( $( this ).val() != "" ){
+        $( "#foreignNumberFront, #foreignNumberLast" ).prop("disabled", true);
+      } else {
+        if( $( "#passportNumber" ).val() == "" ) {
+          $( "#foreignNumberFront, #foreignNumberLast" ).prop("disabled", false);
         }
+      }
     });
+
+    // $('#fModal').on('hidden.bs.modal', function (e) {
+    //   $( "#foreignNumberChange" ).prop( "checked", false );
+    // })
 });
+
+
+function fModalReset(){
+  $( "#foreignNumberCheck" ).val( "false" );
+  $( "#foreignNumberFront, #foreignNumberLast, #passportNumber" ).val( "" ).prop('readonly', false).prop( "disabled", false );
+  $( "span.f-val" ).hide().val("");
+  $( "span.f-txt" ).show();
+}
+
+function fModalCheck() {
+  var ff = $( "#foreignNumberFront" ).val();
+  var fl = $( "#foreignNumberLast" ).val();
+  var pn = $( "#passportNumber" ).val();
+
+  if( ff.length == 0 && fl.length == 0 && pn.length == 0 ) {
+    alertBox({ txt : '외국인 등록번호 또는 여권번호 중 하나만을 선택하여 입력하시기 바랍니다' });
+    return;
+  } else if( pn.length == 0 && ( ff.length > 0 || fl.length > 0 ) ) {
+    if( ff.length != 6 || fl.length != 7 ) {
+      alertBox({ txt : '외국인 등록번호를 모두 입력하세요' });
+      return;
+    }
+
+    if( ff.length == 6 && fl.length == 7 ) {
+      var fVal = $( "#foreignNumberLast" ).val().substr(0,1);
+
+      if( fVal >= 5 && fVal <= 8 ) {
+        if( validRegistrationNumber( ff, fl ) ) {
+          $( "div.f-input .f-txt" ).hide();
+          $( "div.f-input .f-val" ).show().text( "외국인 등록번호 (" + ff + "-*******)" );
+          $( "#foreignNumberCheck" ).val( "true" );
+          $( "#foreignNumberFront, #foreignNumberLast" ).prop( "readonly", true );
+          $("#fModal").modal("hide");
+        } else {
+          alertBox({ txt : '올바른 외국인 등록번호를 입력하세요' });
+          fModalReset();
+        }
+        return;
+
+      } else {
+        alertBox({ txt : '올바른 외국인 등록번호를 입력하세요' });
+        fModalReset();
+      }
+    }
+  } else if( ff.length == 0 && fl.length == 0 && pn != "" ) {
+    var newPn = pn.length > 3 ? pn.substr(0, pn.length - 3 ) + "***" : pn;
+
+    $( "div.f-input .f-txt" ).hide();
+    $( "div.f-input .f-val" ).show().text( "여권번호 (" + newPn + ")" );
+    $( "#foreignNumberCheck" ).val( "true" );
+    $( "#passportNumber" ).prop( "readonly", true );
+    $("#fModal").modal("hide");
+    return;
+  }
+}
+
+function resetInput( t ) {
+  if( $(t).siblings('input[type="text"]').val() != "" ) {
+    $(t).siblings('input[type="text"]').val('').prop('readonly', false).trigger('keyup');
+    $('#foreignNumberCheck').val( "false" );
+    $( "span.f-val" ).hide().val("");
+    $( "span.f-txt" ).show();
+  }
+}
+
+function validRegistrationNumber( f, l ) {
+    var rn = f + "" + l;
+    rn = rn.split("-").join('');
+    if( rn.length !== 13 ) return false;
+ 
+    var checkSum = 0;
+    for(var i=0; i<12; i++) checkSum += ((rn.substr(i,1)>>0)*((i%8)+2));
+ 
+    var rrnMatch = (11-(checkSum%11))%10 == rn.substr(12,1);
+    var frnMatch = (13-(checkSum%11))%10 == rn.substr(12,1);
+
+    return rrnMatch || frnMatch;
+};
+
+
+function ssnCheck(_ssn1, _ssn2) {
+    var ssn1    = _ssn1,
+        ssn2    = _ssn2,
+        ssn     = ssn1+''+ssn2,
+        arr_ssn = [],
+        compare = [2,3,4,5,6,7,8,9,2,3,4,5],
+        sum     = 0;
+
+    // 공식: M = (11 - ((2×A + 3×B + 4×C + 5×D + 6×E + 7×F + 8×G + 9×H + 2×I + 3×J + 4×K + 5×L) % 11)) % 10
+    for (var i = 0; i<13; i++) { 
+        arr_ssn[i] = ssn.substring(i,i+1); 
+    }
+     
+    for (var i = 0; i<12; i++) {
+        sum = sum + (arr_ssn[i] * compare[i]); 
+    }
+ 
+    sum = (11 - (sum % 11)) % 10;
+     
+    if (sum != arr_ssn[12]) { 
+        return false; 
+    }
+ 
+    return true;
+}
 </script>
+<style>
+  input.type-password {
+    -webkit-text-security: disc;
+    font-family: dotsfont;
+}
+</style>
 </head>
 <body>
     <div class="wrapper">
@@ -297,28 +523,133 @@ $( function(){
                                                       주민등록번호 <c:if test="${patientData.foreignerYn eq 'Y'}"><span class="text-danger">(외국인)</span></c:if>
                                                     </th>
                                                     <td>
-                                                      <c:if test="${patientData.foreignerYn eq 'Y'}">
-                                                        <c:if test="${patientData.foreignNumberFront ne ''}">
-                                                          외국인 등록번호 ( <c:out value="${patientData.foreignNumberFront}"/>-******* )
-                                                        </c:if>
+                                                          <div class="resident-number-change" <c:if test="${patientData.foreignerYn eq 'Y'}">style="display:none;"</c:if>>
+                                                            <c:if test="${patientData.residentNumberFront ne ''}">
+                                                              <span class="text-muted mr-3" id="residentNumberView">
+                                                                <c:out value="${patientData.residentNumberFront}"/> - *******
+                                                              </span>
+                                                            </c:if>
+                                                            
+                                                            <span class="form-check-inline" style="width:45%;display:none;" id="residentNumberNew">
+                                                              <input type="text"  id="residentNumberFront" name="residentNumberFront" onkeypress="onlyNumber();" maxlength="6" class="form-control" placeholder="" autocomplete="off" value='<c:out value="${patientData.residentNumberFront}"/>'>
+                                                              <span class="ml-1 mr-1">-</span>
+                                                              <input type="text" id="residentNumberLast" name="residentNumberLast" onkeypress="onlyNumber();" maxlength="7" class="form-control type-password" placeholder="·······" autocomplete="off" value=''>
+                                                            </span>
+                                                            <label class="form-check form-check-inline">
+                                                                <input type="checkbox" class="mr-1" id="residentNumberChange" name="residentNumberChange" value="Y"> 
+                                                                <span class="form-check-label">주민등록번호 수정이 필요한 경우 체크</span>
+                                                            </label>
 
-                                                        <c:if test="${patientData.passportNumber ne ''}">
-                                                          <c:set var = "length" value = "${fn:length(patientData.passportNumber)}"/>
-                                                          <c:set var = "passnum" value = "${fn:substring(patientData.passportNumber, 0, length -3)}" />
+                                                            <script>
+                                                              $( "#residentNumberChange" ).on( "change", function(){
+                                                                var $this = $( this );
+                                                                if( $this.is(":checked") ) {
+                                                                  $( "#residentNumberNew" ).show();
+                                                                  $( "#residentNumberView" ).hide();
+                                                                } else {
+                                                                  $( "#residentNumberNew" ).hide();
+                                                                  $( "#residentNumberView" ).show();
+                                                                }
+                                                              }); 
+                                                            </script>
+                                                          </div>
+  
+                                                          <div class="f-input mb-1" <c:if test="${patientData.foreignerYn ne 'Y'}">style="display:none;"</c:if>>
+                                                            <span class="f-val text-secondary ml-1">
+                                                                <c:if test="${patientData.foreignNumberFront ne ''}">
+                                                                  외국인 등록번호 ( <c:out value="${patientData.foreignNumberFront}"/>-******* )
+                                                                </c:if>
 
-                                                          여권번호 : <c:out value="${passnum}"/>***
-                                                        </c:if>
-                                                      </c:if>
+                                                                <c:if test="${patientData.passportNumber ne ''}">
+                                                                  <c:set var = "length" value = "${fn:length(patientData.passportNumber)}"/>
+                                                                  <c:set var = "passnum" value = "${fn:substring(patientData.passportNumber, 0, length -3)}" />
 
-                                                      <c:if test="${patientData.foreignerYn ne 'Y'}">
-                                                        <c:if test="${patientData.residentNumberFront ne ''}">
-                                                          <c:out value="${patientData.residentNumberFront}"/>-*******
-                                                        </c:if>
+                                                                  여권번호 : <c:out value="${passnum}"/>***
+                                                                </c:if>
+                                                            </span>
 
-                                                        <c:if test="${patientData.residentNumberFront eq ''}">
-                                                          (주민등록번호 미등록 환자)
-                                                        </c:if>
-                                                      </c:if>
+                                                            <c:if test="${patientData.foreignNumberFront eq '' and patientData.passportNumber eq ''}">
+                                                              <span class="f-txt">외국인 고유식별정보를 입력하세요 (선택)</span>
+                                                              
+                                                              <span class="f-edit" style="cursor:pointer;" onclick="$('#fModal').modal('show');">
+                                                                <i class="align-middle ml-2 fas fa-fw fa-edit"></i>
+                                                              </span>
+                                                            </c:if>
+
+                                                            <c:if test="${patientData.foreignNumberFront ne '' or patientData.passportNumber ne ''}">
+                                                              <div>
+                                                                <label class="form-check form-check-inline text-dark p-0 m-0">
+                                                                    <input type="checkbox" class="mr-1" id="foreignNumberChange" name="foreignNumberChange" value="Y"> 
+                                                                    <span class="form-check-label">외국인 고유식별정보 수정이 필요한 경우 체크</span>
+                                                                </label>
+
+                                                                <script>
+                                                                  var tmpText = $( "span.f-val").text();
+                                                                  $( "#foreignNumberChange" ).on( "change", function() {
+                                                                    var $this = $( this );
+                                                                    if( $this.is(":checked") ) {
+                                                                      $( "span.f-val").text("외국인 고유식별정보를 입력해주세요");
+                                                                      $('#fModal').modal('show');
+                                                                      $( "#foreignNumberFront, #foreignNumberLast, #passportNumber" ).val( "" ).prop('readonly', false).prop( "disabled", false );
+                                                                    } else {
+                                                                      $('#fModal').modal('hide');
+                                                                      $( "span.f-val").text(tmpText);
+                                                                    }
+                                                                  });
+                                                                </script>
+                                                              </div>
+                                                            </c:if>
+
+                                                            <c:if test="${patientData.foreignNumberFront eq '' and patientData.passportNumber eq ''}">
+                                                                <input type="checkbox" class="mr-1" style="display: none;" id="foreignNumberChange" name="foreignNumberChange" value="Y" checked="checked"> 
+                                                            </c:if>
+                                                          </div>
+    
+                                                          <!-- 외국인 고유식별 정보 입력 modal -->
+                                                          <div class="modal fade" id="fModal" tabindex="-1" role="dialog" aria-hidden="true" data-memoid="">
+                                                            <div class="modal-dialog modal-dialog-centered" role="document">
+                                                              <div class="modal-content" style="border-bottom-right-radius: 0; border-bottom-left-radius: 0;">
+                                                                <div class="modal-body m-3">
+                                                                  <h2 class="text-center mb-3">외국인 고유식별정보 입력</h2>
+                                                                  <hr/>
+                                                                  <table class="table">
+                                                                    <colgroup>
+                                                                        <col style="width:15%">
+                                                                        <col style="width:35%">
+                                                                    </colgroup>
+                                                                    <tr>
+                                                                      <th>외국인 등록번호</th>
+                                                                      <td>
+                                                                        <div class="form-check-inline">
+                                                                          <input type="hidden" id="foreignNumberCheck" value="false">
+                                                                          <input type="text" id="foreignNumberFront" name="foreignNumberFront" value='<c:out value="${patientData.foreignNumberFront}"/>' onkeypress="onlyNumber();" maxlength="6" class="form-control" placeholder="외국인 등록번호 앞 6자리">
+                                                                          <span class="ml-1 mr-1">-</span>
+                                                                          <input type="text" id="foreignNumberLast" name="foreignNumberLast" value='<c:out value="${patientData.foreignNumberLast}"/>' onkeypress="onlyNumber();" maxlength="7" class="form-control type-password" placeholder="·······"  autocomplete="new-password">
+                                                                          <button type="button" class="btn btn-outline-danger ml-2" onclick="resetInput(this);">x</button>
+                                                                        </div>
+                                                                      </td>
+                                                                    </tr>
+                                                                    <tr>
+                                                                      <th>여권번호</th>
+                                                                      <td>
+                                                                        <div class="form-check-inline">
+                                                                          <input type="text" id="passportNumber" name="passportNumber" value='<c:out value="${patientData.passportNumber}"/>' class="form-control jumin-check" placeholder="여권번호">
+                                                                          <button type="button" class="btn btn-outline-danger ml-2" onclick="resetInput(this);">x</button>
+                                                                        </div>
+                                                                      </td>
+                                                                    </tr>
+                                                                  </table>
+    
+                                                                  <p class="h4 mt-3 text-center">※ <span class="text-secondary">외국인 등록번호</span> 또는 <span class="text-secondary">여권번호</span> 중 하나만을 선택하여 입력하시기 바랍니다.</p>
+                                                                </div>
+                                                                
+                                                                <div class="modal-footer bg-white" style="justify-content: center !important;">
+                                                                  <button type="button" class="btn btn-outline-primary" data-dismiss="modal">취소</button>
+                                                                  <button type="button" class="btn btn-primary" onclick="fModalCheck();">입력 완료</button>
+                                                                </div>
+                                                              </div>
+                                                            </div>
+                                                          </div>
                                                     </td>
                                                 </tr>
                                                 <tr>
@@ -376,7 +707,7 @@ $( function(){
                                                             <input type="text" name="patientPhone" value="${patientData.patientPhone}" class="form-control" placeholder="연락처를 입력해주세요" required <c:if test="${patientData.foreignerYn eq 'Y'}">readonly</c:if>>
                                                         </div>
                                                         <label class="form-check form-check-inline">
-                                                            <input class="form-check-input" name="foreignerYn" type="checkbox" value="Y" <c:if test="${patientData.foreignerYn eq 'Y'}">checked="checked"</c:if>>
+                                                            <input class="form-check-input check-foreigner" name="foreignerYn" type="checkbox" value="Y" <c:if test="${patientData.foreignerYn eq 'Y'}">checked="checked"</c:if>>
                                                             <span class="form-check-label">외국인</span>
                                                         </label>
                                                     </td>

+ 47 - 31
src/main/webapp/WEB-INF/jsp/patient/new.jsp

@@ -203,8 +203,8 @@ $( function(){
             hospitalizationDate : {
                 date:"입소일시를 선택해주세요"
             },
-            residentNumberFront: "주민등록번호 앞 6자리를 입력해주세요",
-            residentNumberLast: "주민등록번호 뒷자리를 입력해주세요"
+            // residentNumberFront: "주민등록번호 앞 6자리를 입력해주세요",
+            // residentNumberLast: "주민등록번호 뒷자리를 입력해주세요"
         },
         onkeyup: function( element, event ) {
             $( element ).valid();
@@ -242,23 +242,36 @@ $( function(){
 
             if( $( "input[name='foreignerYn']" ).is(":checked") ) {
               if( $( "#foreignNumberCheck" ).val() == "false" ) {
-                alertBox({ txt : '외국인인 경우 고유식별정보를 입력해주세요' });
-                return false;
+                // alertBox({ txt : '외국인인 경우 고유식별정보를 입력해주세요' });
+                
+
+                  var ff = $( "#foreignNumberFront" ).val();
+                  var fl = $( "#foreignNumberLast" ).val();
+                  var pn = $( "#passportNumber" ).val();
+
+                  if( $.trim( ff||fl||pn ) != '' ) {
+                    $( "#fModal" ).modal('show');
+                    fModalCheck();
+
+                    return false;
+                  }
               }
             } else {
               var rf = $('input[name="residentNumberFront"]').val();
               var rl = $('input[name="residentNumberLast"]').val();
 
-              var fVal = $('input[name="residentNumberLast"]').val().substr(0,1);
-
-              if( fVal >= 5 && fVal <= 8 ) {
-                alertBox({ txt : '올바른 주민등록번호를 입력해주세요' });
-                return false;
-              }
-              
-              if( ssnCheck( rf, rl ) != true ) {
-                alertBox({ txt : '올바른 주민등록번호를 입력해주세요' });
-                return false;
+              if( $.trim( rf || rl ) != '' ) {
+                var fVal = $('input[name="residentNumberLast"]').val().substr(0,1);
+  
+                if( fVal >= 5 && fVal <= 8 ) {
+                  alertBox({ txt : '올바른 주민등록번호를 입력해주세요' });
+                  return false;
+                }
+                
+                if( validRegistrationNumber( rf, rl ) != true ) {
+                  alertBox({ txt : '올바른 주민등록번호를 입력해주세요' });
+                  return false;
+                }
               }
             }
 
@@ -364,7 +377,7 @@ function fModalCheck() {
       var fVal = $( "#foreignNumberLast" ).val().substr(0,1);
 
       if( fVal >= 5 && fVal <= 8 ) {
-        if( ssnCheck( ff, fl ) ) {
+        if( validRegistrationNumber( ff, fl ) ) {
           $( "div.f-input .f-txt" ).hide();
           $( "div.f-input .f-val" ).show().text( "외국인 등록번호 (" + ff + "-*******)" );
           $( "#foreignNumberCheck" ).val( "true" );
@@ -402,6 +415,20 @@ function resetInput( t ) {
   }
 }
 
+function validRegistrationNumber( f, l ) {
+    var rn = f + "" + l;
+    rn = rn.split("-").join('');
+    if( rn.length !== 13 ) return false;
+ 
+    var checkSum = 0;
+    for(var i=0; i<12; i++) checkSum += ((rn.substr(i,1)>>0)*((i%8)+2));
+ 
+    var rrnMatch = (11-(checkSum%11))%10 == rn.substr(12,1);
+    var frnMatch = (13-(checkSum%11))%10 == rn.substr(12,1);
+
+    return rrnMatch || frnMatch;
+};
+
 function ssnCheck(_ssn1, _ssn2) {
     var ssn1    = _ssn1,
         ssn2    = _ssn2,
@@ -514,44 +541,33 @@ input.type-password
                                                         <input type="text" name="patientNumber" onkeypress="onlyNumber();" maxlength="15" class="form-control" placeholder="환자 번호를 입력해주세요.">
                                                     </td>
 
-                                                    <th><span class="fix">*</span>주민등록번호 
+                                                    <th>주민등록번호 
                                                         <label class="form-check form-check-inline">(
                                                             <input class="form-check-input check-foreigner" type="checkbox">
                                                             <span class="form-check-label">외국인</span>)
                                                         </label>
                                                     </th>
                                                     <td>
-                                                      <!-- <input type="text" style="opacity:0;position:absolute;top:0;left:0;">
-                                                      <input type="password" style="opacity:0;position:absolute;bottom:0;left:0;"> -->
-
                                                       <div class="form-check-inline k-input">
                                                         <div>
-                                                          <input type="text" id="residentNumberFront" name="residentNumberFront" onkeypress="onlyNumber();" maxlength="6" class="form-control" placeholder="주민등록번호 앞 6자리" autocomplete="off" required>
+                                                          <input type="text" id="residentNumberFront" name="residentNumberFront" onkeypress="onlyNumber();" maxlength="6" class="form-control" placeholder="주민등록번호 앞 6자리" autocomplete="off" >
                                                         </div>
                                                         <div>
                                                           <span class="ml-1 mr-1">-</span>
                                                         </div>
                                                         <div>
-                                                          <input type="text" id="residentNumberLast" name="residentNumberLast" onkeypress="onlyNumber();" maxlength="7" class="form-control type-password" placeholder="·······" autocomplete="off" required>
+                                                          <input type="text" id="residentNumberLast" name="residentNumberLast" onkeypress="onlyNumber();" maxlength="7" class="form-control type-password" placeholder="·······" autocomplete="off" >
                                                         </div>
                                                       </div>
 
                                                       <div class="form-check-inline f-input mb-1" style="display: none;">
-                                                        <span class="f-txt">외국인 고유식별정보 입력</span>
+                                                        <span class="f-txt">외국인 고유식별정보 입력하세요 (선택)</span>
                                                         <span class="f-val text-secondary ml-1"></span>
                                                         <span class="f-edit" style="cursor:pointer;" onclick="$('#fModal').modal('show');">
                                                           <i id="memoLinkIcon" class="align-middle ml-2 fas fa-fw fa-edit"></i>
                                                         </span>
-                                                        <!-- <input type="text" name="foreignNumberFront" onkeypress="onlyNumber();" maxlength="6" class="form-control jumin-check" placeholder="외국인 등록번호 앞 6자리">
-                                                        <span class="ml-1 mr-1">-</span>
-                                                        
-                                                        <input type="password" name="foreignNumberLast" onkeypress="onlyNumber();" maxlength="7" class="form-control jumin-check" placeholder="·······" autocomplete="off"> -->
                                                       </div>
 
-                                                      <!-- <div class="f-input" style="display: none;">
-                                                        <input type="text" name="passportNumber" onkeypress="onlyNumber();" maxlength="6" class="form-control jumin-check" placeholder="여권번호">
-                                                      </div> -->
-
                                                       <!-- 외국인 고유식별 정보 입력 modal -->
                                                       <div class="modal fade" id="fModal" tabindex="-1" role="dialog" aria-hidden="true" data-memoid="">
                                                         <div class="modal-dialog modal-dialog-centered" role="document">
@@ -592,7 +608,7 @@ input.type-password
                                                             
                                                             <div class="modal-footer bg-white" style="justify-content: center !important;">
                                                               <button type="button" class="btn btn-outline-primary" data-dismiss="modal">취소</button>
-                                                              <button type="button" class="btn btn-primary" onclick="fModalCheck();">확인</button>
+                                                              <button type="button" class="btn btn-primary" onclick="fModalCheck();">입력 완료</button>
                                                             </div>
                                                           </div>
                                                         </div>

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

@@ -178,6 +178,7 @@ function pushDetail( t ){
 <style>
 .pointer{cursor:pointer;}
 .pointer span:hover{text-decoration: underline;}
+.fa-sync-alt:hover{ transform: rotate(180deg);transition: 0.5s; }
 </style>
 </head>
 <body>

+ 13 - 2
src/main/webapp/WEB-INF/jsp/staff/new.jsp

@@ -24,7 +24,8 @@ $( function(){
                             return $( "input[name='id']" ).val();
                         }
                     }
-                }
+                },
+                adminCheck : true
             },
             phoneNumber : {
                 phoneValid : true
@@ -40,7 +41,7 @@ $( function(){
         },
         messages : {
             id : {
-                remote : "이미 존재하는 아이디입니다"
+                remote : "이미 존재하는 아이디입니다",
             },
             password : {
 //                 minlength : "비밀번호를 확인하세요 (영문, 숫자, 특수문자를 혼합하여 8 ~ 15자 이내)",
@@ -61,6 +62,10 @@ $( function(){
             form.submit();
         }
     });
+
+     $.validator.addMethod('adminCheck', function (value) {
+       return value.indexOf('admin') == -1;
+     }, "admin이 들어가는 아이디는 사용 불가합니다.");
 })
 
 </script>
@@ -90,6 +95,7 @@ $( function(){
                             </nav>
                         </div>
                     </div>
+
                     <div class="row">
                         <div class="col-12">
                             <div class="card">
@@ -105,6 +111,11 @@ $( function(){
                                             <tr>
                                                 <th><span class="fix">*</span>아이디</th>
                                                 <td>
+                                                    <!-- 크롬 autocomplete 방지 -->
+                                                    <input type="text"     name="autoUserId"       style="opacity:0;position:absolute;width:0;height:0;">
+                                                    <input type="password" name="autoUserPassword" style="opacity:0;position:absolute;width:0;height:0;">
+                                                    <!-- --------------------- -->
+
                                                     <input type="text" class="form-control" name="id" required>
                                                     <!-- <button class="btn btn-primary">중복확인</button> -->
                                                 </td>