This commit is contained in:
coco
2026-07-03 16:05:30 +08:00
commit df489d5640
1101 changed files with 779140 additions and 0 deletions
@@ -0,0 +1,269 @@
# 数据管理界面
<cite>
**本文档引用的文件**
- [datamngframe.cpp](file://cpp/Views/datamngframe.cpp)
- [DialListMeasuData.cpp](file://cpp/Views/DialListMeasuData.cpp)
- [DialListMeasuGR.cpp](file://cpp/Views/DialListMeasuGR.cpp)
- [DialListRealTimeMeasuData.cpp](file://cpp/Views/DialListRealTimeMeasuData.cpp)
- [DialListRealTimeMeasuGR.cpp](file://cpp/Views/DialListRealTimeMeasuGR.cpp)
- [DialMeasureData.cpp](file://cpp/Views/DialMeasureData.cpp)
- [DialMeasureDetailInfo.cpp](file://cpp/Views/DialMeasureDetailInfo.cpp)
- [DialRealTimeMeasureData.cpp](file://cpp/Views/DialRealTimeMeasureData.cpp)
- [TdManager.h](file://h/TdManager.h)
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp)
- [DataOperator.h](file://h/DataOperator.h)
- [TaskDataOper.h](file://h/TaskDataOper.h)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
</cite>
## 目录
1. [数据管理框架](#数据管理框架)
2. [测量数据列表展示](#测量数据列表展示)
3. [实时数据刷新机制](#实时数据刷新机制)
4. [测量详情查看功能](#测量详情查看功能)
5. [实时监控界面行为](#实时监控界面行为)
6. [数据查询、过滤与导出](#数据查询过滤与导出)
7. [大数据量列表优化](#大数据量列表优化)
8. [操作指南](#操作指南)
9. [高级开发者指南](#高级开发者指南)
## 数据管理框架
数据管理框架的核心是`CDataMngFrame`类,它负责组织和管理数据管理界面的整体结构。该框架采用MDI(多文档界面)设计,通过分割窗口(Splitter Window)将界面分为左右两个视图:左侧为导航数据视图(`CNavDataView`),右侧为应用数据视图(`CAppDataView`)。
框架通过消息映射(`BEGIN_MESSAGE_MAP`)处理各种数据管理操作,如创建、删除、导出和刷新数据。当用户在导航树中选择一个数据项时,框架会根据数据类型(如2D电阻率、3D激电等)动态创建相应的应用视图,并加载和显示数据。
```mermaid
classDiagram
class CDataMngFrame {
+m_pNavDataView : CView*
+m_pAppDataView : CView*
+m_pDataOperator : CDataOperator*
+OnCreateClient() bool
+OnSchedule() LRESULT
+ShowAppView() bool
+ShowContentListByPageView() bool
}
class CDataOperator {
+ShowRsp2DTdInfo() void
+ShowIps2DpTdInfo() void
+ShowSP2DTdInfo() void
+LoadRsp2dRecordbyPage() void
+LoadIpsp2dRecordbyPage() void
+LoadSP2dRecordbyPage() void
}
CDataMngFrame --> CDataOperator : "使用"
CDataMngFrame --> CView : "包含 m_pNavDataView"
CDataMngFrame --> CView : "包含 m_pAppDataView"
```
**Diagram sources**
- [datamngframe.cpp](file://cpp/Views/datamngframe.cpp#L49-L602)
**Section sources**
- [datamngframe.cpp](file://cpp/Views/datamngframe.cpp#L1-L800)
## 测量数据列表展示
测量数据列表的展示逻辑主要由`CDialListMeasuData``CDialListMeasuGR`两个类实现。`CDialListMeasuData`负责显示测量数据,而`CDialListMeasuGR`负责显示接地电阻信息。
`CDialListMeasuData``OnInitDialog`方法中初始化列表控件,设置列标题(如ID、A、B、M、N、Stack、K、V(mV)、I(mA)、R0(Ohm*m)等),并从数据库查询数据填充列表。它支持分页显示,通过“上一页”和“下一页”按钮进行导航。
```mermaid
flowchart TD
A[初始化对话框] --> B[设置列表控件样式]
B --> C[插入列标题]
C --> D[查询数据库获取数据]
D --> E{数据是否为空?}
E --> |否| F[调用OnShowTdData显示数据]
E --> |是| G[返回]
F --> H[遍历数据向量]
H --> I[格式化并插入列表项]
I --> J[设置列表项文本]
J --> K{是否遍历完成?}
K --> |否| H
K --> |是| L[结束]
```
**Diagram sources**
- [DialListMeasuData.cpp](file://cpp/Views/DialListMeasuData.cpp#L52-L120)
**Section sources**
- [DialListMeasuData.cpp](file://cpp/Views/DialListMeasuData.cpp#L1-L333)
- [DialListMeasuGR.cpp](file://cpp/Views/DialListMeasuGR.cpp#L1-L113)
## 实时数据刷新机制
实时数据的刷新机制由`CDialListRealTimeMeasureData``CDialListRealTimeMeasuGR`类实现。与静态数据列表不同,实时数据需要在测量过程中动态更新。
`CDialListRealTimeMeasureData`提供了三种数据更新方法:
1. `OnShowTdData`: 一次性清空并重新填充整个列表。
2. `OnShowTdDataAppend`: 在列表末尾追加新数据。
3. `OnShowTdDataUpdate`: 智能更新,先查找是否存在该数据,存在则更新,不存在则追加。
这种设计确保了在高频率数据更新场景下的流畅性和准确性。
```mermaid
sequenceDiagram
participant Device as "测量设备"
participant App as "应用程序"
participant List as "实时数据列表"
Device->>App : 发送测量数据包
App->>App : 解析数据包
App->>List : 调用OnShowTdDataUpdate
List->>List : 查找ID匹配的列表项
alt 找到匹配项
List->>List : 更新现有项的数据
else 未找到匹配项
List->>List : 在末尾追加新项
end
List->>List : 确保新项可见(EnsureVisible)
List->>List : 更新界面
```
**Diagram sources**
- [DialListRealTimeMeasuData.cpp](file://cpp/Views/DialListRealTimeMeasuData.cpp#L171-L332)
- [DialListRealTimeMeasuData.cpp](file://cpp/Views/DialListRealTimeMeasuData.cpp#L251-L332)
**Section sources**
- [DialListRealTimeMeasuData.cpp](file://cpp/Views/DialListRealTimeMeasuData.cpp#L1-L486)
- [DialListRealTimeMeasuGR.cpp](file://cpp/Views/DialListRealTimeMeasuGR.cpp#L1-L244)
## 测量详情查看功能
测量详情的查看功能由`CDialMeasureDetailInfo`类实现。该类提供了一个包含“数据”和“接地电阻”两个标签页的对话框,允许用户在一个界面中查看任务的详细信息。
其核心逻辑在`OnInitDialog`方法中:
1. 根据传入的任务参数(`STRemTaskArg`),创建并初始化`CDialListMeasuTask``CDialListMeasuGR`两个子控件。
2. 分别调用`ShowPage(1)``GetGRRequest(m_stTaskArg)`从云端获取任务数据和接地电阻信息。
3. 通过标签页的切换事件(`OnSelchangeTabChg`)来显示或隐藏相应的子控件。
```mermaid
classDiagram
class CDialMeasureDetailInfo {
+m_dialListMeasuTask : CDialListMeasuTask
+m_dialListMeasuGR : CDialListMeasuGR
+OnInitDialog() bool
+OnSelchangeTabChg() void
}
class CDialListMeasuTask {
+ShowPage() void
}
class CDialListMeasuGR {
+GetGRRequest() void
}
CDialMeasureDetailInfo --> CDialListMeasuTask
CDialMeasureDetailInfo --> CDialListMeasuGR
```
**Diagram sources**
- [DialMeasureDetailInfo.cpp](file://cpp/Views/DialMeasureDetailInfo.cpp#L56-L104)
**Section sources**
- [DialMeasureData.cpp](file://cpp/Views/DialMeasureData.cpp#L1-L2262)
- [DialMeasureDetailInfo.cpp](file://cpp/Views/DialMeasureDetailInfo.cpp#L1-L186)
## 实时监控界面行为
实时监控界面由`CDialRealTimeMeasureData`类控制。该类不仅管理数据列表,还处理用户与测量过程的交互,如开始测量、暂停测量、单点测量等。
其行为逻辑如下:
- **按钮状态管理**: 通过`SetBtnStatus`方法根据当前测量状态(如`EN_MEASU_BTN_MEASU_ALL`)启用或禁用按钮,防止用户进行无效操作。
- **测量命令发送**: 当用户点击“开始测量”时,`OnMeasureAll`方法会构造一个`STTrusteeTaskTable`结构体,并通过`PostNetRequest`发送到设备,启动测量任务。
- **数据接收与处理**: 重写`ProcRcvMeasuData`等方法来处理从设备接收的实时数据,并更新UI。
**Section sources**
- [DialRealTimeMeasureData.cpp](file://cpp/Views/DialRealTimeMeasureData.cpp#L1-L1879)
## 数据查询、过滤与导出
数据查询、过滤和导出功能主要由`CTdManager``CDataOperator`两个核心类实现。
`CTdManager`作为数据管理器,提供了与数据库交互的底层接口:
- **查询**: `ShowTdListByTz``ShowTdListByProject`等方法用于从数据库查询任务列表。
- **删除**: `DeleteRsp2DTd``DeleteIpsp2DTd`等方法用于删除不同类型的数据。
- **导入/导出**: `Import2DTdConToDB``ExportRsp2DTdToDAT`等方法用于数据的导入和导出。
`CDataOperator`则作为`CTdManager`的上层封装,为UI提供更便捷的调用接口。例如,`ExportRsp2DTdToExcel`方法会调用`CTdManager`的底层功能,将2D电阻率数据导出为Excel文件。
```mermaid
classDiagram
class CDataOperator {
+ExportRsp2DTdToExcel() UINT
+ExportRsp2DTdToDAT() UINT
+ExportRsp2DTdToCSV() UINT
+ShowRsp2DTdInfo() void
+LoadRsp2dRecordbyPage() void
}
class CTdManager {
+ShowTdListByTz() bool
+DeleteRsp2DTd() void
+Import2DTdConToDB() bool
+ExportRsp2DTdToDAT() UINT
}
CDataOperator --> CTdManager : "使用"
```
**Diagram sources**
- [DataOperator.h](file://h/DataOperator.h#L29-L87)
- [TdManager.h](file://h/TdManager.h#L33-L87)
**Section sources**
- [TdManager.h](file://h/TdManager.h#L1-L109)
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp#L1-L6839)
- [DataOperator.h](file://h/DataOperator.h#L1-L174)
## 大数据量列表优化
在处理大数据量时,直接加载所有数据会导致界面卡顿。项目通过以下两种技术进行优化:
1. **分页加载**: `CDataOperator`类中的`LoadRsp2dRecordbyPage`等方法实现了分页查询。它接收一个起始ID和页大小,只从数据库加载指定范围的数据,显著减少了内存占用和加载时间。
2. **虚拟列表**: 虽然代码中未直接体现,但`CListCtrl`控件支持虚拟列表(Virtual List)模式。在这种模式下,控件不会存储所有数据,而是通过`LVN_GETDISPINFO`消息在需要显示某一行时,由程序动态提供该行的数据。这是一种处理海量数据的高效方式。
**Section sources**
- [DataOperator.h](file://h/DataOperator.h#L76-L83)
- [TaskDataOper.h](file://h/TaskDataOper.h#L378-L382)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L418-L513)
## 操作指南
### 初学者:数据查看与导出
1. **查看数据**:
* 打开“数据管理”界面。
* 在左侧导航树中选择一个任务。
* 右侧会自动显示该任务的测量数据列表。
* 使用“上一页”和“下一页”按钮浏览不同页面的数据。
2. **导出数据**:
* 在导航树中右键点击要导出的任务。
* 选择“导出”菜单下的格式,如“导出为Excel”或“导出为DAT文件”。
* 在弹出的对话框中选择保存路径,点击“保存”即可。
## 高级开发者指南
### 高频率数据更新场景下的UI线程安全处理
在实时监控等高频率数据更新场景下,数据接收通常在后台线程中进行,而UI更新必须在主线程(UI线程)中完成。为确保线程安全,项目采用了以下方案:
1. **消息传递机制**: 后台线程不直接操作UI控件,而是通过`PostMessage``PostNetRequest`向UI线程发送自定义消息(如`WM_MSG_UPDATE_TASK_LIST`)。
2. **UI线程处理**: UI线程的消息循环接收到消息后,调用相应的消息处理函数(如`OnShowTdDataUpdate`)来安全地更新列表控件。
这种“生产者-消费者”模式有效地隔离了数据处理和UI更新,避免了多线程访问共享资源导致的竞态条件和崩溃。
```mermaid
sequenceDiagram
participant WorkerThread as "工作线程"
participant UIThread as "UI线程"
participant ListCtrl as "列表控件"
WorkerThread->>WorkerThread : 接收测量数据
WorkerThread->>UIThread : PostMessage(WM_SHOW_TD_DATA_UPDATE, 数据指针)
UIThread->>UIThread : 消息循环接收到消息
UIThread->>UIThread : 调用OnShowTdDataUpdate
UIThread->>ListCtrl : 安全地更新列表项
ListCtrl->>UIThread : 更新完成
```
**Section sources**
- [DialListRealTimeMeasuData.cpp](file://cpp/Views/DialListRealTimeMeasuData.cpp#L344-L343)
- [DialRealTimeMeasureData.cpp](file://cpp/Views/DialRealTimeMeasureData.cpp#L593-L594)