day2_commit_13_back_to_Json

This commit is contained in:
Terebov_Maksim 2025-02-19 16:56:30 +03:00
parent 3da4b99cc0
commit 907c1c5d1c
6 changed files with 72 additions and 57 deletions

View File

@ -4,9 +4,9 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import ru.myitschool.work.api.ApiService
import ru.myitschool.work.core.Constants
import javax.inject.Singleton
@ -16,9 +16,20 @@ object ApiModule {
@Provides
@Singleton
fun provideRetrofit(): Retrofit {
fun provideOkHttpClient(): OkHttpClient {
val username = "pivanov" // Замените на ваш логин
val password = "password123" // Замените на ваш пароль
return OkHttpClient.Builder()
.addInterceptor(AuthInterceptor(username, password))
.build()
}
@Provides
@Singleton
fun provideRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(Constants.SERVER_ADDRESS)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
}

View File

@ -6,14 +6,17 @@ import retrofit2.http.GET
import retrofit2.http.PATCH
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query
interface ApiService {
// Метод для аутентификации
@POST("/api/auth") // Изменено на POST и путь к аутентификации
@GET("/api/auth") // Используем GET для аутентификации
suspend fun authenticate(
@Body payload: AuthRequest // Передаем объект с логином и паролем
): Response<UserAuthResponse> // Возвращаем UserAuthResponse
@Query("login") login: String, // Передаем логин как параметр запроса
@Query("password") password: String // Передаем пароль как параметр запроса
): Response<UserAuthResponse> // Возвращаем JSON как объект UserAuthResponse
// Другие методы...
@GET("/api/{login}/info") // Получение информации о пользователе
suspend fun getUserInfo(@Path("login") login: String): Response<Map<String, Any>>
@ -30,12 +33,6 @@ interface ApiService {
suspend fun getAllWorkers(): Response<List<EmployeeData>>
}
// Модель данных для запроса аутентификации
data class AuthRequest(
val login: String,
val password: String // Поле для пароля
)
// Модель данных для ответа аутентификации
data class UserAuthResponse(
val role: String // Добавляем поле для роли

View File

@ -0,0 +1,16 @@
package ru.myitschool.work.api
import okhttp3.Interceptor
import okhttp3.Response
import java.util.Base64
class AuthInterceptor(private val username: String, private val password: String) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val credential = Base64.getEncoder().encodeToString("$username:$password".toByteArray())
val newRequest = originalRequest.newBuilder()
.addHeader("Authorization", "Basic $credential")
.build()
return chain.proceed(newRequest)
}
}

View File

@ -1,5 +1,5 @@
package ru.myitschool.work.core
// БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ
object Constants {
const val SERVER_ADDRESS = "const val SERVER_ADDRESS = \"http://localhost:8080\"\n"
const val SERVER_ADDRESS = "http://192.168.1.131:8080"
}

View File

@ -85,15 +85,12 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
}
private fun subscribe() {
viewModel.state.collectWhenStarted(this) { state ->
binding.loading.visibleOrGone(false)
lifecycleScope.launch {
viewModel.state.collect { state ->
binding.loading.visibleOrGone(false)
try {
if (state.maintenance) {
showMaintenanceDialog() // Показываем диалог о техработах
} else if (state.error != null) {
binding.error.text = state.error
binding.error.visibility = View.VISIBLE
} else if (state.success) {
binding.error.visibility = View.GONE
authPreferences.saveLoginState(true)
@ -106,11 +103,11 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
}
Toast.makeText(context, "Авторизация прошла успешно", Toast.LENGTH_SHORT).show()
navigateToMainScreen()
navigateToMainScreen() // Перенаправление на следующий экран
} else if (state.error != null) {
binding.error.text = state.error
binding.error.visibility = View.VISIBLE
}
} catch (e: Exception) {
Log.e("LoginFragment", "Ошибка при обработке состояния", e)
Toast.makeText(context, "Произошла ошибка. Пожалуйста, попробуйте снова.", Toast.LENGTH_SHORT).show()
}
}
}
@ -119,7 +116,7 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
AlertDialog.Builder(requireContext())
.setTitle("Технические работы")
.setMessage("Проводятся техработы, пожалуйста, подождите.")
.setPositiveButton("ОК") { dialog, _ -> dialog.dismiss() }
.setPositiveButton("ОК ") { dialog, _ -> dialog.dismiss() }
.setCancelable(false)
.show()
}

View File

@ -1,53 +1,46 @@
package ru.myitschool.work.ui.login
import android.content.Context
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import okhttp3.Credentials
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import ru.myitschool.work.SessionManager
import ru.myitschool.work.api.ApiService
import ru.myitschool.work.api.AuthRequest
import ru.myitschool.work.api.UserAuthResponse
import ru.myitschool.work.core.Constants
import javax.inject.Inject
@HiltViewModel
class LoginViewModel @Inject constructor(
@ApplicationContext private val context: Context,
private val apiService: ApiService
) : ViewModel() {
private val _state = MutableStateFlow(LoginState())
val state = _state.asStateFlow()
private val apiService: ApiService by lazy {
Retrofit.Builder()
.baseUrl(Constants.SERVER_ADDRESS)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
private val _state = MutableStateFlow(LoginState())
val state: StateFlow<LoginState> get() = _state
fun authenticate(username: String, password: String) {
if (isValidUsername(username)) {
viewModelScope.launch {
try {
val payload = AuthRequest(username, password) // Создаем объект запроса
val response = apiService.authenticate(payload) // Вызываем метод аутентификации
val response = apiService.authenticate(username, password)
Log.d("LoginViewModel", "Response code: ${response.code()}")
if (response.isSuccessful) {
val userAuthResponse = response.body() // Получаем ответ с ролью пользователя
userAuthResponse?.let {
SessionManager.userLogin = username // Сохраняем логин
SessionManager.userRole = it.role // Сохраняем роль
val userAuthResponse = response.body() // Получаем JSON-ответ
Log.d("LoginViewModel", "User Auth Response: $userAuthResponse") // Логируем ответ
// Обработка JSON-ответа
if (userAuthResponse != null) {
SessionManager.userLogin = username
SessionManager.userRole = userAuthResponse.role // Сохраняем роль
_state.value = LoginState(success = true) // Успешная авторизация
} else {
_state.value = LoginState(error = "Ошибка авторизации: Неверные учетные данные.")
}
_state.value = LoginState(success = true, userAuthResponse = userAuthResponse)
} else {
_state.value = LoginState(error = "Ошибка авторизации")
_state.value = LoginState(error = "Ошибка авторизации: ${response.message()}")
}
} catch (e: Exception) {
e.printStackTrace()
@ -60,13 +53,14 @@ class LoginViewModel @Inject constructor(
}
private fun isValidUsername(username: String): Boolean {
return username.length >= 3 && !username.first().isDigit() && username.all { it.isLetterOrDigit() }
return username.isNotEmpty() // Пример проверки логина
}
}
data class LoginState(
val success: Boolean = false,
val error: String? = null,
val maintenance: Boolean = false,
val userAuthResponse: UserAuthResponse? = null // Добавляем поле для хранения информации о роли
)
}
// Состояние аутентификации
data class LoginState(
val success: Boolean = false, // Успешность аутентификации
val userAuthResponse: UserAuthResponse? = null, // Ответ с информацией о пользователе
val error: String? = null, // Сообщение об ошибке
val maintenance: Boolean = false // Состояние техобслуживания
)