From 8c26b4c5a10492932d2c645ec5971ac4539aa993 Mon Sep 17 00:00:00 2001 From: Eric85710 Date: Mon, 27 Apr 2026 18:24:00 +0800 Subject: [PATCH] auth to server-V2 --- .../login_v3/auth/Login_Page_ViewModel.kt | 30 --------- .../login_v3/auth/{ => login}/Login_Page.kt | 9 +-- .../auth/login/Login_Page_ViewModel.kt | 1 + .../login_v3/auth/{ => reg}/Reg_Page.kt | 11 ++-- .../login_v3/auth/reg/Register_ViewModel.kt | 42 ++++++++++++ .../data/repository/basic/Auth_Repository.kt | 22 +++++++ .../data/repository/basic/Main_Repository.kt | 66 ------------------- .../login_v3/navigation/nav_controller.kt | 12 +--- 8 files changed, 74 insertions(+), 119 deletions(-) delete mode 100644 app/src/main/java/com/example/login_v3/auth/Login_Page_ViewModel.kt rename app/src/main/java/com/example/login_v3/auth/{ => login}/Login_Page.kt (96%) create mode 100644 app/src/main/java/com/example/login_v3/auth/login/Login_Page_ViewModel.kt rename app/src/main/java/com/example/login_v3/auth/{ => reg}/Reg_Page.kt (96%) create mode 100644 app/src/main/java/com/example/login_v3/auth/reg/Register_ViewModel.kt create mode 100644 app/src/main/java/com/example/login_v3/data/repository/basic/Auth_Repository.kt diff --git a/app/src/main/java/com/example/login_v3/auth/Login_Page_ViewModel.kt b/app/src/main/java/com/example/login_v3/auth/Login_Page_ViewModel.kt deleted file mode 100644 index 6da181a..0000000 --- a/app/src/main/java/com/example/login_v3/auth/Login_Page_ViewModel.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.login_v3.auth - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.example.login_v3.data.api.api_class.LoginResponse -import com.example.login_v3.data.repository.basic.ITecnologiaRepository -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch -import javax.inject.Inject - - -@HiltViewModel -class LoginViewModel @Inject constructor( - private val repository: ITecnologiaRepository -) : ViewModel() { - - // 使用 StateFlow 或 LiveData 來傳遞結果給 UI - private val _loginResult = MutableStateFlow?>(null) - val loginResult = _loginResult.asStateFlow() - - fun performLogin(username: String, password: String) { - viewModelScope.launch { - // 直接呼叫 repository,ViewModel 不關心資料是從網路還是資料庫來的 - val result = repository.login(username, password) - _loginResult.value = result - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/login_v3/auth/Login_Page.kt b/app/src/main/java/com/example/login_v3/auth/login/Login_Page.kt similarity index 96% rename from app/src/main/java/com/example/login_v3/auth/Login_Page.kt rename to app/src/main/java/com/example/login_v3/auth/login/Login_Page.kt index b44ef54..0c4c38b 100644 --- a/app/src/main/java/com/example/login_v3/auth/Login_Page.kt +++ b/app/src/main/java/com/example/login_v3/auth/login/Login_Page.kt @@ -1,4 +1,4 @@ -package com.example.login_v3.auth +package com.example.login_v3.auth.login import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.AccountCircle @@ -47,8 +46,6 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.navigation.NavBackStackEntry import coil.ImageLoader import coil.compose.AsyncImage import coil.decode.SvgDecoder @@ -159,7 +156,7 @@ fun LoginScreen( label = { Text( emailError.ifEmpty { "Email" }, - color = if (emailError.isNotEmpty()) Red else androidx.compose.ui.graphics.Color.Unspecified + color = if (emailError.isNotEmpty()) Red else Color.Unspecified ) }, @@ -190,7 +187,7 @@ fun LoginScreen( label = { Text( passwordError.ifEmpty { "Password" }, - color = if (passwordError.isNotEmpty()) Red else androidx.compose.ui.graphics.Color.Unspecified + color = if (passwordError.isNotEmpty()) Red else Color.Unspecified ) }, leadingIcon = { diff --git a/app/src/main/java/com/example/login_v3/auth/login/Login_Page_ViewModel.kt b/app/src/main/java/com/example/login_v3/auth/login/Login_Page_ViewModel.kt new file mode 100644 index 0000000..26f9993 --- /dev/null +++ b/app/src/main/java/com/example/login_v3/auth/login/Login_Page_ViewModel.kt @@ -0,0 +1 @@ +package com.example.login_v3.auth.login \ No newline at end of file diff --git a/app/src/main/java/com/example/login_v3/auth/Reg_Page.kt b/app/src/main/java/com/example/login_v3/auth/reg/Reg_Page.kt similarity index 96% rename from app/src/main/java/com/example/login_v3/auth/Reg_Page.kt rename to app/src/main/java/com/example/login_v3/auth/reg/Reg_Page.kt index 3415676..5ad97f3 100644 --- a/app/src/main/java/com/example/login_v3/auth/Reg_Page.kt +++ b/app/src/main/java/com/example/login_v3/auth/reg/Reg_Page.kt @@ -1,4 +1,4 @@ -package com.example.login_v3.auth +package com.example.login_v3.auth.reg import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.AccountCircle @@ -45,8 +44,6 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.hilt.navigation.compose.hiltViewModel -import com.example.login_v3.data.health.HealthCheckViewModel import com.example.login_v3.ui.theme.main_orange import kotlin.text.ifEmpty @@ -137,7 +134,7 @@ fun Register_Screen( label = { Text( user_name_Error.ifEmpty { "username" }, - color = if (user_name_Error.isNotEmpty()) Red else androidx.compose.ui.graphics.Color.Unspecified + color = if (user_name_Error.isNotEmpty()) Red else Color.Unspecified ) }, @@ -168,7 +165,7 @@ fun Register_Screen( label = { Text( emailError.ifEmpty { "Email" }, - color = if (emailError.isNotEmpty()) Red else androidx.compose.ui.graphics.Color.Unspecified + color = if (emailError.isNotEmpty()) Red else Color.Unspecified ) }, @@ -199,7 +196,7 @@ fun Register_Screen( label = { Text( passwordError.ifEmpty { "Password" }, - color = if (passwordError.isNotEmpty()) Red else androidx.compose.ui.graphics.Color.Unspecified + color = if (passwordError.isNotEmpty()) Red else Color.Unspecified ) }, leadingIcon = { diff --git a/app/src/main/java/com/example/login_v3/auth/reg/Register_ViewModel.kt b/app/src/main/java/com/example/login_v3/auth/reg/Register_ViewModel.kt new file mode 100644 index 0000000..4bf0067 --- /dev/null +++ b/app/src/main/java/com/example/login_v3/auth/reg/Register_ViewModel.kt @@ -0,0 +1,42 @@ +package com.example.login_v3.auth.reg + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.login_v3.data.api.api_class.RegisterRequest +import com.example.login_v3.data.repository.basic.AuthRepository +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class RegisterViewModel @Inject constructor( + private val repository: AuthRepository +) : ViewModel() { + + fun handleRegister() { + val request = RegisterRequest( + display_name = "測試員", + email = "test@example.com", + password = "password123", + username = "tester01" + ) + + viewModelScope.launch { + try { + val response = repository.register(request) + if (response.isSuccessful) { + // 註冊成功,處理 response.body() + val successMsg = response.body()?.message + println("註冊成功: $successMsg") + } else { + // 註冊失敗,處理錯誤訊息 (例如 400 重複註冊) + val errorJson = response.errorBody()?.string() + println("註冊失敗: $errorJson") + } + } catch (e: Exception) { + // 處理網路連線異常 + println("網路錯誤: ${e.message}") + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/login_v3/data/repository/basic/Auth_Repository.kt b/app/src/main/java/com/example/login_v3/data/repository/basic/Auth_Repository.kt new file mode 100644 index 0000000..adb4a16 --- /dev/null +++ b/app/src/main/java/com/example/login_v3/data/repository/basic/Auth_Repository.kt @@ -0,0 +1,22 @@ +package com.example.login_v3.data.repository.basic + +import com.example.login_v3.data.api.TecnologiaApi +import com.example.login_v3.data.api.api_class.ApiResponse +import com.example.login_v3.data.api.api_class.RegisterRequest +import retrofit2.Response +import javax.inject.Inject + +class AuthRepository @Inject constructor( + private val api: TecnologiaApi +) { + /** + * 處理用戶註冊 + * 回傳 Response,讓 ViewModel 可以根據 isSuccessful 判斷結果 + */ + suspend fun register(request: RegisterRequest): Response { + return api.register(request) + } + + // 你也可以在這裡加入其他的 Auth 相關功能,例如登入 + // suspend fun login(request: LoginRequest) = api.login(request) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/login_v3/data/repository/basic/Main_Repository.kt b/app/src/main/java/com/example/login_v3/data/repository/basic/Main_Repository.kt index a6cddd0..e69de29 100644 --- a/app/src/main/java/com/example/login_v3/data/repository/basic/Main_Repository.kt +++ b/app/src/main/java/com/example/login_v3/data/repository/basic/Main_Repository.kt @@ -1,66 +0,0 @@ -package com.example.login_v3.data.repository.basic - -import com.example.login_v3.data.api.TecnologiaApi -import com.example.login_v3.data.api.api_class.ApiResponse -import com.example.login_v3.data.api.api_class.FriendRequest -import com.example.login_v3.data.api.api_class.LoginRequest -import com.example.login_v3.data.api.api_class.LoginResponse -import com.example.login_v3.data.api.api_class.User -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import java.lang.Exception -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class TecnologiaRepositoryImpl @Inject constructor( - private val api: TecnologiaApi // Hilt 會從 NetworkModule 找這個 API -) : ITecnologiaRepository { - - override suspend fun login(username: String, password: String): Result { - return try { - val response = api.login(LoginRequest(username, password)) - Result.success(response) - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun getMe(token: String): Result { - return try { - val response = api.getMe("Bearer $token") - Result.success(response) - } catch (e: Exception) { - Result.failure(e) - } - } - - override suspend fun sendFriendRequest(token: String, friendId: String): Result { - return try { - val response = api.sendFriendRequest("Bearer $token", FriendRequest(friendId)) - Result.success(response) - } catch (e: Exception) { - Result.failure(e) - } - } -} - - -@Module -@InstallIn(SingletonComponent::class) -abstract class RepositoryModule { - - @Binds - @Singleton - abstract fun bindTecnologiaRepository( - repositoryImpl: TecnologiaRepositoryImpl // 這裡要對應實作類別的名稱 - ): ITecnologiaRepository -} - -interface ITecnologiaRepository { - suspend fun login(username: String, password: String): Result - suspend fun getMe(token: String): Result - suspend fun sendFriendRequest(token: String, friendId: String): Result -} \ No newline at end of file diff --git a/app/src/main/java/com/example/login_v3/navigation/nav_controller.kt b/app/src/main/java/com/example/login_v3/navigation/nav_controller.kt index 8e0a764..0fd29f9 100644 --- a/app/src/main/java/com/example/login_v3/navigation/nav_controller.kt +++ b/app/src/main/java/com/example/login_v3/navigation/nav_controller.kt @@ -1,23 +1,15 @@ package com.example.login_v3.navigation -import android.R.attr.padding import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.viewmodel.compose.viewModel -import androidx.navigation.NavHostController -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable -import androidx.navigation.compose.rememberNavController -import com.example.login_v3.auth.LoginScreen -import com.example.login_v3.auth.LoginViewModel +import com.example.login_v3.auth.login.LoginScreen import com.example.login_v3.auth.Login_or_Reg_page -import com.example.login_v3.auth.Register_Screen +import com.example.login_v3.auth.reg.Register_Screen import com.example.login_v3.home.HomeScreen -import com.example.login_v3.home.Tg_MarketPlace @Composable fun AppNavGraph(