فهرست منبع

1. 调整连接蓝牙设备的逻辑
2. 修复Bug

xj 3 ماه پیش
والد
کامیت
de820351f6

+ 264 - 3
Loto.pro.user

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.14.2, 2026-02-04T14:40:22. -->
+<!-- Written by QtCreator 4.14.2, 2026-02-06T09:03:15. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
@@ -8,7 +8,7 @@
  </data>
  <data>
   <variable>ProjectExplorer.Project.ActiveTarget</variable>
-  <value type="int">0</value>
+  <value type="int">1</value>
  </data>
  <data>
   <variable>ProjectExplorer.Project.EditorSettings</variable>
@@ -343,9 +343,270 @@
    <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
   </valuemap>
  </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.1</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="DeviceType">GenericLinuxOsType</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">DaJiGui</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">DaJiGui</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{09bab3f2-c9c3-421a-aef1-57a08250e2d5}</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="int" key="EnableQmlDebugging">0</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/kim/Desktop/ISCS_LOTO_Linux/build-Loto-DaJiGui-Debug</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/kim/Desktop/ISCS_LOTO_Linux/build-Loto-DaJiGui-Debug</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+    <value type="int" key="RunSystemFunction">0</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/kim/Desktop/ISCS_LOTO_Linux/build-Loto-DaJiGui-Release</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/kim/Desktop/ISCS_LOTO_Linux/build-Loto-DaJiGui-Release</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="int" key="QtQuickCompiler">0</value>
+    <value type="int" key="RunSystemFunction">0</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+    <value type="int" key="EnableQmlDebugging">0</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/kim/Desktop/ISCS_LOTO_Linux/build-Loto-DaJiGui-Profile</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/kim/Desktop/ISCS_LOTO_Linux/build-Loto-DaJiGui-Profile</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="int" key="QtQuickCompiler">0</value>
+    <value type="int" key="RunSystemFunction">0</value>
+    <value type="int" key="SeparateDebugInfo">0</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.CheckForFreeDiskSpaceStep</value>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
+      <value type="QString" key="RemoteLinux.CheckForFreeDiskSpaceStep.PathToCheck">/</value>
+      <value type="qlonglong" key="RemoteLinux.CheckForFreeDiskSpaceStep.RequiredSpace">5242880</value>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.KillAppStep</value>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.RsyncDeployStep</value>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
+      <value type="QString" key="RemoteLinux.RsyncDeployStep.Flags">-av</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
+    <value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">DeployToGenericLinux</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
+    <valuelist type="QVariantList" key="Analyzer.Perf.Events">
+     <value type="QString">cpu-cycles</value>
+    </valuelist>
+    <valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
+    <value type="int" key="Analyzer.Perf.Frequency">250</value>
+    <valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
+     <value type="QString">-e</value>
+     <value type="QString">cpu-cycles</value>
+     <value type="QString">--call-graph</value>
+     <value type="QString">dwarf,4096</value>
+     <value type="QString">-F</value>
+     <value type="QString">250</value>
+    </valuelist>
+    <value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
+    <value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
+    <value type="int" key="Analyzer.Perf.StackSize">4096</value>
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <valuelist type="QVariantList" key="CustomOutputParsers"/>
+    <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes">
+     <value type="QString">LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH</value>
+     <value type="QString">QML2_IMPORT_PATH=$QTDIR/qml:$QML2_IMPORT_PATH</value>
+     <value type="QString">QTDIR=/home/teamhd/qt5</value>
+     <value type="QString">QT_PLUGIN_PATH=$QTDIR/plugins:$QT_PLUGIN_PATH</value>
+    </valuelist>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">src (on DaJiGui)</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration:/home/kim/Desktop/ISCS_LOTO_Linux/src/src.pro</value>
+    <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/kim/Desktop/ISCS_LOTO_Linux/src/src.pro</value>
+    <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+    <value type="QString" key="RunConfiguration.X11Forwarding">:0</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
  <data>
   <variable>ProjectExplorer.Project.TargetCount</variable>
-  <value type="int">1</value>
+  <value type="int">2</value>
  </data>
  <data>
   <variable>ProjectExplorer.Project.Updater.FileVersion</variable>

+ 25 - 0
build-Loto-DaJiGui-Debug/.qmake.stash

@@ -0,0 +1,25 @@
+QMAKE_CXX.QT_COMPILER_STDCXX = 201402L
+QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 7
+QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 5
+QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 0
+QMAKE_CXX.COMPILER_MACROS = \
+    QT_COMPILER_STDCXX \
+    QMAKE_GCC_MAJOR_VERSION \
+    QMAKE_GCC_MINOR_VERSION \
+    QMAKE_GCC_PATCH_VERSION
+QMAKE_CXX.INCDIRS = \
+    /usr/aarch64-linux-gnu/include/c++/7 \
+    /usr/aarch64-linux-gnu/include/c++/7/aarch64-linux-gnu \
+    /usr/aarch64-linux-gnu/include/c++/7/backward \
+    /usr/lib/gcc-cross/aarch64-linux-gnu/7/include \
+    /usr/lib/gcc-cross/aarch64-linux-gnu/7/include-fixed \
+    /usr/aarch64-linux-gnu/include \
+    /opt/rk3568-rootfs/usr/include/aarch64-linux-gnu \
+    /opt/rk3568-rootfs/usr/include
+QMAKE_CXX.LIBDIRS = \
+    /usr/lib/gcc-cross/aarch64-linux-gnu/7 \
+    /usr/aarch64-linux-gnu/lib \
+    /opt/rk3568-rootfs/lib/aarch64-linux-gnu \
+    /opt/rk3568-rootfs/lib \
+    /opt/rk3568-rootfs/usr/lib/aarch64-linux-gnu \
+    /opt/rk3568-rootfs/usr/lib

+ 6 - 0
build-Loto-DaJiGui-Debug/src/pkg-config_wrapper.sh

@@ -0,0 +1,6 @@
+#!/bin/sh
+PKG_CONFIG_SYSROOT_DIR=/opt/rk3568-rootfs
+export PKG_CONFIG_SYSROOT_DIR
+PKG_CONFIG_LIBDIR=/opt/rk3568-rootfs/usr/lib/pkgconfig:/opt/rk3568-rootfs/usr/share/pkgconfig
+export PKG_CONFIG_LIBDIR
+exec pkg-config "$@"

+ 7 - 1
src/httpclient/HttpGetWorkNodeDetail.cpp

@@ -122,6 +122,8 @@ void HttpGetWorkNodeDetail::httpRequestGetWorkNodeDetail()
 
 void HttpGetWorkNodeDetail::httpRequestGetFormById()
 {
+    if (m_formId == 0) return;
+
     QJsonObject jsonRoot;
     QDateTime currentDateTime = QDateTime::currentDateTime();
     qint64 timestampSeconds = currentDateTime.toMSecsSinceEpoch();
@@ -219,6 +221,10 @@ void HttpGetWorkNodeDetail::slotHttpResponseGetWorkNodeDetail(QByteArray data)
                     WorkNodeFormModel::instance()->setDescription("");
                 }
                 
+                if (formData.isEmpty()) {
+                    emit signalWorkNodeDetailReturnStat(0, "解析表单页完成");
+                    return;
+                }
                 // 解析表单名称(当前任务名称)
                 if (formData.contains("name") && formData.value("name").isString()) {
                     WorkNodeFormModel::instance()->setFormName(formData.value("name").toString());
@@ -350,7 +356,7 @@ void HttpGetWorkNodeDetail::slotHttpResponseGetFormById(QByteArray data)
                     return;
                 }
                 if (!vDataObj.value("fields").isArray()) {
-                    emit signalWorkNodeDetailReturnStat(-3, "解析表单页面失败");
+//                    emit signalWorkNodeDetailReturnStat(-3, "解析表单页面失败");
                     return;
                 }
                 QJsonArray fieldsList = vDataObj.value("fields").toArray();

+ 29 - 11
src/interactive/InteractiveCAN.cpp

@@ -134,6 +134,8 @@ InteractiveCAN::InteractiveCAN()
     connect(m_bleClient, &BLEClient::workTicketResultReceived,
             ReturnKeyLockManager::instance(), &ReturnKeyLockManager::slotReceivedJobTicket,
             Qt::QueuedConnection);
+    connect(ReturnKeyLockManager::instance(), &ReturnKeyLockManager::isProcessingChanged,
+            this, &InteractiveCAN::slotReturnKeyAndLockProcessingChanged);
     // ====================================================
 }
 
@@ -169,6 +171,7 @@ void InteractiveCAN::createColockJobTicket()
 
     m_pointAndLockRfids.clear();
     m_lockRFIDs.clear();
+    m_okOpenKey = true;
 
     for (int i = 0; i < pointsList.count(); i++) {
         QJsonObject pointItem = pointsList[i].toObject();
@@ -480,7 +483,7 @@ void InteractiveCAN::getJobTicketInfo(quint8 nodeId, bool isLeftKey)
             }
             else {
                 m_startGetWorkTicketResultFlag = true;
-                m_bleClient->connectDevice(m_currentKeyMAC, "keyLock");
+                m_bleClient->apiConnectDevice(m_currentKeyMAC);
             }
         }
     }
@@ -600,6 +603,7 @@ void InteractiveCAN::slotHttpResponseUploadJobTicket(QByteArray data)
             return;
         }
         if(codeValue == 200 || codeValue == 0) {
+//            m_okUnlockKey = true;
 //            qDebug() << "[slotHttpResponseUploadJobTicket]" << jsonDoc;
             if (m_bleClient) {
 //                m_bleClient->disconnectDevice();
@@ -847,22 +851,35 @@ void InteractiveCAN::slotGetReturnCANDevices()
 void InteractiveCAN::slotReConnectBLE()
 {
     if (m_bleClient) {
-        m_bleClient->connectDevice(m_currentKeyMAC, "keyLock");
+        m_bleClient->apiConnectDevice(m_currentKeyMAC);
     }
 }
 
 void InteractiveCAN::slotGetPopedDevices(const QString &nfcId, const QString &deviceType, int slotIndex)
 {
     if (deviceType == "lock") {
-        m_popedDevices.locksNfc.append(nfcId);
+
     }
     else if (deviceType == "key") {
-        m_popedDevices.keyNfc = nfcId;
+        m_okUnlockKey = true;
     }
     qDebug() << "[slotGetPopedDevices] " << m_popedDevices.locksNfc;
     qDebug() << "[slotGetPopedDevices] " << m_popedDevices.keyNfc;
 }
 
+void InteractiveCAN::slotReturnKeyAndLockProcessingChanged()
+{
+    if (ReturnKeyLockManager::instance()->isProcessing()) {
+        connect(m_bleClient, &BLEClient::workTicketResultReceived,
+                ReturnKeyLockManager::instance(), &ReturnKeyLockManager::slotReceivedJobTicket,
+                Qt::QueuedConnection);
+    }
+    else {
+        disconnect(m_bleClient, &BLEClient::workTicketResultReceived,
+                   ReturnKeyLockManager::instance(), &ReturnKeyLockManager::slotReceivedJobTicket);
+    }
+}
+
 InteractiveCAN *InteractiveCAN::instance()
 {
     if (!pInstance) {
@@ -934,8 +951,6 @@ void InteractiveCAN::getEKey()
 
 void InteractiveCAN::getLocks()
 {
-    if (m_finishedFlags) return;
-
     if (m_canClient) {
         m_canClient->setWorkingLocks(true);
     }
@@ -1099,6 +1114,10 @@ void InteractiveCAN::resetAll()
 {
     m_searchedBLE = false;
     m_checkedFlags = true;
+
+    m_okOpenKey = false;
+    m_okSendJobTicket = false;
+    m_okUnlockLocks = false;
     m_okUnlockKey = false;
 
     m_pointInfo.clear();
@@ -1119,8 +1138,6 @@ QString InteractiveCAN::retryReadLockRFID(int lockNum)
 
 void InteractiveCAN::slotUnlockEKey(const CANKeyBaseChargeStatus& status)
 {
-//    if (ReturnKeyLockManager::instance()->isProcessing()) return;
-
     if (status.success) {
         if (m_okOpenKey) {
             QMutexLocker locker(&m_mutex);
@@ -1130,7 +1147,6 @@ void InteractiveCAN::slotUnlockEKey(const CANKeyBaseChargeStatus& status)
 
 //                httpRequestPostInsertUnlockKey();
             }
-            m_okUnlockKey = true;
         }
     }
 }
@@ -1198,7 +1214,7 @@ void InteractiveCAN::slotOkSearchedBLE(bool success)
             createColockJobTicket();
         }
         else {
-            m_bleClient->connectDevice(m_currentKeyMAC, "keyLock");
+            m_bleClient->apiConnectDevice(m_currentKeyMAC);
         }
     }
 }
@@ -1208,7 +1224,9 @@ void InteractiveCAN::slotSendJobTicketStatus(bool success)
     if (success) {
         m_okSendJobTicket = true;
         if (WorkNodeFormModel::instance()->modelType() == QString("isolation")) {
-            getLocks();
+            if (!m_okUnlockLocks) {
+                getLocks();
+            }
         }
         else {
             m_finishedFlags = false;

+ 1 - 0
src/interactive/InteractiveCAN.h

@@ -146,6 +146,7 @@ public slots:
     void slotReConnectBLE();
 
     void slotGetPopedDevices(const QString& nfcId, const QString& deviceType, int slotIndex);
+    void slotReturnKeyAndLockProcessingChanged();
 signals:
     void signalReturnDevicesInfo(const QByteArray& info);
     void signalOkSearchedBLE(bool success);

+ 7 - 8
src/interactive/ReturnKeyLockManager.cpp

@@ -264,7 +264,7 @@ void ReturnKeyLockManager::onApiResponse(const QString& nfcId, bool success, con
         lockRfids << nfcId;
 
         InteractiveCAN::instance()->setTaskCode(m_currTask.taskCode.toInt());
-        InteractiveCAN::instance()->httpRequestPostUpdateBackLock(lockRfids);
+//        InteractiveCAN::instance()->httpRequestPostUpdateBackLock(lockRfids);
     }
     else {
         // 分类到对应组
@@ -534,6 +534,11 @@ void ReturnKeyLockManager::slotGetJobTicketResult(int stat, const QJsonObject& d
         else {
             m_failedLocks++;
         }
+
+        m_errorDevices.append(info);
+
+        emit statisticsChanged();
+        emit dataUpdated();
         return;
     }
     else {
@@ -565,6 +570,7 @@ void ReturnKeyLockManager::slotGetJobTicketResult(int stat, const QJsonObject& d
         else {
             if (info.deviceType == "key") {
                 m_failedKeys++;
+
             }
             else {
                 m_failedLocks++;
@@ -629,8 +635,6 @@ void ReturnKeyLockManager::slotGetJobTicketResult(int stat, const QJsonObject& d
         if (!m_currTask.keyNfc.isEmpty()) {
             InteractiveCAN::instance()->setKeyNfc(m_currTask.keyNfc);
         }
-
-        qDebug() << "[slotGetJobTicketResult] ==============" << m_currTask.keyNfc << info.nfcId << m_currTask.lockNfcs << lockInfoList;
     }
 
     // 分类到对应组
@@ -654,13 +658,8 @@ void ReturnKeyLockManager::slotGetJobTicketResult(int stat, const QJsonObject& d
             }
         }
     }
-    if (!m_taskGroups.isEmpty()) {
-        qDebug() << "[slotGetJobTicketResult] " << m_taskGroups.firstKey() << m_taskGroups.keys();
-    }
 
     if (WorkNodeFormModel::instance()->modelType() == "releaseIsolation") {
-        qDebug() << "[slotGetJobTicketResult] " << WorkNodeFormModel::instance()->modelType();
-
         QList<ReturnDeviceInfo> releaseIsolationInfoList = m_taskGroups[m_currTask.taskCode];
         m_taskGroups.clear();
         m_taskGroups[m_currTask.taskCode] = releaseIsolationInfoList;

+ 5 - 1
src/interactive/ReturnKeyLockManager.h

@@ -55,7 +55,7 @@ class ReturnKeyLockManager : public QObject
     QML_NAMED_ELEMENT(ReturnKeyLockManager)
 
     // QML属性
-    Q_PROPERTY(bool isProcessing READ isProcessing NOTIFY isProcessingChanged)
+    Q_PROPERTY(bool isProcessing READ isProcessing WRITE setIsProcessing NOTIFY isProcessingChanged)
     Q_PROPERTY(bool isVisible READ isVisible WRITE setIsVisible NOTIFY isVisibleChanged)
     Q_PROPERTY(int totalTasks READ totalTasks NOTIFY statisticsChanged)
     Q_PROPERTY(int totalKeys READ totalKeys NOTIFY statisticsChanged)
@@ -74,6 +74,10 @@ public:
 
     // 属性访问器
     bool isProcessing() const { return m_isProcessing; }
+    void setIsProcessing(bool okProcess) {
+        m_isProcessing = okProcess;
+        emit isProcessingChanged();
+    }
     bool isVisible() const { return m_isVisible; }
     void setIsVisible(bool visible);
     

+ 76 - 71
src/qml/components/FormCard.qml

@@ -206,82 +206,86 @@ Rectangle {
                     formLabel.text = qsTr(label);
 
                     if (type === "input") {
-                        formControl.source = "MInput.qml";
-                        formControl.item.controlId = id;
-                        formControl.item.modelIndex = groupIndex;
-                        formControl.item.placeholderText = placeholder;
-                        formControl.item.required = required;
-                        formControl.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
-                        formControl.item.height = 48;
-                        formControl.item.readOnly = control.readOnly;
-                        formControl.item.enabled = !control.readOnly;
+                        formControlColumn.source = "MInput.qml";
+                        formControlColumn.item.controlId = id;
+                        formControlColumn.item.modelIndex = groupIndex;
+                        formControlColumn.item.placeholderText = placeholder;
+                        formControlColumn.item.required = required;
+                        formControlColumn.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
+                        formControlColumn.item.height = 48;
+                        formControlColumn.item.readOnly = control.readOnly;
+                        formControlColumn.item.enabled = !control.readOnly;
                         // 回显值
                         if (value !== undefined && value !== "") {
-                            formControl.item.text = value;
+                            formControlColumn.item.text = value;
                         }
 
-                        formControl.item.signalTextChanged.connect(control.slotCollectInputInfo);
+                        formControlColumn.item.signalTextChanged.connect(control.slotCollectInputInfo);
                         // 连接虚拟键盘
-                        formControl.item.signalInputClicked.connect(control.showVirtualKeyboard);
+                        formControlColumn.item.signalInputClicked.connect(control.showVirtualKeyboard);
+                        control.signalSubmit.connect(formControlColumn.item.slotShowRequiredMsg);
                     } else if (type === "switch") {
-                        formControl.source = "MSwitchButton.qml";
-                        formControl.item.text = "";
-                        formControl.item.backgroundVisible = false;
-                        formControl.item.switchWidth = 60;
-                        formControl.item.controlId = id;
-                        formControl.item.modelIndex = groupIndex;
-                        formControl.item.required = required;
-                        formControl.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
-                        formControl.item.height = 48;
-                        formControl.item.enabled = !control.readOnly;
+                        formControlRow.source = "MSwitchButton.qml";
+                        formControlRow.item.text = "";
+                        formControlRow.item.backgroundVisible = false;
+                        formControlRow.item.switchWidth = 60;
+                        formControlRow.item.controlId = id;
+                        formControlRow.item.modelIndex = groupIndex;
+                        formControlRow.item.required = required;
+                        formControlRow.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
+                        formControlRow.item.height = 48;
+                        formControlRow.item.enabled = !control.readOnly;
                         // 回显值
                         if (value !== undefined && value !== "") {
-                            formControl.item.checked = (value === "true" || value === "1");
+                            formControlRow.item.checked = (value === "true" || value === "1");
                         }
 
-                        formControl.item.signalToggled.connect(control.slotCollectSwitchChecked);
+                        formControlColumn.item.signalToggled.connect(control.slotCollectSwitchChecked);
+                        control.signalSubmit.connect(formControlColumn.item.slotShowRequiredMsg);
                     } else if (type === "daterange") {
-                        formControl.source = "MInput.qml";
-                        formControl.item.controlId = id;
-                        formControl.item.modelIndex = groupIndex;
-                        formControl.item.placeholderText = placeholder;
-                        formControl.item.required = required;
-                        formControl.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
-                        formControl.item.height = 48;
-                        formControl.item.readOnly = control.readOnly;
-                        formControl.item.enabled = !control.readOnly;
+                        formControlColumn.source = "MInput.qml";
+                        formControlColumn.item.controlId = id;
+                        formControlColumn.item.modelIndex = groupIndex;
+                        formControlColumn.item.placeholderText = placeholder;
+                        formControlColumn.item.required = required;
+                        formControlColumn.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
+                        formControlColumn.item.height = 48;
+                        formControlColumn.item.readOnly = control.readOnly;
+                        formControlColumn.item.enabled = !control.readOnly;
                         // 回显值
                         if (value !== undefined && value !== "") {
-                            formControl.item.text = value;
+                            formControlColumn.item.text = value;
                         }
 
-                        formControl.item.signalTextChanged.connect(control.slotCollectInputInfo);
+                        formControlColumn.item.signalTextChanged.connect(control.slotCollectInputInfo);
                         // 连接虚拟键盘
-                        formControl.item.signalInputClicked.connect(control.showVirtualKeyboard);
+                        formControlColumn.item.signalInputClicked.connect(control.showVirtualKeyboard);
+                        control.signalSubmit.connect(formControlColumn.item.slotShowRequiredMsg);
                     } else if (type === "timepicker") {
-                        formControl.source = "MDatePicker.qml";
-                        formControl.item.controlId = id;
-                        formControl.item.modelIndex = groupIndex;
-                        formControl.item.placeholderText = placeholder;
-                        formControl.item.required = required;
-                        formControl.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
-                        formControl.item.height = 48;
-                        formControl.item.enabled = !control.readOnly;
+                        formControlColumn.source = "MDatePicker.qml";
+                        formControlColumn.item.controlId = id;
+                        formControlColumn.item.modelIndex = groupIndex;
+                        formControlColumn.item.placeholderText = placeholder;
+                        formControlColumn.item.required = required;
+                        formControlColumn.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
+                        formControlColumn.item.height = 48;
+                        formControlColumn.item.enabled = !control.readOnly;
                         // 回显值
                         if (value !== undefined && value !== "") {
-                            formControl.item.text = value;
+                            formControlColumn.item.text = value;
                         }
 
-                        formControl.item.signalTextChanged.connect(control.slotCollectInputInfo);
+                        formControlColumn.item.signalTextChanged.connect(control.slotCollectInputInfo);
+                        control.signalSubmit.connect(formControlColumn.item.slotShowRequiredMsg);
                     } else if (type === "radio") {
-                        formControl.source = "MRadioButton.qml";
-                        formControl.item.controlId = id;
-                        formControl.item.modelIndex = groupIndex;
-                        formControl.item.required = required;
-                        formControl.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
-                        formControl.item.enabled = !control.readOnly;
-                        formControl.item.fontSize = 15;
-                        formControl.item.backgroundVisible = false;
+                        formControlRow.source = "MRadioButton.qml";
+                        formControlRow.item.controlId = id;
+                        formControlRow.item.modelIndex = groupIndex;
+                        formControlRow.item.required = required;
+                        formControlRow.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
+                        formControlRow.item.enabled = !control.readOnly;
+                        formControlRow.item.fontSize = 15;
+                        formControlRow.item.backgroundVisible = false;
                         var radioOptions = [];
                         var selectedIdx = -1;
                         for (var i = 0; i < options.length; i++) {
@@ -293,38 +297,39 @@ Rectangle {
                             }
                         }
 
-                        formControl.item.model = radioOptions;
-                        formControl.item.height = 48;
+                        formControlRow.item.model = radioOptions;
+                        formControlRow.item.height = 48;
                         // 回显选中状态
                         if (selectedIdx >= 0) {
-                            formControl.item.selectedIndices = [selectedIdx];
+                            formControlRow.item.selectedIndices = [selectedIdx];
                         }
 
-                        formControl.item.signalSelectionChanged.connect(control.slotCollectRadioBtnInfo);
+                        formControlRow.item.signalSelectionChanged.connect(control.slotCollectRadioBtnInfo);
+                        control.signalSubmit.connect(formControlRow.item.slotShowRequiredMsg);
                     } else if (type === "textarea") {
-                        formControl.source = "MTextArea.qml";
-                        formControl.item.controlId = id;
-                        formControl.item.modelIndex = groupIndex;
-                        formControl.item.placeholderText = placeholder;
-                        formControl.item.required = required;
-                        formControl.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
-                        formControl.item.readOnly = control.readOnly;
-                        formControl.item.enabled = !control.readOnly;
+                        formControlColumn.source = "MTextArea.qml";
+                        formControlColumn.item.controlId = id;
+                        formControlColumn.item.modelIndex = groupIndex;
+                        formControlColumn.item.placeholderText = placeholder;
+                        formControlColumn.item.required = required;
+                        formControlColumn.item.requiredMsg = requiredMessage !== "" ? requiredMessage : label.trim()+"不能为空";
+                        formControlColumn.item.readOnly = control.readOnly;
+                        formControlColumn.item.enabled = !control.readOnly;
 
                         formArea.height = control.textAreaHeight;
                         // 回显值
                         if (value !== undefined && value !== "") {
-                            formControl.item.text = value;
+                            formControlColumn.item.text = value;
                         }
 
-                        formControl.item.signalTextAreaChanged.connect(control.slotCollectInputInfo);
+                        formControlColumn.item.signalTextAreaChanged.connect(control.slotCollectInputInfo);
                         // 连接虚拟键盘
-                        formControl.item.signalInputClicked.connect(control.showVirtualKeyboard);
+                        formControlColumn.item.signalInputClicked.connect(control.showVirtualKeyboard);
+
+                        control.signalSubmit.connect(formControlColumn.item.slotShowRequiredMsg);
                     } else {
                         return;
                     }
-
-                    control.signalSubmit.connect(formControl.item.slotShowRequiredMsg);
                 }
             }
         }

+ 1 - 1
src/src.pro

@@ -143,4 +143,4 @@ INSTALLS += qmldir_install
 
 DISTFILES += qml/qmldirs
 LIBS += -lc# 修复pthread线程库链接(原报错有pthread相关符号,显式链接)
-LIBS += -lpthread
+LIBS += -lpthread

+ 108 - 25
src/usr/BluetoothClient.cpp

@@ -4,6 +4,7 @@
 #include <QDBusInterface>
 #include <QLowEnergyConnectionParameters>
 #include <QProcess>
+#include <QDBusPendingReply>
 
 void releaseBluetoothResource() {
     qDebug() << "[BLE] 释放系统蓝牙资源...";
@@ -104,23 +105,16 @@ void BLEClient::stopDeviceDiscovery()
 
 void BLEClient::onDeviceDiscovered(const QBluetoothDeviceInfo& device)
 {
-    m_filterDevice.append("keyLock");
-
     if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
-//        if (!m_filterDevice.empty() && !m_filterDevice.contains(device.name())) {
-//             return;
-//        }
         QString mac = device.address().toString();
         if (!m_selectedMAC.isEmpty() && mac == m_selectedMAC) {
             qInfo() << "[BLE] 发现目标设备:" << device.name() << ",MAC:" << mac;
-            connectDevice(mac, "keyLock");
+            QTimer::singleShot(200, this, [=]() {
+               connectDevice(mac, "keyLock");
+           });
             m_discoveryAgent->stop();
             m_isSearching = false;
         }
-//        connectDevice(mac, device.name());
-
-//        m_discoveryAgent->stop();
-//        m_isSearching = false;
     }
 }
 
@@ -182,20 +176,95 @@ void BLEClient::connectDevice(const QString& macAddress, const QString& name)
         this
     );
 
+    QDBusInterface bluezPropsIface(
+        "org.bluez",
+        "/org/bluez/hci0/dev_" + noPairMAC,
+        "org.freedesktop.DBus.Properties",
+        QDBusConnection::systemBus(),
+        this
+    );
+    bluezDeviceIface.setTimeout(5000);
+    bluezPropsIface.setTimeout(5000);
 
     if (bluezDeviceIface.isValid()) {
+        QVariant trustedValue = QVariant::fromValue(true);
+        QDBusPendingCall pendingCall = bluezPropsIface.asyncCall(
+                    "Set",
+                    "org.bluez.Device1",
+                    "Trusted",
+                    QVariant::fromValue(QDBusVariant(trustedValue))
+                );
+        QDBusPendingReply<void> reply = pendingCall;
+        reply.waitForFinished(); // 阻塞等待DBus调用完成
+        if (reply.isError()) {
+            qWarning() << "[BLE] 设置信任属性失败:" << reply.error().message();
+        } else {
+            qInfo() << "[BLE] 信任属性设置成功";
+        }
+
         // 设置BlueZ设备属性:禁用自动绑定、禁用配对
-        bluezDeviceIface.setProperty("AutoConnect", false);    // 禁用自动连接
-        bluezDeviceIface.setProperty("Bonded", false);         // 取消绑定
-        bluezDeviceIface.setProperty("Trusted", true);         // 信任设备
-        bluezDeviceIface.setProperty("PairingAllowed", false); // 禁用配对
-        bluezDeviceIface.setProperty("Blocked", false);        // 确保设备未被拉黑
-        bluezDeviceIface.call("CancelPairing");                // 取消待处理配对
-        bluezDeviceIface.call("SetPairingMode", false);
-        // 移除已有绑定(若存在)
+        bluezPropsIface.call(
+            "Set",
+            "org.bluez.Device1",
+            "AutoConnect",
+            QVariant::fromValue(QDBusVariant(false))
+        );
+        // 设置Bonded=false
+        bluezPropsIface.call(
+            "Set",
+            "org.bluez.Device1",
+            "Bonded",
+            QVariant::fromValue(QDBusVariant(false))
+        );
+        // 设置PairingAllowed=false
+        bluezPropsIface.call(
+            "Set",
+            "org.bluez.Device1",
+            "PairingAllowed",
+            QVariant::fromValue(QDBusVariant(false))
+        );
+        // 设置Blocked=false
+        bluezPropsIface.call(
+            "Set",
+            "org.bluez.Device1",
+            "Blocked",
+            QVariant::fromValue(QDBusVariant(false))
+        );
+
+        bluezDeviceIface.call("CancelPairing");
         bluezDeviceIface.call("Disconnect");
-        bluezDeviceIface.call("Remove");
+//        bluezDeviceIface.setProperty("AutoConnect", false);    // 禁用自动连接
+//        bluezDeviceIface.setProperty("Bonded", false);         // 取消绑定
+//        bluezDeviceIface.setProperty("Trusted", true);         // 信任设备
+//        bluezDeviceIface.setProperty("PairingAllowed", false); // 禁用配对
+//        bluezDeviceIface.setProperty("Blocked", false);        // 确保设备未被拉黑
+//        bluezDeviceIface.call("CancelPairing");                // 取消待处理配对
+//        bluezDeviceIface.call("SetPairingMode", false);
+//        // 移除已有绑定(若存在)
+//        bluezDeviceIface.call("Disconnect");
+//        bluezDeviceIface.call("Remove");
+        QDBusPendingReply<QVariant> getReply = bluezPropsIface.asyncCall(
+           "Get",
+           "org.bluez.Device1",
+           "Trusted"
+       );
+       getReply.waitForFinished();
+       if (getReply.isError()) {
+           qWarning() << "[BLE] 获取信任属性失败:" << getReply.error().message();
+       } else {
+           bool isTrusted = getReply.value().toBool();
+           if (isTrusted) {
+               qInfo() << "[BLE] 设备信任状态验证通过(Trusted=true)";
+           } else {
+               qWarning() << "[BLE] 设备信任状态验证失败(Trusted=false)";
+           }
+       }
+
+       // 5. 等待BlueZ缓存同步(关键:1秒)
+       QThread::msleep(1000);
         qDebug() << "[BLE] DBus禁用绑定成功:" << "/org/bluez/hci0/dev_" + noPairMAC;
+
+        QThread::msleep(500);
     }
     else {
         qDebug() << "[BLE] 暂未扫描到设备,连接时再禁用绑定";
@@ -225,13 +294,14 @@ void BLEClient::connectDevice(const QString& macAddress, const QString& name)
         emit connectStateChanged(QLowEnergyController::UnconnectedState, "创建蓝牙控制器失败");
         return;
     }
-    m_leController->setRemoteAddressType(QLowEnergyController::RandomAddress);
+//    m_leController->setRemoteAddressType(QLowEnergyController::RandomAddress);
+    m_leController->setRemoteAddressType(QLowEnergyController::PublicAddress);
 
     // 缩短连接超时、调整间隔,避免协商卡住
-    QLowEnergyConnectionParameters params;
-    params.setIntervalRange(6, 12); // 最小连接间隔(7.5ms*6=45ms)最大连接间隔(7.5ms*12=90ms
-    params.setSupervisionTimeout(500); // 监督超时(500ms,默认2000ms太长)
-    m_leController->requestConnectionUpdate(params);
+//    QLowEnergyConnectionParameters params;
+//    params.setIntervalRange(6, 12); // 最小连接间隔(7.5ms*6=45ms)最大连接间隔(7.5ms*12=90ms
+//    params.setSupervisionTimeout(500); // 监督超时(500ms,默认2000ms太长)
+//    m_leController->requestConnectionUpdate(params);
 
     connect(m_leController, &QLowEnergyController::stateChanged, this, &BLEClient::onControllerStateChanged);
     connect(m_leController, &QLowEnergyController::serviceDiscovered, this, &BLEClient::onServiceDiscovered);
@@ -380,6 +450,12 @@ bool BLEClient::isConnected()
     }
 }
 
+void BLEClient::apiConnectDevice(const QString &macAddress)
+{
+    m_selectedMAC = macAddress;
+    m_discoveryAgent->start();
+}
+
 void BLEClient::run()
 {
     while (m_threadstatus) {
@@ -393,12 +469,19 @@ void BLEClient::run()
 void BLEClient::onControllerStateChanged(QLowEnergyController::ControllerState state)
 {
     switch (state) {
-        case QLowEnergyController::ConnectedState:
+        case QLowEnergyController::ConnectedState: {
             qInfo() << "[BLE] 设备连接成功,开始发现服务...";
             emit connectStateChanged(QLowEnergyController::ConnectingState, "连接成功");
+
+            QLowEnergyConnectionParameters params;
+            params.setIntervalRange(6, 12); // 7.5ms*6=45ms ~ 7.5ms*12=90ms
+            params.setSupervisionTimeout(500); // 500ms
+            m_leController->requestConnectionUpdate(params);
+
             // 发现所有服务
             m_leController->discoverServices();
             break;
+        }
         case QLowEnergyController::UnconnectedState:
             emit connectStateChanged(QLowEnergyController::UnconnectedState, "连接断开");
             break;

+ 2 - 0
src/usr/BluetoothClient.h

@@ -157,6 +157,8 @@ public:
     void startGetWorkTicketResult();
 
     bool isConnected();
+
+    void apiConnectDevice(const QString& macAddress);
 protected:
     void run() override;
 signals:

+ 31 - 16
src/usr/CANClient.cpp

@@ -1286,33 +1286,23 @@ void CANClient::readKeyRFIDStatusAsync()
 
             QMutexLocker locker(&m_insertDataMutex);
 
-            QString prevLeftHasKey, prevRightHasKey;
+            QString prevLeftHasKey;
             if (m_keyRFIDStatus.find(nodeId) != m_keyRFIDStatus.end()) {
                 prevLeftHasKey = m_keyRFIDStatus[nodeId].leftKeyRFID;
-                prevRightHasKey = m_keyRFIDStatus[nodeId].rightKeyRFID;
             }
 
             QString currHasLock =  parseRFIDCard(data);;
-            if (!m_keyRFIDStatus.isEmpty()) {
+            if (!prevLeftHasKey.isEmpty()) {
                 if (prevLeftHasKey != currHasLock && !currHasLock.isEmpty() && currHasLock != "00000000") {
                     qInfo() << "[归还检测] 左钥匙:NFC卡号:" << currHasLock;
 
                    emit nfcDeviceDetected(currHasLock, "key", 0);
                 }
-//                if (!prevLeftHasKey && status.leftLocked) {
-//                    qInfo() << "[归还检测] 检测到左钥匙插入!";
-
-//                    if (m_keyRFIDStatus.find(nodeId) != m_keyRFIDStatus.end() &&
-//                        !m_keyRFIDStatus[nodeId].leftKeyRFID.isEmpty() &&
-//                        m_keyRFIDStatus[nodeId].leftKeyRFID != "00000000") {
-//                        qInfo() << "[归还检测] 左钥匙:NFC卡号:" << m_keyRFIDStatus[nodeId].leftKeyRFID;
+                else if (prevLeftHasKey != currHasLock && (currHasLock.isEmpty() || currHasLock == "00000000")) {
+                    qInfo() << "[取出检测] 左钥匙:NFC卡号:" << currHasLock;
 
-//                        emit nfcDeviceDetected(m_keyRFIDStatus[nodeId].leftKeyRFID, "key", 0);
-//                    } else {
-//                        qWarning() << "[归还检测] 左钥匙存在但无法读取NFC";
-//                        emit nfcDeviceError("key", 0);
-//                    }
-//                }
+                    emit signalPopDevices(prevLeftHasKey, "key", 0);
+                }
             }
 
             if (m_keyRFIDStatus.find(nodeId) == m_keyRFIDStatus.end()) {
@@ -1355,6 +1345,26 @@ void CANClient::readKeyRFIDStatusAsync()
             keyStatus.rightKeyReadSuccess = true;
 
             QMutexLocker locker(&m_insertDataMutex);
+
+            QString prevRightHasKey;
+            if (m_keyRFIDStatus.find(nodeId) != m_keyRFIDStatus.end()) {
+                prevRightHasKey = m_keyRFIDStatus[nodeId].rightKeyRFID;
+            }
+
+            QString currHasLock =  keyStatus.rightKeyRFID;
+            if (!prevRightHasKey.isEmpty()) {
+                if (prevRightHasKey != currHasLock && !currHasLock.isEmpty() && currHasLock != "00000000") {
+                    qInfo() << "[归还检测] 右钥匙:NFC卡号:" << currHasLock;
+
+                   emit nfcDeviceDetected(currHasLock, "key", 1);
+                }
+                else if (prevRightHasKey != currHasLock && (currHasLock.isEmpty() || currHasLock == "00000000")) {
+                    qInfo() << "[取出检测] 右钥匙:NFC卡号:" << currHasLock;
+
+                    emit signalPopDevices(prevRightHasKey, "key", 0);
+                }
+            }
+
             if (m_keyRFIDStatus.find(nodeId) == m_keyRFIDStatus.end()) {
                 m_keyRFIDStatus.insert(nodeId, keyStatus);
             }
@@ -1482,6 +1492,11 @@ void CANClient::readLockRFIDStatusAsync()
                         emit nfcDeviceDetected(currHasLock, "lock", lockNum);
                         emit signalLockNfcDeviceDetected(currHasLock);
                     }
+                    else if (prevHasLock != currHasLock && (currHasLock.isEmpty() || currHasLock == "00000000")) {
+                        qInfo() << "[取出检测] 检测到" << (lockNum+1) << "号锁被取出!";
+                        qInfo() << "[取出检测]" << (lockNum+1) << "号锁NFC卡号:" << currHasLock;
+                        emit signalPopDevices(prevHasLock, "lock", lockNum);
+                    }
                 }
                 // ====================================================
 

+ 2 - 2
src/usr/config.h

@@ -73,8 +73,8 @@ public:
 
     QString m_systemMACAddr;
 
-    QString httpHost = "120.27.232.27:9292";
-    //QString httpHost = "192.168.0.10:48080";
+//    QString httpHost = "120.27.232.27:9292";
+    QString httpHost = "192.168.0.10:48080";
     QString tenant_id = "149";
 
     QString userInfoUrl = "/admin-api/system/user/profile/get";                                             // 用户中心