我的界面 修改昵称完成
This commit is contained in:
220
android/.kotlin/errors/errors-1772609249618.log
Normal file
220
android/.kotlin/errors/errors-1772609249618.log
Normal file
@@ -0,0 +1,220 @@
|
||||
kotlin version: 2.2.20
|
||||
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:74)
|
||||
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:210)
|
||||
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:205)
|
||||
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:67)
|
||||
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:60)
|
||||
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:167)
|
||||
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:60)
|
||||
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:54)
|
||||
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:194)
|
||||
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||
at org.gradle.internal.Factories$1.create(Factories.java:31)
|
||||
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:263)
|
||||
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||
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.lang.AssertionError: java.lang.Exception: Could not close incremental caches in D:\code\FlutterApp\build\mobile_scanner\kotlin\compileDebugKotlin\cacheable\caches-jvm\jvm\kotlin: class-fq-name-to-source.tab, source-to-typealias-fq-name.tab, source-to-classes.tab, internal-name-to-source.tab
|
||||
at org.jetbrains.kotlin.com.google.common.io.Closer.close(Closer.java:218)
|
||||
at org.jetbrains.kotlin.incremental.IncrementalCachesManager.close(IncrementalCachesManager.kt:55)
|
||||
at kotlin.io.CloseableKt.closeFinally(Closeable.kt:46)
|
||||
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileNonIncrementally(IncrementalCompilerRunner.kt:293)
|
||||
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:128)
|
||||
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:684)
|
||||
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:94)
|
||||
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1810)
|
||||
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
|
||||
Caused by: java.lang.Exception: Could not close incremental caches in D:\code\FlutterApp\build\mobile_scanner\kotlin\compileDebugKotlin\cacheable\caches-jvm\jvm\kotlin: class-fq-name-to-source.tab, source-to-typealias-fq-name.tab, source-to-classes.tab, internal-name-to-source.tab
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:95)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.close(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.com.google.common.io.Closer.close(Closer.java:205)
|
||||
... 22 more
|
||||
Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\15563\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\mobile_scanner-3.5.7\android\src\main\kotlin\dev\steenbakker\mobile_scanner\BarcodeHandler.kt and D:\code\FlutterApp\android.
|
||||
at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
|
||||
at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
|
||||
at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:33)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:30)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:447)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:426)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:106)
|
||||
at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
|
||||
at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
|
||||
... 24 more
|
||||
Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\15563\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\mobile_scanner-3.5.7\android\src\main\kotlin\dev\steenbakker\mobile_scanner\MobileScannerCallbacks.kt and D:\code\FlutterApp\android.
|
||||
at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
|
||||
at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
|
||||
at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:1007)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:455)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:426)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:106)
|
||||
at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
|
||||
at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
|
||||
at org.jetbrains.kotlin.incremental.AbstractIncrementalCache$SourceToTypealiasFqNameTwoWayMap.close(AbstractIncrementalCache.kt:297)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
|
||||
... 24 more
|
||||
Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\15563\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\mobile_scanner-3.5.7\android\src\main\kotlin\dev\steenbakker\mobile_scanner\BarcodeHandler.kt and D:\code\FlutterApp\android.
|
||||
at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
|
||||
at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
|
||||
at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:1007)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:455)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:426)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:106)
|
||||
at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
|
||||
at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
|
||||
at org.jetbrains.kotlin.incremental.storage.AppendableSetBasicMap.close(BasicMap.kt:157)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
|
||||
... 24 more
|
||||
Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\15563\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\mobile_scanner-3.5.7\android\src\main\kotlin\dev\steenbakker\mobile_scanner\BarcodeHandler.kt and D:\code\FlutterApp\android.
|
||||
at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
|
||||
at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
|
||||
at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:33)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:30)
|
||||
at org.jetbrains.kotlin.incremental.storage.AppendableCollectionExternalizer.save(LazyStorage.kt:151)
|
||||
at org.jetbrains.kotlin.incremental.storage.AppendableCollectionExternalizer.save(LazyStorage.kt:142)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:447)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:426)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:106)
|
||||
at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
|
||||
at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
|
||||
at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
|
||||
... 24 more
|
||||
Suppressed: java.lang.Exception: Could not close incremental caches in D:\code\FlutterApp\build\mobile_scanner\kotlin\compileDebugKotlin\cacheable\caches-jvm\lookups: id-to-file.tab, file-to-id.tab
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:95)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.close(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.LookupStorage.close(LookupStorage.kt:155)
|
||||
... 23 more
|
||||
Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\15563\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\mobile_scanner-3.5.7\android\src\main\kotlin\dev\steenbakker\mobile_scanner\BarcodeHandler.kt and D:\code\FlutterApp\android.
|
||||
at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
|
||||
at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
|
||||
at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
|
||||
at org.jetbrains.kotlin.incremental.storage.LegacyFileExternalizer.save(IdToFileMap.kt:51)
|
||||
at org.jetbrains.kotlin.incremental.storage.LegacyFileExternalizer.save(IdToFileMap.kt:48)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:447)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:426)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:106)
|
||||
at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
|
||||
at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
|
||||
... 25 more
|
||||
Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\15563\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\mobile_scanner-3.5.7\android\src\main\kotlin\dev\steenbakker\mobile_scanner\BarcodeHandler.kt and D:\code\FlutterApp\android.
|
||||
at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
|
||||
at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
|
||||
at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:1007)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:455)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:426)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:106)
|
||||
at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
|
||||
at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
|
||||
... 25 more
|
||||
Suppressed: java.lang.Exception: Could not close incremental caches in D:\code\FlutterApp\build\mobile_scanner\kotlin\compileDebugKotlin\cacheable\caches-jvm\inputs: source-to-output.tab
|
||||
... 25 more
|
||||
Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\15563\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\mobile_scanner-3.5.7\android\src\main\kotlin\dev\steenbakker\mobile_scanner\BarcodeHandler.kt and D:\code\FlutterApp\android.
|
||||
at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
|
||||
at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
|
||||
at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
|
||||
at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
|
||||
at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:1007)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:455)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:426)
|
||||
at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:106)
|
||||
at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
|
||||
at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
|
||||
at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
|
||||
at org.jetbrains.kotlin.incremental.storage.AppendableSetBasicMap.close(BasicMap.kt:157)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
|
||||
at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
|
||||
... 24 more
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@ import 'package:maibu_satabot_v2/features/devices/domain/usecases/select_work_re
|
||||
import 'package:maibu_satabot_v2/features/devices/domain/usecases/unbind_device_usecase.dart';
|
||||
import 'package:maibu_satabot_v2/features/devices/domain/usecases/update_devicename_usecase.dart';
|
||||
import 'package:maibu_satabot_v2/features/devices/presentation/bloc/devices_cubit.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/presentation/bloc/my_cubit.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/repository/my_repository.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/repository/my_repository_impl.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/usecases/updatename_usecase.dart';
|
||||
import 'package:maibu_satabot_v2/features/remote_control/data/repositories/remote_control_repository_impl.dart';
|
||||
import 'package:maibu_satabot_v2/features/remote_control/domain/repositories/remote_control_repository.dart';
|
||||
import 'package:maibu_satabot_v2/features/remote_control/domain/usecase/diff_steer_usecase.dart';
|
||||
@@ -64,9 +68,9 @@ Future<void> init() async {
|
||||
sl.registerLazySingleton<Dio>(() => DioClient.create());
|
||||
|
||||
/// 1.1.2 TcpClient:TCP客户端
|
||||
sl.registerLazySingleton(() => TcpClient( sl<UserStorage>(),
|
||||
getUserDeviceUseCase: sl<GetUserDeviceUseCase>(),
|
||||
switchDeviceUseCase: sl<SwitchDeviceUseCase>(),));
|
||||
sl.registerLazySingleton(
|
||||
() => TcpClient(sl<UserStorage>(), getUserDeviceUseCase: sl<GetUserDeviceUseCase>(), switchDeviceUseCase: sl<SwitchDeviceUseCase>()),
|
||||
);
|
||||
|
||||
/// 1.1.3 NetMessageDispatcher:消息调度器,并将 TcpClient 注入给它
|
||||
sl.registerLazySingleton(() => NetMessageDispatcher(sl()));
|
||||
@@ -86,11 +90,9 @@ Future<void> init() async {
|
||||
sl.registerLazySingleton<ILoggerService>(() => SentryLoggerImpl());
|
||||
|
||||
/// 2. 数据源 (DataSource)
|
||||
sl.registerLazySingleton<AuthHttpDataSource>(
|
||||
() => AuthHttpDataSourceImpl(sl()),
|
||||
);
|
||||
sl.registerLazySingleton<AuthHttpDataSource>(() => AuthHttpDataSourceImpl(sl()));
|
||||
sl.registerLazySingleton<DeviceHttpDatasource>(
|
||||
() => DeviceHttpDatasourceImpl(sl(), sl<UserStorage>()), //
|
||||
() => DeviceHttpDatasourceImpl(sl(), sl<UserStorage>()), //
|
||||
);
|
||||
|
||||
/// 3. 仓库 (Repository)
|
||||
@@ -101,16 +103,32 @@ Future<void> init() async {
|
||||
),
|
||||
);
|
||||
|
||||
// 1. 注册 UpdateNameUsecase
|
||||
sl.registerLazySingleton<UpdateNameUsecase>(
|
||||
() => UpdateNameUsecase(sl<MyRepository>()), // 注入 MyRepository 实例
|
||||
);
|
||||
sl.registerLazySingleton<MyRepository>(
|
||||
() => MyRepositoryImpl(
|
||||
userStorage: sl<UserStorage>(), // 注入 UserStorage
|
||||
),
|
||||
);
|
||||
|
||||
// 2. 注册 MyCubit
|
||||
sl.registerLazySingleton<MyCubit>(
|
||||
() => MyCubit(
|
||||
sl<MyRepository>(), // 注入仓库
|
||||
sl<UpdateNameUsecase>(), // 注入 UseCase
|
||||
),
|
||||
);
|
||||
|
||||
sl.registerLazySingleton<RoutePlanningRepository>(
|
||||
() => RoutePlanningRepositoryImpl(tcp: sl<TcpClient>()), //
|
||||
() => RoutePlanningRepositoryImpl(tcp: sl<TcpClient>()), //
|
||||
);
|
||||
|
||||
sl.registerLazySingleton<RoutePlanningUseCase>(
|
||||
() => RoutePlanningUseCase(sl<RoutePlanningRepository>()), //
|
||||
() => RoutePlanningUseCase(sl<RoutePlanningRepository>()), //
|
||||
);
|
||||
|
||||
|
||||
|
||||
//工作历史
|
||||
sl.registerLazySingleton<DeviceHostrityWorkRepositoryRepository>(
|
||||
() => DeviceHostrityWorkRepositoryImpl(
|
||||
@@ -120,9 +138,7 @@ Future<void> init() async {
|
||||
);
|
||||
|
||||
sl.registerLazySingleton<DeviceRepository>(() => DeviceRepositoryImpl(sl()));
|
||||
sl.registerLazySingleton<RemoteControlRepository>(
|
||||
() => RemoteControlRepositoryImpl(sl(), sl()),
|
||||
);
|
||||
sl.registerLazySingleton<RemoteControlRepository>(() => RemoteControlRepositoryImpl(sl(), sl()));
|
||||
|
||||
/// 4. 用例 (UseCase)
|
||||
sl.registerLazySingleton(() => LoginUseCase(sl()));
|
||||
@@ -137,7 +153,7 @@ Future<void> init() async {
|
||||
sl.registerLazySingleton<SwitchDeviceUseCase>(() => SwitchDeviceUseCase(sl()));
|
||||
|
||||
sl.registerLazySingleton<AuthTcpDatasource>(
|
||||
() => AuthTcpDatasourceImpl(
|
||||
() => AuthTcpDatasourceImpl(
|
||||
sl<TcpClient>(),
|
||||
sl<UserStorage>(),
|
||||
getUserDeviceUseCase: sl<GetUserDeviceUseCase>(),
|
||||
@@ -145,15 +161,12 @@ Future<void> init() async {
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
/// 5. 状态管理 (Cubit/Bloc)
|
||||
sl.registerLazySingleton(() => AppUserCubit()); // AuthCubit 依赖它,必须先注册
|
||||
sl.registerLazySingleton(() => GetDeviceLocationUseCase(sl()));
|
||||
sl.registerLazySingleton(
|
||||
() => DevicesCubit(sl(), sl(), sl(), sl(), sl(), sl(), sl(), sl(), sl(),sl(),sl(), sl()),
|
||||
);
|
||||
sl.registerLazySingleton(() => DevicesCubit(sl(), sl(), sl(), sl(), sl(), sl(), sl(), sl(), sl(), sl(), sl(), sl()));
|
||||
sl.registerFactory(() => RemoteControlCubit(sl()));
|
||||
/* // 工厂模式(留存,每次获取新实例)
|
||||
/* // 工厂模式(留存,每次获取新实例)
|
||||
sl.registerFactory(() => DeviceStatusBloc(sl<NetMessageDispatcher>()));
|
||||
*/
|
||||
//单例模式(全局共享一个实例)
|
||||
@@ -161,16 +174,13 @@ Future<void> init() async {
|
||||
|
||||
/// . 路径生成
|
||||
sl.registerLazySingleton<PathHttpDatasource>(
|
||||
() => PathHttpDatasourceImpl(// 需先注册 http.Client(见下方)
|
||||
() => PathHttpDatasourceImpl(
|
||||
// 需先注册 http.Client(见下方)
|
||||
sl<UserStorage>(),
|
||||
),
|
||||
);
|
||||
sl.registerLazySingleton<PathRepository>(
|
||||
() => PathRepositoryImpl(datasource: sl<PathHttpDatasource>()),
|
||||
);
|
||||
sl.registerLazySingleton<GeneratePathUseCase>(
|
||||
() => GeneratePathUseCaseImpl(sl<PathRepository>()),
|
||||
);
|
||||
sl.registerLazySingleton<PathRepository>(() => PathRepositoryImpl(datasource: sl<PathHttpDatasource>()));
|
||||
sl.registerLazySingleton<GeneratePathUseCase>(() => GeneratePathUseCaseImpl(sl<PathRepository>()));
|
||||
|
||||
///.路径获取和删除
|
||||
sl.registerLazySingleton(() => GetWorkRecordUseCase(sl<PathRepository>()));
|
||||
@@ -178,15 +188,7 @@ Future<void> init() async {
|
||||
|
||||
/// 6. 认证 (Auth)
|
||||
// --- 关键修改点 1: AuthCubit 必须在 GoRouter 之前注册,并传入参数 ---
|
||||
sl.registerLazySingleton(
|
||||
() => AuthCubit(
|
||||
sl<UserStorage>(),
|
||||
sl<TcpClient>(),
|
||||
sl<AppUserCubit>(),
|
||||
sl<NetMessageDispatcher>(),
|
||||
sl<AuthTcpDatasource>(),
|
||||
),
|
||||
);
|
||||
sl.registerLazySingleton(() => AuthCubit(sl<UserStorage>(), sl<TcpClient>(), sl<AppUserCubit>(), sl<NetMessageDispatcher>(), sl<AuthTcpDatasource>()));
|
||||
|
||||
/// 7. 路由 (Router)
|
||||
sl.registerSingleton<GoRouter>(createRouter(sl<AuthCubit>()));
|
||||
|
||||
@@ -33,7 +33,6 @@ class UserStorageImpl implements UserStorage {
|
||||
Future<void> deleteUser() async {
|
||||
await _prefs.remove(_userKey);
|
||||
//返回登陆页面
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -5,4 +5,5 @@ abstract class UserStorage {
|
||||
Future<UserEntity?> getUser();
|
||||
Future<void> deleteUser();
|
||||
Future<bool> hasUser();
|
||||
//Future<bool> updateUser();
|
||||
}
|
||||
|
||||
@@ -392,7 +392,12 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
|
||||
// ====================== 图表视图 ======================
|
||||
Widget _buildChartContentView(DeviceStatusState state) {
|
||||
if (state is! DeviceStatusUpdated) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Color(0xFF1677FF), // 统一使用项目主题蓝色
|
||||
strokeWidth: 4, // 加粗加载圈,视觉更清晰
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final status = state.status;
|
||||
@@ -623,7 +628,12 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
|
||||
child: Text("数据加载失败", style: TextStyle(color: Colors.red, fontSize: 16)),
|
||||
);
|
||||
} else {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Color(0xFF1677FF), // 统一使用项目主题蓝色
|
||||
strokeWidth: 4, // 加粗加载圈,视觉更清晰
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
48
lib/features/my/presentation/bloc/my_cubit.dart
Normal file
48
lib/features/my/presentation/bloc/my_cubit.dart
Normal file
@@ -0,0 +1,48 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:maibu_satabot_v2/core/di/injection.dart';
|
||||
import 'package:maibu_satabot_v2/core/storage/user_storage.dart';
|
||||
|
||||
import 'package:maibu_satabot_v2/features/devices/domain/usecases/unbind_device_usecase.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/presentation/bloc/my_state.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/repository/my_repository.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/usecases/updatename_usecase.dart';
|
||||
|
||||
class MyCubit extends Cubit<MyState> {
|
||||
// 1. 修正变量命名:小驼峰规范(_updateNameUsecase)
|
||||
final UpdateNameUsecase _updateNameUsecase;
|
||||
final MyRepository repository;
|
||||
|
||||
// 2. 构造函数参数顺序与命名对齐
|
||||
MyCubit(this.repository, this._updateNameUsecase) : super(const MyState());
|
||||
|
||||
Future<void> updateName(String nickName) async {
|
||||
emit(state.copyWith(isLoading: true, errorMessage: ''));
|
||||
|
||||
try {
|
||||
final params = UpdateNameParams(nickName);
|
||||
final result = await _updateNameUsecase(params);
|
||||
print("$result 修改名称结构");
|
||||
|
||||
// 4. 恢复 fold 逻辑,处理 UseCase 返回结果(关键:更新 UI 状态)
|
||||
result.fold((failure) => emit(state.copyWith(isLoading: false, errorMessage: failure.message ?? '修改昵称失败')), (successCode) {
|
||||
print("$successCode 修改名称结构");
|
||||
final isSuccess = successCode == 200;
|
||||
if (isSuccess) {
|
||||
emit(state.copyWith(isLoading: false, errorMessage: '', nickName: nickName));
|
||||
} else {
|
||||
emit(state.copyWith(isLoading: false, errorMessage: '修改昵称失败:状态码 $successCode'));
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
emit(state.copyWith(isLoading: false, errorMessage: '修改昵称异常:${e.toString()}'));
|
||||
}
|
||||
}
|
||||
|
||||
// 保留解绑设备方法(如果需要)
|
||||
Future<void> unbindDevice(String deviceId, String deviceName) async {
|
||||
emit(state.copyWith(isLoading: true, errorMessage: ''));
|
||||
// 解绑逻辑(如需保留,需补充 UnbindDeviceUsecase 依赖注入)
|
||||
}
|
||||
}
|
||||
22
lib/features/my/presentation/bloc/my_state.dart
Normal file
22
lib/features/my/presentation/bloc/my_state.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:maibu_satabot_v2/features/devices/domain/entities/device_entity.dart';
|
||||
|
||||
class MyState extends Equatable {
|
||||
final bool isLoading; // 是否正在加载
|
||||
final String? errorMessage; // 错误信息
|
||||
final String? nickName;
|
||||
|
||||
const MyState({this.isLoading = false, this.errorMessage, this.nickName});
|
||||
|
||||
// 使用 copyWith 方便局部更新状态
|
||||
MyState copyWith({bool? isLoading, String? errorMessage, String? nickName}) {
|
||||
return MyState(
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
errorMessage: errorMessage, // 错误信息通常每次更新都要重新赋值或清空
|
||||
nickName: nickName,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [isLoading, errorMessage, nickName];
|
||||
}
|
||||
@@ -3,6 +3,10 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:maibu_satabot_v2/core/di/injection.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/presentation/bloc/my_cubit.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/repository/my_repository.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/usecases/updatename_usecase.dart';
|
||||
import '../../../../core/router/route_paths.dart';
|
||||
import '../../../../core/storage/user_storage.dart';
|
||||
import '../../../auth/presentation/bloc/auth_cubit.dart';
|
||||
@@ -24,7 +28,7 @@ class MyPage extends StatelessWidget {
|
||||
|
||||
if (authState is AuthAuthenticated) {
|
||||
final user = authState.user;
|
||||
userName = user.username ?? '未知用户';
|
||||
userName = user.nickname ?? '未知用户';
|
||||
userId = user.userId ?? '未知ID';
|
||||
}
|
||||
|
||||
@@ -36,7 +40,10 @@ class MyPage extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 顶部用户信息
|
||||
UserInfoCard(userName: userName, userId: userId),
|
||||
BlocProvider(
|
||||
create: (context) => MyCubit(sl<MyRepository>(), sl<UpdateNameUsecase>()),
|
||||
child: UserInfoCard(userName: userName, userId: userId),
|
||||
),
|
||||
|
||||
SizedBox(height: 16),
|
||||
|
||||
@@ -63,24 +70,14 @@ class MyPage extends StatelessWidget {
|
||||
// 添加 context 参数
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => WebViewPage(url: 'https://www.satabot.com/'),
|
||||
),
|
||||
);
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => WebViewPage(url: 'https://www.satabot.com/')));
|
||||
},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 160,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
image: DecorationImage(
|
||||
image: NetworkImage(
|
||||
'https://c.53326.com/d/file/lan20221010/fyhj0ibovbp.jpg',
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
image: DecorationImage(image: NetworkImage('https://c.53326.com/d/file/lan20221010/fyhj0ibovbp.jpg'), fit: BoxFit.cover),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
@@ -89,23 +86,14 @@ class MyPage extends StatelessWidget {
|
||||
right: 12,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
'了解我们',
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
),
|
||||
decoration: BoxDecoration(color: Colors.black.withOpacity(0.5), borderRadius: BorderRadius.circular(4)),
|
||||
child: Text('了解我们', style: TextStyle(color: Colors.white, fontSize: 14)),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 12,
|
||||
bottom: 12,
|
||||
child: Text(
|
||||
'AI赋能农业',
|
||||
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||
),
|
||||
child: Text('AI赋能农业', style: TextStyle(color: Colors.white, fontSize: 16)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -115,35 +103,17 @@ class MyPage extends StatelessWidget {
|
||||
|
||||
Widget _buildFunctionList(BuildContext context) {
|
||||
final items = [
|
||||
{
|
||||
'icon': Icons.play_arrow,
|
||||
'title': '操作视频',
|
||||
'url': 'https://www.satabot.com/Support/index.html',
|
||||
},
|
||||
{
|
||||
'icon': Icons.car_rental,
|
||||
'title': '租赁服务',
|
||||
'url': 'https://www.satabot.com/Leasing.html',
|
||||
},
|
||||
{
|
||||
'icon': Icons.help_outline,
|
||||
'title': '帮助与支持',
|
||||
'url': 'https://www.satabot.com/support/index.html',
|
||||
},
|
||||
{
|
||||
'icon': Icons.policy,
|
||||
'title': '售后政策',
|
||||
'url': 'https://www.satabot.com/Aftersales-Service.html',
|
||||
},
|
||||
{'icon': Icons.play_arrow, 'title': '操作视频', 'url': 'https://www.satabot.com/Support/index.html'},
|
||||
{'icon': Icons.car_rental, 'title': '租赁服务', 'url': 'https://www.satabot.com/Leasing.html'},
|
||||
{'icon': Icons.help_outline, 'title': '帮助与支持', 'url': 'https://www.satabot.com/support/index.html'},
|
||||
{'icon': Icons.policy, 'title': '售后政策', 'url': 'https://www.satabot.com/Aftersales-Service.html'},
|
||||
];
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(color: Colors.grey.withOpacity(0.1), blurRadius: 4),
|
||||
],
|
||||
boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.1), blurRadius: 4)],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -159,13 +129,7 @@ class MyPage extends StatelessWidget {
|
||||
title: Text(item['title'] as String),
|
||||
trailing: Icon(Icons.arrow_forward),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
WebViewPage(url: item['url'] as String),
|
||||
),
|
||||
);
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => WebViewPage(url: item['url'] as String)));
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,17 +1,224 @@
|
||||
// user_info_card.dart
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||
import 'package:maibu_satabot_v2/features/devices/presentation/bloc/devices_cubit.dart';
|
||||
import 'package:mobile_scanner/mobile_scanner.dart'; // 1. 导入扫码库
|
||||
import 'package:get_it/get_it.dart'; // 用于获取 Cubit 实例
|
||||
// 2. 导入你的 Cubit 文件,请根据实际路径调整
|
||||
import 'package:maibu_satabot_v2/features/my/presentation/bloc/my_cubit.dart';
|
||||
import 'package:maibu_satabot_v2/features/my/presentation/bloc/my_state.dart';
|
||||
import 'package:mobile_scanner/mobile_scanner.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import '../../../auth/presentation/bloc/auth_cubit.dart';
|
||||
|
||||
class UserInfoCard extends StatelessWidget {
|
||||
class UserInfoCard extends StatefulWidget {
|
||||
final String userName;
|
||||
final String userId;
|
||||
|
||||
const UserInfoCard({super.key, required this.userName, required this.userId});
|
||||
|
||||
@override
|
||||
State<UserInfoCard> createState() => _UserInfoCardState();
|
||||
}
|
||||
|
||||
class _UserInfoCardState extends State<UserInfoCard> {
|
||||
late TextEditingController _nicknameController;
|
||||
final GetIt _getIt = GetIt.I;
|
||||
MyCubit? _myCubit; // 可空类型
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// 优先从 BlocProvider 获取,获取失败则从 GetIt 兜底
|
||||
try {
|
||||
_myCubit = BlocProvider.of<MyCubit>(context);
|
||||
} catch (e) {
|
||||
debugPrint('从 BlocProvider 获取 MyCubit 失败:$e,尝试从 GetIt 获取');
|
||||
try {
|
||||
_myCubit = _getIt<MyCubit>();
|
||||
} catch (e) {
|
||||
debugPrint('从 GetIt 获取 MyCubit 也失败:$e');
|
||||
}
|
||||
}
|
||||
_nicknameController = TextEditingController(text: widget.userName);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_nicknameController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// 打开修改昵称的底部抽屉
|
||||
void _openEditNicknameBottomSheet() {
|
||||
// 修复1:先校验 _myCubit 是否为 null,避免空断言
|
||||
final myCubit = _myCubit;
|
||||
if (myCubit == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Cubit 初始化失败,无法修改昵称'), backgroundColor: Colors.red));
|
||||
return;
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(16))),
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.8),
|
||||
builder: (context) => BlocProvider.value(
|
||||
// 使用非空的局部变量,无需空断言
|
||||
value: myCubit,
|
||||
child: BlocBuilder<MyCubit, MyState>(
|
||||
builder: (context, myState) {
|
||||
final cubit = context.read<MyCubit>();
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(left: 16, right: 16, top: 20, bottom: MediaQuery.of(context).viewInsets.bottom + 80),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('修改昵称', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
|
||||
IconButton(padding: EdgeInsets.zero, icon: const Icon(Icons.close, size: 20), onPressed: () => Navigator.pop(context)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text('新昵称', style: TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _nicknameController,
|
||||
style: const TextStyle(fontSize: 16),
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
),
|
||||
autofocus: true,
|
||||
enabled: !myState.isLoading,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// 核心:根据 MyState 显示加载/按钮/错误提示
|
||||
if (myState.isLoading)
|
||||
const Center(
|
||||
child: Column(
|
||||
children: [
|
||||
CircularProgressIndicator(color: Colors.blue),
|
||||
SizedBox(height: 8),
|
||||
Text("修改中...", style: TextStyle(color: Colors.grey)),
|
||||
],
|
||||
),
|
||||
)
|
||||
else
|
||||
Column(
|
||||
children: [
|
||||
// 修复2:使用 ?. 和 ?? 避免空断言,安全判断错误信息
|
||||
if (myState.errorMessage?.isNotEmpty ?? false)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: Text(myState.errorMessage ?? "修改失败", style: const TextStyle(color: Colors.red, fontSize: 14)),
|
||||
),
|
||||
|
||||
// 确定修改按钮
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: () => _submitNewNickname(context),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blue,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
child: const Text('确定修改', style: TextStyle(fontSize: 16, color: Colors.white)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 提交新昵称的业务逻辑
|
||||
Future<void> _submitNewNickname(BuildContext context) async {
|
||||
final newNickname = _nicknameController.text.trim();
|
||||
if (newNickname.isEmpty ) {
|
||||
Navigator.pop(context);
|
||||
return;
|
||||
}
|
||||
|
||||
final myCubit = _myCubit;
|
||||
if (myCubit == null) {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Cubit 初始化失败'), backgroundColor: Colors.red));
|
||||
}
|
||||
Navigator.pop(context);
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除重复的加载弹窗(由 BlocBuilder 显示加载状态)
|
||||
await myCubit.updateName(newNickname);
|
||||
|
||||
// 成功后由 BlocBuilder 监听状态并处理弹窗关闭和提示
|
||||
if (context.mounted && myCubit.state.errorMessage!.isEmpty ?? true) {
|
||||
setState(() {
|
||||
_nicknameController.text = newNickname;
|
||||
});
|
||||
Navigator.pop(context);
|
||||
// 触发 AuthCubit 重新获取用户信息
|
||||
}
|
||||
}
|
||||
|
||||
// 扫码绑定设备逻辑(保留)
|
||||
Future<void> _handleScanAndBind(BuildContext context) async {
|
||||
final String? qrCode = await Navigator.push<String>(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MobileScanner(
|
||||
onDetect: (capture) {
|
||||
final List<Barcode> barcodes = capture.barcodes;
|
||||
if (barcodes.isNotEmpty) {
|
||||
final String? code = barcodes.first.rawValue;
|
||||
if (code != null && code.isNotEmpty) {
|
||||
Navigator.pop(context, code);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (qrCode == null || qrCode.isEmpty) return;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => const Center(child: CircularProgressIndicator(color: Color(0xFF1677FF), strokeWidth: 4)),
|
||||
);
|
||||
|
||||
try {
|
||||
final devicesCubit = _getIt<DevicesCubit>();
|
||||
// await devicesCubit.bindDevice(qrCode);
|
||||
if (context.mounted) Navigator.pop(context);
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('设备绑定成功!'), backgroundColor: Colors.green));
|
||||
}
|
||||
} catch (e) {
|
||||
if (context.mounted) Navigator.pop(context);
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('绑定失败:$e'), backgroundColor: Colors.red));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
@@ -21,97 +228,23 @@ class UserInfoCard extends StatelessWidget {
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
image: DecorationImage(
|
||||
image: NetworkImage('https://pic4.zhimg.com/v2-c34c61a90095abb8713de9d1dca7ec7b_r.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
image: DecorationImage(image: NetworkImage('https://pic4.zhimg.com/v2-c34c61a90095abb8713de9d1dca7ec7b_r.jpg'), fit: BoxFit.cover),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(userName, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
Text('用户 id:$userId', style: TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
Text(_nicknameController.text, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
Text('用户 id:${widget.userId}', style: const TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.edit),
|
||||
onPressed: () {},
|
||||
),
|
||||
Spacer(),
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
// 3. 绑定点击事件
|
||||
onPressed: () => _handleScanAndBind(context),
|
||||
),
|
||||
IconButton(icon: const Icon(Icons.edit), onPressed: _openEditNicknameBottomSheet),
|
||||
const Spacer(),
|
||||
IconButton(icon: const Icon(Icons.add), onPressed: () => _handleScanAndBind(context)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// 4. 定义扫码与绑定逻辑
|
||||
Future<void> _handleScanAndBind(BuildContext context) async {
|
||||
// 跳转到扫码页面
|
||||
final String? qrCode = await Navigator.push<String>(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MobileScanner(
|
||||
onDetect: (capture) {
|
||||
final List<Barcode> barcodes = capture.barcodes;
|
||||
if (barcodes.isNotEmpty) {
|
||||
debugPrint('识别到的数据: $barcodes');
|
||||
final String? code = barcodes.first.rawValue;
|
||||
if (code != null && code.isNotEmpty) {
|
||||
// 识别成功,立即返回结果并关闭页面
|
||||
debugPrint('扫码成功,识别到的数据: $code');
|
||||
// Navigator.pop(context, code);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// 如果用户取消或未扫到码,直接返回
|
||||
if (qrCode == null || qrCode.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载对话框
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
|
||||
try {
|
||||
// 5. 获取 Cubit 实例并调用绑定接口
|
||||
final Cubit = GetIt.I<DevicesCubit>();
|
||||
|
||||
// 执行绑定逻辑
|
||||
//await Cubit.bindDevice(qrCode);
|
||||
|
||||
// 关闭加载框
|
||||
if (context.mounted) Navigator.pop(context);
|
||||
|
||||
// 成功提示
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('设备绑定成功!'), backgroundColor: Colors.green),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// 关闭加载框
|
||||
if (context.mounted) Navigator.pop(context);
|
||||
|
||||
// 失败提示
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('绑定失败:$e'), backgroundColor: Colors.red),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
lib/features/my/repository/my_repository.dart
Normal file
8
lib/features/my/repository/my_repository.dart
Normal file
@@ -0,0 +1,8 @@
|
||||
// lib/features/devices/domain/repositories/route_planning_repository.dart
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:maibu_satabot_v2/features/devices/domain/errors/device_failure.dart';
|
||||
|
||||
abstract class MyRepository {
|
||||
// 抽象方法定义:参数是 String nickName,返回 Future<Either<DeviceFailure, int>>
|
||||
Future<Either<DeviceFailure, int>> updateName(String nickName);
|
||||
}
|
||||
61
lib/features/my/repository/my_repository_impl.dart
Normal file
61
lib/features/my/repository/my_repository_impl.dart
Normal file
@@ -0,0 +1,61 @@
|
||||
import 'dart:math';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:maibu_satabot_v2/features/my/repository/my_repository.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../../../core/di/injection.dart';
|
||||
import '../../../../core/storage/user_storage.dart';
|
||||
// 必须导入 DeviceFailure 类
|
||||
import '../../../../features/devices/domain/errors/device_failure.dart';
|
||||
|
||||
class MyRepositoryImpl implements MyRepository {
|
||||
// 可选:注入 UserStorage(如果需要获取 token 等用户信息)
|
||||
final UserStorage _userStorage;
|
||||
|
||||
MyRepositoryImpl({UserStorage? userStorage}) : _userStorage = userStorage ?? sl<UserStorage>();
|
||||
// 🔥 辅助方法:获取 Token
|
||||
Future<String?> _getToken() async {
|
||||
final user = await _userStorage.getUser();
|
||||
return user?.token;
|
||||
}
|
||||
|
||||
// 核心修复:严格匹配抽象类的方法签名
|
||||
@override
|
||||
Future<Either<DeviceFailure, int>> updateName(String nickName) async {
|
||||
final url = Uri.parse('https://serviceri.satabot.com/system/user/profile');
|
||||
|
||||
// 补充:从 UserStorage 获取 token(接口通常需要认证)
|
||||
final token = await _getToken();
|
||||
final headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token', // 按需添加认证头
|
||||
};
|
||||
|
||||
final body = jsonEncode({'nickName': nickName});
|
||||
|
||||
try {
|
||||
final response = await http.put(url, headers: headers, body: body);
|
||||
|
||||
// 1. 处理成功响应(statusCode 200)
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
||||
// 根据接口返回值,返回 Either.right(成功码,比如 1 表示成功)
|
||||
// 示例:假设接口返回 code=200 表示成功
|
||||
final int successCode = data['code'] ?? 1;
|
||||
return Right(successCode);
|
||||
}
|
||||
// 2. 处理失败响应(非 200 状态码)
|
||||
else {
|
||||
final String errorMsg = '修改昵称失败:状态码 ${response.statusCode}';
|
||||
return Left(DeviceFailure.serverError(message: errorMsg));
|
||||
}
|
||||
}
|
||||
// 3. 处理网络异常
|
||||
catch (e) {
|
||||
final String errorMsg = '网络异常:${e.toString()}';
|
||||
return Left(DeviceFailure.serverError(message: errorMsg));
|
||||
}
|
||||
}
|
||||
}
|
||||
26
lib/features/my/usecases/updatename_usecase.dart
Normal file
26
lib/features/my/usecases/updatename_usecase.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:maibu_satabot_v2/core/domain/usecases/base_usecase.dart';
|
||||
import 'package:maibu_satabot_v2/features/devices/domain/errors/device_failure.dart'; // 必须导入
|
||||
import 'package:maibu_satabot_v2/features/my/repository/my_repository.dart';
|
||||
|
||||
// 1. 泛型严格匹配:BaseUseCase<成功类型int, 参数类型UpdateNameParams>
|
||||
class UpdateNameUsecase implements BaseUseCase<int, UpdateNameParams> {
|
||||
final MyRepository myRepository;
|
||||
|
||||
UpdateNameUsecase(this.myRepository);
|
||||
|
||||
// 2. 核心修复:返回值类型从 dynamic 改为 Either<DeviceFailure, int>
|
||||
// 严格覆盖 BaseUseCase 的 call 方法
|
||||
@override
|
||||
Future<Either<DeviceFailure, int>> call(UpdateNameParams params) async {
|
||||
// 3. 调用仓库方法(返回值已匹配 Either<DeviceFailure, int>)
|
||||
return await myRepository.updateName(params.nickName);
|
||||
}
|
||||
}
|
||||
|
||||
// 参数类保持不变(不可变,语义清晰)
|
||||
class UpdateNameParams {
|
||||
final String nickName;
|
||||
|
||||
const UpdateNameParams(this.nickName);
|
||||
}
|
||||
Reference in New Issue
Block a user