Merge branch 'refs/heads/Frontend'
This commit is contained in:
commit
636b2a22fc
82
.kotlin/errors/errors-1740038374254.log
Normal file
82
.kotlin/errors/errors-1740038374254.log
Normal 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
|
||||||
|
|
||||||
|
|
82
.kotlin/errors/errors-1740039190766.log
Normal file
82
.kotlin/errors/errors-1740039190766.log
Normal 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
|
||||||
|
|
||||||
|
|
82
.kotlin/errors/errors-1740053232762.log
Normal file
82
.kotlin/errors/errors-1740053232762.log
Normal 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
|
||||||
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlinAndroid
|
id("com.android.application")
|
||||||
androidApplication
|
id("kotlin-android")
|
||||||
jetbrainsKotlinSerialization version Version.Kotlin.language
|
id("kotlin-kapt") // Добавлено для KAPT
|
||||||
kotlinAnnotationProcessor
|
id("dagger.hilt.android.plugin") // Используйте этот синтаксис для Hilt
|
||||||
id("com.google.dagger.hilt.android").version("2.51.1")
|
id("org.jetbrains.kotlin.plugin.serialization") version Version.Kotlin.language // Убедитесь, что версия актуальна
|
||||||
}
|
}
|
||||||
|
|
||||||
val packageName = "ru.myitschool.work"
|
val packageName = "ru.myitschool.work"
|
||||||
@ -22,9 +22,9 @@ android {
|
|||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
||||||
buildFeatures.viewBinding = true
|
buildFeatures {
|
||||||
|
viewBinding = true
|
||||||
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = Version.Kotlin.javaSource
|
sourceCompatibility = Version.Kotlin.javaSource
|
||||||
@ -37,38 +37,41 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation ("com.squareup.retrofit2:retrofit:2.9.0")
|
// Retrofit and OkHttp
|
||||||
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
|
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||||
implementation ("com.squareup.okhttp3:okhttp:4.9.0")
|
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||||
implementation ("com.github.bumptech.glide:glide:4.15.1")
|
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("androidx.appcompat:appcompat:1.6.1")
|
||||||
implementation("com.google.android.material:material:1.10.0")
|
implementation("com.google.android.material:material:1.10.0")
|
||||||
implementation("androidx.activity:activity:1.10.0")
|
implementation("androidx.activity:activity:1.10.0")
|
||||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
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")
|
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)
|
// Hilt dependencies
|
||||||
implementation(Dependencies.AndroidX.fragment)
|
implementation("com.google.dagger:hilt-android:2.51.1")
|
||||||
implementation(Dependencies.AndroidX.constraintLayout)
|
kapt("com.google.dagger:hilt-android-compiler:2.51.1")
|
||||||
|
|
||||||
|
// Navigation
|
||||||
implementation(Dependencies.AndroidX.Navigation.fragment)
|
implementation(Dependencies.AndroidX.Navigation.fragment)
|
||||||
implementation(Dependencies.AndroidX.Navigation.navigationUi)
|
implementation(Dependencies.AndroidX.Navigation.navigationUi)
|
||||||
|
|
||||||
implementation(Dependencies.Retrofit.library)
|
// DataStore
|
||||||
implementation(Dependencies.Retrofit.gsonConverter)
|
|
||||||
|
|
||||||
|
|
||||||
implementation("com.squareup.picasso:picasso:2.8")
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
|
|
||||||
implementation("androidx.datastore:datastore-preferences:1.1.1")
|
implementation("androidx.datastore:datastore-preferences:1.1.1")
|
||||||
|
|
||||||
|
// ML Kit
|
||||||
implementation("com.google.mlkit:barcode-scanning:17.3.0")
|
implementation("com.google.mlkit:barcode-scanning:17.3.0")
|
||||||
|
|
||||||
|
// CameraX
|
||||||
val cameraX = "1.3.4"
|
val cameraX = "1.3.4"
|
||||||
implementation("androidx.camera:camera-core:$cameraX")
|
implementation("androidx.camera:camera-core:$cameraX")
|
||||||
implementation("androidx.camera:camera-camera2:$cameraX")
|
implementation("androidx.camera:camera-camera2:$cameraX")
|
||||||
@ -76,11 +79,13 @@ dependencies {
|
|||||||
implementation("androidx.camera:camera-view:$cameraX")
|
implementation("androidx.camera:camera-view:$cameraX")
|
||||||
implementation("androidx.camera:camera-mlkit-vision:1.4.0-rc04")
|
implementation("androidx.camera:camera-mlkit-vision:1.4.0-rc04")
|
||||||
|
|
||||||
val hilt = "2.51.1"
|
// Picasso
|
||||||
implementation("com.google.dagger:hilt-android:$hilt")
|
implementation("com.squareup.picasso:picasso:2.8")
|
||||||
kapt("com.google.dagger:hilt-android-compiler:$hilt")
|
|
||||||
|
// Kotlin Serialization
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
kapt {
|
kapt {
|
||||||
correctErrorTypes = true
|
correctErrorTypes = true
|
||||||
}
|
}
|
@ -33,6 +33,7 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
@ -4,4 +4,9 @@ import android.app.Application
|
|||||||
import dagger.hilt.android.HiltAndroidApp
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class App : Application()
|
class App : Application() {
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
SessionManager.init(this) // Инициализация SessionManager
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,39 @@
|
|||||||
package ru.myitschool.work
|
package ru.myitschool.work
|
||||||
|
|
||||||
object SessionManager {
|
import android.content.Context
|
||||||
var userLogin: String? = null // Логин пользователя
|
import android.content.SharedPreferences
|
||||||
var userRole: String? = null // Роль пользователя
|
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() {
|
fun clearSession() {
|
||||||
userLogin = null
|
userLogin = null
|
||||||
userRole = null
|
userRole = null
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package ru.myitschool.work.api
|
package ru.myitschool.work.api
|
||||||
|
|
||||||
|
import LoggingInterceptor
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
@ -7,7 +8,6 @@ import dagger.hilt.components.SingletonComponent
|
|||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
import retrofit2.converter.gson.GsonConverterFactory
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
import ru.myitschool.work.core.Constants
|
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@ -16,19 +16,26 @@ object ApiModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@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 username = "pivanov" // Замените на ваш логин
|
||||||
val password = "password123" // Замените на ваш пароль
|
val password = "password123" // Замените на ваш пароль
|
||||||
return OkHttpClient.Builder()
|
return AuthInterceptor(username, password)
|
||||||
.addInterceptor(AuthInterceptor(username, password))
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideRetrofit(client: OkHttpClient): Retrofit {
|
fun provideRetrofit(client: OkHttpClient): Retrofit {
|
||||||
return Retrofit.Builder()
|
return Retrofit.Builder()
|
||||||
.baseUrl(Constants.SERVER_ADDRESS)
|
.baseUrl("http://10.6.66.110:8080/") // Убедитесь, что URL корректен
|
||||||
.client(client)
|
.client(client)
|
||||||
.addConverterFactory(GsonConverterFactory.create())
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
.build()
|
.build()
|
||||||
|
@ -3,6 +3,7 @@ package ru.myitschool.work.api
|
|||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Header
|
||||||
import retrofit2.http.PATCH
|
import retrofit2.http.PATCH
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
import retrofit2.http.Path
|
import retrofit2.http.Path
|
||||||
@ -10,21 +11,26 @@ import retrofit2.http.Query
|
|||||||
|
|
||||||
interface ApiService {
|
interface ApiService {
|
||||||
// Метод для аутентификации
|
// Метод для аутентификации
|
||||||
@GET("/api/auth") // Используем GET для аутентификации
|
@GET("/api/auth")
|
||||||
suspend fun authenticate(
|
suspend fun authenticate(
|
||||||
@Query("login") login: String, // Передаем логин как параметр запроса
|
@Query("login") login: String,
|
||||||
@Query("password") password: String // Передаем пароль как параметр запроса
|
@Query("password") password: String
|
||||||
): Response<UserAuthResponse> // Возвращаем JSON как объект UserAuthResponse
|
): Response<Unit> // Измените Response<String> на Response<Unit>
|
||||||
|
|
||||||
// Другие методы...
|
@GET("/api/{login}/info")
|
||||||
@GET("/api/{login}/info") // Получение информации о пользователе
|
suspend fun getUserInfo(
|
||||||
suspend fun getUserInfo(@Path("login") login: String): Response<Map<String, Any>>
|
@Path("login") login: String,
|
||||||
|
@Header("Authorization") authHeader: String
|
||||||
|
): Response<EmployeeData>
|
||||||
|
|
||||||
@GET("/api/employee/{login}") // Получение информации о сотруднике
|
@GET("/api/employee/{login}") // Получение информации о сотруднике
|
||||||
suspend fun getEmployeeInfo(@Path("login") login: String): Response<EmployeeData>
|
suspend fun getEmployeeInfo(@Path("login") login: String): Response<EmployeeData>
|
||||||
|
|
||||||
@PATCH("/api/open") // Открыть дверь
|
@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") // Метод для блокировки/разблокировки доступа
|
@POST("/api/employee/toggleAccess") // Метод для блокировки/разблокировки доступа
|
||||||
suspend fun toggleAccess(@Body request: ToggleAccessRequest): Response<Unit>
|
suspend fun toggleAccess(@Body request: ToggleAccessRequest): Response<Unit>
|
||||||
@ -33,16 +39,12 @@ interface ApiService {
|
|||||||
suspend fun getAllWorkers(): Response<List<EmployeeData>>
|
suspend fun getAllWorkers(): Response<List<EmployeeData>>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Модель данных для ответа аутентификации
|
|
||||||
data class UserAuthResponse(
|
|
||||||
val role: String // Добавляем поле для роли
|
|
||||||
)
|
|
||||||
|
|
||||||
// Модель данных для информации о сотруднике
|
// Модель данных для информации о сотруднике
|
||||||
data class EmployeeData(
|
data class EmployeeData(
|
||||||
val name: String,
|
val name: String,
|
||||||
val position: String,
|
val position: String,
|
||||||
val lastVisit: String
|
val lastVisit: String,
|
||||||
|
val avatarUrl: String? // Добавьте это поле
|
||||||
)
|
)
|
||||||
|
|
||||||
// Модель данных для запроса блокировки/разблокировки доступа
|
// Модель данных для запроса блокировки/разблокировки доступа
|
||||||
@ -53,6 +55,5 @@ data class ToggleAccessRequest(
|
|||||||
|
|
||||||
// Модель данных для запроса открытия двери
|
// Модель данных для запроса открытия двери
|
||||||
data class OpenDoorRequest(
|
data class OpenDoorRequest(
|
||||||
val login: String, // Логин сотрудника
|
|
||||||
val value: Long // Код для открытия двери
|
val value: Long // Код для открытия двери
|
||||||
)
|
)
|
15
app/src/main/java/ru/myitschool/work/api/LoginInterceptor.kt
Normal file
15
app/src/main/java/ru/myitschool/work/api/LoginInterceptor.kt
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -2,4 +2,5 @@ package ru.myitschool.work.core
|
|||||||
// БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ
|
// БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ
|
||||||
object Constants {
|
object Constants {
|
||||||
const val SERVER_ADDRESS = "http://10.6.66.110:8080"
|
const val SERVER_ADDRESS = "http://10.6.66.110:8080"
|
||||||
|
//,
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package ru.myitschool.work.ui.Main
|
package ru.myitschool.work.ui.main
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -10,7 +10,6 @@ import retrofit2.Retrofit
|
|||||||
import retrofit2.converter.gson.GsonConverterFactory
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
import ru.myitschool.work.R
|
import ru.myitschool.work.R
|
||||||
import ru.myitschool.work.api.ApiService
|
import ru.myitschool.work.api.ApiService
|
||||||
import ru.myitschool.work.api.EmployeeData
|
|
||||||
import ru.myitschool.work.api.ToggleAccessRequest
|
import ru.myitschool.work.api.ToggleAccessRequest
|
||||||
import ru.myitschool.work.core.Constants
|
import ru.myitschool.work.core.Constants
|
||||||
import ru.myitschool.work.databinding.FragmentAdminBinding
|
import ru.myitschool.work.databinding.FragmentAdminBinding
|
||||||
|
@ -1,201 +1,144 @@
|
|||||||
package ru.myitschool.work.ui.main
|
package ru.myitschool.work.ui.main
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.setFragmentResultListener
|
import androidx.fragment.app.setFragmentResultListener
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import com.squareup.picasso.Picasso
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
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.R
|
||||||
import ru.myitschool.work.SessionManager
|
|
||||||
import ru.myitschool.work.api.AccessLog
|
|
||||||
import ru.myitschool.work.api.ApiService
|
import ru.myitschool.work.api.ApiService
|
||||||
|
import ru.myitschool.work.api.EmployeeData
|
||||||
import ru.myitschool.work.core.Constants
|
import ru.myitschool.work.core.Constants
|
||||||
import ru.myitschool.work.databinding.FragmentMainBinding
|
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 ru.myitschool.work.ui.qr.scan.QrScanDestination
|
||||||
import java.net.HttpURLConnection
|
|
||||||
import java.net.URL
|
|
||||||
|
|
||||||
class MainFragment : Fragment(R.layout.fragment_main) {
|
class MainFragment : Fragment(R.layout.fragment_main) {
|
||||||
private var _binding: FragmentMainBinding? = null
|
private var _binding: FragmentMainBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
private val apiService: ApiService by lazy {
|
private lateinit var apiService: ApiService
|
||||||
Retrofit.Builder()
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
apiService = Retrofit.Builder()
|
||||||
.baseUrl(Constants.SERVER_ADDRESS)
|
.baseUrl(Constants.SERVER_ADDRESS)
|
||||||
.addConverterFactory(GsonConverterFactory.create())
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
.build()
|
.build()
|
||||||
.create(ApiService::class.java)
|
.create(ApiService::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var accessLogAdapter: AccessLogAdapter
|
|
||||||
private val accessLogs = mutableListOf<AccessLog>() // Список для хранения данных проходов
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
_binding = FragmentMainBinding.bind(view) // Подключаем binding
|
_binding = FragmentMainBinding.bind(view)
|
||||||
|
|
||||||
setupUI()
|
setupUI()
|
||||||
fetchUserData()
|
fetchUserInfo()
|
||||||
checkAdminAccess() // Проверяем доступ администратора
|
|
||||||
|
|
||||||
// Проверяем, есть ли результат QR
|
// Проверяем, есть ли результат QR
|
||||||
checkQrResult()
|
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() {
|
private fun checkQrResult() {
|
||||||
// Слушаем результат QR сканирования
|
// Слушаем результат QR сканирования
|
||||||
setFragmentResultListener(QrScanDestination.REQUEST_KEY) { _, bundle ->
|
setFragmentResultListener(QrScanDestination.REQUEST_KEY) { _, bundle ->
|
||||||
val qrData = QrScanDestination.getDataIfExist(bundle)
|
val qrData = QrScanDestination.getDataIfExist(bundle)
|
||||||
if (qrData != null) {
|
if (qrData != null) {
|
||||||
// Если данные QR есть, переходим на экран с результатом
|
// Если данные 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() {
|
private fun setupUI() {
|
||||||
// Настройка RecyclerView
|
binding.refresh.setOnClickListener {
|
||||||
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
fetchUserInfo()
|
||||||
accessLogAdapter = AccessLogAdapter(accessLogs)
|
}
|
||||||
binding.recyclerView.adapter = accessLogAdapter
|
|
||||||
|
|
||||||
// Проверяем, что binding не null, прежде чем устанавливать слушателей
|
binding.scanQrCode?.setOnClickListener {
|
||||||
binding.apply {
|
// Переход к экрану сканирования QR-кода
|
||||||
refresh.setOnClickListener { fetchUserData() }
|
findNavController().navigate(R.id.qrScanFragment) // Убедитесь, что у вас есть правильный ID для навигации
|
||||||
logout.setOnClickListener { logout() }
|
}
|
||||||
scan.setOnClickListener { navigateToQrScan() }
|
|
||||||
|
// Проверяем роль пользователя и показываем кнопку 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 {
|
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 {
|
try {
|
||||||
val response =
|
val response = apiService.getUserInfo(login, authHeader)
|
||||||
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 ?: ""
|
|
||||||
|
|
||||||
// Обновляем UI
|
// Логируем код ответа
|
||||||
updateUI(fullName, position, lastVisit, photoUrl)
|
Log.d("MainFragment", "Response code: ${response.code()}")
|
||||||
|
|
||||||
// Здесь вы можете добавить данные проходов в список
|
if (response.isSuccessful) {
|
||||||
// Пример:
|
val employeeData = response.body()
|
||||||
accessLogs.add(AccessLog("2024-02-31 08:31", "Считыватель 1", "карта"))
|
employeeData?.let {
|
||||||
accessLogAdapter.notifyDataSetChanged() // Обновляем адаптер
|
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) {
|
} 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() {
|
override fun onDestroyView() {
|
||||||
_binding = null // Освобождаем binding, когда представление уничтожается
|
_binding = null
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,47 +1,39 @@
|
|||||||
package ru.myitschool.work.ui.main
|
package ru.myitschool.work.ui.main
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.myitschool.work.SessionManager
|
|
||||||
import ru.myitschool.work.api.ApiService
|
import ru.myitschool.work.api.ApiService
|
||||||
|
import ru.myitschool.work.api.EmployeeData
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class MainViewModel @Inject constructor(
|
class MainViewModel @Inject constructor(
|
||||||
private val apiService: ApiService
|
private val apiService: ApiService
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val _userInfoState = MutableStateFlow<Map<String, Any>?>(null)
|
|
||||||
val userInfoState: StateFlow<Map<String, Any>?> = _userInfoState
|
|
||||||
|
|
||||||
init {
|
private val _employeeData = MutableStateFlow<EmployeeData?>(null)
|
||||||
loadUserData()
|
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 {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
val login = SessionManager.userLogin
|
val response = apiService.getUserInfo(login, authHeader)
|
||||||
if (login != null) {
|
if (response.isSuccessful) {
|
||||||
val response = apiService.getUserInfo(login)
|
_employeeData.value = response.body()
|
||||||
if (response.isSuccessful) {
|
|
||||||
_userInfoState.value = response.body()
|
|
||||||
} else {
|
|
||||||
// Обработка ошибки, если ответ не успешен
|
|
||||||
_userInfoState.value = null // Или установите какое-то состояние ошибки
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Логин равен null, обработайте это состояние
|
_errorMessage.value = "Ошибка получения данных: ${response.message()}"
|
||||||
_userInfoState.value = null // Или установите какое-то состояние ошибки
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// Логирование ошибки
|
Log.e("MainViewModel", "Error fetching user info", e)
|
||||||
e.printStackTrace()
|
_errorMessage.value = "Ошибка сети: ${e.message}"
|
||||||
// Установите состояние ошибки
|
|
||||||
_userInfoState.value = null // Или установите какое-то состояние ошибки
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,4 +44,4 @@ class RootActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
return popBackResult || super.onSupportNavigateUp()
|
return popBackResult || super.onSupportNavigateUp()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package ru.myitschool.work.ui.login
|
package ru.myitschool.work.ui.login
|
||||||
|
|
||||||
|
import ru.myitschool.work.api.ApiService
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
@ -15,7 +16,6 @@ import androidx.navigation.fragment.findNavController
|
|||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import ru.myitschool.work.R
|
import ru.myitschool.work.R
|
||||||
import ru.myitschool.work.SessionManager
|
import ru.myitschool.work.SessionManager
|
||||||
import ru.myitschool.work.api.UserAuthResponse
|
|
||||||
import ru.myitschool.work.databinding.FragmentLoginBinding
|
import ru.myitschool.work.databinding.FragmentLoginBinding
|
||||||
import ru.myitschool.work.utils.collectWhenStarted
|
import ru.myitschool.work.utils.collectWhenStarted
|
||||||
import ru.myitschool.work.utils.visibleOrGone
|
import ru.myitschool.work.utils.visibleOrGone
|
||||||
@ -40,7 +40,7 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState) // Убедитесь, что этот вызов находится здесь
|
||||||
_binding = FragmentLoginBinding.bind(view)
|
_binding = FragmentLoginBinding.bind(view)
|
||||||
|
|
||||||
setupUI()
|
setupUI()
|
||||||
@ -96,12 +96,6 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
|
|||||||
authPreferences.saveLoginState(true)
|
authPreferences.saveLoginState(true)
|
||||||
authPreferences.saveLogin(binding.username.text.toString()) // Сохраняем логин
|
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()
|
Toast.makeText(context, "Авторизация прошла успешно", Toast.LENGTH_SHORT).show()
|
||||||
navigateToMainScreen() // Перенаправление на следующий экран
|
navigateToMainScreen() // Перенаправление на следующий экран
|
||||||
} else if (state.error != null) {
|
} else if (state.error != null) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package ru.myitschool.work.ui.login
|
package ru.myitschool.work.ui.login
|
||||||
|
|
||||||
|
import ru.myitschool.work.api.ApiService
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
@ -8,8 +9,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.myitschool.work.SessionManager
|
import ru.myitschool.work.SessionManager
|
||||||
import ru.myitschool.work.api.ApiService
|
|
||||||
import ru.myitschool.work.api.UserAuthResponse
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@ -21,34 +20,40 @@ class LoginViewModel @Inject constructor(
|
|||||||
val state: StateFlow<LoginState> get() = _state
|
val state: StateFlow<LoginState> get() = _state
|
||||||
|
|
||||||
fun authenticate(username: String, password: String) {
|
fun authenticate(username: String, password: String) {
|
||||||
|
Log.d("LoginViewModel", "Authenticating user: $username") // Логируем начало аутентификации
|
||||||
|
|
||||||
if (isValidUsername(username)) {
|
if (isValidUsername(username)) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
|
Log.d("LoginViewModel", "Sending authentication request to server") // Логируем отправку запроса
|
||||||
val response = apiService.authenticate(username, password)
|
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-ответ
|
when (response.code()) {
|
||||||
Log.d("LoginViewModel", "User Auth Response: $userAuthResponse") // Логируем ответ
|
200 -> {
|
||||||
|
|
||||||
// Обработка JSON-ответа
|
|
||||||
if (userAuthResponse != null) {
|
|
||||||
SessionManager.userLogin = username
|
SessionManager.userLogin = username
|
||||||
SessionManager.userRole = userAuthResponse.role // Сохраняем роль
|
|
||||||
_state.value = LoginState(success = true) // Успешная авторизация
|
_state.value = LoginState(success = true) // Успешная авторизация
|
||||||
} else {
|
Log.d("LoginViewModel", "Authentication successful") // Логируем успешную аутентификацию
|
||||||
_state.value = LoginState(error = "Ошибка авторизации: Неверные учетные данные.")
|
}
|
||||||
|
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) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
_state.value = LoginState(error = "Ошибка сети. Проверьте подключение к интернету.")
|
_state.value = LoginState(error = "Ошибка сети. Проверьте подключение к интернету.")
|
||||||
|
Log.e("LoginViewModel", "Network error: ${e.message}") // Логируем ошибку сети
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_state.value = LoginState(error = "Неправильный логин")
|
_state.value = LoginState(error = "Неправильный логин")
|
||||||
|
Log.d("LoginViewModel", "Invalid username: $username") // Логируем неправильный логин
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +65,6 @@ class LoginViewModel @Inject constructor(
|
|||||||
// Состояние аутентификации
|
// Состояние аутентификации
|
||||||
data class LoginState(
|
data class LoginState(
|
||||||
val success: Boolean = false, // Успешность аутентификации
|
val success: Boolean = false, // Успешность аутентификации
|
||||||
val userAuthResponse: UserAuthResponse? = null, // Ответ с информацией о пользователе
|
|
||||||
val error: String? = null, // Сообщение об ошибке
|
val error: String? = null, // Сообщение об ошибке
|
||||||
val maintenance: Boolean = false // Состояние техобслуживания
|
val maintenance: Boolean = false // Состояние техобслуживания
|
||||||
)
|
)
|
@ -5,8 +5,10 @@ import androidx.navigation.fragment.findNavController
|
|||||||
import ru.myitschool.work.SessionManager
|
import ru.myitschool.work.SessionManager
|
||||||
import ru.myitschool.work.api.OpenDoorRequest
|
import ru.myitschool.work.api.OpenDoorRequest
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.util.Base64
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@ -19,7 +21,9 @@ import ru.myitschool.work.core.Constants
|
|||||||
import ru.myitschool.work.databinding.FragmentQrScanResultBinding
|
import ru.myitschool.work.databinding.FragmentQrScanResultBinding
|
||||||
|
|
||||||
class QrResult : Fragment(R.layout.fragment_qr_scan_result) {
|
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
|
private lateinit var apiService: ApiService
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
@ -27,7 +31,7 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) {
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
binding = FragmentQrScanResultBinding.inflate(inflater, container, false)
|
_binding = FragmentQrScanResultBinding.inflate(inflater, container, false)
|
||||||
apiService = Retrofit.Builder()
|
apiService = Retrofit.Builder()
|
||||||
.baseUrl(Constants.SERVER_ADDRESS)
|
.baseUrl(Constants.SERVER_ADDRESS)
|
||||||
.addConverterFactory(GsonConverterFactory.create())
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
@ -40,8 +44,12 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
// Получаем данные из аргументов
|
||||||
val qrData = QrScanDestination.getDataIfExist(requireArguments())
|
val qrData = QrScanDestination.getDataIfExist(requireArguments())
|
||||||
|
Log.d("QrResult", "QR Data: $qrData") // Логируем полученные данные
|
||||||
|
|
||||||
if (qrData != null) {
|
if (qrData != null) {
|
||||||
|
binding.result.text = "Результат сканирования: $qrData" // Отображаем результат сканирования
|
||||||
sendRequestToServer(qrData)
|
sendRequestToServer(qrData)
|
||||||
} else {
|
} else {
|
||||||
binding.result.text = "Вход был отменён/Operation was cancelled"
|
binding.result.text = "Вход был отменён/Operation was cancelled"
|
||||||
@ -55,23 +63,40 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) {
|
|||||||
private fun sendRequestToServer(qrData: String) {
|
private fun sendRequestToServer(qrData: String) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
try {
|
try {
|
||||||
// Проверяем, что userLogin не равен null
|
val qrValue = qrData.toLong() // Преобразуем данные QR-кода в Long
|
||||||
val login = SessionManager.userLogin
|
val login = SessionManager.userLogin ?: "default_login" // Замените на ваш логин
|
||||||
if (login != null) {
|
val password = "your_password" // Замените на ваш пароль
|
||||||
// Создаем объект OpenDoorRequest с логином и кодом
|
val authHeader = "Basic " + Base64.encodeToString("$login:$password".toByteArray(), Base64.NO_WRAP)
|
||||||
val openDoorRequest = OpenDoorRequest(login, qrData.toLong()) // Преобразуем qrData в Long, если это необходимо
|
|
||||||
val response = apiService.openDoor(openDoorRequest) // Теперь передаем только openDoorRequest
|
// Логируем данные перед отправкой
|
||||||
if (response.isSuccessful) {
|
Log.d("QrResult", "Sending request with QR value: $qrValue and authHeader: $authHeader")
|
||||||
binding.result.text = "Успешно/Success"
|
|
||||||
} else {
|
// Создаем объект запроса
|
||||||
binding.result.text = "Что-то пошло не так/Something wrong"
|
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 {
|
} else {
|
||||||
binding.result.text = "Пользователь не авторизован/Unauthorized user"
|
binding.result.text = "Door Closed" // Сообщение о том, что дверь закрыта
|
||||||
}
|
}
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
binding.result.text = "Некорректные данные QR-кода"
|
||||||
} catch (e: Exception) {
|
} 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()
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,110 +1,65 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:gravity="bottom"
|
android:padding="16dp">
|
||||||
android:padding="16dp"
|
|
||||||
android:background="@android:color/white">
|
|
||||||
|
|
||||||
<!-- Поле для ФИО -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/fullname"
|
android:id="@+id/fullname"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/fullname_label"
|
android:textSize="18sp" />
|
||||||
android:textSize="18sp"
|
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<!-- Фото пользователя. -->
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/photo"
|
android:id="@+id/photo"
|
||||||
android:layout_width="100dp"
|
android:layout_width="100dp"
|
||||||
android:layout_height="100dp"
|
android:layout_height="100dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:contentDescription="@string/photo_description"
|
android:contentDescription="@string/photo_description" />
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<!-- Поле для должности -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/position"
|
android:id="@+id/position"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/position_label"
|
android:textSize="16sp" />
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<!-- Поле для даты последнего входа -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/lastEntry"
|
android:id="@+id/lastEntry"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="2024-02-31 08:31"
|
android:textSize="14sp" />
|
||||||
android:layout_marginBottom="75dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<!-- Кнопка обновления -->
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/refresh"
|
android:id="@+id/refresh"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/refresh"
|
android:text="@string/refresh" />
|
||||||
app:cornerRadius="16dp"
|
|
||||||
android:backgroundTint="@color/colorPrimary"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:layout_marginBottom="12dp"
|
|
||||||
android:padding="12dp"/>
|
|
||||||
|
|
||||||
<!-- Поле ошибки -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/error"
|
android:id="@+id/error"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/error_placeholder"
|
|
||||||
android:textColor="@android:color/holo_red_dark"
|
android:textColor="@android:color/holo_red_dark"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<!-- RecyclerView для списка проходов -->
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recyclerView"
|
android:id="@+id/recyclerView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1" />
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<!-- Кнопки -->
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/scan"
|
android:id="@+id/scan_qr_code"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/scan_qr_code"
|
android:text="Сканировать QR-код"
|
||||||
android:layout_marginBottom="12dp"
|
|
||||||
android:backgroundTint="@color/colorPrimary"
|
|
||||||
app:cornerRadius="16dp"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/logout"
|
android:id="@+id/adminPanelButton"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/logout"
|
android:text="Admin Panel"
|
||||||
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:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -27,5 +27,4 @@
|
|||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
android:layout_marginTop="24dp" />
|
android:layout_marginTop="24dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,3 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -8,20 +9,17 @@
|
|||||||
android:id="@+id/scan_time"
|
android:id="@+id/scan_time"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Время сканирования"
|
android:textSize="14sp" />
|
||||||
android:textSize="16sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/reader_id"
|
android:id="@+id/reader_id"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Идентификатор считывателя"
|
android:textSize="14sp" />
|
||||||
android:textSize="16sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/access_type"
|
android:id="@+id/access_type"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Тип прохода"
|
android:textSize="14sp" />
|
||||||
android:textSize="16sp" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/adminFragment"
|
android:id="@+id/adminFragment"
|
||||||
android:name="ru.myitschool.work.ui.admin.AdminFragment"
|
android:name="ru.myitschool.work.ui.main.AdminFragment"
|
||||||
android:label="Admin Fragment"
|
android:label="Admin Fragment"
|
||||||
tools:layout="@layout/fragment_admin" />
|
tools:layout="@layout/fragment_admin" />
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user