Stormen123 2023-06-22
20230622 김성훈 노드Excel 등록, 사용자, 유지보수담당자 등록 유효성 검사 추가
@8c8afca83b8526ce4162f7581387ada95f112fcb
client/views/pages/SystemManagement/AccessRecord.vue
--- client/views/pages/SystemManagement/AccessRecord.vue
+++ client/views/pages/SystemManagement/AccessRecord.vue
@@ -3,14 +3,10 @@
     <div class="tab-wrap">
       <ul>
         <li>
-          <router-link to="/UserManagement.page">
-            <span class="tab">사용자 관리</span>
-          </router-link>
+            <span class="tab" @click="userSelectListPage">사용자 관리</span>
         </li>
         <li>
-          <router-link to="/AccessRecord.page">
-            <span class="tab active">접속기록 조회</span>
-          </router-link>
+            <span class="tab active" @click="accessLogPage">접속기록 조회</span>
         </li>
       </ul>
     </div>
@@ -21,19 +17,17 @@
       <hr class="margin">
       <div class="search-wrap clear-fix">
         <div class="float-right">
-          <form action="">
-            <label>접속일자</label>
-            <input type="date" name="" id="" />
-            <span>~</span>
-            <input type="date" name="" id="" />
-            <select name="" id="">
-              <option value="">검색조건</option>
-              <option value="">ID</option>
-              <option value="">이름</option>
-            </select>
-            <input type="text" />
-            <button type="button" class="green-btn">검색</button>
-          </form>
+          <label>접속일자</label>
+          <input type="date" value-format="yyyymmdd" v-model="userAccessListSearch.startDate"/>
+          <span>~</span>
+          <input type="date" value-format="yyyymmdd" v-model="userAccessListSearch.endDate"/>
+          <select v-model="userAccessListSearch.searchType">
+            <option value="">검색조건</option>
+            <option value="user_id">ID</option>
+            <option value="user_nm">이름</option>
+          </select>
+          <input type="text" placeholder="검색어를 입력 해주세요." v-model="userAccessListSearch.searchText" @keyup.enter="userAccessList"/>
+          <button type="button" class="green-btn" @click="userAccessList">검색</button>
         </div>
       </div>
       <div>
@@ -57,35 +51,22 @@
             </tr>
           </thead>
           <tbody>
-            <tr>
-              <td>100</td>
-              <td>id_sample_1</td>
-              <td>name_1</td>
-              <td>2023-04-28 16:55:28</td>
-              <td>192.168.0.11</td>
-              <td></td>
-            </tr>
-            <tr>
-              <td>99</td>
-              <td>id_sample_2</td>
-              <td>name_2</td>
-              <td>2023-04-28 16:55:28</td>
-              <td>192.168.0.11</td>
-              <td></td>
+            <tr v-for="(item, idx) in userAccessList" :key="idx">
+              <td data-title="NO">{{ idx + 1 }}</td>
+              <td data-title="접속ID">{{ item.user_id }}</td>
+              <td data-title="접속자이름">{{ item.user_nm }}</td>
+              <td data-title="접속일시">{{ item.cntn_dt }}</td>
+              <td data-title="접속IP">{{ item.cntn_ip }}</td>
+              <td data-title="접속타입">{{ item.cntn_ty }}</td>
             </tr>
           </tbody>
         </table>
       </div>
       <div class="bottom-wrap">
-        <div class="pg-wrap">
-          <a href="#" class="pg-item prev">◀</a>
-          <a href="#" class="pg-item active">1</a>
-          <a href="#" class="pg-item">2</a>
-          <a href="#" class="pg-item">3</a>
-          <a href="#" class="pg-item">4</a>
-          <a href="#" class="pg-item">5</a>
-          <a href="#" class="pg-item next">▶</a>
-        </div>
+        <PaginationButton
+          v-model:currentPage="userAccessListSearch.currentPage"
+          :per-page="userAccessListSearch.perPage" :total-count="userAccessCount" :max-range="5"
+          :click="userAccessList" />
         <div class="btn-wrap">
           <button type="button" class="green-btn">Excel로 저장</button>
         </div>
@@ -95,13 +76,61 @@
 </template>
 
 <script>
+import axios from 'axios';
+import PaginationButton from '../../component/pagination/PaginationButton.vue';
+
 export default {
-  data() {
-    return {};
+  data: () => {
+    return {
+      userAccessListSearch: {
+        currentPage: 1,
+        perPage: 10,
+        searchType: null,
+        searchText: null,
+        startDate: null,
+        endDate: null
+      },
+      userAccessCount: 0,
+      userAccessList: []
+    };
   },
-  methods: {},
+  methods: {
+
+    //접속기록 목록 조회
+    userAccessList: function () {
+      const vm = this;
+      axios({
+        url: '/user/userAccessLog.json',
+        method: 'post',
+        herders: {
+          'Content-Type': "application/json; charset=UTF-8",
+        },
+        data: vm.userAccessListSearch
+      }).then(function(response) {
+        console.log("userAccessList - response : ", response.data);
+        vm.userAccessCount = response.data.userAccessCount;
+        vm.userAccessList = response.data.userAccessList;
+      }).catch(function(error) {
+        console.log("userAccessList - error : ", error);
+        alert("접속기록 목록 조회 오류, 관리자에게 문의해주세요.")
+      })
+    },
+
+    //사용자 목록 페이지 이동
+    userSelectListPage: function () {
+      this.$router.push({ path: '/UserManagement.page'});
+    },
+
+    //접속기록조회 페이지 이동
+    accessLogPage: function () {
+      this.$router.push({ path: '/AccessRecord.page'});
+    },
+  },
   watch: {},
   computed: {},
+  components: {
+    'PaginationButton':PaginationButton,
+  },
   mounted() {
     console.log("Main4 mounted");
   },
client/views/pages/SystemManagement/ChargeManagement.vue
--- client/views/pages/SystemManagement/ChargeManagement.vue
+++ client/views/pages/SystemManagement/ChargeManagement.vue
@@ -37,12 +37,12 @@
           </thead>
           <tbody>
             <tr v-for="(item, idx) in managerList" :key="idx" @click="managerSelectOnePage(item)">
-              <td data-title="NO">{{ item['mntnce_mngr_id'] }}</td>
-              <td data-title="이름">{{ item['mngr_nm'] }}</td>
-              <td data-title="전화번호">{{ HyphenMinus(item['mngr_telno']) }}</td>
-              <td data-title="이메일">{{ item['mngr_eml'] }}</td>
-              <td data-title="소속정보">{{ item['mngr_ogdp_info'] }}</td>
-              <td data-title="등록일자">{{ yyyymmdd(item['reg_dt']) }}</td>
+              <td data-title="NO">{{ item.mntnce_mngr_id }}</td>
+              <td data-title="이름">{{ item.mngr_nm }}</td>
+              <td data-title="전화번호">{{ HyphenMinus(item.mngr_telno) }}</td>
+              <td data-title="이메일">{{ item.mngr_eml }}</td>
+              <td data-title="소속정보">{{ item.mngr_ogdp_info }}</td>
+              <td data-title="등록일자">{{ yyyymmdd(item.reg_dt) }}</td>
             </tr>
           </tbody>
         </table>
client/views/pages/SystemManagement/ManagerAddForm.vue
--- client/views/pages/SystemManagement/ManagerAddForm.vue
+++ client/views/pages/SystemManagement/ManagerAddForm.vue
@@ -69,8 +69,8 @@
   methods: {
 
     //전화번호 입력 시 자동 '-' 삽입
-    getPhoneMask: function(val) {
-      var res = COMMON_UTIL.getMask(val)
+    getPhoneMask: function(telNumber) {
+      var res = COMMON_UTIL.getMask(telNumber)
       this.telno = res
       //서버 전송 값에는 '-' 를 제외하고 숫자만 저장
       this.manager.mngr_telno = this.telno.replace(/[^0-9]/g, '')
@@ -86,7 +86,7 @@
       if (COMMON_UTIL.checkPhone(this.manager.mngr_telno) === false) this.telno_boolean = false;
     },
 
-    // 등록버튼 클릭 시 유효성 검사
+    // 등록버튼 클릭 시 빈칸 검사
     managerInsertCheck: function() {
 
       if (COMMON_UTIL.isEmpty(this.manager.mngr_nm) === false) {
@@ -99,6 +99,11 @@
         return false;
       }
 
+      if (COMMON_UTIL.checkPhone(this.manager.mngr_telno) === false) {
+        alert('전화번호 형식을 확인해주세요.');
+        return false;
+      }
+
       if (COMMON_UTIL.isEmpty(this.manager.mngr_eml) === false) {
         alert('이메일을 입력해주세요.');
         return false;
client/views/pages/SystemManagement/NodeManagement.vue
--- client/views/pages/SystemManagement/NodeManagement.vue
+++ client/views/pages/SystemManagement/NodeManagement.vue
@@ -131,7 +131,7 @@
                 <label for="fileBtn" class="btn-2 green-btn">
                   파일선택
                 </label>
-                <button type="button" class="gray-btn">등록</button>
+                <button type="button" class="gray-btn" @click="nodeExcelInsert">등록</button>
               </td>
             </tr>
             <tr>
@@ -215,6 +215,42 @@
     };
   },
   methods: {
+    
+    //노드 엑셀 업로드
+    nodeExcelInsert: function() {
+      const vm = this;
+      var form = new FormData();
+      var file = document.getElementById("fileBtn");;
+      console.log(file.files[0]);
+      form.append("file", file.files[0]);
+      axios({
+        url: '/node/nodeExcelRead.json',
+        method: 'post',
+        hearders: {
+          'Content-Type': "multipart/form-data",
+        },
+        data: form
+      }).then(function (response) {
+        console.log("nodeExcelInsert - response : ", response.data);
+        let insert = response.data.insert;
+        let error = response.data.error;
+        if (insert > 0 && error > 0) {
+          alert(insert + "건의 노드 등록완료, " + error + "건은 이미 ID가 존재하는 데이터 입니다.")
+          vm.nodeSelectList();
+        } else if(insert === 0) {
+          alert("업로드 파일의 모든 데이터(" + error + "건)는 이미 ID가 존재하는 데이터 입니다.")
+          vm.nodeSelectList();
+        } else if(insert > 0 && error === 0) {
+          alert(insert + "건의 노드 등록완료.")
+          vm.nodeSelectList();
+        }
+      }).catch(function (error) {
+        console.log("nodeExcelInsert - error", error);
+        alert("파일 등록 오류, 관리자에게 문의해주세요.")
+      })
+    },
+
+    //노드목록 조회
     nodeSelectList: function() {
       const vm = this;
       axios({
@@ -234,6 +270,7 @@
       });
     },
 
+    //노드 등록
     nodeInsert: function() {
       const vm = this;
       axios({
@@ -268,6 +305,7 @@
       })
     },
 
+    //노드 수정
     nodeUpdate: function() {
       const vm = this;
       axios({
@@ -303,6 +341,7 @@
       })
     },
 
+    //노드 삭제
     nodeDelete: function() {
       const vm = this;
       axios({
@@ -338,15 +377,16 @@
       })
     },
 
-    nodeSelectOne: function(user) {
+    //노드 상세 조회 
+    nodeSelectOne: function(nodeOne) {
       const vm = this;
 
       this.disabled = true;
-      vm.node.node_id = user.node_id;
-      vm.node.node_nm = user.node_nm;
-      vm.node.node_ty = user.node_ty;
-      vm.node.lat = user.lat;
-      vm.node.lot = user.lot;
+      vm.node.node_id = nodeOne.node_id;
+      vm.node.node_nm = nodeOne.node_nm;
+      vm.node.node_ty = nodeOne.node_ty;
+      vm.node.lat = nodeOne.lat;
+      vm.node.lot = nodeOne.lot;
     }
   },
   watch: {},
client/views/pages/SystemManagement/UserAddForm.vue
--- client/views/pages/SystemManagement/UserAddForm.vue
+++ client/views/pages/SystemManagement/UserAddForm.vue
@@ -24,26 +24,26 @@
         <div class="flex m-b">
           <span>비밀번호 : </span>
           <input type="password" placeholder="Password" v-model="user.user_pw" @change="passwordSyncCheck()">
-          <p>비번 : {{ user.user_pw }}</p>
         </div>
         <div class="flex m-b">
           <span>비밀번호 확인 : </span>
           <input type="password" placeholder="Confirm Password" v-model="passwordCheck" @change="passwordSyncCheck()">
-          <p>체크 : {{ passwordCheck }}</p>
         </div>
-        <div v-if="passwordCheckFlag" style="color:chartreuse">비밀번호 일치</div>
-        <div v-else style="color:red">비밀번호 불일치</div>
+        <div v-if="passwordCheckFlag === true" style="color:chartreuse">비밀번호 일치</div>
+        <div v-else-if="passwordCheckFlag === false" style="color:red">비밀번호 불일치</div>
         <div class="flex m-b">
           <span>이름 : </span>
           <input type="text" placeholder="Name" v-model="user.user_nm">
         </div>
         <div class="flex m-b">
           <span>전화번호 : </span>
-          <input type="text" placeholder="Phone Number" v-model="user.user_telno">
+          <input type="text" placeholder=" '-' 을 제외하고 입력해주세요." maxlength="13" v-model="telno" @change="phoneCheck" @keyup="getPhoneMask(telno)">
+          <p style="color:red" v-if="telno_boolean === false">&nbsp;전화번호 9~11자리를 입력해주세요.</p>
         </div>
         <div class="flex m-b">
           <span>이메일 : </span>
-          <input type="text" placeholder="E-Mail" v-model="user.user_eml">
+          <input type="text" placeholder=" 예) qwer@naver.com" v-model="user.user_eml" @change="emailCheck">
+          <p style="color:red" v-if="email_boolean === false">&nbsp;잘못된 이메일 형식입니다.</p>
         </div>
         <div class="flex m-b">
           <span>관리구역 : </span>
@@ -64,17 +64,17 @@
         <div class="flex m-b">
           <span>권한 : </span>
           <label for="radio_1">
-            <input type="radio" name="radio" id="radio_1" value="si" v-model="user.user_author">
-            시청 관리자
+            <input type="radio" name="radio" id="radio_1" value="시청관리자" v-model="user.user_author">
+            시청관리자
           </label>
           <label for="radio_2">
-            <input type="radio" name="radio" id="radio_2" value="ji" v-model="user.user_author">
-            지자체 관리자
+            <input type="radio" name="radio" id="radio_2" value="지자체관리자" v-model="user.user_author">
+            지자체관리자
           </label>
         </div>
 
         <div class="btn-wrap">
-          <button type="button" class="green-btn" @click="modal_1 = true">등록</button>
+          <button type="button" class="green-btn" @click="userInsertCheck">등록</button>
           <router-link to="/UserManagement.page">
             <span class="btn-2 gray-btn">취소</span>
           </router-link>
@@ -83,14 +83,14 @@
     </div>
   </div>
 
-  <div class="modal-wrap" v-if="modal_1 == true">
+  <div class="modal-wrap" v-if="modal_insert == true">
     <div class="modal-bg">
     </div>
     <div class="modal">
       <p>사용자를 <span class="txt-point">등록</span>하시겠습니까?</p>
       <div class="btn-wrap">
         <button type="button" class="green-btn" @click="userInsert">확인</button>
-        <button type="button" class="gray-btn" @click="modal_1 = false">취소</button>
+        <button type="button" class="gray-btn" @click="modal_insert = false">취소</button>
       </div>
     </div>
   </div>
@@ -98,6 +98,7 @@
 
 <script>
 import axios from 'axios';
+import COMMON_UTIL from '../../../resources/js/commonUtil.ts';
 
 export default {
   data: () => {
@@ -112,11 +113,17 @@
         rm: null
       },
       passwordCheck: null,
-      passwordCheckFlag: false,
-      modal_1: false,
+      passwordCheckFlag: null,
+      telno_boolean: true,
+      email_boolean: true,
+      idChcek_boolean: false,
+      telno: null,
+      modal_insert: false
+
     };
   },
   methods: {
+    //ID 중복 검사
     idChcek: function() {
       const vm = this;
       axios({
@@ -130,27 +137,112 @@
         console.log("idCheck - response : ", response.data);
         if(response.data != null) {
           alert("중복된 ID 입니다.");
+          vm.idChcek_boolean = false;
           return false;
         } else {
           alert("사용가능한 ID 입니다.");
+          vm.idChcek_boolean = true;
           return true;
         }
       }).catch( function (error) {
         console.log("idCheck - error : ", error);
         alert("중복검사 오류, 다시 시도해주세요.");
+        vm.idChcek_boolean = false;
       });
     },
-
+  
+    //비밀번호 일치 여부 검사
     passwordSyncCheck: function () {
-      console.log("this.user.user_pw : ", this.user.user_pw);
-      console.log("this.passwordCheck : ", this.passwordCheck);
-
-      if (this.user.user_pw != this.passwordCheck) this.passwordCheckFlag = false;
-      else this.passwordCheckFlag = true;
+      if (this.user.user_pw != this.passwordCheck && this.user.user_pw != "" && this.passwordCheck != "" &&
+          this.user.user_pw != null && this.passwordCheck != null) {
+        this.passwordCheckFlag = false;
+      } else if (this.user.user_pw === this.passwordCheck && this.user.user_pw != "" && this.passwordCheck != ""&&
+                 this.user.user_pw != null && this.passwordCheck != null) {
+        this.passwordCheckFlag = true;
+      } else if (this.user.user_pw === "" || this.passwordCheck === "") {
+        this.passwordCheckFlag = null;
+      }
     },
 
-    //
-    userInsert: async function() {
+    //전화번호 입력 시 자동 '-' 삽입
+    getPhoneMask: function(telNumber) {
+      var res = COMMON_UTIL.getMask(telNumber)
+      this.telno = res
+      //서버 전송 값에는 '-' 를 제외하고 숫자만 저장
+      this.user.user_telno = this.telno.replace(/[^0-9]/g, '')
+    },
+    
+    emailCheck: function() {
+      this.email_boolean = true;
+      if (COMMON_UTIL.checkEmail(this.user.user_eml) === false) this.email_boolean = false;
+    },
+
+    phoneCheck: function() {
+      this.telno_boolean = true;
+      if (COMMON_UTIL.checkPhone(this.user.user_telno) === false) this.telno_boolean = false;
+    },
+
+    // 등록버튼 클릭 시 빈칸 검사
+    userInsertCheck: function() {
+      if (COMMON_UTIL.isEmpty(this.user.user_id) === false) {
+        alert('ID를 입력해주세요.');
+        return false;
+      }
+
+      if (this.idChcek_boolean === false) {
+        alert("ID중복검사를 완료해주세요.")
+        return false;
+      }
+
+      if (COMMON_UTIL.isEmpty(this.user.user_pw) === false) {
+        alert('비밀번호를 입력해주세요.');
+        return false;
+      }
+
+      if (this.passwordCheckFlag === false || this.passwordCheckFlag === null) {
+        alert('비밀번호가 일치하지 않습니다.');
+        return false;
+      }
+
+      if (COMMON_UTIL.isEmpty(this.user.user_nm) === false) {
+        alert('이름을 입력해주세요.');
+        return false;
+      }
+
+      if (COMMON_UTIL.isEmpty(this.user.user_telno) === false) {
+        alert('전화번호를 입력해주세요.');
+        return false;
+      }
+
+      if (COMMON_UTIL.checkPhone(this.user.user_telno) === false) {
+        alert('전화번호 형식을 확인해주세요.');
+        return false;
+      }
+
+      if (COMMON_UTIL.isEmpty(this.user.user_eml) === false) {
+        alert('이메일을 입력해주세요.');
+        return false;
+      }
+
+      if (COMMON_UTIL.checkEmail(this.user.user_eml) === false) {
+        alert('이메일 형식을 확인해주세요.');
+        return false;
+      }
+
+      // if (COMMON_UTIL.isEmpty(this.user.) === false) {
+      //   alert('관리구역을 선택해주세요.');
+      //   return false;
+      // }
+
+      if (COMMON_UTIL.isEmpty(this.user.user_author) === false) {
+        alert('권한을 선택해주세요.');
+        return false;
+      }
+      this.modal_insert = true
+    },
+
+    // 사용자 등록
+    userInsert: function() {
       const vm = this;
       axios({
         url: '/user/userInsert.json',
client/views/pages/SystemManagement/UserManagement.vue
--- client/views/pages/SystemManagement/UserManagement.vue
+++ client/views/pages/SystemManagement/UserManagement.vue
@@ -19,8 +19,8 @@
         <div class="float-left">
           <select v-model="userListSearch.authorFilter" @change="userSelectList">
             <option value="">권한필터</option>
-            <option value="si">시청관리자</option>
-            <option value="ji">지자체관리자</option>
+            <option value="시청관리자">시청관리자</option>
+            <option value="지자체관리자">지자체관리자</option>
           </select>
         </div>
         <div class="float-right">
@@ -57,18 +57,20 @@
               <th>권한</th>
               <th>전화번호</th>
               <th>관리구역</th>
+              <th>등록일자</th>
               <th>비고</th>
             </tr>
           </thead>
           <tbody>
             <tr v-for="(item, idx) in userList" :key="idx" @click="userSelectOnePage(item)">
               <td data-title="NO">{{ idx + 1 }}</td>
-              <td data-title="ID">{{ item['user_id'] }}</td>
-              <td data-title="이름">{{ item['user_nm'] }}</td>
-              <td data-title="권한">{{ item['user_author'] }}</td>
-              <td data-title="전화번호">{{ item['user_telno'] }}</td>
-              <td data-titel="권리구역">{{ item['dong_korn_nm'] }}</td>
-              <td data-totel="비고">{{ item['rm'] }}</td>
+              <td data-title="ID">{{ item.user_id }}</td>
+              <td data-title="이름">{{ item.user_nm }}</td>
+              <td data-title="권한">{{ item.user_author }}</td>
+              <td data-title="전화번호">{{ HyphenMinus(item.user_telno) }}</td>
+              <td data-titel="관리구역">{{ item.dong_korn_nm }}</td>
+              <td data-titel="등록일자">{{ yyyymmdd(item.reg_dt) }}</td>
+              <td data-totel="비고">{{ item.rm }}</td>
             </tr>
           </tbody>
         </table>
@@ -89,6 +91,7 @@
 <script>
 import axios from 'axios';
 import PaginationButton from '../../component/pagination/PaginationButton.vue';
+import COMMON_UTIL from '../../../resources/js/commonUtil.ts';
 
 export default {
   data: () => {
@@ -127,6 +130,16 @@
       })
     },
 
+    // 전화번호 '-' 추가 후 출력
+    HyphenMinus: function (telno) {
+      return COMMON_UTIL.HyphenMinus(telno);
+    },
+
+    //날짜 시,분,초 자르기
+    yyyymmdd: function (date) {
+      return COMMON_UTIL.yyyymmdd(date);
+    },
+
     //사용자 목록 페이지 이동
     userSelectListPage: function () {
       this.$router.push({ path: '/UserManagement.page'});
Add a comment
List