Merge branch 'refs/heads/Frontend'

This commit is contained in:
EgorVorobev 2025-02-20 16:48:21 +03:00
commit 636b2a22fc
22 changed files with 537 additions and 318 deletions

View File

@ -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

View File

@ -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

View File

@ -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-backups1146231745401124119
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

View File

@ -1,9 +1,9 @@
plugins {
kotlinAndroid
androidApplication
jetbrainsKotlinSerialization version Version.Kotlin.language
kotlinAnnotationProcessor
id("com.google.dagger.hilt.android").version("2.51.1")
id("com.android.application")
id("kotlin-android")
id("kotlin-kapt") // Добавлено для KAPT
id("dagger.hilt.android.plugin") // Используйте этот синтаксис для Hilt
id("org.jetbrains.kotlin.plugin.serialization") version Version.Kotlin.language // Убедитесь, что версия актуальна
}
val packageName = "ru.myitschool.work"
@ -22,9 +22,9 @@ android {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildFeatures.viewBinding = true
buildFeatures {
viewBinding = true
}
compileOptions {
sourceCompatibility = Version.Kotlin.javaSource
@ -37,38 +37,41 @@ android {
}
dependencies {
implementation ("com.squareup.retrofit2:retrofit:2.9.0")
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
implementation ("com.squareup.okhttp3:okhttp:4.9.0")
implementation ("com.github.bumptech.glide:glide:4.15.1")
// Retrofit and OkHttp
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:okhttp:4.9.0")
// Glide
implementation("com.github.bumptech.glide:glide:4.15.1")
kapt("com.github.bumptech.glide:compiler:4.15.1")
// AndroidX Libraries
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.10.0")
implementation("androidx.activity:activity:1.10.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
kapt ("com.github.bumptech.glide:compiler:4.15.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.1")
defaultLibrary()
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
implementation(Dependencies.AndroidX.activity)
implementation(Dependencies.AndroidX.fragment)
implementation(Dependencies.AndroidX.constraintLayout)
// Hilt dependencies
implementation("com.google.dagger:hilt-android:2.51.1")
kapt("com.google.dagger:hilt-android-compiler:2.51.1")
// Navigation
implementation(Dependencies.AndroidX.Navigation.fragment)
implementation(Dependencies.AndroidX.Navigation.navigationUi)
implementation(Dependencies.Retrofit.library)
implementation(Dependencies.Retrofit.gsonConverter)
implementation("com.squareup.picasso:picasso:2.8")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
// DataStore
implementation("androidx.datastore:datastore-preferences:1.1.1")
// ML Kit
implementation("com.google.mlkit:barcode-scanning:17.3.0")
// CameraX
val cameraX = "1.3.4"
implementation("androidx.camera:camera-core:$cameraX")
implementation("androidx.camera:camera-camera2:$cameraX")
@ -76,11 +79,13 @@ dependencies {
implementation("androidx.camera:camera-view:$cameraX")
implementation("androidx.camera:camera-mlkit-vision:1.4.0-rc04")
val hilt = "2.51.1"
implementation("com.google.dagger:hilt-android:$hilt")
kapt("com.google.dagger:hilt-android-compiler:$hilt")
// Picasso
implementation("com.squareup.picasso:picasso:2.8")
// Kotlin Serialization
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
}
kapt {
correctErrorTypes = true
}
}

View File

@ -33,6 +33,7 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -4,4 +4,9 @@ import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class App : Application()
class App : Application() {
override fun onCreate() {
super.onCreate()
SessionManager.init(this) // Инициализация SessionManager
}
}

View File

@ -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

View File

@ -1,5 +1,6 @@
package ru.myitschool.work.api
import LoggingInterceptor
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -7,7 +8,6 @@ import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import ru.myitschool.work.core.Constants
import javax.inject.Singleton
@Module
@ -16,19 +16,26 @@ object ApiModule {
@Provides
@Singleton
fun provideOkHttpClient(): OkHttpClient {
fun provideOkHttpClient(authInterceptor: AuthInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(authInterceptor) // Добавляем интерсептор аутентификации
.addInterceptor(LoggingInterceptor()) // Добавляем интерсептор логирования
.build()
}
@Provides
@Singleton
fun provideAuthInterceptor(): AuthInterceptor {
val username = "pivanov" // Замените на ваш логин
val password = "password123" // Замените на ваш пароль
return OkHttpClient.Builder()
.addInterceptor(AuthInterceptor(username, password))
.build()
return AuthInterceptor(username, password)
}
@Provides
@Singleton
fun provideRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(Constants.SERVER_ADDRESS)
.baseUrl("http://10.6.66.110:8080/") // Убедитесь, что URL корректен
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()

View File

@ -3,6 +3,7 @@ package ru.myitschool.work.api
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
@ -10,21 +11,26 @@ import retrofit2.http.Query
interface ApiService {
// Метод для аутентификации
@GET("/api/auth") // Используем GET для аутентификации
@GET("/api/auth")
suspend fun authenticate(
@Query("login") login: String, // Передаем логин как параметр запроса
@Query("password") password: String // Передаем пароль как параметр запроса
): Response<UserAuthResponse> // Возвращаем JSON как объект UserAuthResponse
@Query("login") login: String,
@Query("password") password: String
): Response<Unit> // Измените Response<String> на Response<Unit>
// Другие методы...
@GET("/api/{login}/info") // Получение информации о пользователе
suspend fun getUserInfo(@Path("login") login: String): Response<Map<String, Any>>
@GET("/api/{login}/info")
suspend fun getUserInfo(
@Path("login") login: String,
@Header("Authorization") authHeader: String
): Response<EmployeeData>
@GET("/api/employee/{login}") // Получение информации о сотруднике
suspend fun getEmployeeInfo(@Path("login") login: String): Response<EmployeeData>
@PATCH("/api/open") // Открыть дверь
suspend fun openDoor(@Body request: OpenDoorRequest): Response<String>
suspend fun openDoor(
@Header("Authorization") authHeader: String,
@Body request: OpenDoorRequest
): Response<Unit> // Измените Response<String> на Response<Unit>
@POST("/api/employee/toggleAccess") // Метод для блокировки/разблокировки доступа
suspend fun toggleAccess(@Body request: ToggleAccessRequest): Response<Unit>
@ -33,16 +39,12 @@ interface ApiService {
suspend fun getAllWorkers(): Response<List<EmployeeData>>
}
// Модель данных для ответа аутентификации
data class UserAuthResponse(
val role: String // Добавляем поле для роли
)
// Модель данных для информации о сотруднике
data class EmployeeData(
val name: String,
val position: String,
val lastVisit: String
val lastVisit: String,
val avatarUrl: String? // Добавьте это поле
)
// Модель данных для запроса блокировки/разблокировки доступа
@ -53,6 +55,5 @@ data class ToggleAccessRequest(
// Модель данных для запроса открытия двери
data class OpenDoorRequest(
val login: String, // Логин сотрудника
val value: Long // Код для открытия двери
)

View File

@ -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
}
}

View File

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

View File

@ -1,4 +1,4 @@
package ru.myitschool.work.ui.Main
package ru.myitschool.work.ui.main
import android.os.Bundle
import android.view.View
@ -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

View File

@ -1,201 +1,144 @@
package ru.myitschool.work.ui.main
import android.graphics.Bitmap
import android.graphics.BitmapFactory
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.setFragmentResultListener
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.coroutines.Dispatchers
import com.squareup.picasso.Picasso
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.EmployeeData
import ru.myitschool.work.core.Constants
import ru.myitschool.work.databinding.FragmentMainBinding
import ru.myitschool.work.SessionManager
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import ru.myitschool.work.ui.qr.scan.QrScanDestination
import java.net.HttpURLConnection
import java.net.URL
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
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<AccessLog>() // Список для хранения данных проходов
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentMainBinding.bind(view) // Подключаем binding
_binding = FragmentMainBinding.bind(view)
setupUI()
fetchUserData()
checkAdminAccess() // Проверяем доступ администратора
fetchUserInfo()
// Проверяем, есть ли результат 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)
val resultBundle = QrScanDestination.packToBundle(qrData)
findNavController().navigate(R.id.qrResultFragment, resultBundle)
} else {
Toast.makeText(requireContext(), "QR данные не найдены", Toast.LENGTH_SHORT).show()
}
}
}
private fun setupUI() {
// Настройка RecyclerView
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
accessLogAdapter = AccessLogAdapter(accessLogs)
binding.recyclerView.adapter = accessLogAdapter
binding.refresh.setOnClickListener {
fetchUserInfo()
}
// Проверяем, что binding не null, прежде чем устанавливать слушателей
binding.apply {
refresh.setOnClickListener { fetchUserData() }
logout.setOnClickListener { logout() }
scan.setOnClickListener { navigateToQrScan() }
binding.scanQrCode?.setOnClickListener {
// Переход к экрану сканирования QR-кода
findNavController().navigate(R.id.qrScanFragment) // Убедитесь, что у вас есть правильный ID для навигации
}
// Проверяем роль пользователя и показываем кнопку AdminPanel, если роль admin
if (SessionManager.userRole == "admin") {
binding.adminPanelButton?.visibility = View.VISIBLE
binding.adminPanelButton?.setOnClickListener {
findNavController().navigate(R.id.adminFragment) // Переход к экрану администратора
}
} else {
binding.adminPanelButton?.visibility = View.GONE // Скрываем кнопку, если не admin
}
}
private fun fetchUserData() {
private fun fetchUserInfo() {
lifecycleScope.launch {
showError(null) // Скрыть ошибку, если она была
val login = SessionManager.userLogin ?: run {
binding.error.text = "Пользователь не авторизован"
binding.error.visibility = View.VISIBLE
return@launch
}
val authHeader = SessionManager.getAuthHeader() ?: run {
binding.error.text = "Ошибка авторизации"
binding.error.visibility = View.VISIBLE
return@launch
}
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 response = apiService.getUserInfo(login, authHeader)
// Обновляем UI
updateUI(fullName, position, lastVisit, photoUrl)
// Логируем код ответа
Log.d("MainFragment", "Response code: ${response.code()}")
// Здесь вы можете добавить данные проходов в список
// Пример:
accessLogs.add(AccessLog("2024-02-31 08:31", "Считыватель 1", "карта"))
accessLogAdapter.notifyDataSetChanged() // Обновляем адаптер
if (response.isSuccessful) {
val employeeData = response.body()
employeeData?.let {
binding.fullname.text = it.name
binding.position.text = it.position
binding.lastEntry.text = it.lastVisit
// Логируем URL аватара
Log.d("MainFragment", "Avatar URL: ${it.avatarUrl}")
// Загрузка аватара с помощью Picasso
if (it.avatarUrl != null) {
Picasso.get()
.load(it.avatarUrl)
.placeholder(R.drawable.ic_refresh) // Замените на ваш ресурс-заполнитель
.error(R.drawable.ic_close) // Замените на ваш ресурс ошибки
.into(binding.photo)
binding.photo.visibility = View.VISIBLE
} else {
binding.photo.visibility = View.GONE // Скрыть, если URL нет
}
} else {
showError(getString(R.string.error_loading_data)) // Показываем ошибку, если данные не загрузились
// Показываем кнопку "Сканировать QR-код" после успешного получения данных
binding.scanQrCode?.visibility = View.VISIBLE
}
} else {
binding.error.text = "Ошибка получения данных: ${response.message()}"
binding.error.visibility = View.VISIBLE
}
} catch (e: Exception) {
showError(e.localizedMessage) // Показываем ошибку при исключении
Log.e("MainFragment", "Error fetching user info", e)
binding.error.text = "Ошибка сети: ${e.message}"
binding.error.visibility = View.VISIBLE
}
}
}
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, если ошибки нет
}
}
}
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
}
override fun onDestroyView() {
_binding = null // Освобождаем binding, когда представление уничтожается
_binding = null
super.onDestroyView()
}
}

View File

@ -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<Map<String, Any>?>(null)
val userInfoState: StateFlow<Map<String, Any>?> = _userInfoState
init {
loadUserData()
}
private val _employeeData = MutableStateFlow<EmployeeData?>(null)
val employeeData: StateFlow<EmployeeData?> get() = _employeeData
private fun loadUserData() {
private val _errorMessage = MutableStateFlow<String?>(null)
val errorMessage: StateFlow<String?> 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}"
}
}
}

View File

@ -44,4 +44,4 @@ class RootActivity : AppCompatActivity() {
}
return popBackResult || super.onSupportNavigateUp()
}
}
}

View File

@ -1,5 +1,6 @@
package ru.myitschool.work.ui.login
import ru.myitschool.work.api.ApiService
import android.os.Bundle
import android.text.Editable
import android.text.InputType
@ -15,7 +16,6 @@ import androidx.navigation.fragment.findNavController
import dagger.hilt.android.AndroidEntryPoint
import ru.myitschool.work.R
import ru.myitschool.work.SessionManager
import ru.myitschool.work.api.UserAuthResponse
import ru.myitschool.work.databinding.FragmentLoginBinding
import ru.myitschool.work.utils.collectWhenStarted
import ru.myitschool.work.utils.visibleOrGone
@ -40,7 +40,7 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
super.onViewCreated(view, savedInstanceState) // Убедитесь, что этот вызов находится здесь
_binding = FragmentLoginBinding.bind(view)
setupUI()
@ -96,12 +96,6 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
authPreferences.saveLoginState(true)
authPreferences.saveLogin(binding.username.text.toString()) // Сохраняем логин
// Сохраняем роль пользователя в SessionManager
val userAuthResponse: UserAuthResponse? = state.userAuthResponse
userAuthResponse?.let {
SessionManager.userRole = it.role // Сохраняем роль
}
Toast.makeText(context, "Авторизация прошла успешно", Toast.LENGTH_SHORT).show()
navigateToMainScreen() // Перенаправление на следующий экран
} else if (state.error != null) {

View File

@ -1,5 +1,6 @@
package ru.myitschool.work.ui.login
import ru.myitschool.work.api.ApiService
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -8,8 +9,6 @@ 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.UserAuthResponse
import javax.inject.Inject
@HiltViewModel
@ -21,34 +20,40 @@ class LoginViewModel @Inject constructor(
val state: StateFlow<LoginState> get() = _state
fun authenticate(username: String, password: String) {
Log.d("LoginViewModel", "Authenticating user: $username") // Логируем начало аутентификации
if (isValidUsername(username)) {
viewModelScope.launch {
try {
Log.d("LoginViewModel", "Sending authentication request to server") // Логируем отправку запроса
val response = apiService.authenticate(username, password)
Log.d("LoginViewModel", "Response code: ${response.code()}")
Log.d("LoginViewModel", "Response code: ${response.code()}") // Логируем код ответа
if (response.isSuccessful) {
val userAuthResponse = response.body() // Получаем JSON-ответ
Log.d("LoginViewModel", "User Auth Response: $userAuthResponse") // Логируем ответ
// Обработка JSON-ответа
if (userAuthResponse != null) {
// Проверяем код ответа
when (response.code()) {
200 -> {
SessionManager.userLogin = username
SessionManager.userRole = userAuthResponse.role // Сохраняем роль
_state.value = LoginState(success = true) // Успешная авторизация
} else {
_state.value = LoginState(error = "Ошибка авторизации: Неверные учетные данные.")
Log.d("LoginViewModel", "Authentication successful") // Логируем успешную аутентификацию
}
400 -> {
_state.value = LoginState(error = "Ошибка авторизации: Неверные учетные данные.")
Log.d("LoginViewModel", "Authentication failed: Invalid credentials") // Логируем ошибку
}
else -> {
_state.value = LoginState(error = "Ошибка авторизации: ${response.message()}")
Log.d("LoginViewModel", "Authentication failed: ${response.message()}") // Логируем ошибку
}
} else {
_state.value = LoginState(error = "Ошибка авторизации: ${response.message()}")
}
} catch (e: Exception) {
e.printStackTrace()
_state.value = LoginState(error = "Ошибка сети. Проверьте подключение к интернету.")
Log.e("LoginViewModel", "Network error: ${e.message}") // Логируем ошибку сети
}
}
} else {
_state.value = LoginState(error = "Неправильный логин")
Log.d("LoginViewModel", "Invalid username: $username") // Логируем неправильный логин
}
}
@ -60,7 +65,6 @@ class LoginViewModel @Inject constructor(
// Состояние аутентификации
data class LoginState(
val success: Boolean = false, // Успешность аутентификации
val userAuthResponse: UserAuthResponse? = null, // Ответ с информацией о пользователе
val error: String? = null, // Сообщение об ошибке
val maintenance: Boolean = false // Состояние техобслуживания
)

View File

@ -5,8 +5,10 @@ import androidx.navigation.fragment.findNavController
import ru.myitschool.work.SessionManager
import ru.myitschool.work.api.OpenDoorRequest
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.util.Base64
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
@ -19,7 +21,9 @@ import ru.myitschool.work.core.Constants
import ru.myitschool.work.databinding.FragmentQrScanResultBinding
class QrResult : Fragment(R.layout.fragment_qr_scan_result) {
private lateinit var binding: FragmentQrScanResultBinding
private var _binding: FragmentQrScanResultBinding? = null
private val binding get() = _binding!!
private lateinit var apiService: ApiService
override fun onCreateView(
@ -27,7 +31,7 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) {
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentQrScanResultBinding.inflate(inflater, container, false)
_binding = FragmentQrScanResultBinding.inflate(inflater, container, false)
apiService = Retrofit.Builder()
.baseUrl(Constants.SERVER_ADDRESS)
.addConverterFactory(GsonConverterFactory.create())
@ -40,8 +44,12 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Получаем данные из аргументов
val qrData = QrScanDestination.getDataIfExist(requireArguments())
Log.d("QrResult", "QR Data: $qrData") // Логируем полученные данные
if (qrData != null) {
binding.result.text = "Результат сканирования: $qrData" // Отображаем результат сканирования
sendRequestToServer(qrData)
} else {
binding.result.text = "Вход был отменён/Operation was cancelled"
@ -55,23 +63,40 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) {
private fun sendRequestToServer(qrData: String) {
lifecycleScope.launch {
try {
// Проверяем, что userLogin не равен null
val login = SessionManager.userLogin
if (login != null) {
// Создаем объект OpenDoorRequest с логином и кодом
val openDoorRequest = OpenDoorRequest(login, qrData.toLong()) // Преобразуем qrData в Long, если это необходимо
val response = apiService.openDoor(openDoorRequest) // Теперь передаем только openDoorRequest
if (response.isSuccessful) {
binding.result.text = "Успешно/Success"
} else {
binding.result.text = "Что-то пошло не так/Something wrong"
}
val qrValue = qrData.toLong() // Преобразуем данные QR-кода в Long
val login = SessionManager.userLogin ?: "default_login" // Замените на ваш логин
val password = "your_password" // Замените на ваш пароль
val authHeader = "Basic " + Base64.encodeToString("$login:$password".toByteArray(), Base64.NO_WRAP)
// Логируем данные перед отправкой
Log.d("QrResult", "Sending request with QR value: $qrValue and authHeader: $authHeader")
// Создаем объект запроса
val request = OpenDoorRequest(qrValue)
// Вызываем метод openDoor с правильными параметрами
val response = apiService.openDoor(authHeader, request)
// Логируем код ответа и тело ответа
Log.d("QrResult", "Response code: ${response.code()}")
Log.d("QrResult", "Response body: ${response.body()}")
if (response.isSuccessful) {
binding.result.text = "Door Opened" // Сообщение о том, что дверь открыта
} else {
binding.result.text = "Пользователь не авторизован/Unauthorized user"
binding.result.text = "Door Closed" // Сообщение о том, что дверь закрыта
}
} catch (e: NumberFormatException) {
binding.result.text = "Некорректные данные QR-кода"
} catch (e: Exception) {
binding.result.text = "Что-то пошло не так/Something wrong"
binding.result.text = "Что-то пошло не так/Something went wrong: ${e.message}"
Log.e("QrResult", "Error sending request to server", e)
}
}
}
override fun onDestroyView() {
_binding = null
super.onDestroyView()
}
}

View File

@ -1,110 +1,65 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:gravity="bottom"
android:padding="16dp"
android:background="@android:color/white">
android:padding="16dp">
<!-- Поле для ФИО -->
<TextView
android:id="@+id/fullname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fullname_label"
android:textSize="18sp"
android:layout_marginBottom="5dp"
android:visibility="gone" />
android:textSize="18sp" />
<!-- Фото пользователя. -->
<ImageView
android:id="@+id/photo"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:contentDescription="@string/photo_description"
android:layout_marginBottom="5dp"
android:visibility="gone" />
android:contentDescription="@string/photo_description" />
<!-- Поле для должности -->
<TextView
android:id="@+id/position"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/position_label"
android:layout_marginBottom="5dp"
android:visibility="gone" />
android:textSize="16sp" />
<!-- Поле для даты последнего входа -->
<TextView
android:id="@+id/lastEntry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2024-02-31 08:31"
android:layout_marginBottom="75dp"
android:visibility="gone" />
android:textSize="14sp" />
<!-- Кнопка обновления -->
<Button
android:id="@+id/refresh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/refresh"
app:cornerRadius="16dp"
android:backgroundTint="@color/colorPrimary"
android:textColor="@android:color/white"
android:layout_marginBottom="12dp"
android:padding="12dp"/>
android:text="@string/refresh" />
<!-- Поле ошибки -->
<TextView
android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/error_placeholder"
android:textColor="@android:color/holo_red_dark"
android:visibility="gone" />
<!-- RecyclerView для списка проходов -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="gone" />
android:layout_weight="1" />
<!-- Кнопки -->
<Button
android:id="@+id/scan"
android:id="@+id/scan_qr_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/scan_qr_code"
android:layout_marginBottom="12dp"
android:backgroundTint="@color/colorPrimary"
app:cornerRadius="16dp"
android:textColor="@android:color/white"
android:text="Сканировать QR-код"
android:visibility="gone" />
<Button
android:id="@+id/logout"
android:id="@+id/adminPanelButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/logout"
android:layout_marginBottom="50dp"
app:cornerRadius="16dp"
android:backgroundTint="@color/colorPrimary"
android:textColor="@android:color/white"
android:visibility="gone" />
<Button
android:id="@+id/admin_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/admin_panel"
app:cornerRadius="16dp"
android:backgroundTint="@color/colorPrimary"
android:layout_marginTop="16dp"
android:text="Admin Panel"
android:visibility="gone" />
</LinearLayout>

View File

@ -27,5 +27,4 @@
android:textColor="@android:color/white"
android:padding="12dp"
android:layout_marginTop="24dp" />
</LinearLayout>

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -8,20 +9,17 @@
android:id="@+id/scan_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Время сканирования"
android:textSize="16sp" />
android:textSize="14sp" />
<TextView
android:id="@+id/reader_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Идентификатор считывателя"
android:textSize="16sp" />
android:textSize="14sp" />
<TextView
android:id="@+id/access_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Тип прохода"
android:textSize="16sp" />
android:textSize="14sp" />
</LinearLayout>

View File

@ -24,7 +24,7 @@
<fragment
android:id="@+id/adminFragment"
android:name="ru.myitschool.work.ui.admin.AdminFragment"
android:name="ru.myitschool.work.ui.main.AdminFragment"
android:label="Admin Fragment"
tools:layout="@layout/fragment_admin" />