code: Сделал api админа и его VM (вроде как)

This commit is contained in:
DKaverznev 2025-02-20 14:26:25 +03:00
parent 7dcfec695d
commit add9651561
8 changed files with 249 additions and 11 deletions

View File

@ -57,6 +57,7 @@ class RetrofitClient(context: Context) {
fun getApiServiceList(): ApiServiceList { fun getApiServiceList(): ApiServiceList {
return retrofitWithAuth.create(ApiServiceList::class.java) return retrofitWithAuth.create(ApiServiceList::class.java)
} }
fun getApiServiceAdmin(): ApiServiceAdmin { fun getApiServiceAdmin(): ApiServiceAdmin {
return retrofitWithAuth.create(ApiServiceAdmin::class.java) return retrofitWithAuth.create(ApiServiceAdmin::class.java)
} }

View File

@ -2,10 +2,8 @@ package ru.myitschool.work.api.admin
import retrofit2.Response import retrofit2.Response
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.PATCH import retrofit2.http.PATCH
import retrofit2.http.Path import retrofit2.http.Path
import ru.myitschool.work.api.main.UserInfo
interface ApiServiceAdmin { interface ApiServiceAdmin {
@PATCH("api/admin/authority/change/{login}") @PATCH("api/admin/authority/change/{login}")

View File

@ -9,6 +9,8 @@ import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.fragment import androidx.navigation.fragment.fragment
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import ru.myitschool.work.R import ru.myitschool.work.R
import ru.myitschool.work.ui.admin.AdminDestination
import ru.myitschool.work.ui.admin.AdminFragment
import ru.myitschool.work.ui.login.LoginDestination import ru.myitschool.work.ui.login.LoginDestination
import ru.myitschool.work.ui.login.LoginFragment import ru.myitschool.work.ui.login.LoginFragment
import ru.myitschool.work.ui.main.MainDestination import ru.myitschool.work.ui.main.MainDestination
@ -36,7 +38,7 @@ class RootActivity : AppCompatActivity() {
fragment<QrScanFragment, QrScanDestination>() fragment<QrScanFragment, QrScanDestination>()
fragment<MainFragment, MainDestination>() fragment<MainFragment, MainDestination>()
fragment<ResultFragment, ResultDestination>() fragment<ResultFragment, ResultDestination>()
/*fragment<AdminFragment, AdminDestination>()*/ fragment<AdminFragment, AdminDestination>()
} }
} }

View File

@ -0,0 +1,6 @@
package ru.myitschool.work.ui.admin
import kotlinx.serialization.Serializable
@Serializable
data object AdminDestination

View File

@ -0,0 +1,101 @@
package ru.myitschool.work.ui.admin
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import dagger.hilt.android.AndroidEntryPoint
import ru.myitschool.work.R
import ru.myitschool.work.databinding.FragmentAdminBinding
import ru.myitschool.work.ui.main.MainDestination
import ru.myitschool.work.utils.AuthPreferences
import ru.myitschool.work.utils.QrPreferences
import ru.myitschool.work.utils.collectWhenStarted
import ru.myitschool.work.utils.visibleOrGone
@AndroidEntryPoint
class AdminFragment : Fragment(R.layout.fragment_admin) {
private var _binding: FragmentAdminBinding? = null
private val binding: FragmentAdminBinding get() = _binding!!
private val viewModel: AdminViewModel by viewModels()
private lateinit var authPreferences: AuthPreferences
private lateinit var qrPreferences: QrPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
authPreferences = AuthPreferences(requireContext())
qrPreferences = QrPreferences(requireContext())
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentAdminBinding.bind(view)
setupOpenComponents()
observeOpenState()
}
private fun setupOpenComponents() {
binding.apply {
block.setOnClickListener {
authPreferences.getLogin().toString().let {
viewModel.block(
it,
true
)
}
}
}
}
private fun observeOpenState() {
viewModel.state.collectWhenStarted(this) { state ->
when (state) {
is AdminViewModel.ResultState.Loading -> {
}
is AdminViewModel.ResultState.Success -> {
}
is AdminViewModel.ResultState.InvalidCredentials -> {
}
is AdminViewModel.ResultState.Error -> {
}
AdminViewModel.ResultState.Initial -> {
}
}
}
}
private fun visibleAll(isVisible: Boolean) {
binding.apply {
}
}
private fun navigateToMainScreen() {
try {
findNavController().apply {
popBackStack(MainDestination, false)
navigate(MainDestination)
}
} catch (e: Exception) {
Log.e("ResultFragment", "Navigation error", e)
Toast.makeText(context, getText(R.string.errorGoText).toString(), Toast.LENGTH_SHORT).show()
}
}
override fun onDestroyView() {
_binding = null
super.onDestroyView()
}
}

View File

@ -0,0 +1,135 @@
package ru.myitschool.work.ui.admin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import ru.myitschool.work.api.admin.AdminJson
import ru.myitschool.work.api.admin.ApiServiceAdmin
import ru.myitschool.work.api.list.ListInfo
import ru.myitschool.work.api.main.ApiServiceMain
import ru.myitschool.work.api.main.Authorities
import ru.myitschool.work.api.main.UserInfo
import ru.myitschool.work.ui.list.ListRepository
import javax.inject.Inject
@HiltViewModel
class AdminViewModel @Inject constructor(
private val apiService: ApiServiceAdmin,
private val apiServiceData: ApiServiceMain,
private val listRepository: ListRepository
) : ViewModel() {
private val _state = MutableStateFlow<ResultState>(ResultState.Initial)
val state = _state.asStateFlow()
private val _stateData = MutableStateFlow<ResultStateData>(ResultStateData.Initial)
val stateData = _stateData.asStateFlow()
fun block(login: String, authority: Boolean) {
viewModelScope.launch {
_state.value = ResultState.Loading
try {
val response = apiService.block(
login = login,
data = AdminJson(
if (authority) Authorities.ROLE_BLOCK
else Authorities.ROLE_USER
)
)
when (response.code()) {
200 -> {
_state.value = ResultState.Success
}
403 -> {
_state.value = ResultState.InvalidCredentials
}
401 -> {
_state.value = ResultState.Error
}
else -> {
_state.value = ResultState.Error
}
}
} catch (t: Throwable) {
_state.value = ResultState.Error
}
}
}
fun getUserData(login: String) {
viewModelScope.launch {
_stateData.value = ResultStateData.Loading
apiServiceData.getDataUser(login).enqueue(object : Callback<UserInfo> {
override fun onResponse(call: Call<UserInfo>, response: Response<UserInfo>) {
when {
response.isSuccessful -> {
val userInfo = response.body()
_stateData.value = userInfo?.let { ResultStateData.Success(it) }!!
}
response.code() == 401 -> {
_stateData.value = ResultStateData.Error("Unauthorized")
}
response.code() == 403 -> {
_stateData.value = ResultStateData.Error("Block")
}
else -> {
_stateData.value = ResultStateData.Error("Error")
}
}
}
override fun onFailure(call: Call<UserInfo>, t: Throwable) {
_stateData.value = ResultStateData.Error("Network Error")
}
})
}
}
private val _listState = MutableStateFlow<ListState>(ListState.Loading)
val listState: StateFlow<ListState> = _listState
sealed class ListState {
data object Loading : ListState()
data class Success(val data: List<ListInfo>) : ListState()
data class Error(val message: String) : ListState()
}
fun loadList(login: String) {
viewModelScope.launch {
_listState.value = ListState.Loading
try {
val list = listRepository.getList(login)
_listState.value = ListState.Success(list)
} catch (e: Exception) {
_listState.value = ListState.Error(e.message ?: "Unknown error")
}
}
}
sealed class ResultState {
data object Initial : ResultState()
data object InvalidCredentials : ResultState()
data object Loading : ResultState()
data object Success : ResultState()
data object Error : ResultState()
}
sealed class ResultStateData {
data object Initial : ResultStateData()
data object Loading : ResultStateData()
data class Success(val userInfo: UserInfo) : ResultStateData()
data class Error(val message: String) : ResultStateData()
}
}

View File

@ -12,6 +12,7 @@ import dagger.hilt.android.AndroidEntryPoint
import ru.myitschool.work.R import ru.myitschool.work.R
import ru.myitschool.work.api.main.Authorities import ru.myitschool.work.api.main.Authorities
import ru.myitschool.work.databinding.FragmentMainBinding import ru.myitschool.work.databinding.FragmentMainBinding
import ru.myitschool.work.ui.admin.AdminDestination
import ru.myitschool.work.ui.list.ListAdapter import ru.myitschool.work.ui.list.ListAdapter
import ru.myitschool.work.ui.login.LoginDestination import ru.myitschool.work.ui.login.LoginDestination
import ru.myitschool.work.ui.scan.qr.QrScanDestination import ru.myitschool.work.ui.scan.qr.QrScanDestination
@ -186,12 +187,12 @@ class MainFragment : Fragment(R.layout.fragment_main) {
private fun navigateToAdmin() { private fun navigateToAdmin() {
try {/* try {
authPreferences.clearLoginState() authPreferences.clearLoginState()
findNavController().apply { findNavController().apply {
popBackStack(AdminDestination, false) popBackStack(AdminDestination, false)
navigate(AdminDestination) navigate(AdminDestination)
}*/ }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("MainFragment", "Error navigating to login", e) Log.e("MainFragment", "Error navigating to login", e)
} }

View File

@ -1,6 +0,0 @@
package ru.myitschool.work.ui.result
object TextStatus {
const val error = "Вход был отменён/Operation was cancelled"
const val success = "Успешно/Success"
}