diff --git a/data/src/main/java/com/kusitms/data/remote/di/AuthTokenInterceptor.kt b/data/src/main/java/com/kusitms/data/remote/di/AuthTokenInterceptor.kt index 5a66828..9b02e47 100644 --- a/data/src/main/java/com/kusitms/data/remote/di/AuthTokenInterceptor.kt +++ b/data/src/main/java/com/kusitms/data/remote/di/AuthTokenInterceptor.kt @@ -23,18 +23,25 @@ class AuthTokenInterceptor @Inject constructor( authDataStore.authToken.first() } ?: "" + val refresh: String? = runBlocking { + authDataStore.refreshToken.first() + }?: "" + // "auth/logout" 엔드포인트 확인 - if (originalRequest.url.encodedPath.endsWith("auth/logout")) { - // logout 엔드포인트의 경우 refreshToken 사용 - requestBuilder.addHeader("Authorization", "${authDataStore.refreshToken}") - } else if(originalRequest.url.encodedPath.endsWith("auth/logout")) - else { - // 다른 엔드포인트의 경우 authToken 사용 + if (!token.isNullOrEmpty()) { requestBuilder.addHeader("Authorization", "$token") } - Log.d("Token is","${authDataStore.authToken}") - Log.d("Token is","${authDataStore.refreshToken}") + // 로그아웃 요청에는 리프레시 토큰도 추가 + if (originalRequest.url.encodedPath.endsWith("v1/auth/logout")) { + val refreshToken: String? = runBlocking { + authDataStore.refreshToken.first() + } + if (!refreshToken.isNullOrEmpty()) { + requestBuilder.addHeader("RefreshToken", "$refresh") + } + } + var request = requestBuilder.build() var response = chain.proceed(request) diff --git a/data/src/main/java/com/kusitms/data/repository/AuthRepositoryImpl.kt b/data/src/main/java/com/kusitms/data/repository/AuthRepositoryImpl.kt index 561afe2..ccbd204 100644 --- a/data/src/main/java/com/kusitms/data/repository/AuthRepositoryImpl.kt +++ b/data/src/main/java/com/kusitms/data/repository/AuthRepositoryImpl.kt @@ -2,6 +2,7 @@ package com.kusitms.data.repository import android.content.Context import android.net.ConnectivityManager +import android.util.Log import com.kusitms.data.local.AuthDataStore import com.kusitms.data.local.DataStoreUtils import com.kusitms.data.remote.api.KusitmsApi @@ -43,7 +44,9 @@ class AuthRepositoryImpl @Inject constructor( override suspend fun logOutMember(): Result { return try { val response = kusitmsApi.logOutMember() + Log.d("response", response.toString()) if (response.result.code == 200) { + Log.d("로그아웃", "성공") authDataStore.clearAllData() Result.success(Unit) } else { diff --git a/domain/src/main/java/com/kusitms/domain/usecase/home/PostAttendCheckUseCase.kt b/domain/src/main/java/com/kusitms/domain/usecase/home/PostAttendCheckUseCase.kt index c2645c8..79c71eb 100644 --- a/domain/src/main/java/com/kusitms/domain/usecase/home/PostAttendCheckUseCase.kt +++ b/domain/src/main/java/com/kusitms/domain/usecase/home/PostAttendCheckUseCase.kt @@ -8,16 +8,10 @@ import javax.inject.Inject class PostAttendCheckUseCase @Inject constructor( private val homeRepository: HomeRepository ) { - operator fun invoke( + suspend operator fun invoke( curriculumId: Int, qrText: String - ): Flow = flow { - homeRepository.postAttendCheck( - curriculumId, qrText - ).onSuccess { - emit(Unit) - }.onFailure { - throw it + ): Result { + return homeRepository.postAttendCheck(curriculumId, qrText) } - } } \ No newline at end of file diff --git a/presentation/src/main/java/com/kusitms/presentation/model/home/attend/AttendViewModel.kt b/presentation/src/main/java/com/kusitms/presentation/model/home/attend/AttendViewModel.kt index 0d3726e..8bb750b 100644 --- a/presentation/src/main/java/com/kusitms/presentation/model/home/attend/AttendViewModel.kt +++ b/presentation/src/main/java/com/kusitms/presentation/model/home/attend/AttendViewModel.kt @@ -17,7 +17,9 @@ import com.kusitms.presentation.R import com.kusitms.presentation.common.ui.theme.KusitmsColorPalette import com.kusitms.presentation.ui.notice.detail.NoticeDetailViewModel import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* +import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import timber.log.Timber import java.text.SimpleDateFormat @@ -37,14 +39,13 @@ class AttendViewModel @Inject constructor( private val getAttendInfoUseCase: GetAttendInfoUseCase, private val getAttendScoreUseCase: GetAttendScoreUseCase, getAttendQrUseCase: GetAttendQrUseCase, - private val getIsLoginUseCase: GetIsLoginUseCase, private val PostAttendCheckUseCase: PostAttendCheckUseCase ):ViewModel() { private val _attendListInit = MutableStateFlow>(emptyList()) val attendListInit : StateFlow> = _attendListInit.asStateFlow() - private val _upcomingAttend = MutableStateFlow(AttendInfoModel(0, "", false, "", "")) + private val _upcomingAttend = MutableStateFlow(AttendInfoModel(0, "커리큘럼이 없습니다", false, "", "")) val upcomingAttend : StateFlow = _upcomingAttend.asStateFlow() private val _attendScore = MutableStateFlow(AttendModel(0, 0, 0, 0, "수료 가능한 점수에요")) @@ -74,7 +75,7 @@ class AttendViewModel @Inject constructor( ) } }.collect { - _attendListInit + _attendListInit.value = it } } } @@ -87,7 +88,7 @@ class AttendViewModel @Inject constructor( }.collect { _upcomingAttend.emit(it) _attendCheckModel.emit( - AttendCheckModel(curriculumId = it.curriculumId, text = "") + AttendCheckModel(curriculumId = it.curriculumId, text = it.curriculumName) ) } } @@ -122,17 +123,21 @@ class AttendViewModel @Inject constructor( fun postAttendCheck() { viewModelScope.launch { - val model = attendCheckModel - PostAttendCheckUseCase(curriculumId = model.value.curriculumId, qrText = model.value.text). - catch { - Log.d("출석 확인", "출석 실패") - _snackbarEvent.emit(AttendSnackBarEvent.Attend_fail) - } - .collectLatest { - Log.d("출석 확인", "출석 성공") - _snackbarEvent.emit(AttendSnackBarEvent.Attend_success) - _qrEnabled.value = true + while (isActive) { + val model = attendCheckModel.value + if(model.curriculumId != 0) { + PostAttendCheckUseCase(curriculumId = model.curriculumId, qrText = model.text) + .onFailure{ + _snackbarEvent.emit(AttendSnackBarEvent.Attend_fail) + } + .onSuccess { + Log.d("출석 확인", "출석 성공") + _snackbarEvent.emit(AttendSnackBarEvent.Attend_success) + _qrEnabled.value = false + } + delay(10000L) // 다음 반복까지 10초 대기 } + } } } diff --git a/presentation/src/main/java/com/kusitms/presentation/model/setting/SettingUiModel.kt b/presentation/src/main/java/com/kusitms/presentation/model/setting/SettingUiModel.kt index 2f76c88..32ef944 100644 --- a/presentation/src/main/java/com/kusitms/presentation/model/setting/SettingUiModel.kt +++ b/presentation/src/main/java/com/kusitms/presentation/model/setting/SettingUiModel.kt @@ -1,5 +1,6 @@ package com.kusitms.presentation.model.setting +import android.util.Log import androidx.annotation.StringRes import androidx.compose.runtime.Composable import androidx.compose.ui.platform.UriHandler @@ -41,13 +42,17 @@ class SettingViewModel @Inject constructor( fun logOut() { viewModelScope.launch { - memberLogOutUseCase() - .onSuccess { + try { + val result = memberLogOutUseCase() + if (result.isSuccess) { + Log.d("로그아웃", "성공") updateSettingStatus(SettingStatus.LOGOUT_SUCCESS) - } - .onFailure { + } else { updateSettingStatus(SettingStatus.ERROR) } + } catch (e: Exception) { + updateSettingStatus(SettingStatus.ERROR) + } } } @@ -83,6 +88,14 @@ class SettingViewModel @Inject constructor( else -> R.string.signout_blank_title } } + @StringRes + fun getOkTextResId(): Int { + return when (this) { + LOGOUT -> R.string.logout_dialog_ok + SIGNOUT -> R.string.signout_dialog_ok + else -> R.string.signout_blank_title + } + } } } diff --git a/presentation/src/main/java/com/kusitms/presentation/navigation/NavGraph.kt b/presentation/src/main/java/com/kusitms/presentation/navigation/NavGraph.kt index 43a6667..0366539 100644 --- a/presentation/src/main/java/com/kusitms/presentation/navigation/NavGraph.kt +++ b/presentation/src/main/java/com/kusitms/presentation/navigation/NavGraph.kt @@ -171,8 +171,7 @@ fun MainNavigation() { kusitmsComposableWithAnimation(NavRoutes.CameraPreview.route) { CameraScreen( - attendViewModel, - navController + attendViewModel ) } diff --git a/presentation/src/main/java/com/kusitms/presentation/ui/home/attend/AttendScreen.kt b/presentation/src/main/java/com/kusitms/presentation/ui/home/attend/AttendScreen.kt index b8f8388..4bddeef 100644 --- a/presentation/src/main/java/com/kusitms/presentation/ui/home/attend/AttendScreen.kt +++ b/presentation/src/main/java/com/kusitms/presentation/ui/home/attend/AttendScreen.kt @@ -119,7 +119,7 @@ fun AttendPreColumn( navController: NavHostController ) { val curri by viewModel.upcomingAttend.collectAsState() - val curriculum = curri?.curriculumName ?: "" + val curriculum = curri.curriculumName ?: "커리큘럼이 없습니다" val eventDateTime = viewModel.combineDateAndTime(curri.date, curri.time) val currentTime = remember { mutableStateOf(LocalDateTime.now()) } val duration = eventDateTime?.let { diff --git a/presentation/src/main/java/com/kusitms/presentation/ui/home/attend/camera/CameraPreview.kt b/presentation/src/main/java/com/kusitms/presentation/ui/home/attend/camera/CameraPreview.kt index c0f3033..fefc926 100644 --- a/presentation/src/main/java/com/kusitms/presentation/ui/home/attend/camera/CameraPreview.kt +++ b/presentation/src/main/java/com/kusitms/presentation/ui/home/attend/camera/CameraPreview.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat +import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController import com.google.mlkit.vision.barcode.BarcodeScanning import com.google.mlkit.vision.common.InputImage @@ -57,6 +58,8 @@ fun CameraScreen( viewModel: AttendViewModel, ) { val snackbarHostState = remember { SnackbarHostState() } + val qrEnabled by viewModel.qrEnabled.collectAsState() + val lifecycleScope = LocalLifecycleOwner.current.lifecycleScope val snackbarContentState = remember { mutableStateOf>(AttendViewModel.AttendSnackBarEvent.None to "") } LaunchedEffect(key1 = Unit) { @@ -66,7 +69,9 @@ fun CameraScreen( AttendViewModel.AttendSnackBarEvent.Attend_fail -> "QR코드를 다시 확인해주세요" else -> "화면 정가운데에 QR코드를 스캔해주세요" } - snackbarContentState.value = event to message + lifecycleScope.launch { + snackbarHostState.showSnackbar(message) + } } } ComposablePermission( @@ -82,7 +87,7 @@ fun CameraScreen( }, onGranted = { val onQrCodeScanned: (String) -> Unit = { qrText -> - if(qrText != "") { + if(qrText != "" && qrEnabled) { viewModel.updateScannedQrCode(qrText) viewModel.postAttendCheck() } diff --git a/presentation/src/main/java/com/kusitms/presentation/ui/setting/SettingMember.kt b/presentation/src/main/java/com/kusitms/presentation/ui/setting/SettingMember.kt index be81fe3..bb37932 100644 --- a/presentation/src/main/java/com/kusitms/presentation/ui/setting/SettingMember.kt +++ b/presentation/src/main/java/com/kusitms/presentation/ui/setting/SettingMember.kt @@ -50,18 +50,21 @@ fun SettingMember( SettingViewModel.SettingStatus.SIGNOUT -> { openDialogState = true } - //처리.. 필요.. SettingViewModel.SettingStatus.ERROR, SettingViewModel.SettingStatus.DEFAULT -> {} else -> {} } } if(openDialogState) { + val titleResId = settingStatus.getTitleResId() + val contentResId = settingStatus.getContentResId() + val okTextResId = settingStatus.getOkTextResId() + KusitmsDialog( - title = stringResource(id = R.string.logout_dialog_title), + title = stringResource(id = titleResId), content = { Text( - text = stringResource(id = R.string.logout_dialog_content), + text = stringResource(id = contentResId), textAlign = TextAlign.Center, style = KusitmsTypo.current.Caption1, color = KusitmsColorPalette.current.Grey400 @@ -69,14 +72,19 @@ fun SettingMember( KusitmsMarginVerticalSpacer(size = 24) }, okColor = KusitmsColorPalette.current.Sub2, - okText = "로그아웃하기", + okText = stringResource(id = okTextResId), onOk = { - viewModel.logOut() + when (settingStatus) { + SettingViewModel.SettingStatus.LOGOUT -> viewModel.logOut() + SettingViewModel.SettingStatus.SIGNOUT -> viewModel.signOut() + else -> {} + } + openDialogState = false }, onCancel = { - !openDialogState + openDialogState = false + viewModel.updateSettingStatus(SettingViewModel.SettingStatus.DEFAULT) }) { - openDialogState = false } } diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 46b3188..b7df5b6 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -162,11 +162,13 @@ 로그아웃 로그아웃을 진행할까요? + 로그아웃하기 - 회원탈퇴 + 회원탈퇴 회원탈퇴를 진행할까요?\n 탈퇴하게 되면 정보가 삭제되며 되돌릴 수 없습니다. + 탈퇴하기 출석 다가오는 커리큘럼