增加产测二维码内容 2114/1 2114/head 2115/target/1
authorCaisking <Casiking@zhihuishixun.com>
Wed, 20 Aug 2025 13:07:46 +0000 (21:07 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Wed, 20 Aug 2025 13:07:46 +0000 (21:07 +0800)
code/sdk/zhihui/UI/producttest/BUTTON_VIEWID_FIX.md [new file with mode: 0644]
code/sdk/zhihui/UI/producttest/include/testModel.h
code/sdk/zhihui/UI/producttest/include/testQRCode.h
code/sdk/zhihui/UI/producttest/include/testView.h
code/sdk/zhihui/UI/producttest/src/testLCD.cpp
code/sdk/zhihui/UI/producttest/src/testModel.cpp
code/sdk/zhihui/UI/producttest/src/testPresenter.cpp
code/sdk/zhihui/UI/producttest/src/testQRCode.cpp
code/sdk/zhihui/UI/producttest/src/testView.cpp

diff --git a/code/sdk/zhihui/UI/producttest/BUTTON_VIEWID_FIX.md b/code/sdk/zhihui/UI/producttest/BUTTON_VIEWID_FIX.md
new file mode 100644 (file)
index 0000000..96b883b
--- /dev/null
@@ -0,0 +1,194 @@
+# 产测成功失败按钮viewId异常问题修复
+
+## 🚨 **问题描述**
+
+产测里面的成功失败按键会变成异常的viewId,导致presenter里面的点击事件不能生效。
+
+## 🔍 **问题分析**
+
+### 1. **问题现象**
+- 成功失败按钮的viewId异常(出现乱码字符如`t\1alԟPl`)
+- 点击事件不生效
+- presenter无法处理按钮点击
+
+### 2. **问题根源**
+通过深入分析,发现了两个关键问题:
+
+#### 问题1:GetTestItemDescription函数返回nullptr
+```cpp
+std::string testModel::GetTestItemDescription(int viewId)
+{
+    if (viewId < 0 || viewId >= MAX_TEST_ITEM)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "testModel::GetTestItemDescription: viewId out of range");
+        return nullptr; // ❌ 问题:返回nullptr
+    }
+    return test_status_list[viewId].test_result;
+}
+```
+
+#### 问题2:枚举顺序与数组初始化顺序不匹配 ⭐ **主要问题**
+**枚举定义顺序**:
+```cpp
+enum test_item_enum {
+   LCD_TEST,        // 0
+   TP_TEST,         // 1
+   MAGETIC_TEST,    // 2
+   LUMINANCE_TEST,  // 3
+   BAT_TEST,        // 4
+   SPK_TEST,        // 5
+   MIC_TEST,        // 6
+   MOTOR_TEST,      // 7
+   HR_TEST,         // 8
+   GSENSOR_TEST,    // 9
+   CAT1_TEST,       // 10
+   KEY_TEST,        // 11
+   BUTTON_TEST,     // 12
+   BT_TEST,         // 13
+   APPI_TEST,       // 14
+   GPS_TEST,        // 15
+   MAX_TEST_ITEM,   // 16
+};
+```
+
+**test_status_list初始化顺序**(修复前):
+```cpp
+test_status_t test_status_list[MAX_TEST_ITEM] = {
+    {LCD_TEST, TEST_STATUS_NONE, "LCD"},           // 索引0 ✅
+    {TP_TEST, TEST_STATUS_NONE, "Touch_Panel"},    // 索引1 ✅
+    {MAGETIC_TEST, TEST_STATUS_NONE, "Magnetic"},  // 索引2 ✅
+    {LUMINANCE_TEST, TEST_STATUS_NONE, "Luminance"}, // 索引3 ✅
+    {BAT_TEST, TEST_STATUS_NONE, "BatteryCharger"}, // 索引4 ✅
+    {SPK_TEST, TEST_STATUS_NONE, "Speaker"},       // 索引5 ✅
+    {KEY_TEST, TEST_STATUS_NONE, "Key"},           // 索引6 ❌ 应该是MIC_TEST
+    {MOTOR_TEST, TEST_STATUS_NONE, "Motor"},       // 索引7 ❌ 应该是MOTOR_TEST
+    {HR_TEST, TEST_STATUS_NONE, "Heart_Rate"},     // 索引8 ❌ 应该是HR_TEST
+    {GSENSOR_TEST, TEST_STATUS_NONE, "G_Sensor"},  // 索引9 ❌ 应该是GSENSOR_TEST
+    {CAT1_TEST, TEST_STATUS_NONE, "CAT1"},         // 索引10 ❌ 应该是CAT1_TEST
+    {BUTTON_TEST, TEST_STATUS_NONE, "Buttons"},    // 索引11 ❌ 应该是KEY_TEST
+    {BT_TEST, TEST_STATUS_NONE, "Bluetooth"},      // 索引12 ❌ 应该是BUTTON_TEST
+    {APPI_TEST, TEST_STATUS_NONE, "SE_Chip"},      // 索引13 ❌ 应该是BT_TEST
+    {GPS_TEST, TEST_STATUS_NONE, "GPS"},           // 索引14 ❌ 应该是APPI_TEST
+    // 索引15缺失:GPS_TEST
+};
+```
+
+### 3. **问题流程**
+```
+AddResultButtons(viewId) 
+→ GetTestItemDescription(viewId) 
+→ 返回错误的描述字符串(因为数组索引与枚举值不匹配)
+→ "TestOK" + 错误字符串 
+→ 异常viewId
+→ SetViewId(异常字符串)
+→ 点击事件处理失败
+```
+
+## 🛠️ **修复方案**
+
+### 1. **修复GetTestItemDescription函数**
+将返回值从`nullptr`改为空字符串:
+```cpp
+std::string testModel::GetTestItemDescription(int viewId)
+{
+    if (viewId < 0 || viewId >= MAX_TEST_ITEM)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "testModel::GetTestItemDescription: viewId out of range");
+        return ""; // ✅ 修复:返回空字符串
+    }
+    return test_status_list[viewId].test_result;
+}
+```
+
+### 2. **修复test_status_list的初始化顺序**
+```cpp
+test_status_t test_status_list[MAX_TEST_ITEM] = {
+    {LCD_TEST, TEST_STATUS_NONE, "LCD"},
+    {TP_TEST, TEST_STATUS_NONE, "Touch_Panel"},
+    {MAGETIC_TEST, TEST_STATUS_NONE, "Magnetic"},
+    {LUMINANCE_TEST, TEST_STATUS_NONE, "Luminance"},
+    {BAT_TEST, TEST_STATUS_NONE, "BatteryCharger"},
+    {SPK_TEST, TEST_STATUS_NONE, "Speaker"},
+    {MIC_TEST, TEST_STATUS_NONE, "Microphone"},      // ✅ 修复:索引6
+    {MOTOR_TEST, TEST_STATUS_NONE, "Motor"},         // ✅ 修复:索引7
+    {HR_TEST, TEST_STATUS_NONE, "Heart_Rate"},       // ✅ 修复:索引8
+    {GSENSOR_TEST, TEST_STATUS_NONE, "G_Sensor"},    // ✅ 修复:索引9
+    {CAT1_TEST, TEST_STATUS_NONE, "CAT1"},           // ✅ 修复:索引10
+    {KEY_TEST, TEST_STATUS_NONE, "Key"},             // ✅ 修复:索引11
+    {BUTTON_TEST, TEST_STATUS_NONE, "Buttons"},      // ✅ 修复:索引12
+    {BT_TEST, TEST_STATUS_NONE, "Bluetooth"},        // ✅ 修复:索引13
+    {APPI_TEST, TEST_STATUS_NONE, "SE_Chip"},        // ✅ 修复:索引14
+    {GPS_TEST, TEST_STATUS_NONE, "GPS"},             // ✅ 修复:索引15
+};
+```
+
+### 3. **在AddResultButtons中添加安全检查**
+```cpp
+// 获取测试项描述
+std::string viewDesc = testModel::GetInstance()->GetTestItemDescription(viewId);
+printf("目前测试项的描述是:%s\n",viewDesc.c_str());
+
+// 安全检查:确保viewDesc不为空
+if (viewDesc.empty())
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddResultButtons: viewDesc is empty for viewId %d", viewId);
+    return false;
+}
+```
+
+## 📊 **修复后的测试项枚举对照表**
+
+| 索引 | 测试项 | 枚举值 | 描述字符串 |
+|------|--------|--------|------------|
+| 0 | LCD测试 | LCD_TEST | "LCD" |
+| 1 | 触摸测试 | TP_TEST | "Touch_Panel" |
+| 2 | 磁力计测试 | MAGETIC_TEST | "Magnetic" |
+| 3 | 亮度测试 | LUMINANCE_TEST | "Luminance" |
+| 4 | 电池充电测试 | BAT_TEST | "BatteryCharger" |
+| 5 | 扬声器测试 | SPK_TEST | "Speaker" |
+| 6 | 麦克风测试 | MIC_TEST | "Microphone" |
+| 7 | 马达测试 | MOTOR_TEST | "Motor" |
+| 8 | 心率测试 | HR_TEST | "Heart_Rate" |
+| 9 | G传感器测试 | GSENSOR_TEST | "G_Sensor" |
+| 10 | CAT1测试 | CAT1_TEST | "CAT1" |
+| 11 | 按键测试 | KEY_TEST | "Key" |
+| 12 | 按钮测试 | BUTTON_TEST | "Buttons" |
+| 13 | 蓝牙测试 | BT_TEST | "Bluetooth" |
+| 14 | SE芯片测试 | APPI_TEST | "SE_Chip" |
+| 15 | GPS测试 | GPS_TEST | "GPS" |
+
+## 🔧 **调试建议**
+
+### 1. **添加详细日志输出**
+在`AddResultButtons`中添加更多日志:
+```cpp
+printf("AddResultButtons: viewId=%d\n", viewId);
+printf("AddResultButtons: viewDesc=%s\n", viewDesc.c_str());
+printf("AddResultButtons: okIdStr=%s\n", okIdStr.c_str());
+printf("AddResultButtons: failIdStr=%s\n", failIdStr.c_str());
+```
+
+### 2. **验证枚举值范围**
+确认传入的`viewId`在0到15之间(对应MAX_TEST_ITEM-1)。
+
+### 3. **检查数组索引映射**
+确认`test_status_list[viewId]`能正确访问到对应的测试项。
+
+## ✅ **修复效果**
+
+修复后:
+- 成功失败按钮的viewId将正确设置(如"TestOKLCD"、"TestNOLCD")
+- 点击事件能够正常生效
+- presenter能够正确处理按钮点击
+- 测试结果能够正确更新
+- 不再出现乱码字符
+
+## 🎯 **测试验证**
+
+修复完成后,请测试:
+1. 进入任意测试界面
+2. 确认成功失败按钮的viewId正确(如"TestOKLCD"、"TestNOLCD")
+3. 点击成功或失败按钮
+4. 确认点击事件被正确处理
+5. 确认测试结果状态正确更新
+6. 确认不再出现乱码字符
index ad8264d..b49df2c 100644 (file)
@@ -75,6 +75,11 @@ namespace OHOS
         test_status_enum GetResult(int viewId);
         std::string GetSummaryString();
         std::string GetTestItemDescription(int viewid);
+        test_status_enum GetTestStatus(int viewid); // 获取指定测试项的状态
+        std::string GetStartTime(); // 获取测试开始时间
+        std::string GetEndTime();   // 获取测试结束时间
+        void SetEndTime();          // 设置测试结束时间
+        bool IsAllTestsCompleted(); // 判断所有测试是否完成
    
 
     private:
index 5d1cc1f..a8f82ac 100644 (file)
@@ -29,11 +29,11 @@ namespace OHOS
         static testQRCodeView *GetInstance(void);
         
         UIScrollView *testQRCodeInitIView(uint8_t);
+        bool testQRCodeScrollViewInit(uint8_t id);
+        std::string GenerateQRCodeContent();
         void ClearAll(void);
 
     private:
-        bool testQRCodeScrollViewInit(uint8_t id);
-        std::string GenerateQRCodeContent();
         UIScrollView *testQRCodeScrollView{nullptr};
         bool initViewStatus{false};
         UILabel *Title{nullptr};           // 标题
index 0208a00..79f994d 100644 (file)
@@ -158,6 +158,10 @@ namespace OHOS
         UILabelButtonExt *button[30] = {NULL};\r
         bool initViewStatus{false};\r
 \r
+        // 添加成员变量来存储按钮viewId字符串,避免悬空指针问题\r
+        std::string okButtonViewId;\r
+        std::string failButtonViewId;\r
+\r
     };\r
     struct test_ext\r
     {\r
index b954aae..7def78e 100644 (file)
@@ -201,9 +201,19 @@ namespace OHOS
         std::string viewDesc = testModel::GetInstance()->GetTestItemDescription(LCD_TEST);
         std::string okIdStr = "TestOK" + viewDesc;
         std::string failIdStr = "TestNO" + viewDesc;
+
+        //打印viewDesc
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "viewDesc: %s", viewDesc.c_str());
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "okIdStr: %s", okIdStr.c_str());
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "failIdStr: %s", failIdStr.c_str());
+
         oktestBtn->SetViewId(okIdStr.c_str());
         failtestBtn->SetViewId(failIdStr.c_str());
 
+        //打印oktestBtn和failtestBtn的viewId
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "oktestBtn->GetViewId(): %s", oktestBtn->GetViewId());
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "failtestBtn->GetViewId(): %s", failtestBtn->GetViewId());
+
         return true;
     }
 
index 40dfc91..46623fc 100644 (file)
@@ -25,16 +25,16 @@ namespace OHOS
         {LUMINANCE_TEST, TEST_STATUS_NONE, "Luminance"},
         {BAT_TEST, TEST_STATUS_NONE, "BatteryCharger"},
         {SPK_TEST, TEST_STATUS_NONE, "Speaker"},
-        {KEY_TEST, TEST_STATUS_NONE, "Key"},
+        {MIC_TEST, TEST_STATUS_NONE, "Microphone"},
         {MOTOR_TEST, TEST_STATUS_NONE, "Motor"},
         {HR_TEST, TEST_STATUS_NONE, "Heart_Rate"},
         {GSENSOR_TEST, TEST_STATUS_NONE, "G_Sensor"},
         {CAT1_TEST, TEST_STATUS_NONE, "CAT1"},
+        {KEY_TEST, TEST_STATUS_NONE, "Key"},
         {BUTTON_TEST, TEST_STATUS_NONE, "Buttons"},
         {BT_TEST, TEST_STATUS_NONE, "Bluetooth"},
         {APPI_TEST, TEST_STATUS_NONE, "SE_Chip"},
         {GPS_TEST, TEST_STATUS_NONE, "GPS"},
-        // { LOWPOWER_TEST,    TEST_STATUS_NONE, "Deep_Sleep_Current"  },
     };
 
     // 设置测试结果
@@ -131,11 +131,22 @@ namespace OHOS
         if (viewId < 0 || viewId >= MAX_TEST_ITEM)
         {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "testModel::GetTestItemDescription: viewId out of range");
-            return nullptr;
+            return ""; // 返回空字符串而不是nullptr 
         }
         return test_status_list[viewId].test_result;
     }
 
+    // 获取指定测试项的状态
+    test_status_enum testModel::GetTestStatus(int viewId)
+    {
+        if (viewId < 0 || viewId >= MAX_TEST_ITEM)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "testModel::GetTestStatus: viewId out of range");
+            return TEST_STATUS_NONE;
+        }
+        return test_status_list[viewId].status;
+    }
+
     // 汇总测试项结果
     std::string testModel::GetSummaryString()
     {
@@ -162,6 +173,48 @@ namespace OHOS
         return m_summary;
     }
 
+    // 获取测试开始时间
+    std::string testModel::GetStartTime()
+    {
+        return m_start_time;
+    }
+
+    // 获取测试结束时间
+    std::string testModel::GetEndTime()
+    {
+        return m_end_time;
+    }
+
+    // 设置测试结束时间
+    void testModel::SetEndTime()
+    {
+        char current_time[9];
+        if (uapi_get_HHMMSS_Time(current_time, ':', true) == ERRCODE_SUCC)
+        {
+            m_end_time = current_time;
+        }
+    }
+
+    // 判断所有测试是否完成
+    bool testModel::IsAllTestsCompleted()
+    {
+        for (int i = 0; i < MAX_TEST_ITEM; i++)
+        {
+            if (test_status_list[i].status == TEST_STATUS_NONE)
+            {
+                return false; // 还有未测试的项
+            }
+        }
+        
+        // 所有测试都完成了,设置结束时间
+        if (m_end_time.empty())
+        {
+            SetEndTime();
+        }
+        
+        return true;
+    }
+
     testModel *testModel::GetInstance(void)
     {
         static testModel instance;
index 7abf16f..0931fb4 100644 (file)
@@ -158,6 +158,16 @@ namespace OHOS
     // 该点击回调主要用于在系统视图界面进行跳转视图\r
     bool testPresenter::OnClick(UIView &view, const ClickEvent &event)\r
     {\r
+        // === VIEWID 点击追踪调试 ===\r
+        printf("=== ONCLICK VIEWID DEBUG ===\n");\r
+        printf("按钮被点击,view.GetViewId() = %s\n", view.GetViewId());\r
+        printf("view.GetViewId() 地址 = %p\n", view.GetViewId());\r
+        printf("view.GetViewId() 长度 = %zu\n", strlen(view.GetViewId()));\r
+        printf("按钮类型 = %d\n", view.GetViewType());\r
+        printf("按钮位置 = (%d, %d)\n", view.GetX(), view.GetY());\r
+        printf("按钮大小 = %dx%d\n", view.GetWidth(), view.GetHeight());\r
+        printf("=== ONCLICK VIEWID DEBUG END ===\n");\r
+        \r
         testView *p_SystemView = testView::GetInstance();\r
         int len=MAX_TESTVIEWID;//sizeof(Test_ViewMapper_t)/sizeof(Test_ViewMapper_t[0]);\r
         //int len=5;\r
@@ -233,13 +243,23 @@ namespace OHOS
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"view.GetViewId() %s ",view.GetViewId());\r
         if (strncmp(view.GetViewId(), "TestOK", 6) == 0 || strncmp(view.GetViewId(), "TestNO", 6) == 0)\r
         {\r
+            printf("=== 成功失败按钮处理调试 ===\n");\r
+            printf("检测到成功/失败按钮点击\n");\r
+            printf("按钮viewId = %s\n", view.GetViewId());\r
+            printf("按钮viewId地址 = %p\n", view.GetViewId());\r
+            printf("按钮viewId长度 = %zu\n", strlen(view.GetViewId()));\r
+            \r
             std::string vid = view.GetViewId();\r
+            printf("转换为std::string后 = %s\n", vid.c_str());\r
+            printf("std::string长度 = %zu\n", vid.length());\r
 \r
             if(testModel::GetInstance()->SetResult(vid))\r
             {\r
+                printf("SetResult成功\n");\r
                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"222");\r
                 return true;\r
             }\r
+            printf("SetResult失败\n");\r
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"111");\r
             return false;\r
         }\r
index d46ec43..c78687f 100644 (file)
@@ -7,15 +7,22 @@
  * @Description: 产测二维码视图实现文件
  */
 #include "wearable_log.h"
-#include "custom_utils.h"
-#include "producttest/include/testPresenter.h"
 #include "producttest/include/testQRCode.h"
-#include "producttest/include/testView.h"
+#include "producttest/include/testPresenter.h"
 #include "producttest/include/testModel.h"
-#include "producttest/include/testabout.h"
+
+#include "ConfigModel.h"
+
+#include "custom_utils.h"
+#include "components/ui_label.h"
+#include "components/ui_label_button_ext.h"
 #include "components/ui_qrcode.h"
 #include "components/ui_scroll_view.h"
-#include "components/ui_label.h"
+#include "common/screen.h"
+#include "gfx_utils/color.h"
+#include "gfx_utils/graphic_log.h"
+#include "gfx_utils/style.h"
+#include "securec.h"
 #include <string>
 
 namespace OHOS
@@ -154,32 +161,172 @@ namespace OHOS
 
     std::string testQRCodeView::GenerateQRCodeContent()
     {
-        std::string qrContent = "产测结果\n";
+        std::string content;
         
-        // 添加设备信息
-        qrContent += "设备: FD230\n";
-        qrContent += "时间: ";
+        // 1. 产品型号(从ConfigModel获取)
+        content += "产品型号: ";
+
+        #ifdef FD230
+        content += "FD230";
+        #elif defined(BOARD_N9)
+        content += "N9";
+        #elif defined(BOARD_W9)
+        content += "W9";
+        #else
+        content += "Unknown";
+        #endif
+         
+        content += "\n";
         
-        // 获取当前时间
-        char current_time[9];
-        if (uapi_get_HHMMSS_Time(current_time, ':', true) == ERRCODE_SUCC)
-        {
-            qrContent += current_time;
+        // 2. 测试开始时间
+        content += "测试开始时间: ";
+        if (testModel::GetInstance()) {
+            content += testModel::GetInstance()->GetStartTime();
+            if (content.back() == '\n') {
+                content.pop_back(); // 移除多余的换行符
+            }
+        } else {
+            content += "获取失败";
         }
-        qrContent += "\n";
+        content += "\n";
         
-        // 添加测试结果
-        std::string testSummary = testModel::GetInstance()->GetSummaryString();
-        if (!testSummary.empty())
-        {
-            qrContent += "测试结果:\n";
-            qrContent += testSummary;
+        // 2.1 测试结束时间(如果有的话)
+        if (testModel::GetInstance() && !testModel::GetInstance()->GetEndTime().empty()) {
+            content += "测试结束时间: ";
+            content += testModel::GetInstance()->GetEndTime();
+            content += "\n";
+        } else if (testModel::GetInstance()) {
+            // 检查是否所有测试都完成了
+            if (testModel::GetInstance()->IsAllTestsCompleted()) {
+                content += "测试结束时间: ";
+                content += testModel::GetInstance()->GetEndTime();
+                content += "\n";
+            }
         }
-        else
-        {
-            qrContent += "暂无测试结果";
+        
+        // 3. 蓝牙地址
+        content += "蓝牙地址: ";
+        uint8_t btaddr[6] = {0};
+        uint8_t btaddr_str[64] = {0};
+        uint32_t len = 6;
+        errcode_t ret = uapi_get_nv_btaddr((uint8_t *)btaddr, &len);
+        if (ret == ERRCODE_SUCC) {
+            sprintf((char *)btaddr_str, "%02X:%02X:%02X:%02X:%02X:%02X", 
+                    btaddr[0], btaddr[1], btaddr[2], btaddr[3], btaddr[4], btaddr[5]);
+            content += (char *)btaddr_str;
+        } else {
+            content += "获取失败";
+        }
+        content += "\n";
+        
+        // 4. IMEI号
+        content += "IMEI: ";
+        if (ConfigModel::GetInstance()) {
+            content += ConfigModel::GetInstance()->Getimei();
+        } else {
+            content += "获取失败";
+        }
+        content += "\n";
+        
+        // 5. 固件版本号
+        content += "固件版本: ";
+        char version_buf[128] = {0};
+        uint32_t version_len = 128;
+        if (uapi_get_buildversion((uint8_t *)version_buf, version_len) == ERRCODE_SUCC) {
+            content += version_buf;
+        } else {
+            content += "获取失败";
+        }
+        content += "\n";
+        
+        // 6. Model版本(4G模块版本)
+        content += "4G模块版本: ";
+        if (ConfigModel::GetInstance()) {
+            content += ConfigModel::GetInstance()->GetmoderVer();
+        } else {
+            content += "获取失败";
+        }
+        content += "\n";
+        
+        // 7. Python版本
+        content += "Python版本: ";
+        if (ConfigModel::GetInstance()) {
+            content += ConfigModel::GetInstance()->GetpyVer();
+        } else {
+            content += "获取失败";
+        }
+        content += "\n";
+        
+        // 8. 测试统计信息
+        content += "\n=== 测试统计 ===\n";
+        if (testModel::GetInstance()) {
+            // 统计成功、失败、未测试的项数
+            int success_count = 0, failed_count = 0, none_count = 0;
+            for (int i = 0; i < MAX_TEST_ITEM; i++) {
+                test_status_enum status = testModel::GetInstance()->GetResult(i);
+                switch (status) {
+                    case TEST_STATUS_SUCCESS:
+                        success_count++;
+                        break;
+                    case TEST_STATUS_ERROR:
+                        failed_count++;
+                        break;
+                    case TEST_STATUS_NONE:
+                        none_count++;
+                        break;
+                }
+            }
+            content += "成功: " + std::to_string(success_count) + "项\n";
+            content += "失败: " + std::to_string(failed_count) + "项\n";
+            content += "未测试: " + std::to_string(none_count) + "项\n";
+            content += "总计: " + std::to_string(MAX_TEST_ITEM) + "项\n";
+        }
+        
+        // 9. 产测结果汇总
+        content += "产测结果汇总:\n";
+        if (testModel::GetInstance()) {
+            int successCount = 0;
+            int failCount = 0;
+            int notTestCount = 0;
+            std::string failedItems;
+            std::string notTestItems;
+            
+            // 遍历所有测试项,统计结果
+            for (int i = 0; i < MAX_TEST_ITEM; i++) {
+                test_status_enum status = testModel::GetInstance()->GetResult(i);
+                std::string itemName = testModel::GetInstance()->GetTestItemDescription(i);
+                
+                if (status == TEST_STATUS_SUCCESS) {
+                    successCount++;
+                } else if (status == TEST_STATUS_ERROR) {
+                    failCount++;
+                    if (!failedItems.empty()) failedItems += ", ";
+                    failedItems += itemName;
+                } else if (status == TEST_STATUS_NONE) {
+                    notTestCount++;
+                    if (!notTestItems.empty()) notTestItems += ", ";
+                    notTestItems += itemName;
+                }
+            }
+            
+            content += "成功项数: " + std::to_string(successCount) + "\n";
+            content += "失败项数: " + std::to_string(failCount) + "\n";
+            content += "未测试项数: " + std::to_string(notTestCount) + "\n";
+            content += "总计: " + std::to_string(MAX_TEST_ITEM) + "\n";
+            
+            // 显示具体的失败项
+            if (failCount > 0) {
+                content += "失败项: " + failedItems + "\n";
+            }
+            
+            // 显示具体的未测试项
+            if (notTestCount > 0) {
+                content += "未测试项: " + notTestItems + "\n";
+            }
+        } else {
+            content += "获取产测结果失败\n";
         }
         
-        return qrContent;
+        return content;
     }
 }
index f6f1760..a18d488 100644 (file)
@@ -326,6 +326,13 @@ namespace OHOS
         // 获取测试项描述\r
         std::string viewDesc = testModel::GetInstance()->GetTestItemDescription(viewId);\r
         printf("目前测试项的描述是:%s\n",viewDesc.c_str());\r
+        \r
+        // 安全检查:确保viewDesc不为空\r
+        if (viewDesc.empty())\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddResultButtons: viewDesc is empty for viewId %d", viewId);\r
+            return false;\r
+        }\r
 \r
         if (oktestBtn)\r
         {\r
@@ -345,10 +352,20 @@ namespace OHOS
                 break;\r
             }\r
 \r
-            // 设置按钮标识\r
-            std::string okIdStr = "TestOK" + viewDesc;\r
-            printf("设置成功按键的viewId %s\n", okIdStr.c_str());\r
-            oktestBtn->SetViewId(okIdStr.c_str());\r
+            // 设置按钮标识 - 修复悬空指针问题\r
+            okButtonViewId = "TestOK" + viewDesc;\r
+            printf("=== VIEWID DEBUG ===\n");\r
+            printf("设置前 oktestBtn->GetViewId() = %s\n", oktestBtn->GetViewId());\r
+            printf("准备设置 viewId = %s\n", okButtonViewId.c_str());\r
+            printf("okButtonViewId 字符串地址 = %p\n", okButtonViewId.c_str());\r
+            printf("okButtonViewId 字符串长度 = %zu\n", okButtonViewId.length());\r
+            \r
+            oktestBtn->SetViewId(okButtonViewId.c_str());\r
+            \r
+            printf("设置后 oktestBtn->GetViewId() = %s\n", oktestBtn->GetViewId());\r
+            printf("设置后 oktestBtn->GetViewId() 地址 = %p\n", oktestBtn->GetViewId());\r
+            printf("=== VIEWID DEBUG END ===\n");\r
+            \r
             UIView::OnClickListener *clickListener = static_cast<UIView::OnClickListener *>(testPresenter::GetInstance());\r
             oktestBtn->SetOnClickListener(clickListener);\r
             scrollView->Add(oktestBtn);\r
@@ -373,10 +390,20 @@ namespace OHOS
                 break;\r
             }\r
 \r
-            // 设置按钮标识(修复了原代码中的错误)\r
-            std::string failIdStr = "TestNO" + viewDesc;\r
-            printf("设置失败按键的viewId %s\n", failIdStr.c_str());\r
-            failtestBtn->SetViewId(failIdStr.c_str());\r
+            // 设置按钮标识(修复了原代码中的错误)- 修复悬空指针问题\r
+            failButtonViewId = "TestNO" + viewDesc;\r
+            printf("=== VIEWID DEBUG FAIL BUTTON ===\n");\r
+            printf("设置前 failtestBtn->GetViewId() = %s\n", failtestBtn->GetViewId());\r
+            printf("准备设置 viewId = %s\n", failButtonViewId.c_str());\r
+            printf("failButtonViewId 字符串地址 = %p\n", failButtonViewId.c_str());\r
+            printf("failButtonViewId 字符串长度 = %zu\n", failButtonViewId.length());\r
+            \r
+            failtestBtn->SetViewId(failButtonViewId.c_str());\r
+            \r
+            printf("设置后 failtestBtn->GetViewId() = %s\n", failtestBtn->GetViewId());\r
+            printf("设置后 failtestBtn->GetViewId() 地址 = %p\n", failtestBtn->GetViewId());\r
+            printf("=== VIEWID DEBUG FAIL BUTTON END ===\n");\r
+            \r
             UIView::OnClickListener *clickListener = static_cast<UIView::OnClickListener *>(testPresenter::GetInstance());\r
             failtestBtn->SetOnClickListener(clickListener);\r
             scrollView->Add(failtestBtn);\r