
+++ .vscode/settings.json
... | ... | @@ -0,0 +1,3 @@ |
1 | +{ | |
2 | + "liveServer.settings.port": 5501 | |
3 | +}(파일 끝에 줄바꿈 문자 없음) |
--- client/views/component/connection/EhojoConnection.vue
+++ client/views/component/connection/EhojoConnection.vue
... | ... | @@ -199,15 +199,9 @@ |
199 | 199 |
|
200 | 200 |
// 기본값 |
201 | 201 |
defaultHeaders: [ |
202 |
- { index: 1, key: "ifId", value: null, required: true }, |
|
203 |
- { index: 2, key: "tranId", value: null, required: true }, |
|
204 |
- { index: 3, key: "trnmtInstCd", value: null, required: true }, |
|
205 |
- { index: 4, key: "rcptnInstCd", value: null, required: true }, |
|
206 |
- { index: 5, key: "trnmtInstSysCd", value: null, required: true }, |
|
207 |
- { index: 6, key: "rcptnInstSysCd", value: null, required: true }, |
|
208 |
- { index: 7, key: "transfGramNo", value: null, required: false }, |
|
209 |
- { index: 8, key: "userDeptCode", value: null, required: false }, |
|
210 |
- { index: 9, key: "userName", value: null, required: false }, |
|
202 |
+ { index: 1, key: "transfGramNo", value: null, required: false }, |
|
203 |
+ { index: 2, key: "userDeptCode", value: null, required: false }, |
|
204 |
+ { index: 3, key: "userName", value: null, required: false }, |
|
211 | 205 |
], |
212 | 206 |
defaultBodys: [ |
213 | 207 |
{ index: 1, key: "curPage", value: 1, required: false }, |
... | ... | @@ -335,8 +329,8 @@ |
335 | 329 |
data: vm.job, |
336 | 330 |
}) |
337 | 331 |
.then((response) => { |
338 |
- if (response.data.checkMessage.status == "0000") { |
|
339 |
- let result = response.data; |
|
332 |
+ if (response.data.checkMessage.status == 0) { |
|
333 |
+ let result = response.data.resultData.dataTable; |
|
340 | 334 |
this.dataTable = result; |
341 | 335 |
this.rowKeys = []; // 초기화 |
342 | 336 |
for (let columnData of result.columnDatas) { |
... | ... | @@ -363,7 +357,6 @@ |
363 | 357 |
jobItm.itm = this.job; |
364 | 358 |
jobItm.dataTable = this.dataTable; |
365 | 359 |
|
366 |
- console.log("@@", jobItm); |
|
367 | 360 |
// 실행 |
368 | 361 |
this.$emit("fnSaveSetup", jobItm); |
369 | 362 |
}, |
--- client/views/layout/TopMenu.vue
+++ client/views/layout/TopMenu.vue
... | ... | @@ -54,6 +54,7 @@ |
54 | 54 |
pathName: "통합관리", |
55 | 55 |
subMenu: [ |
56 | 56 |
{ path: "/user.page", pathName: "사용자관리" }, |
57 |
+ { path: "/adminManagement.page", pathName: "관리자관리" }, |
|
57 | 58 |
{ path: "/department.page", pathName: "부서관리" }, |
58 | 59 |
{ path: "/dbConnectionList.page", pathName: "연계정보관리" }, |
59 | 60 |
], |
--- client/views/layout/back241206_TopMenu.vue
... | ... | @@ -1,148 +0,0 @@ |
1 | -<template> | |
2 | - <nav class="top-menu"> | |
3 | - <ul class="main-menu"> | |
4 | - <li v-for="(mainMenu, idx) in menuList" :key="idx" @mouseover="showAllSubMenus" @mouseout="hideAllSubMenus"> | |
5 | - <p class="depth1" :class="{ active: isMainMenuActive(mainMenu) }">{{ mainMenu.pathName }}</p> | |
6 | - <ul v-if="mainMenu.subMenu" class="sub-menu" :style="subShow ? 'max-height:500px; opacity:1' : 'max-height:0px; opacity:0'"> | |
7 | - <li v-for="(subMenu, idx) in mainMenu.subMenu" :key="idx" :class="{ active: isSubMenuActive(subMenu) }"> | |
8 | - <router-link :to="subMenu.path">{{ subMenu.pathName }}</router-link> | |
9 | - </li> | |
10 | - </ul> | |
11 | - </li> | |
12 | - </ul> | |
13 | - <div class="navbg" :style="subShow ? `height: ${maxSubMenuHeight}px` : `height: 0px`"></div> | |
14 | - </nav> | |
15 | -</template> | |
16 | -<script> | |
17 | - | |
18 | -export default { | |
19 | - data() { | |
20 | - return { | |
21 | - menuList: [ | |
22 | - // { path: "/", pathName: "Dashboard", }, | |
23 | - { | |
24 | - pathName: "데이터관리", | |
25 | - subMenu: [ | |
26 | - { path: "/fileManagement.page", pathName: "파일관리" }, | |
27 | - { path: "/hostManagement.page", pathName: "호스트관리" }, | |
28 | - { path: "/dataManagement.page", pathName: "데이터관리" }, | |
29 | - // { path: "/jobTest.page", pathName: "데이터 공유 관리" }, | |
30 | - ], | |
31 | - }, | |
32 | - { | |
33 | - pathName: "메타관리", | |
34 | - subMenu: [ | |
35 | - { path: "/dataMetaManagement.page", pathName: "데이터 메타 정보" }, | |
36 | - { path: "/termManagement.page", pathName: "표준 용어 관리" }, | |
37 | - ], | |
38 | - }, | |
39 | - { | |
40 | - pathName: "작업관리", | |
41 | - subMenu: [ | |
42 | - // { path: "/scheduleManagement.page", pathName: "작업 스케줄 관리" }, | |
43 | - { path: "/scheduleManagement.page", pathName: "작업 스케줄 관리" }, | |
44 | - //{ path: "/push.page", pathName: "알림관리" }, | |
45 | - //{ path: "/scheduleLogManagement.page", pathName: "로그 관리" }, | |
46 | - ], | |
47 | - }, | |
48 | - { | |
49 | - pathName: "데이터활용", | |
50 | - subMenu: [ | |
51 | - { path: "/customSelectList.page", pathName: "데이터 활용 관리" }, | |
52 | - // { path: "/customInsertDev.page", pathName: "개발테스트" }, | |
53 | - | |
54 | - // { path: "/", pathName: "데이터 활용 공유 관리" }, | |
55 | - // { path: "/", pathName: "GIS데이터 관리" }, | |
56 | - // { path: "/", pathName: "데이터현황 관리" }, | |
57 | - { path: "/gisInfoList.page", pathName: "GIS 기능 관리" }, | |
58 | - { path: "/openApiList.page", pathName: "OpenAPI 목록" }, | |
59 | - { path: "/openApiKeyList.page", pathName: "OpenAPI key 관리" }, | |
60 | - ], | |
61 | - }, | |
62 | - { | |
63 | - pathName: "통합관리", | |
64 | - subMenu: [ | |
65 | - { path: "/user.page", pathName: "사용자관리" }, | |
66 | - { path: "/department.page", pathName: "부서관리" }, | |
67 | - { path: "/dbConnectionList.page", pathName: "연계정보관리" }, | |
68 | - ], | |
69 | - }, | |
70 | - { | |
71 | - pathName: "정보관리", | |
72 | - subMenu: [ | |
73 | - { path: "/myPage.page", pathName: "내정보관리" }, | |
74 | - { path: "/myPagePwd.page", pathName: "비밀번호 변경" }, | |
75 | - // { path: "/", pathName: "부서메일" }, | |
76 | - ], | |
77 | - }, | |
78 | - // { | |
79 | - // pathName: "ai solution", | |
80 | - // subMenu: [ | |
81 | - // { path: "/", pathName: "ai solution" }, | |
82 | - | |
83 | - // ], | |
84 | - // }, | |
85 | - // { | |
86 | - // pathName: "템플릿", | |
87 | - // subMenu: [ | |
88 | - // { path: "/searchbar.page", pathName: "서치바" }, | |
89 | - // { path: "/table.page", pathName: "테이블" }, | |
90 | - // { path: "/btnPosition.page", pathName: "버튼별 위치" }, | |
91 | - // { path: "/formModal.page", pathName: "form modal" }, | |
92 | - // { path: "/listModal.page", pathName: "list modal" }, | |
93 | - // { path: "/icon.page", pathName: "icon" }, | |
94 | - // ], | |
95 | - // }, | |
96 | - // { | |
97 | - // pathName: "레이아웃 템플릿", | |
98 | - // subMenu: [ | |
99 | - // { path: "/vertical.page", pathName: "수직 레이아웃" }, | |
100 | - // { path: "/horizontal.page", pathName: "수평 레이아웃" }, | |
101 | - // ], | |
102 | - // }, | |
103 | - // { | |
104 | - // pathName: "가이드", | |
105 | - // subMenu: [ | |
106 | - // { path: "/guide.page", pathName: "가이드" }, | |
107 | - // ], | |
108 | - // }, | |
109 | - ], | |
110 | - currentRoute: null, | |
111 | - subShow: false | |
112 | - } | |
113 | - }, | |
114 | - methods: { | |
115 | - showAllSubMenus() { | |
116 | - this.subShow = true; | |
117 | - }, | |
118 | - hideAllSubMenus() { | |
119 | - this.subShow = false; | |
120 | - }, | |
121 | - | |
122 | - isMainMenuActive(mainMenu) { | |
123 | - return this.currentRoute && (this.currentRoute.path === mainMenu.path || this.isSubMenuActive(mainMenu.subMenu)); | |
124 | - }, | |
125 | - | |
126 | - isSubMenuActive(subMenu) { | |
127 | - if (!subMenu) return false; | |
128 | - for (let i = 0; i < subMenu.length; i++) { | |
129 | - if (this.currentRoute.path === subMenu[i].path) { | |
130 | - return true; | |
131 | - } | |
132 | - } | |
133 | - return false; | |
134 | - }, | |
135 | - }, | |
136 | - watch: { | |
137 | - $route(to, from) { | |
138 | - this.currentRoute = to; | |
139 | - }, | |
140 | - }, | |
141 | - computed: { | |
142 | - maxSubMenuHeight: function () { | |
143 | - let maxSubItems = Math.max(...this.menuList.map(menu => menu.subMenu.length)); | |
144 | - return maxSubItems * 55; // assuming each item is 50px high | |
145 | - } | |
146 | - }, | |
147 | -} | |
148 | -</script> |
--- client/views/pages/AppRouter.js
+++ client/views/pages/AppRouter.js
... | ... | @@ -1,5 +1,14 @@ |
1 |
+import axios from "axios"; |
|
2 |
+import store from "./AppStore"; |
|
1 | 3 |
import { createWebHistory, createRouter } from "vue-router"; |
4 |
+// #페이지 |
|
5 |
+// 통합관리 |
|
6 |
+import UserManagement from "../pages/integrated/UserManagement.vue"; // 사용자관리 |
|
7 |
+import AdminManagement from "../pages/integrated/AdminManagement.vue"; // 관리자관리 |
|
8 |
+import Department from "../pages/integrated/DepartmentManagement.vue"; // 부서관리 |
|
9 |
+import DBConnectionList from "../pages/dbConnection/DBConnectionList.vue"; // 연계정보관리 |
|
2 | 10 |
|
11 |
+import DBConnectionDetail from "../pages/dbConnection/DBConnectionDetail.vue"; |
|
3 | 12 |
import FileManagement from "../pages/data/FileManagement.vue"; |
4 | 13 |
import HostManagement from "../pages/data/HostManagement.vue"; |
5 | 14 |
import DataManagement from "../pages/data/DataPostManagement.vue"; |
... | ... | @@ -8,16 +17,10 @@ |
8 | 17 |
import DataEditView from "../pages/data/DataEditView.vue"; |
9 | 18 |
import TermManagement from "../pages/meta/TermManagement.vue"; |
10 | 19 |
import DataMetaManagement from "../pages/meta/DataMetaManagement.vue"; |
11 |
- |
|
12 | 20 |
import ScheduleManagement from "../pages/schedule/ScheduleManagement.vue"; |
13 | 21 |
import ScheduleLogManagement from "../pages/schedule/ScheduleLogManagement.vue"; |
14 |
- |
|
15 | 22 |
import Push from "../pages/push/Push.vue"; |
16 |
-import User from "../pages/integration/UserManagement.vue"; |
|
17 |
-import Department from "../pages/integration/DepartmentManagement.vue"; |
|
18 |
-import DBConnectionList from "../pages/dbConnection/DBConnectionList.vue"; |
|
19 | 23 |
import InsertDBConnection from "../pages/dbConnection/InsertDBConnection.vue"; |
20 |
-import DBConnectionDetail from "../pages/dbConnection/DBConnectionDetail.vue"; |
|
21 | 24 |
import CustomSelectList from "../pages/custom/CustomSelectList.vue"; |
22 | 25 |
import CustomSelectOne from "../pages/custom/CustomSelectOne.vue"; |
23 | 26 |
import CustomInsert from "../pages/custom/CustomInsert.vue"; |
... | ... | @@ -34,10 +37,8 @@ |
34 | 37 |
|
35 | 38 |
// 로그인 화면 |
36 | 39 |
import Login from "../pages/login/Login.vue"; |
37 |
- |
|
38 | 40 |
// 차트 |
39 | 41 |
import Chart from "../component/chart/ChartPage.vue"; |
40 |
- |
|
41 | 42 |
// 템플릿 |
42 | 43 |
import Searchbar from "../template/templateElement/Searchbar.vue"; |
43 | 44 |
import Table from "../template/templateElement/Table.vue"; |
... | ... | @@ -50,139 +51,43 @@ |
50 | 51 |
import Icon from "../template/templateElement/Icon.vue"; |
51 | 52 |
import Guide from "../template/guide/TemplateGuide.vue"; |
52 | 53 |
|
53 |
-// 테스트용 |
|
54 |
-import JobTest from "../pages/data/JobTest.vue"; |
|
55 |
-import store from "./AppStore"; |
|
56 |
-import axios from "axios"; |
|
57 | 54 |
|
58 | 55 |
const routes = [ |
59 |
- /* 메인화면 */ |
|
60 |
- // { path: "/", name: "Main", component: Main }, |
|
61 |
- { |
|
62 |
- path: "/fileManagement.page", |
|
63 |
- name: "FileManagement", |
|
64 |
- component: FileManagement, |
|
65 |
- }, |
|
66 |
- { |
|
67 |
- path: "/hostManagement.page", |
|
68 |
- name: "HostManagement", |
|
69 |
- component: HostManagement, |
|
70 |
- }, |
|
71 |
- { |
|
72 |
- path: "/dataManagement.page", |
|
73 |
- name: "DataManagement", |
|
74 |
- component: DataManagement, |
|
75 |
- }, |
|
76 |
- { |
|
77 |
- path: "/insertDataPost.page", |
|
78 |
- name: "InsertDataPost", |
|
79 |
- component: InsertDataPost, |
|
80 |
- }, |
|
81 |
- { |
|
82 |
- path: "/dataPostDetail.page", |
|
83 |
- name: "DataPostDetail", |
|
84 |
- component: DataPostDetail, |
|
85 |
- }, |
|
86 |
- { path: "/DataEditView.page", name: "DataEditView", component: DataEditView }, |
|
87 |
- { |
|
88 |
- path: "/termManagement.page", |
|
89 |
- name: "TermManagement", |
|
90 |
- component: TermManagement, |
|
91 |
- }, |
|
92 |
- { |
|
93 |
- path: "/dataMetaManagement.page", |
|
94 |
- name: "DataMetaManagement", |
|
95 |
- component: DataMetaManagement, |
|
96 |
- }, |
|
56 |
+ // 통합관리 |
|
57 |
+ { path: "/user.page", name: "User", component: UserManagement }, // 사용자관리 |
|
58 |
+ { path: "/adminManagement.page", name: "AdminManagement", component: AdminManagement }, // 관리자관리 |
|
59 |
+ { path: "/department.page", name: "Department", component: Department }, // 부서관리 |
|
60 |
+ { path: "/dbConnectionList.page", name: "DBConnectionList", component: DBConnectionList }, // 연계정보관리 |
|
97 | 61 |
|
98 |
- { path: "/jobTest.page", name: "JobTest", component: JobTest }, |
|
99 |
- { |
|
100 |
- path: "/scheduleManagement.page", |
|
101 |
- name: "ScheduleManagement", |
|
102 |
- component: ScheduleManagement, |
|
103 |
- }, |
|
104 |
- { |
|
105 |
- path: "/scheduleLogManagement.page", |
|
106 |
- name: "ScheduleLogManagement", |
|
107 |
- component: ScheduleLogManagement, |
|
108 |
- }, |
|
62 |
+ { path: "/fileManagement.page", name: "FileManagement", component: FileManagement }, |
|
63 |
+ { path: "/hostManagement.page", name: "HostManagement", component: HostManagement }, |
|
64 |
+ { path: "/dataManagement.page", name: "DataManagement", component: DataManagement }, |
|
65 |
+ { path: "/insertDataPost.page", name: "InsertDataPost", component: InsertDataPost }, |
|
66 |
+ { path: "/dataPostDetail.page", name: "DataPostDetail", component: DataPostDetail }, |
|
67 |
+ { path: "/DataEditView.page", name: "DataEditView", component: DataEditView }, |
|
68 |
+ { path: "/termManagement.page", name: "TermManagement", component: TermManagement }, |
|
69 |
+ { path: "/dataMetaManagement.page", name: "DataMetaManagement", component: DataMetaManagement }, |
|
70 |
+ { path: "/scheduleManagement.page", name: "ScheduleManagement", component: ScheduleManagement }, |
|
71 |
+ { path: "/scheduleLogManagement.page", name: "ScheduleLogManagement", component: ScheduleLogManagement }, |
|
109 | 72 |
{ path: "/push.page", name: "Push", component: Push }, |
110 |
- { path: "/user.page", name: "User", component: User }, |
|
111 |
- { path: "/department.page", name: "Department", component: Department }, |
|
112 |
- { |
|
113 |
- path: "/dbConnectionList.page", |
|
114 |
- name: "DBConnectionList", |
|
115 |
- component: DBConnectionList, |
|
116 |
- }, |
|
117 |
- { |
|
118 |
- path: "/insertDBConnection.page", |
|
119 |
- name: "InsertDBConnection", |
|
120 |
- component: InsertDBConnection, |
|
121 |
- }, |
|
122 |
- { |
|
123 |
- path: "/DBConnectionDetail.page", |
|
124 |
- name: "DBConnectionDetail", |
|
125 |
- component: DBConnectionDetail, |
|
126 |
- }, |
|
127 |
- { |
|
128 |
- path: "/customSelectList.page", |
|
129 |
- name: "CustomSelectList", |
|
130 |
- component: CustomSelectList, |
|
131 |
- }, |
|
132 |
- { |
|
133 |
- path: "/customSelectOne.page", |
|
134 |
- name: "CustomSelectOne", |
|
135 |
- component: CustomSelectOne, |
|
136 |
- }, |
|
73 |
+ { path: "/insertDBConnection.page", name: "InsertDBConnection", component: InsertDBConnection }, |
|
74 |
+ { path: "/DBConnectionDetail.page", name: "DBConnectionDetail", component: DBConnectionDetail }, |
|
75 |
+ { path: "/customSelectList.page", name: "CustomSelectList", component: CustomSelectList }, |
|
76 |
+ { path: "/customSelectOne.page", name: "CustomSelectOne", component: CustomSelectOne }, |
|
137 | 77 |
{ path: "/customInsert.page", name: "CustomInsert", component: CustomInsert }, |
138 |
- { |
|
139 |
- path: "/customInsertDev.page", |
|
140 |
- name: "CustomInsertDev", |
|
141 |
- component: CustomInsertDev, |
|
142 |
- }, |
|
143 |
- { |
|
144 |
- path: "/openApiList.page", |
|
145 |
- name: "OpenApiList", |
|
146 |
- component: OpenApiList, |
|
147 |
- }, |
|
148 |
- { |
|
149 |
- path: "/openApiInsert.page", |
|
150 |
- name: "OpenApiInsert", |
|
151 |
- component: OpenApiInsert, |
|
152 |
- }, |
|
153 |
- { |
|
154 |
- path: "/openApiListOne.page", |
|
155 |
- name: "OpenApiSelectListOne", |
|
156 |
- component: OpenApiSelectListOne, |
|
157 |
- }, |
|
158 |
- { |
|
159 |
- path: "/openApiKeyList.page", |
|
160 |
- name: "OpenApiKeyList", |
|
161 |
- component: OpenApiKeyList, |
|
162 |
- }, |
|
163 |
- { |
|
164 |
- path: "/gisInfoList.page", |
|
165 |
- name: "GisInfoList", |
|
166 |
- component: GisInfoList, |
|
167 |
- }, |
|
168 |
- { |
|
169 |
- path: "/gisInfoInsert.page", |
|
170 |
- name: "GisInfoInsert", |
|
171 |
- component: GisInfoInsert, |
|
172 |
- }, |
|
173 |
- { |
|
174 |
- path: "/gisInfoListOne.page", |
|
175 |
- name: "GisInfoSelectListOne", |
|
176 |
- component: GisInfoSelectListOne, |
|
177 |
- }, |
|
78 |
+ { path: "/customInsertDev.page", name: "CustomInsertDev", component: CustomInsertDev }, |
|
79 |
+ { path: "/openApiList.page", name: "OpenApiList", component: OpenApiList }, |
|
80 |
+ { path: "/openApiInsert.page", name: "OpenApiInsert", component: OpenApiInsert }, |
|
81 |
+ { path: "/openApiListOne.page", name: "OpenApiSelectListOne", component: OpenApiSelectListOne }, |
|
82 |
+ { path: "/openApiKeyList.page", name: "OpenApiKeyList", component: OpenApiKeyList }, |
|
83 |
+ { path: "/gisInfoList.page", name: "GisInfoList", component: GisInfoList }, |
|
84 |
+ { path: "/gisInfoInsert.page", name: "GisInfoInsert", component: GisInfoInsert }, |
|
85 |
+ { path: "/gisInfoListOne.page", name: "GisInfoSelectListOne", component: GisInfoSelectListOne }, |
|
178 | 86 |
{ path: "/myPage.page", name: "myPage", component: myPage }, |
179 | 87 |
{ path: "/myPagePwd.page", name: "myPagePwd", component: myPagePwd }, |
180 |
- |
|
181 | 88 |
{ path: "/login.page", name: "Login", component: Login }, |
182 |
- |
|
183 | 89 |
// 차트 |
184 | 90 |
{ path: "/chart.page", name: "Chart", component: Chart }, |
185 |
- |
|
186 | 91 |
// 템플릿 화면 |
187 | 92 |
{ path: "/searchbar.page", name: "Searchbar", component: Searchbar }, |
188 | 93 |
{ path: "/table.page", name: "Table", component: Table }, |
--- client/views/pages/bu_241206_AppRouter.js
... | ... | @@ -1,261 +0,0 @@ |
1 | -import { createWebHistory, createRouter } from "vue-router"; | |
2 | - | |
3 | -import Main from "../pages/main/Main.vue"; | |
4 | -import FileManagement from "../pages/data/FileManagement.vue"; | |
5 | -import HostManagement from "../pages/data/HostManagement.vue"; | |
6 | -import DataManagement from "../pages/data/DataPostManagement.vue"; | |
7 | -import InsertDataPost from "../pages/data/InsertDataPost.vue"; | |
8 | -import DataPostDetail from "../pages/data/DataPostDetail.vue"; | |
9 | -import DataEditView from "../pages/data/DataEditView.vue"; | |
10 | -import TermManagement from "../pages/meta/TermManagement.vue"; | |
11 | -import DataMetaManagement from "../pages/meta/DataMetaManagement.vue"; | |
12 | - | |
13 | -import ScheduleManagement from "../pages/schedule/ScheduleManagement.vue"; | |
14 | -import ScheduleLogManagement from "../pages/schedule/ScheduleLogManagement.vue"; | |
15 | - | |
16 | -import Push from "../pages/push/Push.vue"; | |
17 | -import User from "../pages/integration/UserManagement.vue"; | |
18 | -import Department from "../pages/integration/DepartmentManagement.vue"; | |
19 | -import DBConnectionList from "../pages/dbConnection/DBConnectionList.vue"; | |
20 | -import InsertDBConnection from "../pages/dbConnection/InsertDBConnection.vue"; | |
21 | -import DBConnectionDetail from "../pages/dbConnection/DBConnectionDetail.vue"; | |
22 | -import CustomSelectList from "../pages/custom/CustomSelectList.vue"; | |
23 | -import CustomSelectOne from "../pages/custom/CustomSelectOne.vue"; | |
24 | -import CustomInsert from "../pages/custom/CustomInsert.vue"; | |
25 | -import CustomInsertDev from "../pages/custom/CustomInsertDev.vue"; | |
26 | -import myPage from "../pages/user/myPage.vue"; | |
27 | -import myPagePwd from "../pages/user/myPagePwd.vue"; | |
28 | -import OpenApiList from "../pages/openapi/OpenApiList.vue"; | |
29 | -import OpenApiInsert from "../pages/openapi/OpenApiInsert.vue"; | |
30 | -import OpenApiSelectListOne from "../pages/openapi/OpenApiSelectListOne.vue"; | |
31 | -import GisInfoList from "../pages/gisinfo/GisInfoList.vue"; | |
32 | -import GisInfoInsert from "../pages/gisinfo/GisInfoInsert.vue"; | |
33 | -import GisInfoSelectListOne from "../pages/gisinfo/GisInfoSelectListOne.vue"; | |
34 | -import OpenApiKeyList from "../pages/openapi/OpenApiKeyList.vue"; | |
35 | - | |
36 | -// 로그인 화면 | |
37 | -import Login from "../pages/login/Login.vue"; | |
38 | -import FindId from "../pages/register/FindId.vue"; | |
39 | -import FindPwd from "../pages/register/FindPwd.vue"; | |
40 | -import Register from "../pages/register/Register.vue"; | |
41 | - | |
42 | -// 차트 | |
43 | -import Chart from "../component/chart/ChartPage.vue"; | |
44 | - | |
45 | -// 템플릿 | |
46 | -import Searchbar from "../template/templateElement/Searchbar.vue"; | |
47 | -import Table from "../template/templateElement/Table.vue"; | |
48 | -import BtnPosition from "../template/templateElement/BtnPosition.vue"; | |
49 | -import Horizontal from "../template/layoutTemplate/Horizontal.vue"; | |
50 | -import Vertical from "../template/layoutTemplate/Vertical.vue"; | |
51 | -import FormModal from "../template/templateElement/FormModal.vue"; | |
52 | -import ListModal from "../template/templateElement/ListModal.vue"; | |
53 | -import AlertModal from "../template/templateElement/AlertModal.vue"; | |
54 | -import Icon from "../template/templateElement/Icon.vue"; | |
55 | -import Guide from "../template/guide/TemplateGuide.vue"; | |
56 | - | |
57 | -// 테스트용 | |
58 | -import JobTest from "../pages/data/JobTest.vue"; | |
59 | -import store from "./AppStore"; | |
60 | -import axios from "axios"; | |
61 | - | |
62 | -const routes = [ | |
63 | - /* 메인화면 */ | |
64 | - // { path: "/", name: "Main", component: Main }, | |
65 | - { | |
66 | - path: "/fileManagement.page", | |
67 | - name: "FileManagement", | |
68 | - component: FileManagement, | |
69 | - }, | |
70 | - { | |
71 | - path: "/hostManagement.page", | |
72 | - name: "HostManagement", | |
73 | - component: HostManagement, | |
74 | - }, | |
75 | - { | |
76 | - path: "/dataManagement.page", | |
77 | - name: "DataManagement", | |
78 | - component: DataManagement, | |
79 | - }, | |
80 | - { | |
81 | - path: "/insertDataPost.page", | |
82 | - name: "InsertDataPost", | |
83 | - component: InsertDataPost, | |
84 | - }, | |
85 | - { | |
86 | - path: "/dataPostDetail.page", | |
87 | - name: "DataPostDetail", | |
88 | - component: DataPostDetail, | |
89 | - }, | |
90 | - { path: "/DataEditView.page", name: "DataEditView", component: DataEditView }, | |
91 | - { | |
92 | - path: "/termManagement.page", | |
93 | - name: "TermManagement", | |
94 | - component: TermManagement, | |
95 | - }, | |
96 | - { | |
97 | - path: "/dataMetaManagement.page", | |
98 | - name: "DataMetaManagement", | |
99 | - component: DataMetaManagement, | |
100 | - }, | |
101 | - | |
102 | - { path: "/jobTest.page", name: "JobTest", component: JobTest }, | |
103 | - { | |
104 | - path: "/scheduleManagement.page", | |
105 | - name: "ScheduleManagement", | |
106 | - component: ScheduleManagement, | |
107 | - }, | |
108 | - { | |
109 | - path: "/scheduleLogManagement.page", | |
110 | - name: "ScheduleLogManagement", | |
111 | - component: ScheduleLogManagement, | |
112 | - }, | |
113 | - { path: "/push.page", name: "Push", component: Push }, | |
114 | - { path: "/user.page", name: "User", component: User }, | |
115 | - { path: "/department.page", name: "Department", component: Department }, | |
116 | - { | |
117 | - path: "/dbConnectionList.page", | |
118 | - name: "DBConnectionList", | |
119 | - component: DBConnectionList, | |
120 | - }, | |
121 | - { | |
122 | - path: "/insertDBConnection.page", | |
123 | - name: "InsertDBConnection", | |
124 | - component: InsertDBConnection, | |
125 | - }, | |
126 | - { | |
127 | - path: "/DBConnectionDetail.page", | |
128 | - name: "DBConnectionDetail", | |
129 | - component: DBConnectionDetail, | |
130 | - }, | |
131 | - { | |
132 | - path: "/customSelectList.page", | |
133 | - name: "CustomSelectList", | |
134 | - component: CustomSelectList, | |
135 | - }, | |
136 | - { | |
137 | - path: "/customSelectOne.page", | |
138 | - name: "CustomSelectOne", | |
139 | - component: CustomSelectOne, | |
140 | - }, | |
141 | - { path: "/customInsert.page", name: "CustomInsert", component: CustomInsert }, | |
142 | - { | |
143 | - path: "/customInsertDev.page", | |
144 | - name: "CustomInsertDev", | |
145 | - component: CustomInsertDev, | |
146 | - }, | |
147 | - { | |
148 | - path: "/openApiList.page", | |
149 | - name: "OpenApiList", | |
150 | - component: OpenApiList, | |
151 | - }, | |
152 | - { | |
153 | - path: "/openApiInsert.page", | |
154 | - name: "OpenApiInsert", | |
155 | - component: OpenApiInsert, | |
156 | - }, | |
157 | - { | |
158 | - path: "/openApiListOne.page", | |
159 | - name: "OpenApiSelectListOne", | |
160 | - component: OpenApiSelectListOne, | |
161 | - }, | |
162 | - { | |
163 | - path: "/openApiKeyList.page", | |
164 | - name: "OpenApiKeyList", | |
165 | - component: OpenApiKeyList, | |
166 | - }, | |
167 | - { | |
168 | - path: "/gisInfoList.page", | |
169 | - name: "GisInfoList", | |
170 | - component: GisInfoList, | |
171 | - }, | |
172 | - { | |
173 | - path: "/gisInfoInsert.page", | |
174 | - name: "GisInfoInsert", | |
175 | - component: GisInfoInsert, | |
176 | - }, | |
177 | - { | |
178 | - path: "/gisInfoListOne.page", | |
179 | - name: "GisInfoSelectListOne", | |
180 | - component: GisInfoSelectListOne, | |
181 | - }, | |
182 | - { path: "/myPage.page", name: "myPage", component: myPage }, | |
183 | - { path: "/myPagePwd.page", name: "myPagePwd", component: myPagePwd }, | |
184 | - | |
185 | - { path: "/login.page", name: "Login", component: Login }, | |
186 | - { path: "/findId.page", name: "FindId", component: FindId }, | |
187 | - { path: "/findPwd.page", name: "FindPwd", component: FindPwd }, | |
188 | - { path: "/register.page", name: "Register", component: Register }, | |
189 | - | |
190 | - // 차트 | |
191 | - { path: "/chart.page", name: "Chart", component: Chart }, | |
192 | - | |
193 | - // 템플릿 화면 | |
194 | - { path: "/searchbar.page", name: "Searchbar", component: Searchbar }, | |
195 | - { path: "/table.page", name: "Table", component: Table }, | |
196 | - { path: "/btnPosition.page", name: "BtnPosition", component: BtnPosition }, | |
197 | - { path: "/horizontal.page", name: "Horizontal", component: Horizontal }, | |
198 | - { path: "/vertical.page", name: "Vertical", component: Vertical }, | |
199 | - { path: "/formModal.page", name: "FormModal", component: FormModal }, | |
200 | - { path: "/listModal.page", name: "ListModal", component: ListModal }, | |
201 | - { path: "/alertModal.page", name: "AlertModal", component: AlertModal }, | |
202 | - { path: "/icon.page", name: "Icon", component: Icon }, | |
203 | - { path: "/guide.page", name: "Guide", component: Guide }, | |
204 | -]; | |
205 | - | |
206 | -const AppRouter = createRouter({ | |
207 | - history: createWebHistory(), | |
208 | - routes, | |
209 | -}); | |
210 | - | |
211 | -AppRouter.beforeEach(async (to, from, next) => { | |
212 | - const userId = store.state.loginUser; | |
213 | - // userId 없음 | |
214 | - if (userId == null) { | |
215 | - if (to.path == "/login.page" || to.path == "/findId.page" || to.path == "/findPwd.page" || to.path == "/register.page") { | |
216 | - next(); | |
217 | - } else { | |
218 | - axios({ | |
219 | - url: "/getLoginInfo.json", | |
220 | - method: "post", | |
221 | - headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
222 | - }) | |
223 | - .then(function (response) { | |
224 | - if (response.data.checkMessage.status > 0) { | |
225 | - store.commit("setLoginUser", response.data.resultData.LoginUserInfo); | |
226 | - next(); | |
227 | - } else { | |
228 | - next("/login.page"); | |
229 | - } | |
230 | - }) | |
231 | - .catch(function (error) { | |
232 | - this.$showAlert("에러 발생", "에러가 발생했습니다. 관리자에게 문의해 주세요."); | |
233 | - }); | |
234 | - } | |
235 | - } | |
236 | - // userId 있음 | |
237 | - else { | |
238 | - if (to.path == "/login.page") { | |
239 | - next("/fileManagement.page"); | |
240 | - } else if (to.path == "/department.page" || to.path == "/user.page" || to.path == "/hostManagement.page" || to.path == "/dbConnectionList.page") { | |
241 | - let authList = store.state.loginUser.user_auth; | |
242 | - let check = false; | |
243 | - for (let auth of authList) { | |
244 | - if (auth == "ROLE_ADMIN") { | |
245 | - check = true; | |
246 | - break; | |
247 | - } | |
248 | - } | |
249 | - if (check) { | |
250 | - next(); | |
251 | - } else { | |
252 | - alert('접근 권한이 없습니다.'); | |
253 | - next("/fileManagement.page"); | |
254 | - } | |
255 | - } else { | |
256 | - next(); | |
257 | - } | |
258 | - } | |
259 | -}); | |
260 | - | |
261 | -export default AppRouter;(파일 끝에 줄바꿈 문자 없음) |
--- client/views/pages/data/JobTest.vue
... | ... | @@ -1,82 +0,0 @@ |
1 | -<template> | |
2 | - <div class="container"> | |
3 | - <div class="content content-box flex100"> | |
4 | - <JobContainer :jobGroup="jobGroup" /> | |
5 | - <div class="flex justify-end mt10"> | |
6 | - <button class="darkg-btn small-btn" @click="saveJobGroup()"> | |
7 | - 데이터 등록 | |
8 | - </button> | |
9 | - </div> | |
10 | - </div> | |
11 | - </div> | |
12 | -</template> | |
13 | - | |
14 | -<script> | |
15 | -import JobContainer from "../../component/connection/jobContainer.vue"; | |
16 | -import axios from "axios"; | |
17 | - | |
18 | -export default { | |
19 | - openPopup: { | |
20 | - type: Boolean, | |
21 | - default: false, | |
22 | - }, | |
23 | - data() { | |
24 | - return { | |
25 | - jobGroup: {}, | |
26 | - }; | |
27 | - }, | |
28 | - methods: { | |
29 | - saveJobGroup: function () { | |
30 | - let vm = this; | |
31 | - axios({ | |
32 | - url: "/job/insertJobGroup.json", | |
33 | - method: "post", | |
34 | - headers: { | |
35 | - "Content-Type": "application/json; charset=UTF-8", | |
36 | - }, | |
37 | - data: vm.jobGroup, | |
38 | - }) | |
39 | - .then(function (response) { | |
40 | - this.$showAlert( | |
41 | - "에러 발생", | |
42 | - "에러가 발생했습니다. 관리자에게 문의해 주세요." | |
43 | - ); | |
44 | - }) | |
45 | - .catch(function (error) { | |
46 | - this.$showAlert( | |
47 | - "에러 발생", | |
48 | - "에러가 발생했습니다. 관리자에게 문의해 주세요." | |
49 | - ); | |
50 | - }); | |
51 | - }, | |
52 | - | |
53 | - selectJobGroup: function () { | |
54 | - let vm = this; | |
55 | - axios({ | |
56 | - url: "/job/selectJobGroup.json", | |
57 | - method: "post", | |
58 | - headers: { | |
59 | - "Content-Type": "application/json; charset=UTF-8", | |
60 | - }, | |
61 | - data: JSON.stringify({ group_id: "JOBGROUP_2024020517352987547982" }), | |
62 | - }) | |
63 | - .then(function (response) { | |
64 | - vm.jobGroup = response.data.resultData.jobGroup; | |
65 | - }) | |
66 | - .catch(function (error) { | |
67 | - this.$showAlert( | |
68 | - "에러 발생", | |
69 | - "에러가 발생했습니다. 관리자에게 문의해 주세요." | |
70 | - ); | |
71 | - }); | |
72 | - }, | |
73 | - }, | |
74 | - components: { | |
75 | - JobContainer: JobContainer, | |
76 | - }, | |
77 | - mounted() { | |
78 | - this.jobGroup = this.$getDefaultJobGroup().jobGroup; | |
79 | - this.selectJobGroup(); | |
80 | - }, | |
81 | -}; | |
82 | -</script>(파일 끝에 줄바꿈 문자 없음) |
+++ client/views/pages/integrated/AdminManagement.vue
... | ... | @@ -0,0 +1,730 @@ |
1 | +<template> | |
2 | + <div class="container"> | |
3 | + <div class="page-titleZone flex justify-between align-center"> | |
4 | + <p class="main-title flex80">관리자 관리</p> | |
5 | + <PageNavigation /> | |
6 | + </div> | |
7 | + <div class="content-wrap"> | |
8 | + <div class="content content-box flex100"> | |
9 | + <div class="column-list"> | |
10 | + <div class="content-titleZone flex justify-between align-center"> | |
11 | + <p class="box-title">관리자 목록</p> | |
12 | + <div class="search-bar"> | |
13 | + <div class="flex justify-end align-center"> | |
14 | + <select class="square-select" v-model="search_data.key"> | |
15 | + <option :value="null">선택</option> | |
16 | + <option value="ui.user_id">아이디</option> | |
17 | + <option value="ui.user_nm">이름</option> | |
18 | + </select> | |
19 | + <div class="search-square"> | |
20 | + <div class="flex justify-end align-center no-gutter"> | |
21 | + <input type="text" class="square-input flex90" placeholder="검색어를 입력해 주세요." v-model="search_data.value" @keyup.enter="fnSelectUserList" /> | |
22 | + <button class="square-button blue-btn flex10" @click="fnSelectUserList"> | |
23 | + <svg-icon type="mdi" :path="searchPath" class="square-icon"></svg-icon> | |
24 | + </button> | |
25 | + </div> | |
26 | + </div> | |
27 | + </div> | |
28 | + </div> | |
29 | + </div> | |
30 | + <div class="flex justify-between align-center"> | |
31 | + <div class="count-zone"> | |
32 | + <p>총 <span>{{ userList.length }}</span>건 중 <span>{{ userSelectList.length }}</span>건 선택</p> | |
33 | + </div> | |
34 | + <div class="cunt-selectZone"> | |
35 | + <select v-model="search.perPage" @change="fnSelectUserList"> | |
36 | + <option value="10">10개 보기</option> | |
37 | + <option value="20">20개 보기</option> | |
38 | + </select> | |
39 | + </div> | |
40 | + </div> | |
41 | + <div class="table-zone"> | |
42 | + <table class="list-table"> | |
43 | + <colgroup> | |
44 | + <col style="width: 5%" /> | |
45 | + <col style="width: 5%" /> | |
46 | + <col style="width: 21%" /> | |
47 | + <col style="width: 21%" /> | |
48 | + <col style="width: 21%" /> | |
49 | + <col style="width: 21%" /> | |
50 | + <col style="width: 6%" /> | |
51 | + </colgroup> | |
52 | + <thead> | |
53 | + <tr> | |
54 | + <th> | |
55 | + <input type="checkbox" v-model="isChkAll" @change="fnChkAll()" /> | |
56 | + </th> | |
57 | + <th>번호</th> | |
58 | + <th>아이디</th> | |
59 | + <th>이름</th> | |
60 | + <th>이메일</th> | |
61 | + <th>등록날짜</th> | |
62 | + <th>잠김여부</th> | |
63 | + </tr> | |
64 | + </thead> | |
65 | + <tbody> | |
66 | + <template v-if="userList.length > 0"> | |
67 | + <tr v-for="(item, idx) in userList" :key="idx" @click="fnSelectUser(item.userId)"> | |
68 | + <td> | |
69 | + <input type="checkbox" :value="item" v-model="userSelectList" @click.stop="" @change="fnChangeChk" /> | |
70 | + </td> | |
71 | + <td>{{ search.totalRows - idx - (search.currentPage - 1) * search.perPage }}</td> | |
72 | + <td>{{ item.userId }}</td> | |
73 | + <td>{{ item.userNm }}</td> | |
74 | + <td>{{ item.userEmail }}</td> | |
75 | + <td>{{ $filters.dateTime(item.creatDt) }}</td> | |
76 | + <td>{{ item.lockAt ? "잠금" : "-" }}</td> | |
77 | + </tr> | |
78 | + </template> | |
79 | + <tr v-else> | |
80 | + <td colspan="8">등록된 데이터가 없습니다.</td> | |
81 | + </tr> | |
82 | + </tbody> | |
83 | + </table> | |
84 | + </div> | |
85 | + <div class="flex justify-end"> | |
86 | + <button class="red-border-btn small-btn" @click="fnDeleteUser">선택 삭제</button> | |
87 | + </div> | |
88 | + <PaginationButton v-model:currentPage="search.currentPage" :perPage="search.perPage" :totalCount="search.totalRows" :maxRange="5" :click="fetchMemberList" /> | |
89 | + </div> | |
90 | + <div class="data-set"> | |
91 | + <div class="form-box"> | |
92 | + <div class="content-titleZone"> | |
93 | + <p class="box-title" v-if="editMode == 'create'">관리자 등록</p> | |
94 | + <p class="box-title" v-else>관리자 수정</p> | |
95 | + </div> | |
96 | + <div class="table-zone"> | |
97 | + <table class="form-table2"> | |
98 | + <colgroup> | |
99 | + <col style="width: 10%" /> | |
100 | + <col style="width: 40%" /> | |
101 | + <col style="width: 10%" /> | |
102 | + <col style="width: 40%" /> | |
103 | + </colgroup> | |
104 | + <tbody> | |
105 | + <tr> | |
106 | + <th>아이디</th> | |
107 | + <td style="display: flex"> | |
108 | + <input type="text" class="full-input" v-model="currentUser.userId" :disabled="editMode == 'update'" /> | |
109 | + <button class="small-btn blue-border-btn" style="flex-grow: 1" v-if="editMode == 'create'" @click="fnDuplicateChk('id')">중복확인</button> | |
110 | + </td> | |
111 | + <th>이름</th> | |
112 | + <td> | |
113 | + <input type="text" class="full-input" v-model="currentUser.userNm" /> | |
114 | + </td> | |
115 | + </tr> | |
116 | + <tr v-if="editMode == 'create'"> | |
117 | + <th>비밀번호</th> | |
118 | + <td> | |
119 | + <input type="password" class="full-input" style="width: 100%" v-model="currentUser.userPassword" /> | |
120 | + </td> | |
121 | + <th>비밀번호 확인</th> | |
122 | + <td> | |
123 | + <input type="password" class="full-input" style="width: 100%" v-model="userPasswordConfirm" /> | |
124 | + </td> | |
125 | + </tr> | |
126 | + <tr> | |
127 | + <th>이메일</th> | |
128 | + <td style="display: flex"> | |
129 | + <input type="text" class="full-input" v-model="currentUser.userEmail" /> | |
130 | + <button class="small-btn blue-border-btn" style="flex-grow: 1" @click="fnDuplicateChk('email')">중복확인</button> | |
131 | + </td> | |
132 | + <template v-if="editMode == 'update'"> | |
133 | + <th>잠김여부</th> | |
134 | + <td style="display: flex"> | |
135 | + <input type="text" class="full-input" :value="currentUser.lockAt ? '잠금 (사용불가)' : '미잠금 (사용가능)'" readonly> | |
136 | + <button class="blue-border-btn small-btn" style="flex-grow: 1" v-if="currentUser.lockAt" @click="fnUpdateUserLockAt">잠금해제</button> | |
137 | + </td> | |
138 | + </template> | |
139 | + <template v-else> | |
140 | + <th></th> | |
141 | + <td></td> | |
142 | + </template> | |
143 | + </tr> | |
144 | + </tbody> | |
145 | + </table> | |
146 | + </div> | |
147 | + <div class="flex justify-end"> | |
148 | + <button class="blue-border-btn small-btn" v-if="editMode == 'update'" @click="fnOpenModal">비밀번호 변경</button> | |
149 | + <button class="blue-btn small-btn" v-if="editMode == 'create'" @click="fnInsertUser">등록</button> | |
150 | + <button class="blue-btn small-btn" v-else @click="fnUpdateUser">수정</button> | |
151 | + <button class="blue-border-btn small-btn" @click="fnCancel"><span v-if="editMode == 'create'">초기화</span><span v-else>취소</span></button> | |
152 | + </div> | |
153 | + </div> | |
154 | + </div> | |
155 | + </div> | |
156 | + </div> | |
157 | + </div> | |
158 | + <!-- 비밀번호 변경 모달 --> | |
159 | + <div v-show="modalOpen" class="modal-wrapper"> | |
160 | + <div class="modal-container small-modal"> | |
161 | + <div class="modal-title"> | |
162 | + <div class="flex justify-between align-center"> | |
163 | + <h2>비밀번호 변경</h2> | |
164 | + <button class="close-btn" @click="fnCloseModal">X</button> | |
165 | + </div> | |
166 | + </div> | |
167 | + <div class="modal-content-monthly"> | |
168 | + <div class="table-zone"> | |
169 | + <table class="form-table"> | |
170 | + <colgroup> | |
171 | + <col style="width: 40%" /> | |
172 | + <col style="width: 60%" /> | |
173 | + </colgroup> | |
174 | + <tbody> | |
175 | + <tr> | |
176 | + <th>새 비밀번호</th> | |
177 | + <td> | |
178 | + <input type="password" class="full-input" v-model="userPassword" /> | |
179 | + </td> | |
180 | + </tr> | |
181 | + <tr> | |
182 | + <th>새 비밀번호 확인</th> | |
183 | + <td> | |
184 | + <input type="password" class="full-input" v-model="userPasswordConfirm" /> | |
185 | + </td> | |
186 | + </tr> | |
187 | + </tbody> | |
188 | + </table> | |
189 | + <div class="modal-end flex justify-between" style="flex-wrap: nowrap;"> | |
190 | + <button class="blue-btn large-btn" @click="fnUpdateUserPassword">수정</button> | |
191 | + <button class="blue-border-btn large-btn" @click="fnCloseModal">취소</button> | |
192 | + </div> | |
193 | + </div> | |
194 | + </div> | |
195 | + </div> | |
196 | + </div> | |
197 | +</template> | |
198 | +<script> | |
199 | +import axios from "axios"; | |
200 | +// icon용 svg import | |
201 | +import SvgIcon from "@jamescoyle/vue-icon"; | |
202 | +import { mdiClose, mdiMagnify } from "@mdi/js"; | |
203 | +// 컴포넌트 import | |
204 | +import PageNavigation from "../../component/PageNavigation.vue"; | |
205 | +import PaginationButton from "../../component/PaginationButton.vue"; | |
206 | + | |
207 | +export default { | |
208 | + components: { SvgIcon, PageNavigation, PaginationButton }, | |
209 | + | |
210 | + data() { | |
211 | + return { | |
212 | + // icon용 svg path | |
213 | + closePath: mdiClose, | |
214 | + searchPath: mdiMagnify, | |
215 | + | |
216 | + // 검색 | |
217 | + search: this.$getDefaultSerchVO(), | |
218 | + search_data: this.$getDefaultSerchItem(null, "string"), | |
219 | + | |
220 | + // default | |
221 | + editMode: 'create', | |
222 | + | |
223 | + memberVO: {}, | |
224 | + originUser: {}, | |
225 | + currentUser: {}, | |
226 | + | |
227 | + userPassword: null, | |
228 | + userPasswordConfirm: null, | |
229 | + | |
230 | + isChkAll: false, | |
231 | + userList: [], | |
232 | + userSelectList: [], | |
233 | + | |
234 | + deptList: [], | |
235 | + | |
236 | + // 비밀번호 변경 | |
237 | + modalOpen: false, | |
238 | + | |
239 | + // 중복검사 | |
240 | + isIdChk: false, | |
241 | + isEmailChk: false, | |
242 | + }; | |
243 | + }, | |
244 | + | |
245 | + mounted() { | |
246 | + this.fnSelectUser(); // 관리자 개별 조회 | |
247 | + this.fnSelectUserList(); // 관리자 목록 조회 | |
248 | + this.fnSelectDeptList(); // 부서 목록 조회 | |
249 | + }, | |
250 | + | |
251 | + watch: { | |
252 | + //아이디 값 변경 시 중복 검사 false로 변경 | |
253 | + "currentUser.userId"() { | |
254 | + this.isIdChk = false; | |
255 | + }, | |
256 | + //이메일 값 변경 시 중복 검사 false로 변경 | |
257 | + "currentUser.userEmail"() { | |
258 | + this.isEmailChk = false; | |
259 | + }, | |
260 | + }, | |
261 | + | |
262 | + methods: { | |
263 | + // 관리자 목록 조회 | |
264 | + fnSelectUserList() { | |
265 | + const vm = this; | |
266 | + // 데이터 세팅 | |
267 | + let data = vm.search; | |
268 | + data.searchObjectList = []; // 초기화 | |
269 | + data.searchObjectList.push(vm.search_data); | |
270 | + // 실행 | |
271 | + axios({ | |
272 | + url: "/member/list/ROLE_ADMIN", | |
273 | + method: "post", | |
274 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
275 | + data: data, | |
276 | + }) | |
277 | + .then(response => { | |
278 | + if (response.data != null) { | |
279 | + vm.userList = response.data.resultData.members; | |
280 | + vm.search = response.data.resultData.searchVO; | |
281 | + } else { | |
282 | + this.$showAlert("관리자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요."); | |
283 | + } | |
284 | + }) | |
285 | + .catch(error => { | |
286 | + vm.$showAlert("관리자 관리", "목록 불러오기 오류, 관리자에게 문의바랍니다."); | |
287 | + }); | |
288 | + }, | |
289 | + // 관리자 목록 전체 선택 | |
290 | + fnChkAll() { | |
291 | + if (this.isChkAll) { | |
292 | + this.userSelectList = this.userList; | |
293 | + } else { | |
294 | + this.userSelectList = []; | |
295 | + } | |
296 | + }, | |
297 | + // 관리자 목록 개별 선택 | |
298 | + fnChangeChk() { | |
299 | + if (this.userSelectList.length == this.userList.length) { | |
300 | + this.isChkAll = true; | |
301 | + } else { | |
302 | + this.isChkAll = false; | |
303 | + } | |
304 | + }, | |
305 | + // 관리자 선택 삭제 | |
306 | + async fnDeleteUser() { | |
307 | + const vm = this; | |
308 | + // 선택 목록 확인 | |
309 | + if (vm.userSelectList.length === 0) { | |
310 | + vm.$showAlert("관리자 관리", "선택한 관리자가 없습니다."); | |
311 | + return; | |
312 | + } | |
313 | + // 삭제 확인 | |
314 | + if (!(await vm.$showConfirm("관리자 관리", "선택한 관리자를 삭제하시겠습니까?"))) { | |
315 | + return; | |
316 | + } | |
317 | + | |
318 | + // 실행 | |
319 | + axios({ | |
320 | + url: "/member", | |
321 | + method: "delete", | |
322 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
323 | + data: vm.userSelectList, | |
324 | + }) | |
325 | + .then(response => { | |
326 | + if (response.data.checkMessage.status === 200) { | |
327 | + vm.$showAlert("관리자 관리", "선택한 관리자가 삭제되었습니다."); | |
328 | + | |
329 | + // 삭제 후 작업 | |
330 | + vm.isChkAll = false; // 체크 박스 리셋 | |
331 | + vm.userSelectList = []; // 관리자 선택 목록 초기화 | |
332 | + vm.fnSelectUserList(); // 전체 재조회 | |
333 | + } else { | |
334 | + vm.$showAlert("관리자 관리", response.data.checkMessage.message); | |
335 | + } | |
336 | + }) | |
337 | + .catch(error => { | |
338 | + vm.$showAlert("관리자 관리", "처리 중 오류가 발생했습니다. 관리자에게 문의바랍니다."); | |
339 | + }); | |
340 | + }, | |
341 | + | |
342 | + // 부서 목록 조회 | |
343 | + fnSelectDeptList() { | |
344 | + const vm = this; | |
345 | + // 데이터 세팅팅 | |
346 | + let search = Object.assign({}, this.$getDefaultSerchVO()); | |
347 | + search.currentPage = 0; | |
348 | + search.perPage = 0; | |
349 | + // 실행 | |
350 | + axios({ | |
351 | + url: "/department/departments", | |
352 | + method: "post", | |
353 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
354 | + data: search, | |
355 | + }) | |
356 | + .then(response => { | |
357 | + if (response.data != null) { | |
358 | + vm.deptList = response.data.resultData.selectDeptList; | |
359 | + } else { | |
360 | + this.$showAlert("관리자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요."); | |
361 | + } | |
362 | + }) | |
363 | + .catch(error => { | |
364 | + vm.$showAlert("관리자 관리", "목록 불러오기 오류, 관리자에게 문의바랍니다."); | |
365 | + }); | |
366 | + }, | |
367 | + | |
368 | + // 관리자 등록 | |
369 | + fnInsertUser() { | |
370 | + const vm = this; | |
371 | + // 유효성 검사 | |
372 | + if (!vm.insertValidation()) { | |
373 | + return; | |
374 | + } | |
375 | + // 데이터 세팅 | |
376 | + vm.currentUser.author = 'ROLE_ADMIN' | |
377 | + // 실행 | |
378 | + axios({ | |
379 | + url: "/member", | |
380 | + method: "post", | |
381 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
382 | + data: vm.currentUser, | |
383 | + }) | |
384 | + .then(response => { | |
385 | + if (response.data.checkMessage.status === 200) { | |
386 | + vm.$showAlert("관리자 관리", "관리자 등록이 완료되었습니다."); | |
387 | + vm.currentUser = Object.assign({}, vm.memberVO); // 초기화 | |
388 | + vm.fnSelectUserList(); | |
389 | + } else { | |
390 | + vm.$showAlert("관리자 관리", response.data.checkMessage.message); | |
391 | + } | |
392 | + }) | |
393 | + .catch(error => { | |
394 | + vm.$showAlert("관리자 관리", "관리자 등록에 실패했습니다. 다시 시도해주세요."); | |
395 | + }); | |
396 | + }, | |
397 | + | |
398 | + // 관리자 개별 조회 | |
399 | + fnSelectUser(userId) { | |
400 | + const vm = this; | |
401 | + // 데이터 세팅 | |
402 | + let url = null; | |
403 | + if (vm.$isEmpty(userId)) { | |
404 | + url = "/member/selectUser"; | |
405 | + } else { | |
406 | + url = "/member/selectUser/" + userId; | |
407 | + } | |
408 | + // 실행 | |
409 | + axios({ | |
410 | + url: url, | |
411 | + method: "post", | |
412 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
413 | + }) | |
414 | + .then(response => { | |
415 | + if (vm.$isEmpty(userId)) { | |
416 | + vm.memberVO = response.data; | |
417 | + } else { | |
418 | + vm.editMode = 'update'; | |
419 | + vm.originUser = response.data; | |
420 | + vm.currentUser = Object.assign({}, response.data); | |
421 | + } | |
422 | + }) | |
423 | + .catch(error => { | |
424 | + vm.$showAlert("관리자 관리", "불러오기 오류, 관리자에게 문의바랍니다."); | |
425 | + }); | |
426 | + }, | |
427 | + | |
428 | + // 관리자 수정 | |
429 | + fnUpdateUser() { | |
430 | + const vm = this; | |
431 | + // 유효성 검사 | |
432 | + if (!vm.updateValidation()) { | |
433 | + return; | |
434 | + } | |
435 | + // 실행 | |
436 | + axios({ | |
437 | + url: "/member", | |
438 | + method: "put", | |
439 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
440 | + data: vm.currentUser | |
441 | + }) | |
442 | + .then(response => { | |
443 | + if (response.data.checkMessage.status === 200) { | |
444 | + vm.$showAlert("관리자 관리", "관리자 정보가 수정되었습니다."); | |
445 | + vm.originUser = Object.assign({}, vm.memberVO); // 초기화 | |
446 | + vm.currentUser = Object.assign({}, vm.memberVO); // 초기화 | |
447 | + vm.editMode = 'create'; | |
448 | + vm.fnSelectUserList(); | |
449 | + } else { | |
450 | + vm.$showAlert("관리자 관리", response.data.checkMessage.message); | |
451 | + } | |
452 | + }) | |
453 | + .catch(error => { | |
454 | + vm.$showAlert("관리자 관리", "수정 오류, 관리자에게 문의해주세요."); | |
455 | + }); | |
456 | + }, | |
457 | + | |
458 | + // 중복확인 버튼 동작 | |
459 | + fnDuplicateChk(type) { | |
460 | + if (type == 'id') { | |
461 | + this.idDuplicateChk(); | |
462 | + } else if (type == 'email') { | |
463 | + this.emailDuplicateChk(); | |
464 | + } | |
465 | + }, | |
466 | + // 아이디 중복 검사 | |
467 | + idDuplicateChk() { | |
468 | + const vm = this; | |
469 | + // 유효성 검사 | |
470 | + if (!vm.$idCheck(vm.currentUser.userId)) { | |
471 | + vm.$showAlert("관리자 관리", "아이디 형식이 올바르지 않습니다. (5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용가능)"); | |
472 | + return false; | |
473 | + } | |
474 | + // 실행 | |
475 | + axios({ | |
476 | + url: "/member/" + vm.currentUser.userId, | |
477 | + method: "get", | |
478 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
479 | + }) | |
480 | + .then(response => { | |
481 | + if (response.data.resultData.checkDuplicateUserId) { | |
482 | + vm.isIdChk = false; | |
483 | + vm.$showAlert("관리자 관리", "사용중인 아이디입니다."); | |
484 | + } else { | |
485 | + vm.isIdChk = true; | |
486 | + vm.$showAlert("관리자 관리", "사용할 수 있는 아이디입니다."); | |
487 | + } | |
488 | + }) | |
489 | + .catch(error => { | |
490 | + this.$showAlert("관리자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요."); | |
491 | + }); | |
492 | + }, | |
493 | + // 이메일 중복 검사 | |
494 | + emailDuplicateChk() { | |
495 | + const vm = this; | |
496 | + // 유효성 검사 | |
497 | + if (!vm.validationEmail()) { | |
498 | + return; | |
499 | + } | |
500 | + // 실행 | |
501 | + axios({ | |
502 | + url: "/member/email", | |
503 | + method: "get", | |
504 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
505 | + data: vm.currentUser.userEmail, | |
506 | + }) | |
507 | + .then(response => { | |
508 | + if (response.data.resultData.result) { | |
509 | + vm.$showAlert("관리자 관리", "사용중인 이메일입니다."); | |
510 | + vm.isEmailChk = false; | |
511 | + } else { | |
512 | + vm.$showAlert("관리자 관리", "사용할 수 있는 이메일입니다."); | |
513 | + vm.isEmailChk = true; | |
514 | + } | |
515 | + }) | |
516 | + .catch(error => { | |
517 | + this.$showAlert("관리자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요."); | |
518 | + }); | |
519 | + }, | |
520 | + | |
521 | + // 관리자 잠금 해제 | |
522 | + fnUpdateUserLockAt() { | |
523 | + const vm = this; | |
524 | + // 실행 | |
525 | + axios({ | |
526 | + url: "/member/updateUser/LockAt/" + vm.currentUser.userId, | |
527 | + method: "post", | |
528 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
529 | + }) | |
530 | + .then(response => { | |
531 | + if (response.data.checkMessage.status === 200) { | |
532 | + vm.$showAlert("관리자 관리", "관리자 잠금이 해제되었습니다."); | |
533 | + vm.fnSelectUser(vm.currentUser.userId); // 관리자 개별 재조회 | |
534 | + } else { | |
535 | + vm.$showAlert("관리자 관리", response.data.checkMessage.message); | |
536 | + } | |
537 | + }) | |
538 | + .catch(error => { | |
539 | + vm.$showAlert("관리자 관리", "수정 오류, 관리자에게 문의해주세요."); | |
540 | + }); | |
541 | + }, | |
542 | + | |
543 | + // 관리자 비밀번호 변경 모달 열기 | |
544 | + fnOpenModal() { | |
545 | + this.userPassword = null; | |
546 | + this.userPasswordConfirm = null; | |
547 | + | |
548 | + this.modalOpen = true; | |
549 | + }, | |
550 | + // 관리자 비밀번호 변경 모달 열기 | |
551 | + fnCloseModal() { | |
552 | + this.modalOpen = false; | |
553 | + }, | |
554 | + // 관리자 비밀번호 변경 | |
555 | + fnUpdateUserPassword() { | |
556 | + const vm = this; | |
557 | + // 유효성 검사 | |
558 | + vm.currentUser.userPassword = vm.userPassword; | |
559 | + if (!vm.validationPassword()) { | |
560 | + return; | |
561 | + } | |
562 | + // 실행 | |
563 | + axios({ | |
564 | + url: "/member", | |
565 | + method: "patch", | |
566 | + headers: { | |
567 | + "Content-Type": "application/json", | |
568 | + }, | |
569 | + data: { | |
570 | + userId: vm.currentUser.userId, | |
571 | + userPassword: vm.userPassword, | |
572 | + }, | |
573 | + }) | |
574 | + .then(response => { | |
575 | + if (response.data.resultData.result) { | |
576 | + vm.$showAlert("비밀번호 변경", "비밀번호 변경에 성공했습니다."); | |
577 | + vm.modalOpen = false; | |
578 | + } else { | |
579 | + vm.$showAlert("비밀번호 변경", "비밀번호 변경에 실패했습니다. 다시 시도해주세요."); | |
580 | + } | |
581 | + }) | |
582 | + .catch(error => { | |
583 | + vm.$showAlert("비밀번호 변경", "비밀번호 변경에 실패했습니다. 다시 시도해주세요."); | |
584 | + }); | |
585 | + }, | |
586 | + | |
587 | + // 관리자 등록 취소 | |
588 | + fnCancel() { | |
589 | + if (this.editMode == 'update') { | |
590 | + this.editMode = 'create'; | |
591 | + } | |
592 | + // 초기화 | |
593 | + this.userPassword = null; | |
594 | + this.userPasswordConfirm = null; | |
595 | + this.currentUser = Object.assign({}, this.memberVO); | |
596 | + }, | |
597 | + | |
598 | + // #유효성 검사 | |
599 | + // 등록용 유효성 검사 | |
600 | + insertValidation() { | |
601 | + // 아이디 유효성 검사 | |
602 | + if (!this.validationId()) { | |
603 | + return false; | |
604 | + } | |
605 | + // 아이디 중복 검사 여부 | |
606 | + if (!this.isIdChk) { | |
607 | + this.$showAlert("관리자 관리", "아이디 중복 확인 후 시도해주세요."); | |
608 | + return false; | |
609 | + } | |
610 | + | |
611 | + // 이름 유효성 검사 | |
612 | + if (!this.validationName()) { | |
613 | + return false; | |
614 | + } | |
615 | + | |
616 | + // 비밀번호 유효성 검사 | |
617 | + if (!this.validationPassword()) { | |
618 | + return false; | |
619 | + } | |
620 | + | |
621 | + // 이메일 유효성 검사 | |
622 | + if (!this.validationEmail()) { | |
623 | + return false; | |
624 | + } | |
625 | + // 이메일 중복 검사 여부 | |
626 | + if (!this.isEmailChk) { | |
627 | + this.$showAlert("관리자 관리", "이메일 중복확인 후 등록해주세요."); | |
628 | + return false; | |
629 | + } | |
630 | + | |
631 | + return true; | |
632 | + }, | |
633 | + // 수정용 유효성 검사 | |
634 | + updateValidation() { | |
635 | + if (JSON.stringify(this.currentUser) === JSON.stringify(this.originUser)) { | |
636 | + this.$showAlert("관리자 관리", "수정된 정보가 없습니다."); | |
637 | + return; | |
638 | + } | |
639 | + | |
640 | + // 이름 유효성 검사 | |
641 | + if (!this.validationName()) { | |
642 | + return false; | |
643 | + } | |
644 | + | |
645 | + // 이메일 유효성 검사 | |
646 | + if (!this.validationEmail()) { | |
647 | + return false; | |
648 | + } | |
649 | + | |
650 | + // 이메일 중복 검사 여부 | |
651 | + if (!this.isEmailChk) { | |
652 | + this.$showAlert("관리자 관리", "이메일 중복확인 후 수정해주세요."); | |
653 | + return false; | |
654 | + } | |
655 | + | |
656 | + return true; | |
657 | + }, | |
658 | + // 아이디 유효성 검사 | |
659 | + validationId() { | |
660 | + let id = this.currentUser.userId; | |
661 | + | |
662 | + if (this.$isEmpty(id)) { | |
663 | + this.$showAlert("관리자 관리", "아이디를 입력해주세요."); | |
664 | + return false; | |
665 | + } | |
666 | + | |
667 | + if (!this.$idCheck(id)) { | |
668 | + this.$showAlert("관리자 관리", "아이디 형식이 올바르지 않습니다. (5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용가능)"); | |
669 | + return false; | |
670 | + } | |
671 | + | |
672 | + return true; | |
673 | + }, | |
674 | + // 이름 유효성 검사 | |
675 | + validationName() { | |
676 | + let name = this.currentUser.userNm; | |
677 | + | |
678 | + if (this.$isEmpty(name)) { | |
679 | + this.$showAlert("관리자 관리", "이름을 입력해주세요."); | |
680 | + return false; | |
681 | + } | |
682 | + | |
683 | + let validateName = /^[가-힣A-Za-z\s]+$/; | |
684 | + if (!validateName.test(name)) { | |
685 | + this.$showAlert("관리자 관리", "이름에 숫자와 특수문자를 입력할 수 없습니다."); | |
686 | + return false; | |
687 | + } | |
688 | + | |
689 | + return true; | |
690 | + }, | |
691 | + // 비밀번호 유효성 검사 | |
692 | + validationPassword() { | |
693 | + if (this.$isEmpty(this.currentUser.userPassword)) { | |
694 | + this.$showAlert("관리자 관리", "비밀번호를 입력해주세요."); | |
695 | + return false; | |
696 | + } | |
697 | + | |
698 | + if (!this.$pwCheck(this.currentUser.userPassword)) { | |
699 | + this.$showAlert("관리자 관리", "비밀번호 형식이 올바르지 않습니다. (8~16자의 영문 대문자, 소문자, 숫자, 특수문자 사용가능)"); | |
700 | + return false; | |
701 | + } | |
702 | + | |
703 | + if (this.currentUser.userPassword !== this.userPasswordConfirm) { | |
704 | + this.$showAlert("관리자 관리", "비밀번호가 일치하지 않습니다. 다시 입력해주세요."); | |
705 | + return false; | |
706 | + } | |
707 | + | |
708 | + return true; | |
709 | + }, | |
710 | + // 이메일 유효성 검사 | |
711 | + validationEmail() { | |
712 | + let email = this.currentUser.userEmail; | |
713 | + | |
714 | + // 1. null검사 | |
715 | + if (this.$isEmpty(email)) { | |
716 | + this.$showAlert("관리자 관리", "이메일을 입력해주세요."); | |
717 | + return false; | |
718 | + } | |
719 | + | |
720 | + // 2. 정규식 검사 | |
721 | + if (!this.$email(email)) { | |
722 | + this.$showAlert("관리자 관리", "이메일 형식이 올바르지 않습니다."); | |
723 | + return false; | |
724 | + } | |
725 | + | |
726 | + return true; | |
727 | + }, | |
728 | + }, | |
729 | +}; | |
730 | +</script>(파일 끝에 줄바꿈 문자 없음) |
--- client/views/pages/integration/DBConnectionList.vue
+++ client/views/pages/integrated/DBConnectionList.vue
No changes |
--- client/views/pages/integration/DepartmentManagement.vue
+++ client/views/pages/integrated/DepartmentManagement.vue
... | ... | @@ -537,11 +537,11 @@ |
537 | 537 |
return false; |
538 | 538 |
} |
539 | 539 |
|
540 |
- // 3. 상위 부서 검사 null 검사 |
|
541 |
- if (vm.$isEmpty(vm.departmentData.upper_dept) || vm.$isEmpty(vm.departmentData.upper_dept_nm)) { |
|
542 |
- vm.$showAlert("부서 등록", "상위 부서를 선택해주세요."); |
|
543 |
- return false; |
|
544 |
- } |
|
540 |
+ // // 3. 상위 부서 검사 null 검사 |
|
541 |
+ // if (vm.$isEmpty(vm.departmentData.upper_dept) || vm.$isEmpty(vm.departmentData.upper_dept_nm)) { |
|
542 |
+ // vm.$showAlert("부서 등록", "상위 부서를 선택해주세요."); |
|
543 |
+ // return false; |
|
544 |
+ // } |
|
545 | 545 |
|
546 | 546 |
// 4. 권한 null 검사 |
547 | 547 |
if (vm.$isEmpty(vm.departmentData.author)) { |
--- client/views/pages/integration/InsertDBConnection.vue
+++ client/views/pages/integrated/InsertDBConnection.vue
No changes |
+++ client/views/pages/integrated/UserManagement.vue
... | ... | @@ -0,0 +1,737 @@ |
1 | +<template> | |
2 | + <div class="container"> | |
3 | + <div class="page-titleZone flex justify-between align-center"> | |
4 | + <p class="main-title flex80">사용자 관리</p> | |
5 | + <PageNavigation /> | |
6 | + </div> | |
7 | + <div class="content-wrap"> | |
8 | + <div class="content content-box flex100"> | |
9 | + <div class="column-list"> | |
10 | + <div class="content-titleZone flex justify-between align-center"> | |
11 | + <p class="box-title">사용자 목록</p> | |
12 | + <div class="search-bar"> | |
13 | + <div class="flex justify-end align-center"> | |
14 | + <select class="square-select" v-model="search_data.key"> | |
15 | + <option :value="null">선택</option> | |
16 | + <option value="ui.user_id">아이디</option> | |
17 | + <option value="ui.user_nm">이름</option> | |
18 | + <option value="orgnzt_info.dept_nm">부서</option> | |
19 | + </select> | |
20 | + <div class="search-square"> | |
21 | + <div class="flex justify-end align-center no-gutter"> | |
22 | + <input type="text" class="square-input flex90" placeholder="검색어를 입력해 주세요." v-model="search_data.value" @keyup.enter="fnSelectUserList" /> | |
23 | + <button class="square-button blue-btn flex10" @click="fnSelectUserList"> | |
24 | + <svg-icon type="mdi" :path="searchPath" class="square-icon"></svg-icon> | |
25 | + </button> | |
26 | + </div> | |
27 | + </div> | |
28 | + </div> | |
29 | + </div> | |
30 | + </div> | |
31 | + <div class="flex justify-between align-center"> | |
32 | + <div class="count-zone"> | |
33 | + <p>총 <span>{{ userList.length }}</span>건 중 <span>{{ userSelectList.length }}</span>건 선택</p> | |
34 | + </div> | |
35 | + <div class="cunt-selectZone"> | |
36 | + <select v-model="search.perPage" @change="fnSelectUserList"> | |
37 | + <option value="10">10개 보기</option> | |
38 | + <option value="20">20개 보기</option> | |
39 | + </select> | |
40 | + </div> | |
41 | + </div> | |
42 | + <div class="table-zone"> | |
43 | + <table class="list-table"> | |
44 | + <colgroup> | |
45 | + <col style="width: 5%" /> | |
46 | + <col style="width: 5%" /> | |
47 | + <col style="width: 17%" /> | |
48 | + <col style="width: 17%" /> | |
49 | + <col style="width: 17%" /> | |
50 | + <col style="width: 17%" /> | |
51 | + <col style="width: 17%" /> | |
52 | + <col style="width: 5%" /> | |
53 | + </colgroup> | |
54 | + <thead> | |
55 | + <tr> | |
56 | + <th> | |
57 | + <input type="checkbox" v-model="isChkAll" @change="fnChkAll()" /> | |
58 | + </th> | |
59 | + <th>번호</th> | |
60 | + <th>아이디</th> | |
61 | + <th>이름</th> | |
62 | + <th>이메일</th> | |
63 | + <th>부서</th> | |
64 | + <th>등록날짜</th> | |
65 | + <th>잠김여부</th> | |
66 | + </tr> | |
67 | + </thead> | |
68 | + <tbody> | |
69 | + <template v-if="userList.length > 0"> | |
70 | + <tr v-for="(item, idx) in userList" :key="idx" @click="fnSelectUser(item.userId)"> | |
71 | + <td> | |
72 | + <input type="checkbox" :value="item" v-model="userSelectList" @click.stop="" @change="fnChangeChk" /> | |
73 | + </td> | |
74 | + <td>{{ search.totalRows - idx - (search.currentPage - 1) * search.perPage }}</td> | |
75 | + <td>{{ item.userId }}</td> | |
76 | + <td>{{ item.userNm }}</td> | |
77 | + <td>{{ item.userEmail }}</td> | |
78 | + <td>{{ item.deptNm }}</td> | |
79 | + <td>{{ $filters.dateTime(item.creatDt) }}</td> | |
80 | + <td>{{ item.lockAt ? "잠금" : "-" }}</td> | |
81 | + </tr> | |
82 | + </template> | |
83 | + <tr v-else> | |
84 | + <td colspan="8">등록된 데이터가 없습니다.</td> | |
85 | + </tr> | |
86 | + </tbody> | |
87 | + </table> | |
88 | + </div> | |
89 | + <div class="flex justify-end"> | |
90 | + <button class="red-border-btn small-btn" @click="fnDeleteUser">선택 삭제</button> | |
91 | + </div> | |
92 | + <PaginationButton v-model:currentPage="search.currentPage" :perPage="search.perPage" :totalCount="search.totalRows" :maxRange="5" :click="fetchMemberList" /> | |
93 | + </div> | |
94 | + <div class="data-set"> | |
95 | + <div class="form-box"> | |
96 | + <div class="content-titleZone"> | |
97 | + <p class="box-title" v-if="editMode == 'create'">사용자 등록</p> | |
98 | + <p class="box-title" v-else>사용자 수정</p> | |
99 | + </div> | |
100 | + <div class="table-zone"> | |
101 | + <table class="form-table2"> | |
102 | + <colgroup> | |
103 | + <col style="width: 10%" /> | |
104 | + <col style="width: 40%" /> | |
105 | + <col style="width: 10%" /> | |
106 | + <col style="width: 40%" /> | |
107 | + </colgroup> | |
108 | + <tbody> | |
109 | + <tr> | |
110 | + <th>아이디</th> | |
111 | + <td style="display: flex"> | |
112 | + <input type="text" class="full-input" v-model="currentUser.userId" :disabled="editMode == 'update'" /> | |
113 | + <button class="small-btn blue-border-btn" style="flex-grow: 1" v-if="editMode == 'create'" @click="fnDuplicateChk('id')">중복확인</button> | |
114 | + </td> | |
115 | + <th>이름</th> | |
116 | + <td> | |
117 | + <input type="text" class="full-input" v-model="currentUser.userNm" /> | |
118 | + </td> | |
119 | + </tr> | |
120 | + <tr v-if="editMode == 'create'"> | |
121 | + <th>비밀번호</th> | |
122 | + <td> | |
123 | + <input type="password" class="full-input" style="width: 100%" v-model="currentUser.userPassword" /> | |
124 | + </td> | |
125 | + <th>비밀번호 확인</th> | |
126 | + <td> | |
127 | + <input type="password" class="full-input" style="width: 100%" v-model="userPasswordConfirm" /> | |
128 | + </td> | |
129 | + </tr> | |
130 | + <tr> | |
131 | + <th>이메일</th> | |
132 | + <td style="display: flex"> | |
133 | + <input type="text" class="full-input" v-model="currentUser.userEmail" /> | |
134 | + <button class="small-btn blue-border-btn" style="flex-grow: 1" @click="fnDuplicateChk('email')">중복확인</button> | |
135 | + </td> | |
136 | + <th>부서</th> | |
137 | + <td> | |
138 | + <select class="full-select" v-model="currentUser.dept_code"> | |
139 | + <option :value="null" disabled>부서를 선택해주세요.</option> | |
140 | + <option v-for="(item, idx) in deptList" :key="idx" :value="item.dept_code"> {{ item.dept_nm }} </option> | |
141 | + </select> | |
142 | + </td> | |
143 | + </tr> | |
144 | + <tr v-if="editMode == 'update'"> | |
145 | + <th>잠김여부</th> | |
146 | + <td style="display: flex"> | |
147 | + <input type="text" class="full-input" :value="currentUser.lockAt ? '잠금 (사용불가)' : '미잠금 (사용가능)'" readonly> | |
148 | + <button class="blue-border-btn small-btn" style="flex-grow: 1" v-if="currentUser.lockAt" @click="fnUpdateUserLockAt">잠금해제</button> | |
149 | + </td> | |
150 | + <th></th> | |
151 | + <td></td> | |
152 | + </tr> | |
153 | + </tbody> | |
154 | + </table> | |
155 | + </div> | |
156 | + <div class="flex justify-end"> | |
157 | + <button class="blue-border-btn small-btn" v-if="editMode == 'update'" @click="fnOpenModal">비밀번호 변경</button> | |
158 | + <button class="blue-btn small-btn" v-if="editMode == 'create'" @click="fnInsertUser">등록</button> | |
159 | + <button class="blue-btn small-btn" v-else @click="fnUpdateUser">수정</button> | |
160 | + <button class="blue-border-btn small-btn" @click="fnCancel">취소</button> | |
161 | + </div> | |
162 | + </div> | |
163 | + </div> | |
164 | + </div> | |
165 | + </div> | |
166 | + </div> | |
167 | + <!-- 비밀번호 변경 모달 --> | |
168 | + <div v-show="modalOpen" class="modal-wrapper"> | |
169 | + <div class="modal-container small-modal"> | |
170 | + <div class="modal-title"> | |
171 | + <div class="flex justify-between align-center"> | |
172 | + <h2>비밀번호 변경</h2> | |
173 | + <button class="close-btn" @click="fnCloseModal">X</button> | |
174 | + </div> | |
175 | + </div> | |
176 | + <div class="modal-content-monthly"> | |
177 | + <div class="table-zone"> | |
178 | + <table class="form-table"> | |
179 | + <colgroup> | |
180 | + <col style="width: 40%" /> | |
181 | + <col style="width: 60%" /> | |
182 | + </colgroup> | |
183 | + <tbody> | |
184 | + <tr> | |
185 | + <th>새 비밀번호</th> | |
186 | + <td> | |
187 | + <input type="password" class="full-input" v-model="userPassword" /> | |
188 | + </td> | |
189 | + </tr> | |
190 | + <tr> | |
191 | + <th>새 비밀번호 확인</th> | |
192 | + <td> | |
193 | + <input type="password" class="full-input" v-model="userPasswordConfirm" /> | |
194 | + </td> | |
195 | + </tr> | |
196 | + </tbody> | |
197 | + </table> | |
198 | + <div class="modal-end flex justify-between" style="flex-wrap: nowrap;"> | |
199 | + <button class="blue-btn large-btn" @click="fnUpdateUserPassword">수정</button> | |
200 | + <button class="blue-border-btn small-btn" @click="fnCancel"><span v-if="editMode == 'create'">초기화</span><span v-else>취소</span></button> | |
201 | + </div> | |
202 | + </div> | |
203 | + </div> | |
204 | + </div> | |
205 | + </div> | |
206 | +</template> | |
207 | +<script> | |
208 | +import axios from "axios"; | |
209 | +// icon용 svg import | |
210 | +import SvgIcon from "@jamescoyle/vue-icon"; | |
211 | +import { mdiClose, mdiMagnify } from "@mdi/js"; | |
212 | +// 컴포넌트 import | |
213 | +import PageNavigation from "../../component/PageNavigation.vue"; | |
214 | +import PaginationButton from "../../component/PaginationButton.vue"; | |
215 | + | |
216 | +export default { | |
217 | + components: { SvgIcon, PageNavigation, PaginationButton }, | |
218 | + | |
219 | + data() { | |
220 | + return { | |
221 | + // icon용 svg path | |
222 | + closePath: mdiClose, | |
223 | + searchPath: mdiMagnify, | |
224 | + | |
225 | + // 검색 | |
226 | + search: this.$getDefaultSerchVO(), | |
227 | + search_data: this.$getDefaultSerchItem(null, "string"), | |
228 | + | |
229 | + // default | |
230 | + editMode: 'create', | |
231 | + | |
232 | + memberVO: {}, | |
233 | + originUser: {}, | |
234 | + currentUser: {}, | |
235 | + | |
236 | + userPassword: null, | |
237 | + userPasswordConfirm: null, | |
238 | + | |
239 | + isChkAll: false, | |
240 | + userList: [], | |
241 | + userSelectList: [], | |
242 | + | |
243 | + deptList: [], | |
244 | + | |
245 | + // 비밀번호 변경 | |
246 | + modalOpen: false, | |
247 | + | |
248 | + // 중복검사 | |
249 | + isIdChk: false, | |
250 | + isEmailChk: false, | |
251 | + }; | |
252 | + }, | |
253 | + | |
254 | + mounted() { | |
255 | + this.fnSelectUser(); // 사용자 개별 조회 | |
256 | + this.fnSelectUserList(); // 사용자 목록 조회 | |
257 | + this.fnSelectDeptList(); // 부서 목록 조회 | |
258 | + }, | |
259 | + | |
260 | + watch: { | |
261 | + //아이디 값 변경 시 중복 검사 false로 변경 | |
262 | + "currentUser.userId"() { | |
263 | + this.isIdChk = false; | |
264 | + }, | |
265 | + //이메일 값 변경 시 중복 검사 false로 변경 | |
266 | + "currentUser.userEmail"() { | |
267 | + this.isEmailChk = false; | |
268 | + }, | |
269 | + }, | |
270 | + | |
271 | + methods: { | |
272 | + // 사용자 목록 조회 | |
273 | + fnSelectUserList() { | |
274 | + const vm = this; | |
275 | + // 데이터 세팅 | |
276 | + let data = vm.search; | |
277 | + data.searchObjectList = []; // 초기화 | |
278 | + data.searchObjectList.push(vm.search_data); | |
279 | + // 실행 | |
280 | + axios({ | |
281 | + url: "/member/list", | |
282 | + method: "post", | |
283 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
284 | + data: data, | |
285 | + }) | |
286 | + .then(response => { | |
287 | + if (response.data != null) { | |
288 | + vm.userList = response.data.resultData.members; | |
289 | + vm.search = response.data.resultData.searchVO; | |
290 | + } else { | |
291 | + this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요."); | |
292 | + } | |
293 | + }) | |
294 | + .catch(error => { | |
295 | + vm.$showAlert("사용자 관리", "목록 불러오기 오류, 관리자에게 문의바랍니다."); | |
296 | + }); | |
297 | + }, | |
298 | + // 사용자 목록 전체 선택 | |
299 | + fnChkAll() { | |
300 | + if (this.isChkAll) { | |
301 | + this.userSelectList = this.userList; | |
302 | + } else { | |
303 | + this.userSelectList = []; | |
304 | + } | |
305 | + }, | |
306 | + // 사용자 목록 개별 선택 | |
307 | + fnChangeChk() { | |
308 | + if (this.userSelectList.length == this.userList.length) { | |
309 | + this.isChkAll = true; | |
310 | + } else { | |
311 | + this.isChkAll = false; | |
312 | + } | |
313 | + }, | |
314 | + // 사용자 선택 삭제 | |
315 | + async fnDeleteUser() { | |
316 | + const vm = this; | |
317 | + // 선택 목록 확인 | |
318 | + if (vm.userSelectList.length === 0) { | |
319 | + vm.$showAlert("사용자 관리", "선택한 사용자가 없습니다."); | |
320 | + return; | |
321 | + } | |
322 | + // 삭제 확인 | |
323 | + if (!(await vm.$showConfirm("사용자 관리", "선택한 사용자를 삭제하시겠습니까?"))) { | |
324 | + return; | |
325 | + } | |
326 | + | |
327 | + // 실행 | |
328 | + axios({ | |
329 | + url: "/member", | |
330 | + method: "delete", | |
331 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
332 | + data: vm.userSelectList, | |
333 | + }) | |
334 | + .then(response => { | |
335 | + if (response.data.checkMessage.status === 200) { | |
336 | + vm.$showAlert("사용자 관리", "선택한 사용자가 삭제되었습니다."); | |
337 | + | |
338 | + // 삭제 후 작업 | |
339 | + vm.isChkAll = false; // 체크 박스 리셋 | |
340 | + vm.userSelectList = []; // 사용자 선택 목록 초기화 | |
341 | + vm.fnSelectUserList(); // 전체 재조회 | |
342 | + } else { | |
343 | + vm.$showAlert("사용자 관리", response.data.checkMessage.message); | |
344 | + } | |
345 | + }) | |
346 | + .catch(error => { | |
347 | + vm.$showAlert("사용자 관리", "처리 중 오류가 발생했습니다. 관리자에게 문의바랍니다."); | |
348 | + }); | |
349 | + }, | |
350 | + | |
351 | + // 부서 목록 조회 | |
352 | + fnSelectDeptList() { | |
353 | + const vm = this; | |
354 | + // 데이터 세팅팅 | |
355 | + let search = Object.assign({}, this.$getDefaultSerchVO()); | |
356 | + search.currentPage = 0; | |
357 | + search.perPage = 0; | |
358 | + // 실행 | |
359 | + axios({ | |
360 | + url: "/department/departments", | |
361 | + method: "post", | |
362 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
363 | + data: search, | |
364 | + }) | |
365 | + .then(response => { | |
366 | + if (response.data != null) { | |
367 | + vm.deptList = response.data.resultData.selectDeptList; | |
368 | + } else { | |
369 | + this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요."); | |
370 | + } | |
371 | + }) | |
372 | + .catch(error => { | |
373 | + vm.$showAlert("사용자 관리", "목록 불러오기 오류, 관리자에게 문의바랍니다."); | |
374 | + }); | |
375 | + }, | |
376 | + | |
377 | + // 사용자 등록 | |
378 | + fnInsertUser() { | |
379 | + const vm = this; | |
380 | + // 유효성 검사 | |
381 | + if (!vm.insertValidation()) { | |
382 | + return; | |
383 | + } | |
384 | + // 실행 | |
385 | + axios({ | |
386 | + url: "/member", | |
387 | + method: "post", | |
388 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
389 | + data: vm.currentUser, | |
390 | + }) | |
391 | + .then(response => { | |
392 | + if (response.data.checkMessage.status === 200) { | |
393 | + vm.$showAlert("사용자 관리", "사용자 등록이 완료되었습니다."); | |
394 | + vm.currentUser = Object.assign({}, vm.memberVO); // 초기화 | |
395 | + vm.fnSelectUserList(); | |
396 | + } else { | |
397 | + vm.$showAlert("사용자 관리", response.data.checkMessage.message); | |
398 | + } | |
399 | + }) | |
400 | + .catch(error => { | |
401 | + vm.$showAlert("사용자 관리", "사용자 등록에 실패했습니다. 다시 시도해주세요."); | |
402 | + }); | |
403 | + }, | |
404 | + | |
405 | + // 사용자 개별 조회 | |
406 | + fnSelectUser(userId) { | |
407 | + const vm = this; | |
408 | + // 데이터 세팅 | |
409 | + let url = null; | |
410 | + if (vm.$isEmpty(userId)) { | |
411 | + url = "/member/selectUser"; | |
412 | + } else { | |
413 | + url = "/member/selectUser/" + userId; | |
414 | + } | |
415 | + // 실행 | |
416 | + axios({ | |
417 | + url: url, | |
418 | + method: "post", | |
419 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
420 | + }) | |
421 | + .then(response => { | |
422 | + if (vm.$isEmpty(userId)) { | |
423 | + vm.memberVO = response.data; | |
424 | + } else { | |
425 | + vm.editMode = 'update'; | |
426 | + vm.originUser = response.data; | |
427 | + vm.currentUser = Object.assign({}, response.data); | |
428 | + } | |
429 | + }) | |
430 | + .catch(error => { | |
431 | + vm.$showAlert("사용자 관리", "불러오기 오류, 관리자에게 문의바랍니다."); | |
432 | + }); | |
433 | + }, | |
434 | + | |
435 | + // 사용자 수정 | |
436 | + fnUpdateUser() { | |
437 | + const vm = this; | |
438 | + // 유효성 검사 | |
439 | + if (!vm.updateValidation()) { | |
440 | + return; | |
441 | + } | |
442 | + // 실행 | |
443 | + axios({ | |
444 | + url: "/member", | |
445 | + method: "put", | |
446 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
447 | + data: vm.currentUser | |
448 | + }) | |
449 | + .then(response => { | |
450 | + if (response.data.checkMessage.status === 200) { | |
451 | + vm.$showAlert("사용자 관리", "사용자 정보가 수정되었습니다."); | |
452 | + vm.originUser = Object.assign({}, vm.memberVO); // 초기화 | |
453 | + vm.currentUser = Object.assign({}, vm.memberVO); // 초기화 | |
454 | + vm.editMode = 'create'; | |
455 | + vm.fnSelectUserList(); | |
456 | + } else { | |
457 | + vm.$showAlert("사용자 관리", response.data.checkMessage.message); | |
458 | + } | |
459 | + }) | |
460 | + .catch(error => { | |
461 | + vm.$showAlert("사용자 관리", "수정 오류, 관리자에게 문의해주세요."); | |
462 | + }); | |
463 | + }, | |
464 | + | |
465 | + // 중복확인 버튼 동작 | |
466 | + fnDuplicateChk(type) { | |
467 | + if (type == 'id') { | |
468 | + this.idDuplicateChk(); | |
469 | + } else if (type == 'email') { | |
470 | + this.emailDuplicateChk(); | |
471 | + } | |
472 | + }, | |
473 | + // 아이디 중복 검사 | |
474 | + idDuplicateChk() { | |
475 | + const vm = this; | |
476 | + // 유효성 검사 | |
477 | + if (!vm.$idCheck(vm.currentUser.userId)) { | |
478 | + vm.$showAlert("사용자 관리", "아이디 형식이 올바르지 않습니다. (5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용가능)"); | |
479 | + return false; | |
480 | + } | |
481 | + // 실행 | |
482 | + axios({ | |
483 | + url: "/member/" + vm.currentUser.userId, | |
484 | + method: "get", | |
485 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
486 | + }) | |
487 | + .then(response => { | |
488 | + if (response.data.resultData.checkDuplicateUserId) { | |
489 | + vm.isIdChk = false; | |
490 | + vm.$showAlert("사용자 관리", "사용중인 아이디입니다."); | |
491 | + } else { | |
492 | + vm.isIdChk = true; | |
493 | + vm.$showAlert("사용자 관리", "사용할 수 있는 아이디입니다."); | |
494 | + } | |
495 | + }) | |
496 | + .catch(error => { | |
497 | + this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요."); | |
498 | + }); | |
499 | + }, | |
500 | + // 이메일 중복 검사 | |
501 | + emailDuplicateChk() { | |
502 | + const vm = this; | |
503 | + // 유효성 검사 | |
504 | + if (!vm.validationEmail()) { | |
505 | + return; | |
506 | + } | |
507 | + // 실행 | |
508 | + axios({ | |
509 | + url: "/member/email", | |
510 | + method: "get", | |
511 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
512 | + data: vm.currentUser.userEmail, | |
513 | + }) | |
514 | + .then(response => { | |
515 | + if (response.data.resultData.result) { | |
516 | + vm.$showAlert("사용자 관리", "사용중인 이메일입니다."); | |
517 | + vm.isEmailChk = false; | |
518 | + } else { | |
519 | + vm.$showAlert("사용자 관리", "사용할 수 있는 이메일입니다."); | |
520 | + vm.isEmailChk = true; | |
521 | + } | |
522 | + }) | |
523 | + .catch(error => { | |
524 | + this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요."); | |
525 | + }); | |
526 | + }, | |
527 | + | |
528 | + // 사용자 잠금 해제 | |
529 | + fnUpdateUserLockAt() { | |
530 | + const vm = this; | |
531 | + // 실행 | |
532 | + axios({ | |
533 | + url: "/member/updateUser/LockAt/" + vm.currentUser.userId, | |
534 | + method: "post", | |
535 | + headers: { "Content-Type": "application/json; charset=UTF-8" }, | |
536 | + }) | |
537 | + .then(response => { | |
538 | + if (response.data.checkMessage.status === 200) { | |
539 | + vm.$showAlert("사용자 관리", "사용자 잠금이 해제되었습니다."); | |
540 | + vm.fnSelectUser(vm.currentUser.userId); // 사용자 개별 재조회 | |
541 | + } else { | |
542 | + vm.$showAlert("사용자 관리", response.data.checkMessage.message); | |
543 | + } | |
544 | + }) | |
545 | + .catch(error => { | |
546 | + vm.$showAlert("사용자 관리", "수정 오류, 관리자에게 문의해주세요."); | |
547 | + }); | |
548 | + }, | |
549 | + | |
550 | + // 사용자 비밀번호 변경 모달 열기 | |
551 | + fnOpenModal() { | |
552 | + this.userPassword = null; | |
553 | + this.userPasswordConfirm = null; | |
554 | + | |
555 | + this.modalOpen = true; | |
556 | + }, | |
557 | + // 사용자 비밀번호 변경 모달 열기 | |
558 | + fnCloseModal() { | |
559 | + this.modalOpen = false; | |
560 | + }, | |
561 | + // 사용자 비밀번호 변경 | |
562 | + fnUpdateUserPassword() { | |
563 | + const vm = this; | |
564 | + // 유효성 검사 | |
565 | + vm.currentUser.userPassword = vm.userPassword; | |
566 | + if (!vm.validationPassword()) { | |
567 | + return; | |
568 | + } | |
569 | + // 실행 | |
570 | + axios({ | |
571 | + url: "/member", | |
572 | + method: "patch", | |
573 | + headers: { | |
574 | + "Content-Type": "application/json", | |
575 | + }, | |
576 | + data: { | |
577 | + userId: vm.currentUser.userId, | |
578 | + userPassword: vm.userPassword, | |
579 | + }, | |
580 | + }) | |
581 | + .then(response => { | |
582 | + if (response.data.resultData.result) { | |
583 | + vm.$showAlert("비밀번호 변경", "비밀번호 변경에 성공했습니다."); | |
584 | + vm.modalOpen = false; | |
585 | + } else { | |
586 | + vm.$showAlert("비밀번호 변경", "비밀번호 변경에 실패했습니다. 다시 시도해주세요."); | |
587 | + } | |
588 | + }) | |
589 | + .catch(error => { | |
590 | + vm.$showAlert("비밀번호 변경", "비밀번호 변경에 실패했습니다. 다시 시도해주세요."); | |
591 | + }); | |
592 | + }, | |
593 | + | |
594 | + // 사용자 등록 취소 | |
595 | + fnCancel() { | |
596 | + if (this.editMode == 'update') { | |
597 | + this.editMode = 'create'; | |
598 | + } | |
599 | + // 초기화 | |
600 | + this.userPassword = null; | |
601 | + this.userPasswordConfirm = null; | |
602 | + this.currentUser = Object.assign({}, this.memberVO); | |
603 | + }, | |
604 | + | |
605 | + // #유효성 검사 | |
606 | + // 등록용 유효성 검사 | |
607 | + insertValidation() { | |
608 | + // 아이디 유효성 검사 | |
609 | + if (!this.validationId()) { | |
610 | + return false; | |
611 | + } | |
612 | + // 아이디 중복 검사 여부 | |
613 | + if (!this.isIdChk) { | |
614 | + this.$showAlert("사용자 관리", "아이디 중복 확인 후 시도해주세요."); | |
615 | + return false; | |
616 | + } | |
617 | + | |
618 | + // 이름 유효성 검사 | |
619 | + if (!this.validationName()) { | |
620 | + return false; | |
621 | + } | |
622 | + | |
623 | + // 비밀번호 유효성 검사 | |
624 | + if (!this.validationPassword()) { | |
625 | + return false; | |
626 | + } | |
627 | + | |
628 | + // 이메일 유효성 검사 | |
629 | + if (!this.validationEmail()) { | |
630 | + return false; | |
631 | + } | |
632 | + // 이메일 중복 검사 여부 | |
633 | + if (!this.isEmailChk) { | |
634 | + this.$showAlert("사용자 관리", "이메일 중복확인 후 등록해주세요."); | |
635 | + return false; | |
636 | + } | |
637 | + | |
638 | + return true; | |
639 | + }, | |
640 | + // 수정용 유효성 검사 | |
641 | + updateValidation() { | |
642 | + if (JSON.stringify(this.currentUser) === JSON.stringify(this.originUser)) { | |
643 | + this.$showAlert("사용자 관리", "수정된 정보가 없습니다."); | |
644 | + return; | |
645 | + } | |
646 | + | |
647 | + // 이름 유효성 검사 | |
648 | + if (!this.validationName()) { | |
649 | + return false; | |
650 | + } | |
651 | + | |
652 | + // 이메일 유효성 검사 | |
653 | + if (!this.validationEmail()) { | |
654 | + return false; | |
655 | + } | |
656 | + | |
657 | + // 이메일 중복 검사 여부 | |
658 | + if (!this.isEmailChk) { | |
659 | + this.$showAlert("사용자 관리", "이메일 중복확인 후 수정해주세요."); | |
660 | + return false; | |
661 | + } | |
662 | + | |
663 | + return true; | |
664 | + }, | |
665 | + // 아이디 유효성 검사 | |
666 | + validationId() { | |
667 | + let id = this.currentUser.userId; | |
668 | + | |
669 | + if (this.$isEmpty(id)) { | |
670 | + this.$showAlert("사용자 관리", "아이디를 입력해주세요."); | |
671 | + return false; | |
672 | + } | |
673 | + | |
674 | + if (!this.$idCheck(id)) { | |
675 | + this.$showAlert("사용자 관리", "아이디 형식이 올바르지 않습니다. (5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용가능)"); | |
676 | + return false; | |
677 | + } | |
678 | + | |
679 | + return true; | |
680 | + }, | |
681 | + // 이름 유효성 검사 | |
682 | + validationName() { | |
683 | + let name = this.currentUser.userNm; | |
684 | + | |
685 | + if (this.$isEmpty(name)) { | |
686 | + this.$showAlert("사용자 관리", "이름을 입력해주세요."); | |
687 | + return false; | |
688 | + } | |
689 | + | |
690 | + let validateName = /^[가-힣A-Za-z\s]+$/; | |
691 | + if (!validateName.test(name)) { | |
692 | + this.$showAlert("사용자 관리", "이름에 숫자와 특수문자를 입력할 수 없습니다."); | |
693 | + return false; | |
694 | + } | |
695 | + | |
696 | + return true; | |
697 | + }, | |
698 | + // 비밀번호 유효성 검사 | |
699 | + validationPassword() { | |
700 | + if (this.$isEmpty(this.currentUser.userPassword)) { | |
701 | + this.$showAlert("사용자 관리", "비밀번호를 입력해주세요."); | |
702 | + return false; | |
703 | + } | |
704 | + | |
705 | + if (!this.$pwCheck(this.currentUser.userPassword)) { | |
706 | + this.$showAlert("사용자 관리", "비밀번호 형식이 올바르지 않습니다. (8~16자의 영문 대문자, 소문자, 숫자, 특수문자 사용가능)"); | |
707 | + return false; | |
708 | + } | |
709 | + | |
710 | + if (this.currentUser.userPassword !== this.userPasswordConfirm) { | |
711 | + this.$showAlert("사용자 관리", "비밀번호가 일치하지 않습니다. 다시 입력해주세요."); | |
712 | + return false; | |
713 | + } | |
714 | + | |
715 | + return true; | |
716 | + }, | |
717 | + // 이메일 유효성 검사 | |
718 | + validationEmail() { | |
719 | + let email = this.currentUser.userEmail; | |
720 | + | |
721 | + // 1. null검사 | |
722 | + if (this.$isEmpty(email)) { | |
723 | + this.$showAlert("사용자 관리", "이메일을 입력해주세요."); | |
724 | + return false; | |
725 | + } | |
726 | + | |
727 | + // 2. 정규식 검사 | |
728 | + if (!this.$email(email)) { | |
729 | + this.$showAlert("사용자 관리", "이메일 형식이 올바르지 않습니다."); | |
730 | + return false; | |
731 | + } | |
732 | + | |
733 | + return true; | |
734 | + }, | |
735 | + }, | |
736 | +}; | |
737 | +</script>(파일 끝에 줄바꿈 문자 없음) |
--- client/views/pages/integration/UserManagement.vue
... | ... | @@ -1,845 +0,0 @@ |
1 | -<template> | |
2 | - <div class="container"> | |
3 | - <div class="page-titleZone flex justify-between align-center"> | |
4 | - <p class="main-title flex80">사용자 관리</p> | |
5 | - <PageNavigation /> | |
6 | - </div> | |
7 | - <div class="content-wrap"> | |
8 | - <div class="content content-box flex100"> | |
9 | - <div class="column-list"> | |
10 | - <div class="content-titleZone flex justify-between align-center"> | |
11 | - <p class="box-title">사용자 목록</p> | |
12 | - <div class="flex justify-end align-center"> | |
13 | - <select class="square-select" v-model="search_data.key"> | |
14 | - <option :value="null" disabled>선택</option> | |
15 | - <option value="ui.user_id">아이디</option> | |
16 | - <option value="ui.user_nm">이름</option> | |
17 | - <option value="orgnzt_info.dept_nm">부서</option> | |
18 | - </select> | |
19 | - <div class="search-square"> | |
20 | - <input type="text" class="square-input" v-model="search_data.value" placeholder="검색어를 입력해주세요." @keyup.enter="searchUser" /> | |
21 | - <button class="square-button blue-btn" @click="searchUser"> | |
22 | - <svg-icon type="mdi" :path="searchPath" class="square-icon"></svg-icon> | |
23 | - </button> | |
24 | - </div> | |
25 | - </div> | |
26 | - </div> | |
27 | - <div class="flex justify-between align-center"> | |
28 | - <div class="count-zone"> | |
29 | - <p>총 <span>{{ memberList.length }}</span>건 중 <span>{{ selectedMembers.length }}</span>건 선택</p> | |
30 | - </div> | |
31 | - <div class="cunt-selectZone"> | |
32 | - <select v-model="selectedPerPage" @change="updatePerPage"> | |
33 | - <option value="10">10개 보기</option> | |
34 | - <option value="20">20개 보기</option> | |
35 | - </select> | |
36 | - </div> | |
37 | - </div> | |
38 | - <div class="table-zone"> | |
39 | - <table class="list-table"> | |
40 | - <colgroup> | |
41 | - <col style="width: 5%" /> | |
42 | - <col style="width: 5%" /> | |
43 | - <col style="width: 16%" /> | |
44 | - <col style="width: 16%" /> | |
45 | - <col style="width: 16%" /> | |
46 | - <col style="width: 16%" /> | |
47 | - <col style="width: 16%" /> | |
48 | - <col style="width: 5%" /> | |
49 | - </colgroup> | |
50 | - <thead> | |
51 | - <tr> | |
52 | - <th> | |
53 | - <input type="checkbox" @click="memberCheckAll" v-model="checkAll" /> | |
54 | - </th> | |
55 | - <th>No</th> | |
56 | - <th>아이디</th> | |
57 | - <th>이름</th> | |
58 | - <th>이메일</th> | |
59 | - <th>부서</th> | |
60 | - <th>등록날짜</th> | |
61 | - <th>잠김여부</th> | |
62 | - </tr> | |
63 | - </thead> | |
64 | - <tbody> | |
65 | - <tr v-for="(member, index) in memberList" :key="index" @click="loadHostData(member)"> | |
66 | - <td> | |
67 | - <input type="checkbox" @click.stop="" v-model="selectedMembers" :value="member.userId" name="memberList" /> | |
68 | - </td> | |
69 | - <td>{{ memberIdx - index }}</td> | |
70 | - <td>{{ member.userId }}</td> | |
71 | - <td>{{ member.userNm }}</td> | |
72 | - <td>{{ member.userEmail }}</td> | |
73 | - <td>{{ member.deptNm }}</td> | |
74 | - <td>{{ $filters.dateTime(member.creatDt) }}</td> | |
75 | - <td>{{ member.lockAt == false ? "X" : "Y" }}</td> | |
76 | - </tr> | |
77 | - </tbody> | |
78 | - </table> | |
79 | - </div> | |
80 | - <!-- <div v-if="this.author == 'ROLE_ADMIN'" class="flex justify-end"> --> | |
81 | - <PaginationButton v-model:currentPage="search.currentPage" :perPage="search.perPage" :totalCount="search.totalRows" :maxRange="5" :click="fetchMemberList" /> | |
82 | - <div class="flex justify-end"> | |
83 | - <button class="red-border-btn small-btn" @click="deleteSelectedMembers">선택 삭제</button> | |
84 | - </div> | |
85 | - </div> | |
86 | - <div class="data-set"> | |
87 | - <div class="form-box"> | |
88 | - <div class="content-titleZone"> | |
89 | - <p class="box-title" v-if="!dataLoaded">사용자 등록</p> | |
90 | - <p class="box-title" v-else>사용자 수정</p> | |
91 | - </div> | |
92 | - <div class="table-zone"> | |
93 | - <table class="form-table2"> | |
94 | - <colgroup> | |
95 | - <col style="width: 10%" /> | |
96 | - <col style="width: 40%" /> | |
97 | - <col style="width: 10%" /> | |
98 | - <col style="width: 40%" /> | |
99 | - </colgroup> | |
100 | - <tbody> | |
101 | - <tr> | |
102 | - <th>아이디</th> | |
103 | - <td style="display: flex"> | |
104 | - <input type="text" name="" id="userId" class="full-input" v-model="memberData.userId" :disabled="dataLoaded" /> | |
105 | - <button @click="checkDuplicate" style="flex-grow: 1" class="small-btn blue-border-btn" v-if="!dataLoaded"> 중복확인 </button> | |
106 | - </td> | |
107 | - <th>이름</th> | |
108 | - <td> | |
109 | - <input type="text" name="" id="userNm" class="full-input" v-model="memberData.userNm" /> | |
110 | - </td> | |
111 | - </tr> | |
112 | - <tr v-if="!dataLoaded"> | |
113 | - <th>비밀번호</th> | |
114 | - <td> | |
115 | - <input id="userPassword" type="password" class="full-input" style="width: 100%" v-model="memberData.userPassword" /> | |
116 | - </td> | |
117 | - <th>비밀번호 변경 확인</th> | |
118 | - <td> | |
119 | - <input id="passwordConfirm" type="password" class="full-input" style="width: 100%" v-model="passwordConfirm" /> | |
120 | - </td> | |
121 | - </tr> | |
122 | - <tr> | |
123 | - <th>이메일</th> | |
124 | - <td style="display: flex"> | |
125 | - <input type="text" name="" id="email" class="full-input" v-model="memberData.userEmail" /> | |
126 | - <button style="flex-grow: 1" class="small-btn blue-border-btn" v-if=" | |
127 | - dataLoaded && | |
128 | - originalmemberData.userEmail !== memberData.userEmail | |
129 | - " @click="mailDuplicateCheck()"> 중복확인 </button> | |
130 | - <button style="flex-grow: 1" class="small-btn blue-border-btn" v-if="!dataLoaded" @click="mailDuplicateCheck()"> 중복확인 </button> | |
131 | - </td> | |
132 | - <th>권한</th> | |
133 | - <td style="display: flex"> | |
134 | - <select class="full-select" v-model="memberData.author" @change="changeAuthor"> | |
135 | - <option :value="null" disabled>권한을 선택해주세요.</option> | |
136 | - <option v-for="(author, idx) in authorList" :key="idx" :value="author.author">{{ author.author_dc }}</option> | |
137 | - </select> | |
138 | - </td> | |
139 | - </tr> | |
140 | - <tr> | |
141 | - <th>부서</th> | |
142 | - <td> | |
143 | - <select name="" id="deptNm" class="full-select" v-model="memberData.dept_code"> | |
144 | - <option :value="null" disabled>부서를 선택해주세요.</option> | |
145 | - <option v-for="(department, idx) in departmentList" :key="idx" :value="department.dept_code"> {{ department.dept_nm }} </option> | |
146 | - </select> | |
147 | - </td> | |
148 | - <th><template v-if="dataLoaded">잠김여부</template></th> | |
149 | - <td style="display: flex"> | |
150 | - <template v-if="dataLoaded"> | |
151 | - <input type="text" class="full-input" :value="memberData.lockAt ? '사용불가' : '사용가능'" readonly> | |
152 | - <button class="blue-border-btn small-btn" @click="toggleLockAtStatus" style="flex-grow: 1"> {{ memberData.lockAt ? "잠금해제" : "잠금설정" }} </button> | |
153 | - </template> | |
154 | - </td> | |
155 | - </tr> | |
156 | - </tbody> | |
157 | - </table> | |
158 | - </div> | |
159 | - <!-- <div v-if="this.author == 'ROLE_ADMIN' || memberData.userId == this.userId" class="flex justify-end"> --> | |
160 | - <div class="flex justify-end"> | |
161 | - <template v-if="dataLoaded"> | |
162 | - <button class="blue-border-btn small-btn" @click="openModal()">비밀번호 변경</button> | |
163 | - <button class="blue-btn small-btn" @click="updateMember()">수정</button> | |
164 | - <button class="red-border-btn small-btn" @click="insertForm()">취소</button> | |
165 | - </template> | |
166 | - <template v-else> | |
167 | - <button class="blue-btn small-btn" @click="memberInsert()">등록</button> | |
168 | - <button class="darkg-border-btn small-btn" @click="resetForm()">초기화</button> | |
169 | - </template> | |
170 | - </div> | |
171 | - </div> | |
172 | - </div> | |
173 | - </div> | |
174 | - </div> | |
175 | - </div> | |
176 | - <!-- 비밀번호 변경 모달 --> | |
177 | - <div v-show="modalOpen" class="modal-wrapper"> | |
178 | - <div class="modal-container small-modal"> | |
179 | - <div class="modal-title text-ct"> | |
180 | - <h2>비밀번호 변경</h2> | |
181 | - </div> | |
182 | - <div class="modal-content-monthly"> | |
183 | - <div class="table-zone"> | |
184 | - <table class="form-table2"> | |
185 | - <colgroup> | |
186 | - <col style="width: 40%" /> | |
187 | - <col style="width: 60%" /> | |
188 | - </colgroup> | |
189 | - <tbody> | |
190 | - <tr> | |
191 | - <th>새 비밀번호</th> | |
192 | - <td> | |
193 | - <input type="password" id="pwChange" class="full-input" v-model="pwChange" /> | |
194 | - </td> | |
195 | - </tr> | |
196 | - <tr> | |
197 | - <th>새 비밀번호 확인</th> | |
198 | - <td> | |
199 | - <input type="password" id="pwChangeCheck" class="full-input" v-model="pwChangeCheck" /> | |
200 | - </td> | |
201 | - </tr> | |
202 | - </tbody> | |
203 | - </table> | |
204 | - </div> | |
205 | - </div> | |
206 | - <div class="modal-end flex justify-between" style="flex-wrap: nowrap;"> | |
207 | - <button class="blue-btn large-btn" @click="passwordChange()">변경</button> | |
208 | - <button class="gray-btn large-btn" @click="closeModal()">취소</button> | |
209 | - </div> | |
210 | - </div> | |
211 | - </div> | |
212 | -</template> | |
213 | -<script> | |
214 | -import PageNavigation from "../../component/PageNavigation.vue"; | |
215 | -import PaginationButton from "../../component/PaginationButton.vue"; | |
216 | -import SvgIcon from "@jamescoyle/vue-icon"; | |
217 | -import { mdiMagnify } from "@mdi/js"; | |
218 | -import axios from "axios"; | |
219 | -import store from "../AppStore"; | |
220 | - | |
221 | -export default { | |
222 | - data() { | |
223 | - return { | |
224 | - search: this.$getDefaultSerchVO(), | |
225 | - search_data: this.$getDefaultSerchItem(null, "String"), | |
226 | - | |
227 | - searchPath: mdiMagnify, | |
228 | - inputValue: null, | |
229 | - | |
230 | - memberData: { | |
231 | - userId: null, | |
232 | - userPassword: null, | |
233 | - userNm: null, | |
234 | - deptNm: null, | |
235 | - userEmail: null, | |
236 | - author: null, | |
237 | - dept_code: null, | |
238 | - lockAt: null, | |
239 | - }, | |
240 | - userId: null, | |
241 | - authList: null, | |
242 | - author: null, | |
243 | - dept_code: null, | |
244 | - | |
245 | - memberList: [], | |
246 | - passwordConfirm: null, | |
247 | - changePwConfirm: null, | |
248 | - changPw: null, | |
249 | - departmentList: [], | |
250 | - authorList: [], | |
251 | - isDuplicateChecked: false, | |
252 | - emailDuplicateChecked: false, | |
253 | - memberIdx: 0, | |
254 | - selectedMembers: [], | |
255 | - checkAll: false, | |
256 | - //페이지 당 보여줄 수 | |
257 | - selectedPerPage: "10", | |
258 | - //비밀번호 변경 모달창 | |
259 | - modalOpen: false, | |
260 | - pwChange: null, | |
261 | - pwChangeCheck: null, | |
262 | - changeEmail: null, | |
263 | - | |
264 | - //부서 | |
265 | - dept_search_data: this.$getDefaultSerchItem(null, "String"), | |
266 | - deptSearch: this.$getDefaultSerchVO(), | |
267 | - }; | |
268 | - }, | |
269 | - methods: { | |
270 | - searchInit: function () { | |
271 | - this.search.searchObjectList.push(this.search_data); | |
272 | - }, | |
273 | - | |
274 | - deptSearchInit: function () { | |
275 | - this.deptSearch.searchObjectList.push(this.dept_search_data); | |
276 | - }, | |
277 | - | |
278 | - insertForm: function () { | |
279 | - this.dataLoaded = false; | |
280 | - this.resetForm(); | |
281 | - }, | |
282 | - | |
283 | - toggleLockAtStatus() { | |
284 | - this.memberData.lockAt = !this.memberData.lockAt; | |
285 | - }, | |
286 | - | |
287 | - //사용자 등록 | |
288 | - memberInsert: function () { | |
289 | - const vm = this; | |
290 | - | |
291 | - if (!vm.memberInsertValidation()) { | |
292 | - return; | |
293 | - } | |
294 | - | |
295 | - axios({ | |
296 | - url: "/member", | |
297 | - method: "post", | |
298 | - headers: { | |
299 | - "Content-Type": "application/json; charset=UTF-8", | |
300 | - }, | |
301 | - data: vm.memberData, | |
302 | - }) | |
303 | - .then(function (response) { | |
304 | - if (response.data.checkMessage.status === 200) { | |
305 | - vm.$showAlert("사용자 등록", "사용자 등록이 완료되었습니다."); | |
306 | - vm.fetchMemberList(); | |
307 | - vm.resetData(); | |
308 | - } else { | |
309 | - vm.$showAlert("사용자 등록", response.data.checkMessage.message); | |
310 | - } | |
311 | - }) | |
312 | - .catch(function (error) { | |
313 | - vm.$showAlert( | |
314 | - "사용자 등록", | |
315 | - "사용자 등록에 실패했습니다. 다시 시도해주세요." | |
316 | - ); | |
317 | - }); | |
318 | - }, | |
319 | - | |
320 | - //검색기준 유효성 검사 | |
321 | - searchUser: function () { | |
322 | - if (!this.search_data.key) { | |
323 | - this.$showAlert("회원 검색", "검색 기준을 선택하세요."); | |
324 | - return; | |
325 | - } | |
326 | - this.fetchMemberList(); | |
327 | - }, | |
328 | - | |
329 | - //사용자 목록 조회 | |
330 | - fetchMemberList() { | |
331 | - const vm = this; | |
332 | - axios({ | |
333 | - url: "/member/list", | |
334 | - method: "post", | |
335 | - data: vm.search, | |
336 | - }) | |
337 | - .then(function (response) { | |
338 | - if (response.data) { | |
339 | - vm.memberList = response.data.resultData.selectMemberList; | |
340 | - vm.search.totalRows = response.data.resultData.totalRow; | |
341 | - vm.memberIdx = | |
342 | - vm.search.totalRows - | |
343 | - (vm.search.currentPage - 1) * vm.search.perPage; | |
344 | - } else { | |
345 | - this.$showAlert( | |
346 | - "에러 발생", | |
347 | - "에러가 발생했습니다. 관리자에게 문의해 주세요." | |
348 | - ); | |
349 | - } | |
350 | - }) | |
351 | - .catch(function (error) { | |
352 | - vm.$showAlert( | |
353 | - "회원 목록", | |
354 | - "목록 불러오기 오류, 관리자에게 문의바랍니다." | |
355 | - ); | |
356 | - }); | |
357 | - }, | |
358 | - | |
359 | - //사용자 정보 변경 | |
360 | - updateMember: async function () { | |
361 | - const vm = this; | |
362 | - | |
363 | - if ( | |
364 | - JSON.stringify(vm.memberData) === | |
365 | - JSON.stringify(vm.originalmemberData) && | |
366 | - (vm.changPw === null || vm.changPw === "") | |
367 | - ) { | |
368 | - vm.$showAlert("사용자 수정", "수정된 정보가 없습니다."); | |
369 | - return; | |
370 | - } | |
371 | - | |
372 | - if (!vm.updateMemberInfoValidation()) return; | |
373 | - | |
374 | - axios | |
375 | - .put("/member", vm.memberData) | |
376 | - .then((response) => { | |
377 | - if (response.data.checkMessage.status === 200) { | |
378 | - vm.$showAlert("사용자 수정", "사용자 정보가 수정되었습니다."); | |
379 | - vm.changPw = null; | |
380 | - vm.changePwConfirm = null; | |
381 | - vm.resetData(); | |
382 | - vm.fetchMemberList(); | |
383 | - } else { | |
384 | - vm.$showAlert("사용자 수정", response.data.checkMessage.message); | |
385 | - } | |
386 | - }) | |
387 | - .catch((error) => { | |
388 | - // vm.$showAlert('사용자 수정', '수정 오류, 관리자에게 문의해주세요.'); | |
389 | - }); | |
390 | - }, | |
391 | - | |
392 | - //사용자 정보 변경용 유효성 검사 | |
393 | - updateMemberInfoValidation: function () { | |
394 | - const vm = this; | |
395 | - | |
396 | - //1.사용자 이름 유효성 검사 | |
397 | - let validateName = /^[가-힣A-Za-z\s]+$/; | |
398 | - if (!validateName.test(vm.memberData.userNm)) { | |
399 | - vm.$showAlert( | |
400 | - "사용자 수정", | |
401 | - "이름에 숫자와 특수문자를 입력할 수 없습니다." | |
402 | - ); | |
403 | - return false; | |
404 | - } | |
405 | - | |
406 | - //2.이메일 null 검사 | |
407 | - if (!vm.memberData.userEmail) { | |
408 | - vm.$showAlert("사용자 수정", "이메일을 입력하세요."); | |
409 | - document.getElementById("email").focus(); | |
410 | - return false; | |
411 | - } | |
412 | - //3.이메일 유효성 검사 | |
413 | - if (!vm.$email(vm.memberData.userEmail)) { | |
414 | - vm.$showAlert("사용자 수정", "이메일 형식이 올바르지 않습니다."); | |
415 | - document.getElementById("email").focus(); | |
416 | - return false; | |
417 | - } | |
418 | - //4.이메일 중복 검사 여부 체크 | |
419 | - //이메일을 안바꾼 경우(전처리) | |
420 | - if ( | |
421 | - vm.dataLoaded && | |
422 | - vm.originalmemberData.userEmail === vm.memberData.userEmail | |
423 | - ) { | |
424 | - vm.emailDuplicateChecked = true; | |
425 | - } | |
426 | - if (!vm.emailDuplicateChecked) { | |
427 | - vm.$showAlert("사용자 수정", "이메일 중복확인 후 등록해주세요."); | |
428 | - return false; | |
429 | - } | |
430 | - | |
431 | - return true; | |
432 | - }, | |
433 | - | |
434 | - getAuthorList() { | |
435 | - const vm = this; | |
436 | - axios({ | |
437 | - url: "/member/getAuthorInfo", | |
438 | - method: "get", | |
439 | - }) | |
440 | - .then(function (response) { | |
441 | - vm.authorList = response.data.resultData.getAuthorInfo; | |
442 | - }) | |
443 | - .catch(function (error) { | |
444 | - this.$showAlert( | |
445 | - "에러 발생", | |
446 | - "에러가 발생했습니다. 관리자에게 문의해 주세요." | |
447 | - ); | |
448 | - }); | |
449 | - }, | |
450 | - | |
451 | - //ID중복 검사 | |
452 | - checkDuplicate() { | |
453 | - const vm = this; | |
454 | - | |
455 | - if (!vm.$idCheck(vm.memberData.userId)) { | |
456 | - vm.$showAlert( | |
457 | - "사용자 등록", | |
458 | - "아이디 형식이 올바르지 않습니다. (5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용가능)" | |
459 | - ); | |
460 | - document.getElementById("userId").focus(); | |
461 | - return false; | |
462 | - } | |
463 | - | |
464 | - axios({ | |
465 | - url: "/member/" + vm.memberData.userId, | |
466 | - method: "get", | |
467 | - headers: { | |
468 | - "Content-Type": "application/json; charset=UTF-8", | |
469 | - }, | |
470 | - }) | |
471 | - .then((response) => { | |
472 | - if (response.data.resultData.checkDuplicateUserId) { | |
473 | - vm.$showAlert("아이디 중복확인", "사용중인 아이디입니다."); | |
474 | - vm.isDuplicateChecked = false; | |
475 | - } else { | |
476 | - vm.$showAlert("아이디 중복확인", "사용할 수 있는 아이디입니다."); | |
477 | - vm.isDuplicateChecked = true; | |
478 | - } | |
479 | - }) | |
480 | - .catch((error) => { | |
481 | - this.$showAlert( | |
482 | - "에러 발생", | |
483 | - "에러가 발생했습니다. 관리자에게 문의해 주세요." | |
484 | - ); | |
485 | - }); | |
486 | - }, | |
487 | - | |
488 | - //사용자 선택 삭제 | |
489 | - async deleteSelectedMembers() { | |
490 | - const vm = this; | |
491 | - | |
492 | - if (vm.selectedMembers.length === 0) { | |
493 | - vm.$showAlert("사용자 삭제", "선택한 사용자가 없습니다."); | |
494 | - return; | |
495 | - } | |
496 | - | |
497 | - if ( | |
498 | - !(await vm.$showConfirm( | |
499 | - "사용자삭제", | |
500 | - "선택한 사용자를 삭제하시겠습니까?" | |
501 | - )) | |
502 | - ) { | |
503 | - return; | |
504 | - } | |
505 | - | |
506 | - axios({ | |
507 | - url: "/member", | |
508 | - method: "delete", | |
509 | - headers: { | |
510 | - "Content-Type": "application/json", | |
511 | - }, | |
512 | - data: vm.selectedMembers, | |
513 | - }) | |
514 | - .then(function (response) { | |
515 | - if (response.data.checkMessage.status === 200) { | |
516 | - vm.$showAlert("사용자 삭제", "선택한 사용자가 삭제되었습니다."); | |
517 | - vm.checkAll = false; | |
518 | - vm.selectedMembers = []; | |
519 | - vm.fetchMemberList(); | |
520 | - } else { | |
521 | - // vm.$showAlert('사용자 삭제','선택한 사용자 삭제에 실패하였습니다. 다시 시도해주세요.') | |
522 | - vm.$showAlert("사용자 삭제", response.data.checkMessage.message); | |
523 | - } | |
524 | - }) | |
525 | - .catch(function (error) { | |
526 | - vm.$showAlert("사용자 삭제", "삭제오류, 관리자에게 문의바랍니다."); | |
527 | - }); | |
528 | - }, | |
529 | - | |
530 | - //사용자 등록 유효성 검사 | |
531 | - memberInsertValidation: function () { | |
532 | - const vm = this; | |
533 | - //1.ID null 검사 | |
534 | - if (vm.$isEmpty(vm.memberData.userId)) { | |
535 | - vm.$showAlert("사용자 등록", "아이디(ID)를 입력해주세요."); | |
536 | - document.getElementById("userId").focus(); | |
537 | - return false; | |
538 | - } | |
539 | - //2. ID 중복 검사 | |
540 | - if (!vm.isDuplicateChecked) { | |
541 | - vm.$showAlert("사용자 등록", "아이디 중복확인 후 등록해주세요."); | |
542 | - return false; | |
543 | - } | |
544 | - //3. 이름 null 검사 | |
545 | - if (vm.$isEmpty(vm.memberData.userNm)) { | |
546 | - vm.$showAlert("사용자 등록", "이름을 입력해주세요."); | |
547 | - document.getElementById("userNm").focus(); | |
548 | - return false; | |
549 | - } | |
550 | - //4. 이름 유효성 검사 | |
551 | - let validateName = /^[가-힣A-Za-z\s]+$/; | |
552 | - if (!validateName.test(vm.memberData.userNm)) { | |
553 | - vm.$showAlert( | |
554 | - "사용자 등록", | |
555 | - "이름에 숫자와 특수문자를 입력할 수 없습니다." | |
556 | - ); | |
557 | - document.getElementById("userNm").focus(); | |
558 | - return false; | |
559 | - } | |
560 | - //5. 비밀번호 null 검사 | |
561 | - if (vm.$isEmpty(vm.memberData.userPassword)) { | |
562 | - vm.$showAlert("사용자 등록", "비밀번호를 입력해주세요."); | |
563 | - document.getElementById("userPassword").focus(); | |
564 | - return false; | |
565 | - } | |
566 | - | |
567 | - //6. 비밀번호 유효성 검사 | |
568 | - if (!vm.$pwCheck(vm.memberData.userPassword)) { | |
569 | - vm.$showAlert( | |
570 | - "사용자 등록", | |
571 | - "비밀번호 형식이 올바르지 않습니다. (8~16자의 영문 대문자, 소문자, 숫자, 특수문자 사용가능)" | |
572 | - ); | |
573 | - document.getElementById("userPassword").focus(); | |
574 | - return false; | |
575 | - } | |
576 | - | |
577 | - //7. 비밀번호와 비밀번호 확일 일치여부 검사 | |
578 | - if (vm.memberData.userPassword !== vm.passwordConfirm) { | |
579 | - vm.$showAlert( | |
580 | - "사용자 등록", | |
581 | - "비밀번호가 일치하지 않습니다. 다시 입력해주세요." | |
582 | - ); | |
583 | - document.getElementById("passwordConfirm").focus(); | |
584 | - return false; | |
585 | - } | |
586 | - //8.이메일 null 검사 | |
587 | - if (!vm.memberData.userEmail) { | |
588 | - vm.$showAlert("사용자 등록", "이메일을 입력하세요."); | |
589 | - document.getElementById("email").focus(); | |
590 | - return false; | |
591 | - } | |
592 | - //9.이메일 유효성 검사 | |
593 | - if (!vm.$email(vm.memberData.userEmail)) { | |
594 | - vm.$showAlert("사용자 등록", "이메일 형식이 올바르지 않습니다."); | |
595 | - document.getElementById("email").focus(); | |
596 | - return false; | |
597 | - } | |
598 | - //10.이메일 중복검사 여부 확인 | |
599 | - if (!vm.emailDuplicateChecked) { | |
600 | - vm.$showAlert("사용자 등록", "이메일 중복확인 후 등록해주세요."); | |
601 | - document.getElementById("email").focus(); | |
602 | - return false; | |
603 | - } | |
604 | - //11. 권한 null 검사 | |
605 | - if (vm.$isEmpty(vm.memberData.author)) { | |
606 | - vm.$showAlert("사용자 등록", "권한을 선택해주세요."); | |
607 | - document.getElementById("author").focus(); | |
608 | - return false; | |
609 | - } | |
610 | - | |
611 | - return true; | |
612 | - }, | |
613 | - | |
614 | - resetData() { | |
615 | - this.memberData = {}; // 데이터를 초기화합니다. | |
616 | - this.dataLoaded = false; // 데이터 로드 상태를 초기화합니다. | |
617 | - this.passwordConfirm = null; | |
618 | - this.changePwConfirm = null; | |
619 | - }, | |
620 | - | |
621 | - //사용자 선택 삭제용 선택 기능 | |
622 | - check: function (member) { | |
623 | - this.selectedMembers.push(member.userId); | |
624 | - }, | |
625 | - | |
626 | - //사용자 선택 삭제용 전체 선택 기능 | |
627 | - memberCheckAll() { | |
628 | - this.checkAll = !this.checkAll; | |
629 | - | |
630 | - if (this.checkAll) { | |
631 | - this.memberList.forEach((member) => { | |
632 | - this.selectedMembers.push(member.userId); | |
633 | - }); | |
634 | - } else { | |
635 | - this.selectedMembers = []; | |
636 | - } | |
637 | - }, | |
638 | - | |
639 | - resetForm() { | |
640 | - this.memberData = { | |
641 | - userId: null, | |
642 | - userPassword: null, | |
643 | - userNm: null, | |
644 | - deptNm: null, | |
645 | - userEmail: null, | |
646 | - author: null, | |
647 | - }; | |
648 | - this.passwordConfirm = null; | |
649 | - this.changePwConfirm = null; | |
650 | - }, | |
651 | - | |
652 | - loadHostData(member) { | |
653 | - this.memberData = Object.assign({}, member); // 클릭한 호스트의 데이터를 복사하여 저장합니다. | |
654 | - this.originalmemberData = Object.assign({}, member); | |
655 | - this.changeAuthor(); | |
656 | - this.dataLoaded = true; // 데이터가 로드되었음을 표시합니다. | |
657 | - }, | |
658 | - | |
659 | - //10개보기, 20개보기 | |
660 | - changePerPage: function () { | |
661 | - this.search.perPage = this.selectedPerPage; | |
662 | - this.fetchMemberList(); | |
663 | - }, | |
664 | - | |
665 | - closeModal: function () { | |
666 | - this.modalOpen = false; | |
667 | - }, | |
668 | - //비밀번호 변경 모달 열기 | |
669 | - openModal: function () { | |
670 | - this.modalOpen = true; | |
671 | - this.pwChange = null; | |
672 | - this.pwChangeCheck = null; | |
673 | - }, | |
674 | - | |
675 | - //비밀번호 변경 유효성 검사 | |
676 | - passwordChangeValidation: function () { | |
677 | - const vm = this; | |
678 | - //1.변경 비밀번호의 null검사 | |
679 | - if (vm.$isEmpty(vm.pwChange)) { | |
680 | - vm.$showAlert("비밀번호 변경", "변경할 비밀번호를 입력하세요."); | |
681 | - document.getElementById("pwChange").focus(); | |
682 | - return false; | |
683 | - } | |
684 | - //2.변경 비밀번호의 형식검사 | |
685 | - if (!vm.$pwCheck(vm.pwChange)) { | |
686 | - vm.$showAlert("비밀번호 변경", "비밀번호 형식이 올바르지 않습니다."); | |
687 | - document.getElementById("pwChange").focus(); | |
688 | - return false; | |
689 | - } | |
690 | - //3.변경 비밀번호와 비밀번호 확인의 일치여부 확인 | |
691 | - if (vm.pwChange !== vm.pwChangeCheck) { | |
692 | - vm.$showAlert("비밀번호 변경", "비밀번호 형식이 올바르지 않습니다."); | |
693 | - document.getElementById("pwChangeCheck").focus(); | |
694 | - return false; | |
695 | - } | |
696 | - | |
697 | - return true; | |
698 | - }, | |
699 | - //유저 비밀번호 변경 | |
700 | - passwordChange: function () { | |
701 | - const vm = this; | |
702 | - if (!vm.passwordChangeValidation()) { | |
703 | - return; | |
704 | - } | |
705 | - | |
706 | - axios({ | |
707 | - url: "/member", | |
708 | - method: "patch", | |
709 | - headers: { | |
710 | - "Content-Type": "application/json", | |
711 | - }, | |
712 | - data: { | |
713 | - userId: vm.memberData.userId, | |
714 | - userPassword: vm.pwChange, | |
715 | - }, | |
716 | - }) | |
717 | - .then(function (response) { | |
718 | - if (response.data.resultData.result) { | |
719 | - vm.$showAlert("비밀번호 변경", "비밀번호 변경에 성공하였습니다."); | |
720 | - vm.modalOpen = false; | |
721 | - } else { | |
722 | - vm.$showAlert( | |
723 | - "비밀번호 변경", | |
724 | - "비밀번호 변경에 실패하였습니다. 다시 시도해주세요." | |
725 | - ); | |
726 | - } | |
727 | - }) | |
728 | - .catch(function (error) { | |
729 | - vm.$showAlert( | |
730 | - "비밀번호 변경", | |
731 | - "비밀번호 변경에 실패하였습니다. 다시 시도해주세요." | |
732 | - ); | |
733 | - }); | |
734 | - }, | |
735 | - | |
736 | - //이메일 중복검사 | |
737 | - mailDuplicateCheck: function () { | |
738 | - const vm = this; | |
739 | - if (!vm.mailValidation()) { | |
740 | - return; | |
741 | - } | |
742 | - | |
743 | - axios({ | |
744 | - url: "/member/email", | |
745 | - method: "post", | |
746 | - headers: { | |
747 | - "Content-Type": "application/json;", | |
748 | - }, | |
749 | - data: { | |
750 | - userEmail: vm.memberData.userEmail, | |
751 | - }, | |
752 | - }) | |
753 | - .then((response) => { | |
754 | - if (response.data.resultData.result) { | |
755 | - vm.$showAlert("이메일 중복확인", "사용중인 이메일입니다."); | |
756 | - vm.emailDuplicateChecked = false; | |
757 | - } else { | |
758 | - vm.$showAlert("이메일 중복확인", "사용할 수 있는 이메일입니다."); | |
759 | - vm.emailDuplicateChecked = true; | |
760 | - } | |
761 | - }) | |
762 | - .catch((error) => { | |
763 | - this.$showAlert( | |
764 | - "에러 발생", | |
765 | - "에러가 발생했습니다. 관리자에게 문의해 주세요." | |
766 | - ); | |
767 | - }); | |
768 | - }, | |
769 | - | |
770 | - //이메일 유효성 검사 | |
771 | - mailValidation: function () { | |
772 | - const vm = this; | |
773 | - //1.null검사 | |
774 | - if (!vm.memberData.userEmail) { | |
775 | - vm.$showAlert("사용자 등록", "이메일을 입력하세요."); | |
776 | - document.getElementById("email").focus(); | |
777 | - return false; | |
778 | - } | |
779 | - //2.정규식 검사 | |
780 | - if (!vm.$email(vm.memberData.userEmail)) { | |
781 | - vm.$showAlert("사용자 등록", "이메일 형식이 올바르지 않습니다."); | |
782 | - document.getElementById("email").focus(); | |
783 | - return false; | |
784 | - } | |
785 | - | |
786 | - return true; | |
787 | - }, | |
788 | - | |
789 | - | |
790 | - // 권한 변경 시 부서 선택 | |
791 | - changeAuthor() { | |
792 | - const vm = this; | |
793 | - | |
794 | - this.deptSearch.searchObjectList[0].key = 'role_chk'; | |
795 | - if (vm.memberData.author == 'ROLE_ADMIN') { | |
796 | - this.deptSearch.searchObjectList[0].value = 1; | |
797 | - } else { | |
798 | - this.deptSearch.searchObjectList[0].value = 0; | |
799 | - } | |
800 | - | |
801 | - axios({ | |
802 | - url: "/department/departments", | |
803 | - method: "post", | |
804 | - data: vm.deptSearch, | |
805 | - }) | |
806 | - .then(function (response) { | |
807 | - vm.departmentList = response.data.resultData.selectDeptList; | |
808 | - vm.memberData.deptNm = vm.departmentList[0].dept_nm; | |
809 | - vm.memberData.dept_code = vm.departmentList[0].dept_code; | |
810 | - }) | |
811 | - .catch(function (error) { | |
812 | - vm.$showAlert( | |
813 | - "부서 조회", | |
814 | - "목록 불러오기 오류, 관리자에게 문의바랍니다." | |
815 | - ); | |
816 | - }); | |
817 | - } | |
818 | - }, | |
819 | - watch: { | |
820 | - //아이디 값 변경 시 중복체크여부 false로 변경 | |
821 | - "memberData.userId": function (newVal, oldVal) { | |
822 | - this.isDuplicateChecked = false; | |
823 | - }, | |
824 | - //이메일 값 변경 시 중복체크여부 false로 변경 | |
825 | - "memberData.userEmail": function (newVal, oldVal) { | |
826 | - this.emailDuplicateChecked = false; | |
827 | - }, | |
828 | - }, | |
829 | - components: { | |
830 | - PageNavigation: PageNavigation, | |
831 | - PaginationButton: PaginationButton, | |
832 | - SvgIcon: SvgIcon, | |
833 | - }, | |
834 | - mounted() { | |
835 | - this.fetchMemberList(); | |
836 | - this.deptSearchInit(); | |
837 | - this.getAuthorList(); | |
838 | - this.searchInit(); | |
839 | - this.userId = store.state.loginUser.user_id; | |
840 | - this.authList = store.state.loginUser.user_auth; | |
841 | - this.author = store.state.loginUser.user_auth[0]; | |
842 | - this.dept_code = store.state.loginUser.dept_code; | |
843 | - }, | |
844 | -}; | |
845 | -</script>(파일 끝에 줄바꿈 문자 없음) |
--- package-lock.json
+++ package-lock.json
... | ... | @@ -1,5 +1,5 @@ |
1 | 1 |
{ |
2 |
- "name": "Taken-BI-Manager", |
|
2 |
+ "name": "Taken_BI_Manager_renewal", |
|
3 | 3 |
"lockfileVersion": 3, |
4 | 4 |
"requires": true, |
5 | 5 |
"packages": { |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?