Skip to content

Commit aa1e0d6

Browse files
authored
Merge pull request #93 from TaskFlow-CLAP/CLAP-203
CLAP-203 관리자 목록 조회 관련 API 연결
2 parents bb567c2 + ba13a75 commit aa1e0d6

26 files changed

+291
-705
lines changed

src/components/api-logs/ApiLogsFilterBar.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
<template>
2-
<div class="flex gap-4">
2+
<div class="flex gap-4 z-30">
33
<FilterDropdown
44
title="조회 기간"
55
:option-list="TERM_LIST"
66
:value="String(store.params.term)"
77
@update:value="onParamsChange.onTermChange" />
8-
<FilterDropdown
8+
<FilterDropdownMulti
99
title="구분"
10-
:option-list="LOGIN_LOGS_DIVISION_LIST"
11-
:value="store.params.division"
12-
@update:value="onParamsChange.onDivisionChange" />
10+
:option-list="API_LOGS_DIVISION_LIST"
11+
:value="store.params.logStatus"
12+
@update:value="onParamsChange.onLogStatusChange" />
1313
<FilterInput
1414
title="아이디"
1515
width="full"
1616
:value="store.params.nickName"
1717
@update:value="onParamsChange.onNickNameChange" />
18-
<FilterIpAddress @update:value="onParamsChange.onIpAddressChange" />
18+
<FilterIpAddress @update:value="onParamsChange.onClientIpChange" />
1919
<FilterDropdown
2020
title="페이지 당 개수"
2121
:option-list="PAGE_SIZE_LIST"
@@ -29,9 +29,10 @@ import FilterDropdown from '../filters/FilterDropdown.vue'
2929
import FilterInput from '../filters/FilterInput.vue'
3030
import { useLogsParamsStore } from '@/stores/params'
3131
import { PAGE_SIZE_LIST, TERM_LIST } from '@/constants/common'
32-
import { LOGIN_LOGS_DIVISION_LIST } from '@/constants/admin'
32+
import { API_LOGS_DIVISION_LIST } from '@/constants/admin'
3333
import { useLogsParamsChange } from '../hooks/useLogsParamsChange'
3434
import FilterIpAddress from '../filters/FilterIpAddress.vue'
35+
import FilterDropdownMulti from '../filters/FilterDropdownMulti.vue'
3536
3637
const store = useLogsParamsStore()
3738
store.$reset()

src/components/api-logs/ApiLogsList.vue

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66

77
<template #listCards>
88
<ApiLogsListCard
9-
v-for="info in DUMMY_API_LOGS_LIST_DATA"
9+
v-for="info in data?.content"
1010
:key="info.logId"
1111
:info="info" />
1212
</template>
1313

1414
<template #pagination>
1515
<ListPagination
16-
:page-number="params.page"
17-
:total-page="DUMMY_TOTAL_PAGE"
16+
:page-number="params.page + 1"
17+
:total-page="totalPage || 0"
1818
@update:page-number="onPageChange" />
1919
</template>
2020
</ListContainer>
@@ -23,16 +23,35 @@
2323
<script setup lang="ts">
2424
import ListPagination from '../lists/ListPagination.vue'
2525
import ListContainer from '../lists/ListContainer.vue'
26-
import { useRequestParamsStore } from '@/stores/params'
26+
import { useLogsParamsStore } from '@/stores/params'
2727
import ApiLogsListBar from './ApiLogsListBar.vue'
2828
import ApiLogsListCard from './ApiLogsListCard.vue'
29-
import { DUMMY_API_LOGS_LIST_DATA } from '@/datas/dummy'
29+
import { axiosInstance } from '@/utils/axios'
30+
import { useQuery } from '@tanstack/vue-query'
31+
import type { ApiLogsResponse } from '@/types/admin'
32+
import { computed } from 'vue'
3033
31-
const { params } = useRequestParamsStore()
32-
const DUMMY_TOTAL_PAGE = 18
34+
const { params } = useLogsParamsStore()
3335
const onPageChange = (value: number) => {
3436
params.page = value
3537
}
3638
37-
// Data Handling
39+
const fetchApiLogsList = async () => {
40+
const response = await axiosInstance.get('/api/managements/logs/general', {
41+
params: {
42+
...params,
43+
logStatus: params.logStatus.join(',')
44+
}
45+
})
46+
return response.data
47+
}
48+
49+
const { data } = useQuery<ApiLogsResponse>({
50+
queryKey: ['apiLogs', params],
51+
queryFn: fetchApiLogsList
52+
})
53+
54+
const totalPage = computed(() => {
55+
return data.value?.totalPages
56+
})
3857
</script>

src/components/api-logs/ApiLogsListBar.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
:content="tab.content"
77
:width="tab.width"
88
:sortBy="tab.sortBy"
9-
:current-order-request="params.orderRequest"
9+
:current-order-request="orderRequest"
1010
@toggle-sort-by="toggleSortBy" />
1111
</div>
1212
</template>
@@ -16,8 +16,13 @@ import { useLogsParamsStore } from '@/stores/params'
1616
import ListBarTab from '../lists/ListBarTab.vue'
1717
import { LOGS_LIST_BAR_TAB } from '@/constants/admin'
1818
import { useLogsParamsChange } from '../hooks/useLogsParamsChange'
19+
import { computed } from 'vue'
1920
2021
const { params } = useLogsParamsStore()
22+
const orderRequest = computed(() => ({
23+
sortBy: 'REQUESTED_AT',
24+
sortDirection: params.sortDirection
25+
}))
2126
2227
const { toggleSortBy } = useLogsParamsChange()
2328
</script>

src/components/api-logs/ApiLogsListCard.vue

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,22 @@
1515
<script setup lang="ts">
1616
import type { ListCardProps } from '@/types/common'
1717
import ListCardTab from '../lists/ListCardTab.vue'
18-
import type { LogsListData } from '@/types/admin'
18+
import type { ApiLogsListData } from '@/types/admin'
19+
import { formatDate } from '@/utils/date'
20+
import { API_LOGS_DIVISION_LIST } from '@/constants/admin'
1921
20-
const { info } = defineProps<{ info: LogsListData }>()
22+
const { info } = defineProps<{ info: ApiLogsListData }>()
2123
const myRequestTabList: ListCardProps[] = [
22-
{ content: info.division, width: 80, isTextXs: true, isTextBody: true },
23-
{ content: info.createdAt, width: 180, isTextXs: true },
24+
{
25+
content: API_LOGS_DIVISION_LIST.find(el => el.value === info.logStatus)?.content,
26+
width: 80,
27+
isTextXs: true,
28+
isTextBody: true
29+
},
30+
{ content: formatDate(info.requestAt), width: 180, isTextXs: true },
2431
{ content: info.nickName, width: 80 },
25-
{ content: info.ipAddress, width: 120, isTextXs: true },
26-
{ content: String(info.status), width: 40, isTextXs: true, isStatusCode: true },
27-
{ content: info.result }
32+
{ content: info.clientIp, width: 120, isTextXs: true },
33+
{ content: String(info.statusCode), width: 40, isTextXs: true, isStatusCode: true },
34+
{ content: '' }
2835
]
2936
</script>

src/components/hooks/useLogsParamsChange.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,25 @@ import { useLogsParamsStore } from '@/stores/params'
33
export const useLogsParamsChange = () => {
44
const { params } = useLogsParamsStore()
55

6+
const onArrayChange = <Value extends number | string>(array: Value[], value: Value) => {
7+
return array.includes(value) ? array.filter(el => el !== value) : [...array, value]
8+
}
9+
610
const onTermChange = (value: string) => {
711
if (value === '') {
812
params.term = ''
913
} else {
1014
params.term = Number(value)
1115
}
1216
}
13-
const onDivisionChange = (value: string) => {
14-
params.division = value
17+
const onLogStatusChange = (value: string) => {
18+
params.logStatus = onArrayChange(params.logStatus!, value)
1519
}
1620
const onNickNameChange = (value: string) => {
1721
params.nickName = value
1822
}
19-
const onIpAddressChange = (value: string) => {
20-
params.ipAddress = value
23+
const onClientIpChange = (value: string) => {
24+
params.clientIp = value
2125
}
2226
const onPageSizeChange = (value: string) => {
2327
params.pageSize = Number(value)
@@ -29,9 +33,9 @@ export const useLogsParamsChange = () => {
2933

3034
return {
3135
onTermChange,
32-
onDivisionChange,
36+
onLogStatusChange,
3337
onNickNameChange,
34-
onIpAddressChange,
38+
onClientIpChange,
3539
onPageSizeChange,
3640
toggleSortBy
3741
}

src/components/login-logs/LoginLogsFilterBar.vue

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
<template>
2-
<div class="flex gap-4">
2+
<div class="flex gap-4 z-30">
33
<FilterDropdown
44
title="조회 기간"
55
:option-list="TERM_LIST"
66
:value="String(store.params.term)"
77
@update:value="onParamsChange.onTermChange" />
8-
<FilterDropdown
8+
<FilterDropdownMulti
99
title="구분"
1010
:option-list="LOGIN_LOGS_DIVISION_LIST"
11-
:value="store.params.division"
12-
@update:value="onParamsChange.onDivisionChange" />
11+
:value="store.params.logStatus"
12+
@update:value="onParamsChange.onLogStatusChange" />
1313
<FilterInput
1414
title="아이디"
1515
width="full"
1616
:value="store.params.nickName"
1717
@update:value="onParamsChange.onNickNameChange" />
18-
<FilterIpAddress @update:value="onParamsChange.onIpAddressChange" />
18+
<FilterIpAddress @update:value="onParamsChange.onClientIpChange" />
1919
<FilterDropdown
2020
title="페이지 당 개수"
2121
:option-list="PAGE_SIZE_LIST"
@@ -29,9 +29,10 @@ import FilterDropdown from '../filters/FilterDropdown.vue'
2929
import FilterInput from '../filters/FilterInput.vue'
3030
import { useLogsParamsStore } from '@/stores/params'
3131
import { PAGE_SIZE_LIST, TERM_LIST } from '@/constants/common'
32-
import { LOGIN_LOGS_DIVISION_LIST } from '@/constants/admin'
3332
import { useLogsParamsChange } from '../hooks/useLogsParamsChange'
3433
import FilterIpAddress from '../filters/FilterIpAddress.vue'
34+
import FilterDropdownMulti from '../filters/FilterDropdownMulti.vue'
35+
import { LOGIN_LOGS_DIVISION_LIST } from '@/constants/admin'
3536
3637
const store = useLogsParamsStore()
3738
store.$reset()

src/components/login-logs/LoginLogsList.vue

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66

77
<template #listCards>
88
<LoginLogsListCard
9-
v-for="info in DUMMY_LOGIN_LOGS_LIST_DATA"
9+
v-for="info in data?.content"
1010
:key="info.logId"
1111
:info="info" />
12+
<NoContent v-if="data?.content.length === 0" />
1213
</template>
1314

1415
<template #pagination>
1516
<ListPagination
16-
:page-number="params.page"
17-
:total-page="DUMMY_TOTAL_PAGE"
17+
:page-number="params.page + 1"
18+
:total-page="totalPage || 0"
1819
@update:page-number="onPageChange" />
1920
</template>
2021
</ListContainer>
@@ -23,16 +24,36 @@
2324
<script setup lang="ts">
2425
import ListPagination from '../lists/ListPagination.vue'
2526
import ListContainer from '../lists/ListContainer.vue'
26-
import { DUMMY_LOGIN_LOGS_LIST_DATA } from '@/datas/dummy'
27-
import { useRequestParamsStore } from '@/stores/params'
27+
import { useLogsParamsStore } from '@/stores/params'
2828
import LoginLogsListBar from './LoginLogsListBar.vue'
2929
import LoginLogsListCard from './LoginLogsListCard.vue'
30+
import { axiosInstance } from '@/utils/axios'
31+
import { useQuery } from '@tanstack/vue-query'
32+
import { computed } from 'vue'
33+
import type { LoginLogsResponse } from '@/types/admin'
34+
import NoContent from '../lists/NoContent.vue'
3035
31-
const { params } = useRequestParamsStore()
32-
const DUMMY_TOTAL_PAGE = 18
36+
const { params } = useLogsParamsStore()
3337
const onPageChange = (value: number) => {
3438
params.page = value
3539
}
3640
37-
// Data Handling
41+
const fetchLoginLogsList = async () => {
42+
const response = await axiosInstance.get('/api/managements/logs/login', {
43+
params: {
44+
...params,
45+
logStatus: params.logStatus.join(',')
46+
}
47+
})
48+
return response.data
49+
}
50+
51+
const { data } = useQuery<LoginLogsResponse>({
52+
queryKey: ['loginLogs', params],
53+
queryFn: fetchLoginLogsList
54+
})
55+
56+
const totalPage = computed(() => {
57+
return data.value?.totalPages
58+
})
3859
</script>

src/components/login-logs/LoginLogsListBar.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
:content="tab.content"
77
:width="tab.width"
88
:sortBy="tab.sortBy"
9-
:current-order-request="params.orderRequest"
9+
:current-order-request="orderRequest"
1010
@toggle-sort-by="toggleSortBy" />
1111
</div>
1212
</template>
@@ -16,8 +16,13 @@ import ListBarTab from '../lists/ListBarTab.vue'
1616
import { useLogsParamsStore } from '@/stores/params'
1717
import { LOGS_LIST_BAR_TAB } from '@/constants/admin'
1818
import { useLogsParamsChange } from '../hooks/useLogsParamsChange'
19+
import { computed } from 'vue'
1920
2021
const { params } = useLogsParamsStore()
22+
const orderRequest = computed(() => ({
23+
sortBy: 'REQUESTED_AT',
24+
sortDirection: params.sortDirection
25+
}))
2126
2227
const { toggleSortBy } = useLogsParamsChange()
2328
</script>

src/components/login-logs/LoginLogsListCard.vue

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,31 @@
1515
<script setup lang="ts">
1616
import type { ListCardProps } from '@/types/common'
1717
import ListCardTab from '../lists/ListCardTab.vue'
18-
import type { LogsListData } from '@/types/admin'
18+
import type { LoginLogsListData } from '@/types/admin'
19+
import { formatDate } from '@/utils/date'
1920
20-
const { info } = defineProps<{ info: LogsListData }>()
21+
const logStatus = {
22+
LOGIN: '로그인 시도',
23+
LOGOUT: '로그아웃'
24+
}
25+
26+
const { info } = defineProps<{ info: LoginLogsListData }>()
2127
const myRequestTabList: ListCardProps[] = [
22-
{ content: info.division, width: 80, isTextXs: true, isTextBody: true },
23-
{ content: info.createdAt, width: 180, isTextXs: true },
28+
{
29+
content: logStatus[info.logStatus as keyof typeof logStatus],
30+
width: 80,
31+
isTextXs: true,
32+
isTextBody: true
33+
},
34+
{ content: formatDate(info.requestAt), width: 180, isTextXs: true },
2435
{ content: info.nickName, width: 80 },
25-
{ content: info.ipAddress, width: 120, isTextXs: true },
26-
{ content: String(info.status), width: 40, isTextXs: true, isStatusCode: true },
27-
{ content: info.result }
36+
{ content: info.clientIp, width: 120, isTextXs: true },
37+
{ content: String(info.statusCode), width: 40, isTextXs: true, isStatusCode: true },
38+
{
39+
content:
40+
info.statusCode !== 200 && info.failedAttempts !== 0
41+
? `failedAttempts = ${info.failedAttempts}`
42+
: ''
43+
}
2844
]
2945
</script>

src/components/member-management/MemberManagementFilterBar.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
@update:value="value => (params.nickName = value)" />
1111
<FilterInput
1212
title="부서"
13-
:value="params.department"
14-
@update:value="value => (params.department = value)" />
13+
:value="String(params.departmentName)"
14+
@update:value="value => (params.departmentName = value)" />
1515
<FilterInput
1616
title="이메일"
1717
width="full"

0 commit comments

Comments
 (0)