diff --git a/.kotlin/errors/errors-1740038374254.log b/.kotlin/errors/errors-1740038374254.log new file mode 100644 index 0000000..1531ea7 --- /dev/null +++ b/.kotlin/errors/errors-1740038374254.log @@ -0,0 +1,82 @@ +kotlin version: 2.0.21 +error message: Daemon compilation failed: null +java.lang.Exception + at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:69) + at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:65) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:240) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111) + at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:76) + at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62) + at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) + at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59) + at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:174) + at java.base/java.util.concurrent.FutureTask.run(Unknown Source) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:195) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:128) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:170) + at org.gradle.internal.Factories$1.create(Factories.java:31) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:267) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:131) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:136) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:165) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:134) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) + at java.base/java.util.concurrent.FutureTask.run(Unknown Source) + at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) + at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) + at java.base/java.lang.Thread.run(Unknown Source) +Caused by: java.nio.file.DirectoryNotEmptyException: C:\Users\User\AppData\Local\Temp\kotlin-backups11164380389062662786 + at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(Unknown Source) + at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(Unknown Source) + at java.base/java.nio.file.Files.delete(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash$lambda$11$lambda$10$lambda$9(CompilationTransaction.kt:244) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source) + at java.base/java.util.ArrayList.forEach(Unknown Source) + at java.base/java.util.stream.SortedOps$RefSortingSink.end(Unknown Source) + at java.base/java.util.stream.Sink$ChainedReference.end(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source) + at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.close(CompilationTransaction.kt:254) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.tryCompileIncrementally(IncrementalCompilerRunner.kt:747) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:120) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:675) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:92) + at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1660) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source) + at java.base/java.lang.reflect.Method.invoke(Unknown Source) + at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) + at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source) + at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source) + at java.base/java.security.AccessController.doPrivileged(Unknown Source) + at java.rmi/sun.rmi.transport.Transport.serviceCall(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source) + at java.base/java.security.AccessController.doPrivileged(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) + ... 3 more + + diff --git a/.kotlin/errors/errors-1740039190766.log b/.kotlin/errors/errors-1740039190766.log new file mode 100644 index 0000000..38660ba --- /dev/null +++ b/.kotlin/errors/errors-1740039190766.log @@ -0,0 +1,82 @@ +kotlin version: 2.0.21 +error message: Daemon compilation failed: null +java.lang.Exception + at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:69) + at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:65) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:240) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111) + at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:76) + at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62) + at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) + at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59) + at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:174) + at java.base/java.util.concurrent.FutureTask.run(Unknown Source) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:195) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:128) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:170) + at org.gradle.internal.Factories$1.create(Factories.java:31) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:267) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:131) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:136) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:165) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:134) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) + at java.base/java.util.concurrent.FutureTask.run(Unknown Source) + at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) + at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) + at java.base/java.lang.Thread.run(Unknown Source) +Caused by: java.nio.file.DirectoryNotEmptyException: C:\Users\User\AppData\Local\Temp\kotlin-backups8341820686666786180 + at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(Unknown Source) + at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(Unknown Source) + at java.base/java.nio.file.Files.delete(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash$lambda$11$lambda$10$lambda$9(CompilationTransaction.kt:244) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source) + at java.base/java.util.ArrayList.forEach(Unknown Source) + at java.base/java.util.stream.SortedOps$RefSortingSink.end(Unknown Source) + at java.base/java.util.stream.Sink$ChainedReference.end(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source) + at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.close(CompilationTransaction.kt:254) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.tryCompileIncrementally(IncrementalCompilerRunner.kt:747) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:120) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:675) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:92) + at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1660) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source) + at java.base/java.lang.reflect.Method.invoke(Unknown Source) + at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) + at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source) + at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source) + at java.base/java.security.AccessController.doPrivileged(Unknown Source) + at java.rmi/sun.rmi.transport.Transport.serviceCall(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source) + at java.base/java.security.AccessController.doPrivileged(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) + ... 3 more + + diff --git a/app/src/main/java/ru/myitschool/work/App.kt b/app/src/main/java/ru/myitschool/work/App.kt index 3085135..0b0dbf7 100644 --- a/app/src/main/java/ru/myitschool/work/App.kt +++ b/app/src/main/java/ru/myitschool/work/App.kt @@ -4,4 +4,9 @@ import android.app.Application import dagger.hilt.android.HiltAndroidApp @HiltAndroidApp -class App : Application() \ No newline at end of file +class App : Application() { + override fun onCreate() { + super.onCreate() + SessionManager.init(this) // Инициализация SessionManager + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/SessionManager.kt b/app/src/main/java/ru/myitschool/work/SessionManager.kt index 4f43031..fcb9b40 100644 --- a/app/src/main/java/ru/myitschool/work/SessionManager.kt +++ b/app/src/main/java/ru/myitschool/work/SessionManager.kt @@ -1,10 +1,39 @@ package ru.myitschool.work -object SessionManager { - var userLogin: String? = null // Логин пользователя - var userRole: String? = null // Роль пользователя +import android.content.Context +import android.content.SharedPreferences +import java.util.Base64 + +object SessionManager { + private const val PREF_NAME = "user_session" + private const val KEY_USER_LOGIN = "user_login" + private const val KEY_USER_ROLE = "user_role" + + private lateinit var preferences: SharedPreferences + + fun init(context: Context) { + preferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + } + + var userLogin: String? + get() = preferences.getString(KEY_USER_LOGIN, null) + set(value) { + preferences.edit().putString(KEY_USER_LOGIN, value).apply() + } + + var userRole: String? + get() = preferences.getString(KEY_USER_ROLE, null) + set(value) { + preferences.edit().putString(KEY_USER_ROLE, value).apply() + } + + fun getAuthHeader(): String { + val username = userLogin ?: return "" + val password = "password123" // Замените на ваш пароль + val credential = Base64.getEncoder().encodeToString("$username:$password".toByteArray()) + return "Basic $credential" + } - // Метод для очистки данных сессии fun clearSession() { userLogin = null userRole = null diff --git a/app/src/main/java/ru/myitschool/work/api/ApiModule.kt b/app/src/main/java/ru/myitschool/work/api/ApiModule.kt index 4d8d491..9f0fb34 100644 --- a/app/src/main/java/ru/myitschool/work/api/ApiModule.kt +++ b/app/src/main/java/ru/myitschool/work/api/ApiModule.kt @@ -1,5 +1,6 @@ package ru.myitschool.work.api +import LoggingInterceptor import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -17,7 +18,8 @@ object ApiModule { @Singleton fun provideOkHttpClient(authInterceptor: AuthInterceptor): OkHttpClient { return OkHttpClient.Builder() - .addInterceptor(authInterceptor) // Добавляем интерсептор + .addInterceptor(authInterceptor) // Добавляем интерсептор аутентификации + .addInterceptor(LoggingInterceptor()) // Добавляем интерсептор логирования .build() } diff --git a/app/src/main/java/ru/myitschool/work/api/ApiService.kt b/app/src/main/java/ru/myitschool/work/api/ApiService.kt index 2723c8d..c49b33a 100644 --- a/app/src/main/java/ru/myitschool/work/api/ApiService.kt +++ b/app/src/main/java/ru/myitschool/work/api/ApiService.kt @@ -4,6 +4,7 @@ import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.Body import retrofit2.http.GET +import retrofit2.http.Header import retrofit2.http.PATCH import retrofit2.http.POST import retrofit2.http.Path @@ -17,9 +18,11 @@ interface ApiService { @Query("password") password: String ): Response // Измените Response на Response - // Другие методы... - @GET("/api/{login}/info") // Получение информации о пользователе - suspend fun getUserInfo(@Path("login") login: String): Response> + @GET("/api/{login}/info") + suspend fun getUserInfo( + @Path("login") login: String, + @Header("Authorization") authHeader: String + ): Response @GET("/api/employee/{login}") // Получение информации о сотруднике suspend fun getEmployeeInfo(@Path("login") login: String): Response diff --git a/app/src/main/java/ru/myitschool/work/api/LoginInterceptor.kt b/app/src/main/java/ru/myitschool/work/api/LoginInterceptor.kt new file mode 100644 index 0000000..ffc7c5c --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/api/LoginInterceptor.kt @@ -0,0 +1,15 @@ +import okhttp3.Interceptor +import okhttp3.Response +import android.util.Log + +class LoggingInterceptor : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + Log.d("LoggingInterceptor", "Sending request to ${request.url} with headers ${request.headers}") + + val response = chain.proceed(request) + + Log.d("LoggingInterceptor", "Received response for ${response.request.url} with code ${response.code}") + return response + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt b/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt index e183075..325ba50 100644 --- a/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt @@ -10,7 +10,6 @@ import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import ru.myitschool.work.R import ru.myitschool.work.api.ApiService -import ru.myitschool.work.api.EmployeeData import ru.myitschool.work.api.ToggleAccessRequest import ru.myitschool.work.core.Constants import ru.myitschool.work.databinding.FragmentAdminBinding diff --git a/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt b/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt index 1524b9c..b0e43bf 100644 --- a/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt @@ -1,201 +1,98 @@ package ru.myitschool.work.ui.main -import android.graphics.Bitmap -import android.graphics.BitmapFactory import android.os.Bundle import android.view.View -import android.widget.Toast +import android.widget.Button +import android.widget.ImageView +import android.widget.TextView import androidx.fragment.app.Fragment -import androidx.fragment.app.setFragmentResultListener import androidx.lifecycle.lifecycleScope -import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.coroutines.Dispatchers +import androidx.recyclerview.widget.RecyclerView import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory import ru.myitschool.work.R -import ru.myitschool.work.SessionManager -import ru.myitschool.work.api.AccessLog import ru.myitschool.work.api.ApiService +import ru.myitschool.work.api.AccessLog import ru.myitschool.work.core.Constants import ru.myitschool.work.databinding.FragmentMainBinding -import ru.myitschool.work.ui.qr.scan.QrScanDestination -import java.net.HttpURLConnection -import java.net.URL +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import ru.myitschool.work.SessionManager class MainFragment : Fragment(R.layout.fragment_main) { private var _binding: FragmentMainBinding? = null private val binding get() = _binding!! - private val apiService: ApiService by lazy { - Retrofit.Builder() + private lateinit var apiService: ApiService + private lateinit var accessLogAdapter: AccessLogAdapter + private val accessLogs = mutableListOf() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + apiService = Retrofit.Builder() .baseUrl(Constants.SERVER_ADDRESS) .addConverterFactory(GsonConverterFactory.create()) .build() .create(ApiService::class.java) } - private lateinit var accessLogAdapter: AccessLogAdapter - private val accessLogs = mutableListOf() // Список для хранения данных проходов - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - _binding = FragmentMainBinding.bind(view) // Подключаем binding + _binding = FragmentMainBinding.bind(view) setupUI() - fetchUserData() - checkAdminAccess() // Проверяем доступ администратора - - // Проверяем, есть ли результат QR - checkQrResult() - } - - private fun checkAdminAccess() { - // Проверяем, является ли пользователь администратором - if (SessionManager.userRole == "admin") { - binding.adminPanel.visibility = View.VISIBLE // Показываем кнопку AdminPanel - binding.adminPanel.setOnClickListener { - findNavController().navigate(R.id.adminFragment) // Переход на экран администратора - } - } else { - binding.adminPanel.visibility = View.GONE // Скрываем кнопку для обычных пользователей - } - } - - private fun checkQrResult() { - // Слушаем результат QR сканирования - setFragmentResultListener(QrScanDestination.REQUEST_KEY) { _, bundle -> - val qrData = QrScanDestination.getDataIfExist(bundle) - if (qrData != null) { - // Если данные QR есть, переходим на экран с результатом - findNavController().navigate(R.id.qrResultFragment) - } - } + fetchUserInfo() + fetchAccessLogs() } private fun setupUI() { - // Настройка RecyclerView binding.recyclerView.layoutManager = LinearLayoutManager(requireContext()) accessLogAdapter = AccessLogAdapter(accessLogs) binding.recyclerView.adapter = accessLogAdapter - // Проверяем, что binding не null, прежде чем устанавливать слушателей - binding.apply { - refresh.setOnClickListener { fetchUserData() } - logout.setOnClickListener { logout() } - scan.setOnClickListener { navigateToQrScan() } + binding.refresh.setOnClickListener { + fetchUserInfo() + fetchAccessLogs() } } - private fun fetchUserData() { + private fun fetchUserInfo() { lifecycleScope.launch { - showError(null) // Скрыть ошибку, если она была - try { - val response = - SessionManager.userLogin?.let { apiService.getUserInfo(it) } // Получаем данные пользователя - if (response != null) { - if (response.isSuccessful) { - response.body()?.let { data -> - // Извлекаем значения из Map - val fullName = data["name"] as? String ?: "Неизвестно" - val position = data["position"] as? String ?: "Неизвестно" - val lastVisit = data["lastVisit"] as? String ?: "Неизвестно" - val photoUrl = data["photo"] as? String ?: "" + val login = SessionManager.userLogin ?: return@launch + val authHeader = "Basic ${SessionManager.getAuthHeader()}" + val response = apiService.getUserInfo(login, authHeader) - // Обновляем UI - updateUI(fullName, position, lastVisit, photoUrl) - - // Здесь вы можете добавить данные проходов в список - // Пример: - accessLogs.add(AccessLog("2024-02-31 08:31", "Считыватель 1", "карта")) - accessLogAdapter.notifyDataSetChanged() // Обновляем адаптер - } - } else { - showError(getString(R.string.error_loading_data)) // Показываем ошибку, если данные не загрузились - } + if (response.isSuccessful) { + val employeeData = response.body() + employeeData?.let { + binding.fullname.text = it.name + binding.position.text = it.position + binding.lastEntry.text = it.lastVisit + // Здесь можно установить изображение пользователя, если оно доступно + binding.photo.visibility = View.VISIBLE + binding.fullname.visibility = View.VISIBLE + binding.position.visibility = View.VISIBLE + binding.lastEntry.visibility = View.VISIBLE } - } catch (e: Exception) { - showError(e.localizedMessage) // Показываем ошибку при исключении - } - } - } - - private fun updateUI(fullName: String, position1: String, lastVisit: String, photoUrl: String) { - // Проверяем, что binding не null, прежде чем обновлять UI - binding?.apply { - fullname.text = fullName - position.text = position1 - lastEntry.text = lastVisit - if (photoUrl.isNotEmpty()) { - // Загружаем изображение - lifecycleScope.launch { - val bitmap = loadImageFromUrl(photoUrl) - bitmap?.let { photo.setImageBitmap(it) } - } - } - - // Показываем элементы - fullname.visibility = View.VISIBLE - position.visibility = View.VISIBLE - lastEntry.visibility = View.VISIBLE - photo.visibility = View.VISIBLE - logout.visibility = View.VISIBLE - scan.visibility = View.VISIBLE - } - } - - private suspend fun loadImageFromUrl(urlString: String): Bitmap? { - return withContext(Dispatchers.IO) { - try { - val url = URL(urlString) - val connection = url.openConnection() as HttpURLConnection - connection.doInput = true - connection.connect() - val inputStream = connection.inputStream - BitmapFactory.decodeStream(inputStream) - } catch (e: Exception) { - e.printStackTrace() - null - } - } - } - - private fun showError(message: String?) { - // Проверяем, что binding не null, прежде чем обновлять ошибку - binding.apply { - if (message != null) { - error.text = message - error.visibility = View.VISIBLE - - // Скрываем остальные элементы, когда возникает ошибка - fullname.visibility = View.GONE - position.visibility = View.GONE - lastEntry.visibility = View.GONE - photo.visibility = View.GONE - logout.visibility = View.GONE - scan.visibility = View.GONE - recyclerView.visibility = View.GONE // Скрываем RecyclerView при ошибке } else { - error.visibility = View.GONE - recyclerView.visibility = View.VISIBLE // Показываем RecyclerView, если ошибки нет + binding.error.text = "Ошибка получения данных" + binding.error.visibility = View.VISIBLE } } } - private fun logout() { - // Очистите данные пользователя - Toast.makeText(requireContext(), getString(R.string.logged_out), Toast.LENGTH_SHORT).show() - findNavController().navigate(R.id.loginFragment) // Переход на экран входа - } - - private fun navigateToQrScan() { - findNavController().navigate(R.id.qrScanFragment) // Переход на экран сканирования QR + private fun fetchAccessLogs() { + // Здесь вы можете реализовать логику для получения данных о проходах + // Например, вы можете сделать запрос к API для получения списка AccessLog + // Для примера, добавим несколько фиктивных данных + accessLogs.clear() + accessLogs.add(AccessLog("2024-02-31 08:31", "Reader 1", "карта")) + accessLogs.add(AccessLog("2024-02-31 09:00", "Reader 2", "смартфон")) + accessLogAdapter.notifyDataSetChanged() } override fun onDestroyView() { - _binding = null // Освобождаем binding, когда представление уничтожается + _binding = null super.onDestroyView() } } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/Main/MainViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/Main/MainViewModel.kt index e18e24a..3fb2ad1 100644 --- a/app/src/main/java/ru/myitschool/work/ui/Main/MainViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/Main/MainViewModel.kt @@ -1,47 +1,39 @@ package ru.myitschool.work.ui.main +import android.util.Log 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.launch -import ru.myitschool.work.SessionManager import ru.myitschool.work.api.ApiService +import ru.myitschool.work.api.EmployeeData import javax.inject.Inject @HiltViewModel class MainViewModel @Inject constructor( private val apiService: ApiService ) : ViewModel() { - private val _userInfoState = MutableStateFlow?>(null) - val userInfoState: StateFlow?> = _userInfoState - init { - loadUserData() - } + private val _employeeData = MutableStateFlow(null) + val employeeData: StateFlow get() = _employeeData - private fun loadUserData() { + private val _errorMessage = MutableStateFlow(null) + val errorMessage: StateFlow get() = _errorMessage + + fun fetchUserInfo(login: String, authHeader: String) { viewModelScope.launch { try { - val login = SessionManager.userLogin - if (login != null) { - val response = apiService.getUserInfo(login) - if (response.isSuccessful) { - _userInfoState.value = response.body() - } else { - // Обработка ошибки, если ответ не успешен - _userInfoState.value = null // Или установите какое-то состояние ошибки - } + val response = apiService.getUserInfo(login, authHeader) + if (response.isSuccessful) { + _employeeData.value = response.body() } else { - // Логин равен null, обработайте это состояние - _userInfoState.value = null // Или установите какое-то состояние ошибки + _errorMessage.value = "Ошибка получения данных: ${response.message()}" } } catch (e: Exception) { - // Логирование ошибки - e.printStackTrace() - // Установите состояние ошибки - _userInfoState.value = null // Или установите какое-то состояние ошибки + Log.e("MainViewModel", "Error fetching user info", e) + _errorMessage.value = "Ошибка сети: ${e.message}" } } } diff --git a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt index a74667e..15fc52d 100644 --- a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt @@ -8,6 +8,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch +import ru.myitschool.work.SessionManager import javax.inject.Inject @HiltViewModel @@ -31,6 +32,7 @@ class LoginViewModel @Inject constructor( // Проверяем код ответа when (response.code()) { 200 -> { + SessionManager.userLogin = username _state.value = LoginState(success = true) // Успешная авторизация Log.d("LoginViewModel", "Authentication successful") // Логируем успешную аутентификацию } diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index 8106711..19416c9 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -1,110 +1,50 @@ + android:padding="16dp"> - + android:textSize="18sp" /> - + android:contentDescription="@string/photo_description" /> - + android:textSize="16sp" /> - + android:textSize="14sp" /> -