a
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
# 任务参数配置
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp)
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
- [GeoMative.rc](file://GeoMative.rc)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件围绕任务参数配置功能进行深入文档化,重点聚焦于DialCfgTaskPacket对话框的UI组件与交互逻辑,涵盖:
|
||||
- 循环次数、时间间隔、PLC ID等参数的配置与校验规则(循环次数与时间间隔范围为1-60000)。
|
||||
- 任务选择下拉框的数据来源:通过CTaskDataOper::QueryTdBrowseInfo从数据库查询任务列表。
|
||||
- 任务包属性的存储结构:涉及tdTaskPacket与tdTaskPacketInfo两张表的关联关系。
|
||||
- 提供代码示例路径,展示OnInitDialog中初始化UI控件与OnOK中保存配置数据的具体实现。
|
||||
|
||||
## 项目结构
|
||||
任务参数配置功能位于视图层(Views)与数据操作层(Operator)之间,UI由DialCfgTaskPacket负责,数据访问由TaskDataOper封装。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "视图层"
|
||||
DCP["DialCfgTaskPacket<br/>对话框"]
|
||||
end
|
||||
subgraph "数据访问层"
|
||||
TDO["CTaskDataOper<br/>任务数据操作"]
|
||||
end
|
||||
subgraph "数据库"
|
||||
TP["tdTaskPacket<br/>主表"]
|
||||
TPI["tdTaskPacketInfo<br/>明细表"]
|
||||
TD["td<br/>任务基础表"]
|
||||
end
|
||||
DCP --> TDO
|
||||
TDO --> TD
|
||||
TDO --> TP
|
||||
TDO --> TPI
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h#L1-L54)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L1-L177)
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L297-L336)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L685-L716)
|
||||
|
||||
章节来源
|
||||
- [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h#L1-L54)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L1-L177)
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L297-L336)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L685-L716)
|
||||
|
||||
## 核心组件
|
||||
- DialCfgTaskPacket:任务参数配置对话框,包含任务选择下拉框、任务列表、循环次数、时间间隔、PLC ID输入框及添加/删除按钮。
|
||||
- CTaskDataOper:封装数据库访问,提供任务浏览信息查询、任务包属性查询、任务包信息查询以及任务包写入等接口。
|
||||
|
||||
章节来源
|
||||
- [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h#L1-L54)
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L297-L336)
|
||||
|
||||
## 架构总览
|
||||
DialCfgTaskPacket作为UI入口,调用CTaskDataOper完成数据库读写;数据库层面以tdTaskPacket为主表存储任务包属性(循环次数、时间间隔、PLC ID),以tdTaskPacketInfo为明细表存储任务包内任务序列(TaskID、TaskName、TaskPacketID);任务基础信息来源于td表。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant D as "DialCfgTaskPacket"
|
||||
participant O as "CTaskDataOper"
|
||||
participant DB as "数据库"
|
||||
U->>D : 打开“任务参数配置”对话框
|
||||
D->>O : QueryTdBrowseInfo(查询任务列表)
|
||||
O->>DB : SELECT td
|
||||
DB-->>O : 返回任务列表
|
||||
O-->>D : 返回任务列表
|
||||
D->>D : 初始化下拉框与列表列头
|
||||
U->>D : 输入循环次数/时间间隔/PLC ID
|
||||
U->>D : 添加任务到列表
|
||||
D->>D : 去重检查与序号更新
|
||||
U->>D : 点击“保存”
|
||||
D->>D : 参数校验(1-60000, PLC ID非空)
|
||||
D->>O : InsertTaskPacketInfo(批量写入)
|
||||
O->>DB : INSERT tdTaskPacket
|
||||
O->>DB : DELETE tdTaskPacketInfo WHERE TaskPacketID=1
|
||||
O->>DB : INSERT tdTaskPacketInfo (逐条)
|
||||
DB-->>O : 提交事务
|
||||
O-->>D : 写入成功
|
||||
D-->>U : 显示保存结果
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L123-L177)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L206-L300)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L685-L716)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L1085-L1140)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### DialCfgTaskPacket 对话框
|
||||
- UI控件
|
||||
- 任务选择下拉框:用于选择可执行的任务项。
|
||||
- 任务列表:显示已选任务序列,包含序号、任务名、任务ID三列。
|
||||
- 按钮:添加、删除。
|
||||
- 参数输入框:循环次数、时间间隔(分钟)、PLC ID。
|
||||
- 初始化流程(OnInitDialog)
|
||||
- 查询任务列表并填充下拉框。
|
||||
- 读取任务包属性(循环次数、时间间隔、PLC ID)并回填到对应输入框。
|
||||
- 初始化任务列表列头与内容。
|
||||
- 交互逻辑
|
||||
- 添加:校验下拉框选中状态,去重检查后插入列表。
|
||||
- 删除:选中行删除,末尾行删除时需重排序号。
|
||||
- 保存:对循环次数、时间间隔进行范围校验(1-60000),对PLC ID进行非空校验;收集列表数据与参数,调用数据操作层写入数据库。
|
||||
|
||||
章节来源
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L47-L108)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L123-L177)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L206-L300)
|
||||
- [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h#L1-L54)
|
||||
|
||||
### 任务选择下拉框数据来源
|
||||
- 数据源:CTaskDataOper::QueryTdBrowseInfo返回std::vector<STTdBrowseInfo>,其中包含任务名与任务ID。
|
||||
- 下拉框填充:将任务名加入组合框,同时将任务ID存入SetItemData以便后续使用。
|
||||
- 使用场景:添加任务时,根据下拉框当前选中项获取任务ID与任务名。
|
||||
|
||||
章节来源
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L1013-L1083)
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L297-L306)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L123-L142)
|
||||
|
||||
### 任务包属性与存储结构
|
||||
- 属性结构:STTaskPacketAttr包含循环次数、时间间隔、PLC ID三项。
|
||||
- 存储位置:
|
||||
- 主表:tdTaskPacket(主键字段MainID=1,存储循环次数、时间间隔、PLC ID)。
|
||||
- 明细表:tdTaskPacketInfo(字段TaskPacketID=1,存储每个任务的TaskID与TaskName)。
|
||||
- 写入策略:先写入tdTaskPacket,再清空tdTaskPacketInfo中TaskPacketID=1的旧记录,最后批量插入新任务序列,事务提交。
|
||||
|
||||
章节来源
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L324-L335)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L685-L716)
|
||||
|
||||
### 参数验证规则
|
||||
- 循环次数与时间间隔:必须为整数且在1至60000之间。
|
||||
- PLC ID:必须非空。
|
||||
- 重复任务:列表中不允许出现相同任务ID。
|
||||
|
||||
章节来源
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L206-L258)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L110-L121)
|
||||
|
||||
### 代码示例路径
|
||||
- OnInitDialog中初始化UI控件与读取任务包属性
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L123-L177)
|
||||
- OnOK中保存配置数据
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L206-L300)
|
||||
- 任务包写入数据库
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L685-L716)
|
||||
|
||||
章节来源
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L123-L177)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L206-L300)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L685-L716)
|
||||
|
||||
## 依赖分析
|
||||
- DialCfgTaskPacket依赖CTaskDataOper进行数据库读写。
|
||||
- CTaskDataOper依赖ADO Recordset访问td、tdTaskPacket、tdTaskPacketInfo表。
|
||||
- UI资源定义在GeoMative.rc中,包含对话框控件ID与布局。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CDialCfgTaskPacket {
|
||||
+DoDataExchange(pDX)
|
||||
+OnInitDialog() bool
|
||||
+OnOK() void
|
||||
+OnButtonAdd() void
|
||||
+OnButtonDel() void
|
||||
-InitialTaskList() void
|
||||
-IsRepeatTask(iTaskID) bool
|
||||
-m_listTaskPacket
|
||||
-m_cmbTaskName
|
||||
}
|
||||
class CTaskDataOper {
|
||||
+QueryTdBrowseInfo(vt, bIsQueryTimerTd) void
|
||||
+QueryTdBrowseInfo(vt, iSptType, iType, bIsQueryTimerTd) void
|
||||
+QueryTaskPacketAttr(iLoopTime, iInterval, strPlcID) bool
|
||||
+QueryTaskPacketInfo(vt) bool
|
||||
+InsertTaskPacketInfo(vt, stAttr) bool
|
||||
}
|
||||
CDialCfgTaskPacket --> CTaskDataOper : "调用"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h#L1-L54)
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L297-L336)
|
||||
|
||||
章节来源
|
||||
- [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h#L1-L54)
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L297-L336)
|
||||
|
||||
## 性能考虑
|
||||
- 列表操作:删除末尾行时避免重排所有序号,仅在需要时更新后续行序号,降低O(n)更新成本。
|
||||
- 数据库写入:批量插入tdTaskPacketInfo,减少多次往返;使用事务保证一致性。
|
||||
- UI输入限制:对PLC ID设置最大长度,减少无效输入带来的处理开销。
|
||||
|
||||
章节来源
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L81-L108)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L158-L160)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L685-L716)
|
||||
|
||||
## 故障排查指南
|
||||
- 无法加载任务列表
|
||||
- 检查CTaskDataOper::QueryTdBrowseInfo是否抛出异常或返回空集。
|
||||
- 确认数据库连接正常,td表存在且包含有效记录。
|
||||
- 保存失败
|
||||
- 检查InsertTaskPacketInfo返回值与事务回滚日志。
|
||||
- 确认循环次数、时间间隔、PLC ID均满足校验条件。
|
||||
- 重复任务
|
||||
- 确认IsRepeatTask逻辑正确,列表中不存在相同TaskID。
|
||||
- UI无响应
|
||||
- 检查消息映射与控件ID是否匹配(见资源定义)。
|
||||
|
||||
章节来源
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L1013-L1083)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L685-L716)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L206-L300)
|
||||
|
||||
## 结论
|
||||
DialCfgTaskPacket通过CTaskDataOper实现了任务参数配置的完整闭环:从任务列表加载、参数输入与校验,到任务包属性与任务序列的持久化存储。其设计遵循清晰的职责分离与事务一致性保障,适合在实际工程中扩展与维护。
|
||||
|
||||
## 附录
|
||||
- 控件ID与资源定义参考
|
||||
- [GeoMative.rc](file://GeoMative.rc#L1925-L1941)
|
||||
@@ -0,0 +1,286 @@
|
||||
# 任务配置
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
- [SptManager.cpp](file://cpp/Managers/SptManager.cpp)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [项目结构](#项目结构)
|
||||
2. [任务包配置流程](#任务包配置流程)
|
||||
3. [任务与项目、测区的关联关系](#任务与项目测区的关联关系)
|
||||
4. [任务配置数据的验证机制和错误处理策略](#任务配置数据的验证机制和错误处理策略)
|
||||
5. [任务配置驱动脚本生成过程](#任务配置驱动脚本生成过程)
|
||||
6. [任务配置API使用示例](#任务配置api使用示例)
|
||||
|
||||
## 项目结构
|
||||
|
||||
Geomative Studio项目的任务配置功能主要集中在`cpp/Views`和`cpp/Operator`目录下。核心文件包括`DialCfgTaskPacket.cpp`用于任务包配置的UI交互,`TaskDataOper.cpp`负责任务数据的数据库操作,以及`SptManager.cpp`管理脚本文件的创建和同步。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "UI层"
|
||||
DialCfgTaskPacket["DialCfgTaskPacket.cpp<br/>任务包配置对话框"]
|
||||
end
|
||||
subgraph "业务逻辑层"
|
||||
TaskDataOper["TaskDataOper.cpp<br/>任务数据操作"]
|
||||
SptManager["SptManager.cpp<br/>脚本管理"]
|
||||
end
|
||||
subgraph "数据层"
|
||||
Database[(dptt数据库)]
|
||||
end
|
||||
DialCfgTaskPacket --> TaskDataOper
|
||||
TaskDataOper --> Database
|
||||
SptManager --> TaskDataOper
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
- [SptManager.cpp](file://cpp/Managers/SptManager.cpp)
|
||||
|
||||
**Section sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
- [SptManager.cpp](file://cpp/Managers/SptManager.cpp)
|
||||
|
||||
## 任务包配置流程
|
||||
|
||||
任务包配置功能通过`DialCfgTaskPacket`对话框实现,允许用户将多个测量任务组合成一个任务包进行管理。配置流程包括:
|
||||
|
||||
1. 初始化对话框时,从数据库查询所有可用任务并填充到下拉列表中
|
||||
2. 用户选择任务后点击"添加"按钮,将选中的任务添加到任务包列表中
|
||||
3. 用户可删除已添加的任务
|
||||
4. 配置任务包的循环次数、时间间隔和PLC ID等属性
|
||||
5. 保存配置时进行数据验证,确保参数在有效范围内
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> Init["初始化对话框"]
|
||||
Init --> Query["查询可用任务"]
|
||||
Query --> Display["显示任务下拉列表"]
|
||||
Display --> Select["用户选择任务"]
|
||||
Select --> Add["点击添加按钮"]
|
||||
Add --> Check["检查任务是否重复"]
|
||||
Check --> |是| Warn["提示任务已存在"]
|
||||
Check --> |否| Insert["插入任务到列表"]
|
||||
Insert --> Continue["继续添加其他任务?"]
|
||||
Continue --> |是| Select
|
||||
Continue --> |否| Config["配置循环参数"]
|
||||
Config --> Validate["验证输入参数"]
|
||||
Validate --> |无效| Error["显示错误信息"]
|
||||
Validate --> |有效| Save["保存任务包配置"]
|
||||
Save --> End([结束])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp)
|
||||
|
||||
**Section sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp)
|
||||
|
||||
## 任务与项目、测区的关联关系
|
||||
|
||||
任务配置与项目、测区之间存在明确的层级关联关系。每个任务必须归属于一个测区,而测区又属于特定的项目。这种关系在dptt数据库中通过外键约束实现:
|
||||
|
||||
- `project`表存储项目信息
|
||||
- `tz`表存储测区信息,包含指向`project`表的外键`PRID`
|
||||
- `td`表存储任务信息,包含指向`tz`表的外键`TZID`
|
||||
|
||||
当创建新任务时,系统会自动获取默认测区ID,并将该ID与任务关联。这种设计确保了任务数据的组织结构清晰,便于按项目和测区进行数据管理和查询。
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
PROJECT {
|
||||
uuid id PK
|
||||
string PRname
|
||||
timestamp create_time
|
||||
}
|
||||
TZ {
|
||||
uuid id PK
|
||||
string TzName
|
||||
uuid PRID FK
|
||||
timestamp create_time
|
||||
}
|
||||
TD {
|
||||
uuid id PK
|
||||
string TDname
|
||||
uuid TZID FK
|
||||
uuid SCID FK
|
||||
int Ttype
|
||||
int Stype
|
||||
timestamp CreateTime
|
||||
}
|
||||
PROJECT ||--o{ TZ : "包含"
|
||||
TZ ||--o{ TD : "包含"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
|
||||
**Section sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
|
||||
## 任务配置数据的验证机制和错误处理策略
|
||||
|
||||
系统在任务配置过程中实施了严格的验证机制和错误处理策略,确保数据的完整性和有效性:
|
||||
|
||||
1. **输入验证**:
|
||||
- 循环次数必须在1-60000之间
|
||||
- 时间间隔必须在1-60000之间
|
||||
- PLC ID不能为空
|
||||
|
||||
2. **重复性检查**:
|
||||
- 添加任务时检查是否已存在相同任务ID,避免重复
|
||||
|
||||
3. **事务处理**:
|
||||
- 所有数据库操作都在事务中执行,确保数据一致性
|
||||
- 操作失败时自动回滚事务
|
||||
|
||||
4. **异常处理**:
|
||||
- 使用try-catch捕获数据库操作异常
|
||||
- 显示详细的错误信息给用户
|
||||
|
||||
5. **多语言支持**:
|
||||
- 根据系统语言设置显示相应的错误提示信息
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始保存]) --> ValidateLoop["验证循环次数"]
|
||||
ValidateLoop --> |无效| ShowError1["显示范围错误"]
|
||||
ValidateLoop --> |有效| ValidateInterval["验证时间间隔"]
|
||||
ValidateInterval --> |无效| ShowError2["显示范围错误"]
|
||||
ValidateInterval --> |有效| ValidatePLC["验证PLC ID"]
|
||||
ValidatePLC --> |为空| ShowError3["显示不能为空"]
|
||||
ValidatePLC --> |有效| BeginTrans["开始事务"]
|
||||
BeginTrans --> InsertData["插入任务包数据"]
|
||||
InsertData --> Commit["提交事务"]
|
||||
Commit --> |成功| Success["显示保存成功"]
|
||||
Commit --> |失败| Rollback["回滚事务"]
|
||||
Rollback --> ShowError4["显示保存失败"]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp)
|
||||
|
||||
**Section sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp)
|
||||
|
||||
## 任务配置驱动脚本生成过程
|
||||
|
||||
任务配置通过`SptManager`与`ProManager`的协作模式驱动后续的脚本生成过程。当任务配置完成后,系统会根据配置参数自动生成相应的测量脚本文件。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant UI as "用户界面"
|
||||
participant TaskConfig as "任务配置"
|
||||
participant SptManager as "SptManager"
|
||||
participant ProManager as "ProManager"
|
||||
participant Database as "数据库"
|
||||
UI->>TaskConfig : 配置任务参数
|
||||
TaskConfig->>Database : 保存任务配置
|
||||
Database-->>TaskConfig : 保存成功
|
||||
TaskConfig->>SptManager : 请求生成脚本
|
||||
SptManager->>ProManager : 获取项目/测区信息
|
||||
ProManager-->>SptManager : 返回项目结构
|
||||
SptManager->>Database : 查询任务详情
|
||||
Database-->>SptManager : 返回任务数据
|
||||
SptManager->>SptManager : 生成脚本文件
|
||||
SptManager->>Database : 保存脚本信息
|
||||
Database-->>SptManager : 保存成功
|
||||
SptManager-->>TaskConfig : 脚本生成完成
|
||||
TaskConfig-->>UI : 显示操作结果
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [SptManager.cpp](file://cpp/Managers/SptManager.cpp)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
|
||||
**Section sources**
|
||||
- [SptManager.cpp](file://cpp/Managers/SptManager.cpp)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
|
||||
## 任务配置API使用示例
|
||||
|
||||
以下是通过编程方式创建和修改任务参数的API使用示例:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CTaskDataOper {
|
||||
+Create1DTask(ST1DTaskParam, CString) int
|
||||
+Create2DTask(ST2DTaskParam, CString) int
|
||||
+Create3DTask(ST3DTaskParam, CString) int
|
||||
+InsertTaskPacketInfo(vector~STTdBrowseInfo~, STTaskPacketAttr) bool
|
||||
+QueryTaskPacketInfo(vector~STTdBrowseInfo~) bool
|
||||
+QueryTaskPacketAttr(int&, int&, CString&) bool
|
||||
}
|
||||
class ST1DTaskParam {
|
||||
+CString strTDName
|
||||
+int iSptID
|
||||
+CString strSptName
|
||||
+int iSptType
|
||||
+int iTestType
|
||||
+int iStacking
|
||||
+int iTxWave
|
||||
+int iTxPeriod
|
||||
+int iSAInterval
|
||||
+CString strTestPlace
|
||||
}
|
||||
class ST2DTaskParam {
|
||||
+CString strTDName
|
||||
+int iSptID
|
||||
+CString strSptName
|
||||
+int iSptType
|
||||
+int iTestType
|
||||
+int iStacking
|
||||
+int iTxWave
|
||||
+int iTxPeriod
|
||||
+int iSAInterval
|
||||
+CString strTestPlace
|
||||
+int iStartElec
|
||||
+int iEndElec
|
||||
+int iEAmount
|
||||
+int iAR
|
||||
+int iCableLayout
|
||||
+int iSkipCable
|
||||
+int iRollCnt
|
||||
+float fEspace
|
||||
+BYTE ucTestGRFlag
|
||||
+UINT uiDevID
|
||||
}
|
||||
class ST3DTaskParam {
|
||||
+CString strTDName
|
||||
+int iSptID
|
||||
+CString strSptName
|
||||
+int iSptType
|
||||
+int iTestType
|
||||
+int iStacking
|
||||
+int iTxWave
|
||||
+int iTxPeriod
|
||||
+int iSAInterval
|
||||
+CString strTestPlace
|
||||
+int iEAmount
|
||||
+int iAR
|
||||
+int iCableLayout
|
||||
+int iSkipCable
|
||||
+BYTE ucTestGRFlag
|
||||
+UINT uiDevID
|
||||
}
|
||||
class STTaskPacketAttr {
|
||||
+int iLoopTimes
|
||||
+int iInterval
|
||||
+CString strPlcID
|
||||
}
|
||||
CTaskDataOper --> ST1DTaskParam : "使用"
|
||||
CTaskDataOper --> ST2DTaskParam : "使用"
|
||||
CTaskDataOper --> ST3DTaskParam : "使用"
|
||||
CTaskDataOper --> STTaskPacketAttr : "使用"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
|
||||
**Section sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
@@ -0,0 +1,249 @@
|
||||
# 任务验证与存储
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp)
|
||||
- [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [CTaskDataOper类的作用](#ctaskdataoper类的作用)
|
||||
3. [任务数据持久化机制](#任务数据持久化机制)
|
||||
4. [InsertTaskPacketInfo方法分析](#inserttaskpacketinfo方法分析)
|
||||
5. [数据验证流程](#数据验证流程)
|
||||
6. [任务包配置数据存储结构](#任务包配置数据存储结构)
|
||||
7. [错误处理策略](#错误处理策略)
|
||||
8. [UI到数据库的完整流程示例](#ui到数据库的完整流程示例)
|
||||
|
||||
## 简介
|
||||
本文档深入分析了GeomativeStudio软件中任务配置的验证与存储机制,重点阐述了CTaskDataOper类在任务数据持久化中的核心作用。文档详细描述了任务列表和属性信息如何通过InsertTaskPacketInfo方法写入数据库,包括对tdTaskPacket和tdTaskPacketInfo表的操作。同时,文档解释了数据验证流程、存储结构定义以及错误处理策略。
|
||||
|
||||
## CTaskDataOper类的作用
|
||||
CTaskDataOper类是GeomativeStudio系统中负责任务数据操作的核心类,主要承担任务数据的持久化、查询、验证和管理功能。该类通过ADO数据库连接与后端数据库进行交互,实现了任务数据的增删改查操作。
|
||||
|
||||
该类的主要职责包括:
|
||||
- 任务数据的创建与持久化
|
||||
- 任务数据的查询与检索
|
||||
- 任务数据的验证与去重
|
||||
- 事务管理与错误处理
|
||||
- 任务包配置的存储与读取
|
||||
|
||||
**Section sources**
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L338-L445)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L42-L55)
|
||||
|
||||
## 任务数据持久化机制
|
||||
任务数据持久化机制是系统确保任务配置信息可靠存储的关键组件。系统通过CTaskDataOper类提供的方法,将用户在UI界面配置的任务信息持久化到数据库中,确保数据的一致性和完整性。
|
||||
|
||||
持久化过程遵循以下原则:
|
||||
- 使用数据库事务确保操作的原子性
|
||||
- 通过外键约束维护数据完整性
|
||||
- 采用参数化查询防止SQL注入
|
||||
- 实现批量操作提高性能
|
||||
|
||||
系统主要涉及以下数据库表:
|
||||
- td: 存储任务基本信息
|
||||
- tdTaskPacket: 存储任务包主配置
|
||||
- tdTaskPacketInfo: 存储任务包中包含的任务列表
|
||||
|
||||
**Section sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L679-L703)
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L418-L420)
|
||||
|
||||
## InsertTaskPacketInfo方法分析
|
||||
InsertTaskPacketInfo方法是任务包信息存储的核心方法,负责将任务列表和属性信息写入数据库。该方法实现了对tdTaskPacket和tdTaskPacketInfo表的批量插入操作。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> BeginTrans["开始事务"]
|
||||
BeginTrans --> DeleteMain["删除tdTaskPacket表中MainID=1的记录"]
|
||||
DeleteMain --> InsertMain["插入新的任务包主配置"]
|
||||
InsertMain --> DeleteDetail["删除tdTaskPacketInfo表中TaskPacketID=1的记录"]
|
||||
DeleteDetail --> LoopStart["循环遍历任务列表"]
|
||||
LoopStart --> InsertDetail["插入单个任务信息到tdTaskPacketInfo表"]
|
||||
InsertDetail --> LoopCheck{"是否还有任务?"}
|
||||
LoopCheck --> |是| LoopStart
|
||||
LoopCheck --> |否| CommitTrans["提交事务"]
|
||||
CommitTrans --> End([结束])
|
||||
Exception["异常捕获"] --> RollbackTrans["回滚事务"]
|
||||
RollbackTrans --> ReturnFalse["返回false"]
|
||||
BeginTrans --> Exception
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L668-L714)
|
||||
|
||||
**Section sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L668-L714)
|
||||
|
||||
## 数据验证流程
|
||||
系统实现了完善的数据验证流程,确保任务配置的准确性和唯一性。其中,防止重复添加任务是重要的验证逻辑之一。
|
||||
|
||||
### IsRepeatTask方法实现逻辑
|
||||
IsRepeatTask方法用于验证任务是否已存在于任务包中,防止重复添加。该方法通过遍历UI界面上已添加的任务列表,检查新任务的ID是否已存在。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> GetItemCount["获取任务列表项数"]
|
||||
GetItemCount --> LoopStart["设置循环索引i=0"]
|
||||
LoopStart --> CheckIndex{"i < 任务总数?"}
|
||||
CheckIndex --> |否| ReturnFalse["返回false"]
|
||||
CheckIndex --> |是| GetTaskID["获取第i项任务ID"]
|
||||
GetTaskID --> CompareID{"任务ID匹配?"}
|
||||
CompareID --> |是| ReturnTrue["返回true"]
|
||||
CompareID --> |否| IncrementI["i++"]
|
||||
IncrementI --> LoopStart
|
||||
ReturnTrue --> End([结束])
|
||||
ReturnFalse --> End
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L109-L121)
|
||||
|
||||
**Section sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L109-L121)
|
||||
- [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h#L47)
|
||||
|
||||
## 任务包配置数据存储结构
|
||||
系统定义了清晰的数据结构来存储任务包配置信息,包括STTdBrowseInfo和STTaskPacketAttr两个关键数据结构。
|
||||
|
||||
### STTdBrowseInfo数据结构
|
||||
该结构用于存储任务的基本浏览信息,包括任务ID和任务名称。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class STTdBrowseInfo {
|
||||
+int iTaskID
|
||||
+CString strTaskName
|
||||
+STTdBrowseInfo()
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L297-L306)
|
||||
|
||||
### STTaskPacketAttr数据结构
|
||||
该结构用于存储任务包的属性配置,包括循环次数、时间间隔和PLC ID。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class STTaskPacketAttr {
|
||||
+int iLoopTimes
|
||||
+int iInterval
|
||||
+CString strPlcID
|
||||
+STTaskPacketAttr()
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TaskDataOper.h](file://h/TaskDataOper.h#L324-L335)
|
||||
|
||||
### 数据库表结构
|
||||
系统使用两个数据库表来存储任务包配置:
|
||||
|
||||
#### tdTaskPacket表
|
||||
存储任务包的主配置信息。
|
||||
|
||||
| 字段名 | 数据类型 | 描述 |
|
||||
|--------|---------|------|
|
||||
| MainID | Integer | 主键,固定为1 |
|
||||
| LoopTimes | Integer | 循环次数 |
|
||||
| Interval | Integer | 时间间隔(秒) |
|
||||
| PLCID | Text | PLC设备ID |
|
||||
|
||||
**Section sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L685-L687)
|
||||
|
||||
#### tdTaskPacketInfo表
|
||||
存储任务包中包含的具体任务列表。
|
||||
|
||||
| 字段名 | 数据类型 | 描述 |
|
||||
|--------|---------|------|
|
||||
| TaskID | Integer | 任务ID |
|
||||
| TaskName | Text | 任务名称 |
|
||||
| TaskPacketID | Integer | 任务包ID,固定为1 |
|
||||
|
||||
**Section sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L697-L699)
|
||||
|
||||
## 错误处理策略
|
||||
系统实现了完善的错误处理策略,确保在数据保存失败时能够正确回滚并提供用户友好的提示信息。
|
||||
|
||||
### 事务回滚机制
|
||||
系统使用数据库事务来确保数据操作的原子性。当任何操作失败时,系统会自动回滚事务,保持数据一致性。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant UI as "用户界面"
|
||||
participant Logic as "业务逻辑"
|
||||
participant DB as "数据库"
|
||||
UI->>Logic : 请求保存任务包
|
||||
Logic->>DB : 开始事务
|
||||
DB-->>Logic : 事务开始
|
||||
Logic->>DB : 删除旧配置
|
||||
DB-->>Logic : 删除完成
|
||||
Logic->>DB : 插入新配置
|
||||
DB-->>Logic : 插入完成
|
||||
alt 操作成功
|
||||
Logic->>DB : 提交事务
|
||||
DB-->>Logic : 提交成功
|
||||
Logic->>UI : 显示"保存成功"
|
||||
else 操作失败
|
||||
Logic->>DB : 回滚事务
|
||||
DB-->>Logic : 回滚完成
|
||||
Logic->>UI : 显示错误信息
|
||||
end
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L677-L712)
|
||||
|
||||
### 用户提示信息
|
||||
系统根据不同的错误情况提供相应的用户提示信息:
|
||||
|
||||
| 错误类型 | 中文提示 | 英文提示 |
|
||||
|---------|--------|--------|
|
||||
| 保存失败 | 保存失败 | Save failed |
|
||||
| 循环次数无效 | 循环次数的值必须在1-60000之间 | The value of LoopTimes should between 1 to 60000 |
|
||||
| 时间间隔无效 | 时间间隔的值必须在1-60000之间 | The value of Interval Time should between 1 to 60000 |
|
||||
| PLC ID为空 | 请输入PLC ID | Please input plcid |
|
||||
| 任务重复 | 任务已存在 | This task has been exist |
|
||||
|
||||
**Section sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L285-L297)
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L222-L235)
|
||||
|
||||
## UI到数据库的完整流程示例
|
||||
以下是从UI数据收集到数据库存储的完整流程示例:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
UIStart([用户界面]) --> SelectTask["用户选择任务"]
|
||||
SelectTask --> ValidateTask["验证任务是否重复"]
|
||||
ValidateTask --> |重复| ShowError["显示'任务已存在'"]
|
||||
ValidateTask --> |不重复| AddToList["添加到任务列表"]
|
||||
AddToList --> ConfigureAttr["配置任务包属性"]
|
||||
ConfigureAttr --> ValidateInput["验证输入参数"]
|
||||
ValidateInput --> |无效| ShowInputError["显示参数错误"]
|
||||
ValidateInput --> |有效| CollectData["收集UI数据"]
|
||||
CollectData --> CreateStruct["创建STTdBrowseInfo和STTaskPacketAttr结构"]
|
||||
CreateStruct --> CallInsert["调用InsertTaskPacketInfo方法"]
|
||||
CallInsert --> DBStart["开始数据库操作"]
|
||||
DBStart --> BeginTrans["开始事务"]
|
||||
BeginTrans --> DeleteOld["删除旧配置"]
|
||||
DeleteOld --> InsertNew["插入新配置"]
|
||||
InsertNew --> Commit["提交事务"]
|
||||
Commit --> |成功| ShowSuccess["显示'保存成功'"]
|
||||
Commit --> |失败| Rollback["回滚事务"]
|
||||
Rollback --> ShowDBError["显示'保存失败'"]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L206-L300)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L668-L714)
|
||||
|
||||
**Section sources**
|
||||
- [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L206-L300)
|
||||
@@ -0,0 +1,334 @@
|
||||
# 测区创建与配置
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp)
|
||||
- [TestingZone.h](file://h/TestingZone.h)
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp)
|
||||
- [opcreatetzdlg.h](file://h/opcreatetzdlg.h)
|
||||
- [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp)
|
||||
- [testzone.xml](file://CACHE/testzone.xml)
|
||||
- [project.xml](file://CACHE/project.xml)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件围绕“测区创建与配置”主题,系统梳理GeomativeStudio中测区(Testing Zone)的创建流程、用户输入校验、测区类型(TZtype)业务规则、与数据库的交互、以及测区配置界面(如DialCfgTerrain)的数据绑定与持久化策略。重点说明:
|
||||
- CProManager类中创建新测区的核心方法调用链与事务控制
|
||||
- TestingZone类如何构建测区元数据模型及其字段约束
|
||||
- 测区配置界面的UI逻辑与数据绑定机制
|
||||
- 用户配置参数如何序列化并持久化到testzone.xml文件
|
||||
- 常见配置错误的排查与修复建议
|
||||
|
||||
## 项目结构
|
||||
与测区创建与配置直接相关的模块分布如下:
|
||||
- 管理层:CProManager(工程与测区管理)
|
||||
- 模型层:CTestingZone(测区元数据封装)
|
||||
- 视图层:opcreatetzdlg(创建测区对话框)、DialCfgTerrain(地形配置对话框)
|
||||
- 缓存与持久化:CACHE目录下的testzone.xml、project.xml
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "管理层"
|
||||
PM["CProManager<br/>测区创建/下发/同步"]
|
||||
end
|
||||
subgraph "模型层"
|
||||
TZ["CTestingZone<br/>测区元数据"]
|
||||
end
|
||||
subgraph "视图层"
|
||||
Dlg["COpCreateTzDlg<br/>创建测区对话框"]
|
||||
Terrain["CDialCfgTerrain<br/>地形配置对话框"]
|
||||
end
|
||||
subgraph "缓存与持久化"
|
||||
XML_TZ["CACHE/testzone.xml"]
|
||||
XML_PRJ["CACHE/project.xml"]
|
||||
end
|
||||
Dlg --> PM
|
||||
PM --> TZ
|
||||
PM --> XML_TZ
|
||||
PM --> XML_PRJ
|
||||
Terrain --> XML_TZ
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L945-L1013)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L1-L82)
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp#L539-L693)
|
||||
- [testzone.xml](file://CACHE/testzone.xml#L1-L57)
|
||||
- [project.xml](file://CACHE/project.xml#L1-L22)
|
||||
|
||||
章节来源
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L945-L1013)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L1-L82)
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp#L539-L693)
|
||||
- [testzone.xml](file://CACHE/testzone.xml#L1-L57)
|
||||
- [project.xml](file://CACHE/project.xml#L1-L22)
|
||||
|
||||
## 核心组件
|
||||
- CProManager:提供测区创建、设备下发、同步等功能;负责数据库事务与设备通信。
|
||||
- CTestingZone:封装测区元数据(名称、类型、创建日期、描述、位置、CN等),用于UI展示与业务逻辑。
|
||||
- COpCreateTzDlg:测区创建对话框,负责用户输入校验与TZtype赋值。
|
||||
- CDialCfgTerrain:地形配置对话框,负责地形数据的导入、校验与写入原始dat文件。
|
||||
|
||||
章节来源
|
||||
- [TestingZone.h](file://h/TestingZone.h#L1-L33)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L1-L82)
|
||||
- [opcreatetzdlg.h](file://h/opcreatetzdlg.h#L1-L53)
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp#L539-L693)
|
||||
|
||||
## 架构总览
|
||||
测区创建与下发的关键流程如下:
|
||||
- 用户通过对话框输入测区基本信息(名称、类型、日期、位置、描述)
|
||||
- CProManager在数据库中插入测区记录并生成唯一CN
|
||||
- 将测区元数据序列化为testzone.xml并下发至设备
|
||||
- 设备侧接收后,写入dev_syn_td标记同步状态
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant D as "COpCreateTzDlg"
|
||||
participant PM as "CProManager"
|
||||
participant DB as "数据库"
|
||||
participant DEV as "设备"
|
||||
participant FS as "本地文件系统"
|
||||
U->>D : 打开创建测区对话框
|
||||
D->>D : 输入校验与TZtype赋值
|
||||
D-->>PM : 返回测区参数
|
||||
PM->>DB : 插入tz记录并生成CN
|
||||
PM->>FS : 生成testzone.xml
|
||||
PM->>DEV : 下发testzone.xml
|
||||
DEV-->>PM : 返回下发结果
|
||||
PM->>DB : 写入dev_syn_td(IsSyned=true)
|
||||
PM-->>U : 创建完成/错误提示
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L945-L1013)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L800-L943)
|
||||
- [testzone.xml](file://CACHE/testzone.xml#L1-L57)
|
||||
|
||||
章节来源
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L945-L1013)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L800-L943)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### CProManager类:创建新测区的核心流程
|
||||
- 对话框调用与参数收集
|
||||
- 通过COpCreateTzDlg收集测区名称、位置、描述、创建日期等参数。
|
||||
- 对话框内部将TZtype固定为“3”,体现“默认测区”的强制逻辑。
|
||||
- 数据库插入与ID回填
|
||||
- 使用Command执行INSERT语句,插入tz记录并返回ID。
|
||||
- 通过查询再次确认ID,保证后续流程使用正确ID。
|
||||
- XML生成与下发
|
||||
- 以CMarkup生成testzone.xml,包含type、location、desc、create_date、test_date、cn、testzone_name等节点。
|
||||
- 调用AddTzInDev创建设备端测区目录与类型标记,随后通过SendFile下发testzone.xml。
|
||||
- 同步状态维护
|
||||
- 下发成功后,向dev_syn_td写入IsSyned=true,标记该测区已同步。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["开始"]) --> OpenDlg["打开测区创建对话框"]
|
||||
OpenDlg --> Validate["输入校验<br/>名称必填"]
|
||||
Validate --> |通过| InsertTZ["插入tz记录"]
|
||||
Validate --> |不通过| Error["提示错误并终止"]
|
||||
InsertTZ --> GenXML["生成testzone.xml"]
|
||||
GenXML --> SendFile["下发testzone.xml到设备"]
|
||||
SendFile --> |成功| MarkSync["写入dev_syn_td(IsSyned=true)"]
|
||||
SendFile --> |失败| Rollback["删除设备端测区并回滚"]
|
||||
MarkSync --> End(["结束"])
|
||||
Error --> End
|
||||
Rollback --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L945-L1013)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L800-L943)
|
||||
|
||||
章节来源
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L945-L1013)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L800-L943)
|
||||
|
||||
### TestingZone类:测区元数据模型
|
||||
- 字段定义与约束
|
||||
- 名称、创建日期、描述、位置、CN、TZtype等均来自数据库tz表查询结果。
|
||||
- ShowDetailInfo根据TZtype映射为“1D VES | 2D ERI”、“3D ERT”或“All Type”,用于UI展示。
|
||||
- 数据来源
|
||||
- 通过ADO Recordset按ID查询tz表,填充成员变量。
|
||||
- 使用场景
|
||||
- 在工程树或详情面板中展示测区信息;与CProManager配合进行测区同步。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CTestingZone {
|
||||
+DWORD m_dwID
|
||||
-_ConnectionPtr m_pConnection
|
||||
-CString m_szTZname
|
||||
-CString m_szCDate
|
||||
-CString m_szDesc
|
||||
-CString m_szLocation
|
||||
-CString m_szCN
|
||||
-CString m_szTZtype
|
||||
+ShowDetailInfo(tzDetailList) bool
|
||||
+CTestingZone(dwID, connection)
|
||||
+~CTestingZone()
|
||||
}
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [TestingZone.h](file://h/TestingZone.h#L1-L33)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L1-L82)
|
||||
|
||||
章节来源
|
||||
- [TestingZone.h](file://h/TestingZone.h#L1-L33)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L1-L82)
|
||||
|
||||
### COpCreateTzDlg:测区创建对话框与TZtype业务规则
|
||||
- 用户输入验证
|
||||
- 名称必填校验;其他字段长度限制(位置、描述)。
|
||||
- TZtype强制逻辑
|
||||
- 对话框内部将m_edTzType硬编码为“3”,即“默认测区”类型。
|
||||
- 这意味着创建新测区时,类型必须为3,否则后续流程会报错或不一致。
|
||||
- 交互细节
|
||||
- OnOK中完成UpdateData与校验,随后设置TZtype并关闭对话框。
|
||||
|
||||
章节来源
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [opcreatetzdlg.h](file://h/opcreatetzdlg.h#L1-L53)
|
||||
|
||||
### DialCfgTerrain:地形配置界面与数据绑定
|
||||
- UI与数据绑定
|
||||
- 通过DoDataExchange绑定控件,支持列表项编辑、删除、新增等操作。
|
||||
- 支持从dat文件导入地形数据,写入指定位置并追加结束符。
|
||||
- 输入校验与写入策略
|
||||
- 校验dat文件头三行是否包含有效装置类型信息;禁止Wenner(gamma)与1D装置写入地形数据。
|
||||
- 根据装置类型确定末尾0的个数,确保文件格式正确。
|
||||
- 写入格式包含“地形数据标志”“点数”“各点坐标”“首电极对应点号”“若干0结束符”。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Enter(["进入地形配置"]) --> Import["导入dat文件"]
|
||||
Import --> Parse["解析文件头信息<br/>校验装置类型"]
|
||||
Parse --> |不合法| Warn["提示错误并终止"]
|
||||
Parse --> |合法| Edit["编辑地形点列表"]
|
||||
Edit --> Save["保存到原文件"]
|
||||
Save --> Write["写入标志/点数/坐标/首电极点号/结束符"]
|
||||
Write --> Done(["完成"])
|
||||
Warn --> Done
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp#L539-L693)
|
||||
|
||||
章节来源
|
||||
- [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp#L539-L693)
|
||||
|
||||
### XML文件生成规则与持久化
|
||||
- testzone.xml生成规则
|
||||
- 根元素为testzone,子元素包含type、location、desc、create_date、create_time、test_date、test_time、cn、testzone_name、testzone_3D_script、vess、eris、erts等。
|
||||
- 元素层级清晰,便于设备侧解析与同步。
|
||||
- project.xml生成规则
|
||||
- 根元素为project,包含工程相关信息及testzones节点,其中包含多个测区的TYPE与CN。
|
||||
- 持久化路径
|
||||
- 本地缓存路径:CACHE/projects/{PrCN}/{TzCN}/testzone.xml
|
||||
- 设备侧路径:/SD/projects/{PrCN}/{TzCN}/testzone.xml
|
||||
|
||||
章节来源
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L800-L943)
|
||||
- [testzone.xml](file://CACHE/testzone.xml#L1-L57)
|
||||
- [project.xml](file://CACHE/project.xml#L1-L22)
|
||||
|
||||
## 依赖关系分析
|
||||
- CProManager依赖ADO数据库连接与设备通信接口,负责事务控制与文件下发。
|
||||
- CTestingZone依赖数据库查询结果,用于UI展示与业务逻辑。
|
||||
- COpCreateTzDlg与DialCfgTerrain分别负责用户输入与地形数据配置,最终驱动CProManager完成测区创建与下发。
|
||||
- XML文件作为中间介质,贯穿本地与设备两端的数据交换。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
Dlg["COpCreateTzDlg"] --> PM["CProManager"]
|
||||
Terrain["CDialCfgTerrain"] --> PM
|
||||
PM --> DB["数据库"]
|
||||
PM --> XML["testzone.xml"]
|
||||
PM --> DEV["设备"]
|
||||
TZ["CTestingZone"] --> DB
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L945-L1013)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L1-L82)
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp#L539-L693)
|
||||
|
||||
章节来源
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L945-L1013)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L1-L82)
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp#L539-L693)
|
||||
|
||||
## 性能考量
|
||||
- 数据库事务:CProManager在下发成功后才提交事务,避免半写状态;失败时回滚并清理设备端测区,减少资源浪费。
|
||||
- 文件IO:XML生成与下发采用一次性写入,避免频繁小块写入;地形文件写入采用定位与覆盖策略,减少磁盘碎片。
|
||||
- UI响应:对话框在关键校验处短路返回,降低无效计算;列表控件批量更新,提升渲染效率。
|
||||
|
||||
## 故障排查指南
|
||||
- 测区类型设置错误
|
||||
- 现象:创建测区时报TZType错误或设备端同步失败。
|
||||
- 原因:对话框内部强制TZtype为“3”,若外部逻辑绕过对话框,可能导致类型不一致。
|
||||
- 处理:确保通过COpCreateTzDlg创建测区,或在调用CProManager前显式设置TZtype为“3”。
|
||||
|
||||
- 必填字段缺失
|
||||
- 现象:对话框提示名称为空或校验失败。
|
||||
- 处理:完善名称、位置、描述等字段后再提交;注意长度限制。
|
||||
|
||||
- 地形文件写入失败
|
||||
- 现象:写地形数据到原文件失败或未找到结束符。
|
||||
- 原因:dat文件格式不符合要求、装置类型不支持写地形、首电极点号越界。
|
||||
- 处理:检查文件头三行、装置类型合法性、点号范围;确保末尾0个数符合约定。
|
||||
|
||||
- 下发失败
|
||||
- 现象:设备返回失败或本地提示发送失败。
|
||||
- 处理:检查设备通信状态、路径权限、文件完整性;必要时删除设备端测区并重试。
|
||||
|
||||
- 同步状态异常
|
||||
- 现象:dev_syn_td中IsSyned未置位或置位错误。
|
||||
- 处理:确认下发成功后是否执行写入dev_syn_td;若失败则回滚并清理设备端测区。
|
||||
|
||||
章节来源
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp#L539-L693)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L800-L943)
|
||||
|
||||
## 结论
|
||||
- 测区创建流程由对话框输入、数据库插入、XML生成与下发、同步状态维护构成,CProManager承担核心协调职责。
|
||||
- TestingZone提供稳定的测区元数据封装,支撑UI展示与业务逻辑。
|
||||
- DialCfgTerrain负责地形配置,严格遵循文件格式规范,保障设备侧可正确解析。
|
||||
- TZtype强制为“3”的设计体现了默认测区的业务规则,应严格遵守以避免后续错误。
|
||||
|
||||
## 附录
|
||||
- 关键流程参考路径
|
||||
- [创建测区对话框](file://cpp/Views/opcreatetzdlg.cpp#L54-L92)
|
||||
- [创建测区数据库流程](file://cpp/Managers/ProManager.cpp#L945-L1013)
|
||||
- [下发测区XML流程](file://cpp/Managers/ProManager.cpp#L800-L943)
|
||||
- [测区元数据模型](file://cpp/ProblemZone/TestingZone.cpp#L1-L82)
|
||||
- [地形配置与写入](file://cpp/Views/DialCfgTerrain.cpp#L539-L693)
|
||||
- [测区XML样例](file://CACHE/testzone.xml#L1-L57)
|
||||
- [工程XML样例](file://CACHE/project.xml#L1-L22)
|
||||
@@ -0,0 +1,250 @@
|
||||
# 测区数据同步
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [SynOperator.cpp](file://cpp/Operator/SynOperator.cpp)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
|
||||
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
|
||||
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
|
||||
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
|
||||
- [OnLineSynTdDlg.cpp](file://cpp/Views/OnLineSynTdDlg.cpp)
|
||||
- [OnLineSynDevDlg.cpp](file://cpp/Views/OnLineSynDevDlg.cpp)
|
||||
- [OpSynDlg.cpp](file://cpp/Views/OpSynDlg.cpp)
|
||||
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
|
||||
- [DataOperator.cpp](file://cpp/Operator/DataOperator.cpp)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概述](#架构概述)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档全面构建了测区数据同步机制的技术文档,重点描述了CProManager如何协调FileTransfer和UpdateDataBase组件实现测区数据在本地应用与GD10设备间的双向同步。详细说明了同步协议的实现细节,包括数据包格式、传输校验机制(如CRC16/CRC32)和断点续传逻辑。解释了同步过程中对testzone.xml文件的读取、解析和更新流程,以及如何确保设备端与PC端测区数据的一致性。分析了同步失败的异常处理策略,如网络中断、设备无响应等情况下的重试机制和错误码定义。提供了性能优化建议,包括大数据量测区的分批传输策略和同步进度的UI反馈实现。文档包含实际同步日志的分析示例,帮助开发者诊断常见同步问题。
|
||||
|
||||
## 项目结构
|
||||
项目结构显示了测区数据同步相关的文件和目录,包括CACHE、DB、Install、LOG、Release、cpp、h、res、tools等目录。关键文件包括ProManager.cpp、SynOperator.cpp、UpdateDataBase.cpp、FileTransfer.cpp等,这些文件实现了测区数据同步的核心功能。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[GeomativeStudio] --> B[CACHE]
|
||||
A --> C[DB]
|
||||
A --> D[Install]
|
||||
A --> E[LOG]
|
||||
A --> F[Release]
|
||||
A --> G[cpp]
|
||||
A --> H[h]
|
||||
A --> I[res]
|
||||
A --> J[tools]
|
||||
G --> K[Managers]
|
||||
G --> L[Operator]
|
||||
G --> M[Tools]
|
||||
G --> N[Views]
|
||||
K --> O[ProManager.cpp]
|
||||
L --> P[SynOperator.cpp]
|
||||
L --> Q[UpdateDataBase.cpp]
|
||||
M --> R[FileTransfer.cpp]
|
||||
M --> S[Crc16.cpp]
|
||||
M --> T[Crc32.cpp]
|
||||
N --> U[OnLineSynTdDlg.cpp]
|
||||
N --> V[OnLineSynDevDlg.cpp]
|
||||
N --> W[OpSynDlg.cpp]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [SynOperator.cpp](file://cpp/Operator/SynOperator.cpp)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
|
||||
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
|
||||
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
|
||||
- [OnLineSynTdDlg.cpp](file://cpp/Views/OnLineSynTdDlg.cpp)
|
||||
- [OnLineSynDevDlg.cpp](file://cpp/Views/OnLineSynDevDlg.cpp)
|
||||
- [OpSynDlg.cpp](file://cpp/Views/OpSynDlg.cpp)
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [SynOperator.cpp](file://cpp/Operator/SynOperator.cpp)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
|
||||
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
|
||||
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
|
||||
- [OnLineSynTdDlg.cpp](file://cpp/Views/OnLineSynTdDlg.cpp)
|
||||
- [OnLineSynDevDlg.cpp](file://cpp/Views/OnLineSynDevDlg.cpp)
|
||||
- [OpSynDlg.cpp](file://cpp/Views/OpSynDlg.cpp)
|
||||
|
||||
## 核心组件
|
||||
核心组件包括CProManager、CSynOperator、CUpdateDataBase、FileTransfer、Crc16、Crc32等类,这些类实现了测区数据同步的核心功能。CProManager负责管理工程和测区,CSynOperator负责同步操作,CUpdateDataBase负责数据库更新,FileTransfer负责文件传输,Crc16和Crc32负责数据校验。
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [SynOperator.cpp](file://cpp/Operator/SynOperator.cpp)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
|
||||
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
|
||||
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
|
||||
|
||||
## 架构概述
|
||||
测区数据同步机制的架构包括本地应用、GD10设备、网络通信、文件传输、数据校验等组件。CProManager协调FileTransfer和UpdateDataBase组件,实现测区数据在本地应用与GD10设备间的双向同步。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[本地应用] --> B[CProManager]
|
||||
B --> C[FileTransfer]
|
||||
B --> D[UpdateDataBase]
|
||||
C --> E[GD10设备]
|
||||
D --> F[数据库]
|
||||
E --> G[网络通信]
|
||||
C --> H[Crc16]
|
||||
C --> I[Crc32]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
|
||||
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
|
||||
|
||||
## 详细组件分析
|
||||
### CProManager分析
|
||||
CProManager类负责管理工程和测区,包括创建工程、创建测区、同步数据等操作。它通过调用FileTransfer和UpdateDataBase组件实现测区数据的同步。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CProManager {
|
||||
+ShowTzList()
|
||||
+GetDMS()
|
||||
+ShowProList()
|
||||
+CreateProjectInDB()
|
||||
+InsertDefaultTzToProject()
|
||||
+CreateProjectInDev()
|
||||
+CreateDefaultTzInDev()
|
||||
+CreateTzInDev()
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
|
||||
### CSynOperator分析
|
||||
CSynOperator类负责同步操作,包括同步测区数据、同步任务数据等。它通过调用CProManager和FileTransfer组件实现数据同步。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CSynOperator {
|
||||
+Syn()
|
||||
+InitialSynDlg()
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [SynOperator.cpp](file://cpp/Operator/SynOperator.cpp)
|
||||
|
||||
### CUpdateDataBase分析
|
||||
CUpdateDataBase类负责数据库更新,包括更新数据库版本、更新数据库结构等。它通过解析XML文件实现数据库的更新。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CUpdateDataBase {
|
||||
+QueryPreVersion()
|
||||
+CheckNecessaryVersion()
|
||||
+WriteVersionToDB()
|
||||
+GetDBUpdatesInfo()
|
||||
+ParserUpdateDBXml()
|
||||
+AddDBTable()
|
||||
+DeleteDBTable()
|
||||
+AddTableCol()
|
||||
+ModifyTableCol()
|
||||
+ModifyDBTable()
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
|
||||
### FileTransfer分析
|
||||
FileTransfer类负责文件传输,包括发送文件、接收文件等。它通过调用底层通信接口实现文件的传输。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class FileTransfer {
|
||||
+error()
|
||||
+status()
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
|
||||
|
||||
### Crc16和Crc32分析
|
||||
Crc16和Crc32类负责数据校验,包括计算CRC16和CRC32校验码。它们通过查表法实现高效的校验码计算。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Crc16 {
|
||||
+table[256]
|
||||
+initialized
|
||||
+Crc16()
|
||||
}
|
||||
class Crc32 {
|
||||
+table[256]
|
||||
+initialized
|
||||
+Crc32()
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
|
||||
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [SynOperator.cpp](file://cpp/Operator/SynOperator.cpp)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
|
||||
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
|
||||
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
|
||||
|
||||
## 依赖分析
|
||||
测区数据同步机制的依赖包括本地应用、GD10设备、网络通信、文件传输、数据校验等。CProManager依赖于FileTransfer和UpdateDataBase组件,FileTransfer依赖于Crc16和Crc32组件。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[CProManager] --> B[FileTransfer]
|
||||
A --> C[UpdateDataBase]
|
||||
B --> D[Crc16]
|
||||
B --> E[Crc32]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
|
||||
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
|
||||
|
||||
## 性能考虑
|
||||
为了提高测区数据同步的性能,可以采用分批传输策略,将大数据量的测区数据分成多个小批次进行传输。同时,可以通过UI反馈显示同步进度,提高用户体验。
|
||||
|
||||
## 故障排除指南
|
||||
同步失败的常见原因包括网络中断、设备无响应、数据校验失败等。可以通过重试机制和错误码定义来处理这些异常情况。例如,当网络中断时,可以等待网络恢复后重新尝试同步;当设备无响应时,可以检查设备连接状态并重新连接。
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [SynOperator.cpp](file://cpp/Operator/SynOperator.cpp)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
|
||||
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
|
||||
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
|
||||
|
||||
## 结论
|
||||
本文档详细描述了测区数据同步机制的实现细节,包括核心组件、架构概述、详细组件分析、依赖分析、性能考虑和故障排除指南。通过本文档,开发者可以更好地理解和实现测区数据同步功能。
|
||||
@@ -0,0 +1,234 @@
|
||||
# 测区管理
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp)
|
||||
- [TestingZone.h](file://h/TestingZone.h)
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp)
|
||||
- [opcreatetzdlg.h](file://h/opcreatetzdlg.h)
|
||||
- [appdatatzlistview.cpp](file://cpp/Views/appdatatzlistview.cpp)
|
||||
- [database_modify.xml](file://database_modify.xml)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [项目与测区层级关系](#项目与测区层级关系)
|
||||
2. [CProManager::ShowTzList方法分析](#cpromanagershowtzlist方法分析)
|
||||
3. [测区类型(TZtype)枚举值及业务含义](#测区类型tztype枚举值及业务含义)
|
||||
4. [测区配置数据持久化机制](#测区配置数据持久化机制)
|
||||
5. [测区创建完整性校验流程](#测区创建完整性校验流程)
|
||||
6. [测区数据模型字段说明](#测区数据模型字段说明)
|
||||
|
||||
## 项目与测区层级关系
|
||||
|
||||
在GeomativeStudio系统中,项目与测区之间存在明确的父子层级关系。每个项目可以包含多个测区,但每个测区只能属于一个项目。这种关系通过数据库中的外键约束实现,其中测区表(tz)中的PRID字段引用项目表(project)的ID字段。
|
||||
|
||||
项目作为数据管理的基本单元,包含了测区的集合。当用户选择一个项目时,系统会根据该项目的句柄查询其下属的所有测区,并在UI界面上展示这些测区列表。这种层级结构确保了数据组织的逻辑性和一致性,同时也便于数据的同步和管理。
|
||||
|
||||
项目与测区的关系还体现在设备端的数据同步过程中。当项目被同步到设备时,其包含的测区也会被同步。系统通过dev_syn_td表来跟踪项目和测区在设备上的同步状态,其中PRCN字段对应项目的CN码,TzCN字段对应测区的CN码。
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L33-L37)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L18-L44)
|
||||
|
||||
## CProManager::ShowTzList方法分析
|
||||
|
||||
CProManager::ShowTzList方法负责根据项目句柄查询数据库并填充测区列表控件。该方法首先通过项目句柄获取对应的项目ID,然后执行SQL查询语句从数据库中获取该项目下的所有测区信息。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> GetProjectID["从项目句柄获取项目ID"]
|
||||
GetProjectID --> CheckItemCount{"列表项数不为0?"}
|
||||
CheckItemCount --> |是| DeleteAllItems["删除所有列表项"]
|
||||
CheckItemCount --> |否| BuildSQLQuery
|
||||
DeleteAllItems --> BuildSQLQuery
|
||||
BuildSQLQuery --> ExecuteQuery["执行SQL查询"]
|
||||
ExecuteQuery --> CheckEOF{"记录集未结束?"}
|
||||
CheckEOF --> |是| InsertListItem["插入列表项"]
|
||||
InsertListItem --> SetItemText["设置列表项文本"]
|
||||
SetItemText --> GenerateHandle["生成测区句柄"]
|
||||
GenerateHandle --> SetItemData["设置列表项数据"]
|
||||
SetItemData --> MoveNext["移动到下一条记录"]
|
||||
MoveNext --> CheckEOF
|
||||
CheckEOF --> |否| CloseRecordset["关闭记录集"]
|
||||
CloseRecordset --> ReturnTrue["返回true"]
|
||||
ReturnTrue --> End([结束])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L53-L92)
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L53-L92)
|
||||
|
||||
## 测区类型(TZtype)枚举值及业务含义
|
||||
|
||||
测区类型(TZtype)是一个重要的枚举值,用于标识测区的业务类型。根据代码分析,TZtype的取值及其业务含义如下:
|
||||
|
||||
- **TZtype=0或1**: 表示"1D VES | 2D ERI"类型,即一维垂直电测深或二维电阻率成像。这两种类型在系统中被视为同一类别进行处理。
|
||||
- **TZtype=2**: 表示"3D ERT"类型,即三维电阻率层析成像,适用于需要三维空间数据采集的场景。
|
||||
- **TZtype=3**: 表示"DefaultTestZone"类型,即默认测区。这是一个特殊的测区类型,每个项目创建时都会自动创建一个默认测区。
|
||||
|
||||
默认测区(type=3)具有特殊处理逻辑。在创建项目时,系统会自动调用InsertDefaultTzToProject方法为新项目创建一个默认测区。这个默认测区的名称固定为"DefaultTestZone",描述和位置均为"None"。在设备同步过程中,系统会对TZtype=3进行强制检查,如果发现类型不匹配会抛出错误。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CTestingZone {
|
||||
+ShowDetailInfo(CListCtrl&)
|
||||
+CTestingZone(DWORD, _ConnectionPtr&)
|
||||
+~CTestingZone()
|
||||
-m_dwID DWORD
|
||||
-m_pConnection _ConnectionPtr
|
||||
-m_szTZname CString
|
||||
-m_szCDate CString
|
||||
-m_szDesc CString
|
||||
-m_szLocation CString
|
||||
-m_szCN CString
|
||||
-m_szTZtype CString
|
||||
}
|
||||
CTestingZone --> "1" CListCtrl : "填充"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L62-L73)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L319-L341)
|
||||
|
||||
**Section sources**
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L62-L73)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L319-L341)
|
||||
|
||||
## 测区配置数据持久化机制
|
||||
|
||||
测区配置数据在设备端通过testzone.xml文件进行持久化存储。该文件的生成遵循特定的规则,并具有明确的元素结构。
|
||||
|
||||
testzone.xml文件的生成规则如下:当测区数据需要同步到设备时,系统会在本地CACHE目录下创建相应的项目和测区目录结构,然后生成testzone.xml文件。文件路径遵循"\\CACHE\\projects\\{项目CN}\\{测区CN}\\"的层级关系,与项目XML文件保持一致的目录结构。
|
||||
|
||||
testzone.xml文件的元素结构包括以下关键字段:
|
||||
- **type**: 测区类型,对应数据库中的TZtype字段
|
||||
- **cn**: 测区唯一标识码,对应数据库中的CN字段
|
||||
- **location**: 测区位置信息
|
||||
- **desc**: 测区描述信息
|
||||
- **create_date**: 创建日期
|
||||
- **testzone_name**: 测区名称
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> CreateDirectory["创建本地目录"]
|
||||
CreateDirectory --> CreateXML["创建XML文档"]
|
||||
CreateXML --> AddRoot["添加根元素testzone"]
|
||||
AddRoot --> AddType["添加type元素"]
|
||||
AddType --> AddLocation["添加location元素"]
|
||||
AddLocation --> AddDesc["添加desc元素"]
|
||||
AddDesc --> AddCreateDate["添加create_date元素"]
|
||||
AddCreateDate --> AddCreateTime["添加create_time元素"]
|
||||
AddCreateTime --> AddTestDate["添加test_date元素"]
|
||||
AddTestDate --> AddTestTime["添加test_time元素"]
|
||||
AddTestTime --> AddCN["添加cn元素"]
|
||||
AddCN --> AddName["添加testzone_name元素"]
|
||||
AddName --> Add3DScript["添加testzone_3D_script元素"]
|
||||
Add3DScript --> AddVess["添加vess元素"]
|
||||
AddVess --> AddEris["添加eris元素"]
|
||||
AddEris --> AddErts["添加erts元素"]
|
||||
AddErts --> AddWels["添加wels元素"]
|
||||
AddWels --> SaveFile["保存文件"]
|
||||
SaveFile --> SendToDevice["发送到设备"]
|
||||
SendToDevice --> UpdateDB["更新数据库同步状态"]
|
||||
UpdateDB --> End([结束])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L586-L605)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L838-L856)
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L586-L605)
|
||||
|
||||
## 测区创建完整性校验流程
|
||||
|
||||
测区创建时的完整性校验流程包括多个步骤,确保数据的完整性和一致性。当用户通过UI界面创建新测区时,系统会执行以下校验流程:
|
||||
|
||||
首先,系统会检查测区名称是否为空。如果名称为空,会弹出错误提示"测区名称不能为空",并阻止创建操作。这是最基本的完整性校验,确保每个测区都有一个有效的名称标识。
|
||||
|
||||
对于TZtype=3的默认测区,系统有特殊的强制检查机制。在CreateDefaultTzInDev方法中,系统会检查从数据库读取的测区类型是否为3。如果不是,会立即返回错误并显示相应的错误信息。这种强制检查确保了默认测区的特殊性不会被破坏。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant UI as "用户界面"
|
||||
participant ProManager as "CProManager"
|
||||
participant Database as "数据库"
|
||||
UI->>ProManager : 调用CreateTzInDB
|
||||
ProManager->>UI : 显示创建对话框
|
||||
UI->>ProManager : 输入测区信息并确认
|
||||
ProManager->>ProManager : 验证测区名称是否为空
|
||||
alt 名称为空
|
||||
ProManager->>UI : 显示错误提示
|
||||
ProManager-->>UI : 返回失败
|
||||
else 名称有效
|
||||
ProManager->>Database : 查询同名测区是否存在
|
||||
Database-->>ProManager : 返回查询结果
|
||||
alt 测区已存在
|
||||
ProManager->>UI : 显示"测区已存在"提示
|
||||
ProManager-->>UI : 返回重复错误
|
||||
else 测区不存在
|
||||
ProManager->>Database : 插入新测区记录
|
||||
Database-->>ProManager : 返回插入结果
|
||||
ProManager->>Database : 查询新测区ID
|
||||
Database-->>ProManager : 返回测区ID
|
||||
ProManager-->>UI : 返回成功
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L67)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L956-L1009)
|
||||
|
||||
**Section sources**
|
||||
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L67)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L956-L1009)
|
||||
|
||||
## 测区数据模型字段说明
|
||||
|
||||
测区数据模型包含多个关键属性字段,这些字段在UI界面中有相应的展示方式。主要字段包括:
|
||||
|
||||
- **ID**: 测区的唯一标识符,数据库主键,用于内部引用和关联
|
||||
- **名称(TZname)**: 测区的名称,在测区列表中作为第一列显示
|
||||
- **描述(TZdesc)**: 测区的详细描述信息,在列表中作为描述列显示
|
||||
- **创建日期(Cdate)**: 测区的创建日期,格式化为"YYYY-MM-DD"显示
|
||||
- **位置(location)**: 测区的地理位置信息
|
||||
- **类型(TZtype)**: 测区的业务类型,决定测区的功能和处理方式
|
||||
- **CN码**: 测区的唯一编码,用于设备同步和数据交换
|
||||
|
||||
在UI界面中,这些字段通过CListCtrl控件进行展示。测区列表视图(appdatatzlistview.cpp)定义了列表的列结构,包括测区名称、类型、创建日期和描述等列。每个列表项的数据通过SetItemData方法存储测区句柄,便于后续操作时快速定位对应的测区对象。
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
PROJECT ||--o{ TESTING_ZONE : "包含"
|
||||
PROJECT {
|
||||
int ID PK
|
||||
string CN UK
|
||||
string PRname
|
||||
datetime PRdate
|
||||
string PRdesc
|
||||
string location
|
||||
}
|
||||
TESTING_ZONE {
|
||||
int ID PK
|
||||
int PRID FK
|
||||
string CN UK
|
||||
string TZname
|
||||
int TZtype
|
||||
datetime Cdate
|
||||
string TZdesc
|
||||
string location
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TestingZone.h](file://h/TestingZone.h#L24-L29)
|
||||
- [appdatatzlistview.cpp](file://cpp/Views/appdatatzlistview.cpp#L86-L100)
|
||||
- [database_modify.xml](file://database_modify.xml#L13-L18)
|
||||
|
||||
**Section sources**
|
||||
- [TestingZone.h](file://h/TestingZone.h#L24-L29)
|
||||
- [appdatatzlistview.cpp](file://cpp/Views/appdatatzlistview.cpp#L86-L100)
|
||||
@@ -0,0 +1,289 @@
|
||||
# 项目生命周期管理
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [ProManager.h](file://h/ProManager.h)
|
||||
- [opcreateprojectdlg.cpp](file://cpp/Views/opcreateprojectdlg.cpp)
|
||||
- [opcreateprojectdlg.h](file://h/opcreateprojectdlg.h)
|
||||
- [Project.cpp](file://cpp/ProblemZone/Project.cpp)
|
||||
- [Project.h](file://h/Project.h)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp)
|
||||
- [TestingZone.h](file://h/TestingZone.h)
|
||||
- [Device.h](file://h/Device.h)
|
||||
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [项目创建流程](#项目创建流程)
|
||||
2. [项目元数据收集与验证](#项目元数据收集与验证)
|
||||
3. [项目唯一标识符生成机制](#项目唯一标识符生成机制)
|
||||
4. [数据库记录插入与默认测区创建](#数据库记录插入与默认测区创建)
|
||||
5. [项目数据同步到GD10设备](#项目数据同步到gd10设备)
|
||||
6. [XML缓存文件生成](#xml缓存文件生成)
|
||||
7. [项目删除操作与级联清理](#项目删除操作与级联清理)
|
||||
8. [项目状态管理与性能优化](#项目状态管理与性能优化)
|
||||
|
||||
## 项目创建流程
|
||||
|
||||
项目生命周期管理的核心功能始于项目创建流程,该流程通过`CProManager::CreateProjectInDB`方法实现。此方法首先实例化`COpCreateProjectDlg`对话框,用于收集用户输入的项目元数据。当用户点击确定按钮时,系统会验证输入数据的完整性并执行后续操作。
|
||||
|
||||
项目创建流程遵循严格的事务处理机制,确保数据的一致性和完整性。整个流程包括元数据收集、冲突检测、数据库插入和设备同步等多个阶段。在数据库操作层面,系统使用ADODB组件与Access数据库进行交互,通过SQL语句执行数据的增删改查操作。
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L249-L317)
|
||||
- [ProManager.h](file://h/ProManager.h#L51-L52)
|
||||
|
||||
## 项目元数据收集与验证
|
||||
|
||||
项目元数据的收集通过`opCreateProjectDlg`对话框完成,该对话框提供了用户友好的界面来输入项目相关信息。收集的元数据包括项目CN(唯一标识符)、名称、描述、位置、日期、持续时间、工程监督员(PS)、现场管理员(CS)、工程负责人(PM)、品质保证员(QAS)和标准等关键字段。
|
||||
|
||||
系统在数据提交前执行严格的验证机制。首先检查工程名称是否为空,如果为空则弹出提示信息要求用户重新输入。同时,系统还会检测工程名称中是否包含特殊字符,若存在特殊字符也会阻止提交并给出相应提示。此外,在将数据写入数据库之前,系统会查询数据库以确保工程名称的唯一性,避免重复创建相同名称的工程。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始创建项目]) --> ShowDialog["显示opCreateProjectDlg对话框"]
|
||||
ShowDialog --> CollectData["收集项目元数据"]
|
||||
CollectData --> ValidateEmpty["验证必填字段是否为空"]
|
||||
ValidateEmpty --> |为空| ShowError1["显示错误提示"]
|
||||
ValidateEmpty --> |不为空| ValidateSpecial["验证特殊字符"]
|
||||
ValidateSpecial --> |包含特殊字符| ShowError2["显示特殊字符错误"]
|
||||
ValidateSpecial --> |无特殊字符| CheckDuplicate["检查工程名称重复"]
|
||||
CheckDuplicate --> |已存在| ShowError3["显示重复名称错误"]
|
||||
CheckDuplicate --> |不存在| InsertDB["插入数据库记录"]
|
||||
InsertDB --> CreateDefaultTz["创建默认测区"]
|
||||
CreateDefaultTz --> End([项目创建完成])
|
||||
ShowError1 --> End
|
||||
ShowError2 --> End
|
||||
ShowError3 --> End
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [opcreateprojectdlg.cpp](file://cpp/Views/opcreateprojectdlg.cpp#L79-L114)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L274-L284)
|
||||
|
||||
**Section sources**
|
||||
- [opcreateprojectdlg.cpp](file://cpp/Views/opcreateprojectdlg.cpp#L21-L192)
|
||||
- [opcreateprojectdlg.h](file://h/opcreateprojectdlg.h#L15-L68)
|
||||
|
||||
## 项目唯一标识符生成机制
|
||||
|
||||
项目唯一标识符(CN)的生成机制是确保项目数据完整性和可追溯性的关键环节。系统采用`CGUCodeCreator::GenerateGUIDCode()`方法生成全局唯一标识符作为项目CN。该方法通过复杂的算法生成具有高度唯一性的字符串,有效避免了项目标识符冲突的可能性。
|
||||
|
||||
在`COpCreateProjectDlg`对话框初始化时,系统自动调用`OnProGenCn`方法生成默认的CN值并填充到输入框中。用户可以选择接受系统生成的CN,也可以手动输入自定义的CN。然而,即使用户手动输入CN,系统仍然会在数据库插入前检查其唯一性,确保不会出现重复的CN值。
|
||||
|
||||
项目CN不仅是数据库中的主键标识,还在后续的设备同步过程中发挥重要作用。它被用作文件路径的组成部分,确保每个项目在设备上的存储位置具有唯一性。这种设计使得系统能够准确地识别和管理多个项目,为数据同步和检索提供了可靠的基础。
|
||||
|
||||
**Section sources**
|
||||
- [opcreateprojectdlg.cpp](file://cpp/Views/opcreateprojectdlg.cpp#L117-L122)
|
||||
- [ProManager.h](file://h/ProManager.h#L67)
|
||||
- [opcreateprojectdlg.h](file://h/opcreateprojectdlg.h#L59)
|
||||
|
||||
## 数据库记录插入与默认测区创建
|
||||
|
||||
在完成元数据验证后,系统执行数据库记录插入操作。`CProManager::CreateProjectInDB`方法构建SQL插入语句,将收集到的项目元数据写入Access数据库的project表中。插入的字段包括CN、PRname、PRdesc、location、PRdate、duration、PS、CS、PM、QAS和standard等。
|
||||
|
||||
数据库插入操作完成后,系统会自动为新创建的项目生成一个默认测区。这一过程由`InsertDefaultTzToProject`方法实现,该方法首先删除该工程下可能存在的旧默认测区,然后插入一个新的默认测区记录。默认测区的CN同样通过`CGUCodeCreator::GenerateGUIDCode()`方法生成,确保其唯一性。
|
||||
|
||||
默认测区的创建遵循特定的命名规则和类型定义,其名称固定为"DefaultTestZone",类型值为3。这种设计保证了每个项目都至少包含一个测区,为后续的数据采集和管理提供了基础结构。同时,通过事务性操作确保了项目与默认测区之间的数据一致性。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CProManager {
|
||||
+CreateProjectInDB(DWORD& dwID) UINT
|
||||
+InsertDefaultTzToProject(DWORD dwProjectID) UINT
|
||||
-m_pConnection _ConnectionPtr
|
||||
-m_dmsLinkList CLinkList<CDataMngStruct*>
|
||||
-m_handleProcessor CHandleProcessor
|
||||
-m_stateProcessor CStateProcessor
|
||||
-m_guCodeCreator CGUCodeCreator
|
||||
}
|
||||
class CGUCodeCreator {
|
||||
+GenerateGUIDCode() CString
|
||||
}
|
||||
class COpCreateProjectDlg {
|
||||
+OnOK() void
|
||||
+OnProGenCn() void
|
||||
-m_edCN CString
|
||||
-m_edName CString
|
||||
-m_edPrDesc CString
|
||||
-m_edLocation CString
|
||||
-m_edPrDate CTime
|
||||
-m_edDuration int
|
||||
-m_edPS CString
|
||||
-m_edCS CString
|
||||
-m_edPM CString
|
||||
-m_edQAS CString
|
||||
-m_edStandard CString
|
||||
-m_bCNS bool
|
||||
-m_guCodeCreator CGUCodeCreator
|
||||
}
|
||||
CProManager --> CGUCodeCreator : "使用"
|
||||
CProManager --> COpCreateProjectDlg : "调用"
|
||||
COpCreateProjectDlg --> CGUCodeCreator : "使用"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L288-L306)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L319-L341)
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L249-L341)
|
||||
|
||||
## 项目数据同步到GD10设备
|
||||
|
||||
项目数据从数据库到GD10设备的同步过程是项目生命周期管理的重要环节。`CProManager::CreateProjectInDev`方法负责将项目数据同步到指定的GD10设备。该过程首先从数据库读取项目详细信息,然后检查设备上是否已存在同名项目,以避免重复创建。
|
||||
|
||||
同步过程包含多个关键步骤:首先生成项目XML缓存文件,然后通过`CDevice::SendFile`方法将文件传输到设备。在传输前,系统会创建相应的目录结构,路径格式为"/SD/projects/{项目CN}/"。文件传输成功后,系统更新数据库中的同步状态,记录设备与项目之间的关联关系。
|
||||
|
||||
如果文件传输失败,系统会执行回滚操作,删除已在设备上创建的项目,并向用户显示错误提示。这种事务性处理机制确保了数据的一致性,防止出现部分同步导致的数据不一致问题。同时,系统还实现了错误重试机制,提高了同步过程的可靠性。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant UI as 用户界面
|
||||
participant ProMgr as CProManager
|
||||
participant DB as 数据库
|
||||
participant Device as CDevice
|
||||
participant FileSys as 文件系统
|
||||
UI->>ProMgr : 调用CreateProjectInDev
|
||||
ProMgr->>DB : 查询项目信息
|
||||
DB-->>ProMgr : 返回项目数据
|
||||
ProMgr->>DB : 检查设备同步记录
|
||||
DB-->>ProMgr : 返回检查结果
|
||||
ProMgr->>FileSys : 创建CACHE目录
|
||||
FileSys-->>ProMgr : 确认目录创建
|
||||
ProMgr->>ProMgr : 生成project.xml
|
||||
ProMgr->>Device : 调用SendFile
|
||||
Device->>Device : 传输文件到GD10
|
||||
Device-->>ProMgr : 返回传输结果
|
||||
alt 传输成功
|
||||
ProMgr->>DB : 更新同步状态
|
||||
DB-->>ProMgr : 确认更新
|
||||
ProMgr-->>UI : 返回成功状态
|
||||
else 传输失败
|
||||
ProMgr->>Device : 删除设备上的项目
|
||||
Device-->>ProMgr : 确认删除
|
||||
ProMgr-->>UI : 返回失败状态
|
||||
end
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L343-L483)
|
||||
- [Device.h](file://h/Device.h#L59-L60)
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L343-L483)
|
||||
|
||||
## XML缓存文件生成
|
||||
|
||||
XML缓存文件的生成是项目数据同步过程中的关键步骤。系统使用`CMarkup`类创建符合特定格式的XML文件,文件名为"project.xml",存储在本地CACHE目录中。XML文件的结构设计遵循预定义的模式,包含项目的所有元数据信息。
|
||||
|
||||
XML文件的根元素为"project",其下包含多个子元素,如project_name、cn、description、location、create_date、create_time、test_date、test_time、duration、PS、CS、PM、QA、standard和testzone_count等。这些元素准确反映了项目在数据库中的属性,确保了数据的一致性。
|
||||
|
||||
在生成XML文件时,系统会设置适当的编码格式(ansi)和XML声明。文件内容经过格式化处理,包含适当的换行符,提高了可读性。生成的XML文件不仅用于设备同步,还可作为数据备份和交换的中间格式,增强了系统的灵活性和可维护性。
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
PROJECT ||--o{ TESTZONE : "包含"
|
||||
PROJECT {
|
||||
string CN PK
|
||||
string PRname
|
||||
string PRdesc
|
||||
string location
|
||||
date PRdate
|
||||
int duration
|
||||
string PS
|
||||
string CS
|
||||
string PM
|
||||
string QAS
|
||||
string standard
|
||||
}
|
||||
TESTZONE {
|
||||
int ID PK
|
||||
string CN UK
|
||||
string TZname
|
||||
int TZtype
|
||||
date Cdate
|
||||
string TZdesc
|
||||
string location
|
||||
int PRID FK
|
||||
}
|
||||
DEVICE ||--o{ DEV_SYN_TD : "关联"
|
||||
DEVICE {
|
||||
string DESN PK
|
||||
string DevName
|
||||
string ModelNO
|
||||
string MDate
|
||||
string HWV
|
||||
string SWV
|
||||
string MacAddress
|
||||
}
|
||||
DEV_SYN_TD {
|
||||
int ID PK
|
||||
string DESN FK
|
||||
string PrCN FK
|
||||
string PrName
|
||||
string TzCN FK
|
||||
string TzName
|
||||
boolean IsSyned
|
||||
}
|
||||
PROJECT ||--o{ DEV_SYN_TD : "同步到"
|
||||
TESTZONE ||--o{ DEV_SYN_TD : "同步到"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L402-L425)
|
||||
- [Project.h](file://h/Project.h#L26-L37)
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L398-L428)
|
||||
|
||||
## 项目删除操作与级联清理
|
||||
|
||||
项目删除操作涉及复杂的级联清理策略,以确保数据完整性和系统稳定性。虽然具体的删除方法实现未在提供的代码片段中显示,但从`ProManager.h`头文件中可以推断出系统提供了`DeleteProjectInDB`和`DeleteProjectInDev`等方法用于删除项目。
|
||||
|
||||
项目删除过程需要考虑多个关联实体的清理,包括测区、任务数据以及设备上的同步文件。系统可能采用事务性删除机制,确保所有相关数据被一致地清除。在删除数据库记录的同时,还需要清理设备上的对应文件和目录,如"/SD/projects/{项目CN}/"路径下的所有内容。
|
||||
|
||||
级联清理策略可能包括:首先删除与项目关联的所有测区数据,然后删除项目本身;在设备端,先删除测区文件,再删除项目目录。这种分层删除方式可以有效避免因外键约束导致的删除失败。同时,系统可能还实现了删除前的确认机制和备份功能,防止误删重要数据。
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.h](file://h/ProManager.h#L48-L49)
|
||||
|
||||
## 项目状态管理与性能优化
|
||||
|
||||
项目状态管理通过`m_dmsLinkList`缓存数据管理结构实现性能优化。`CProManager`类中的`m_dmsLinkList`成员变量是一个链表容器,用于缓存已加载的项目和测区数据管理结构。这种缓存机制避免了频繁的数据库查询,显著提高了数据访问性能。
|
||||
|
||||
当需要获取特定项目的管理结构时,系统首先检查`m_dmsLinkList`中是否已存在对应的`CDataMngStruct`对象。如果存在则直接返回缓存对象;如果不存在,则从数据库加载数据并创建新的管理结构对象,然后将其添加到链表中以便后续重用。这种设计模式有效减少了数据库访问次数,提升了系统响应速度。
|
||||
|
||||
缓存管理还包括适当的清理机制。在`CProManager`析构函数中,系统会遍历并删除链表中的所有对象,释放占用的内存资源。这种资源管理策略确保了系统的稳定运行,防止内存泄漏。同时,通过句柄处理器(`m_handleProcessor`)管理对象的生命周期,实现了高效的内存使用和对象复用。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A([获取DMS对象]) --> B{"缓存中存在?"}
|
||||
B --> |是| C[返回缓存对象]
|
||||
B --> |否| D[从数据库加载数据]
|
||||
D --> E[创建新的DMS对象]
|
||||
E --> F[添加到m_dmsLinkList]
|
||||
F --> G[返回新对象]
|
||||
C --> H([使用DMS对象])
|
||||
G --> H
|
||||
H --> I{"操作完成?"}
|
||||
I --> |否| H
|
||||
I --> |是| J[释放资源]
|
||||
J --> K([结束])
|
||||
style A fill:#4CAF50,stroke:#388E3C
|
||||
style C fill:#2196F3,stroke:#1976D2
|
||||
style D fill:#FF9800,stroke:#F57C00
|
||||
style E fill:#FF9800,stroke:#F57C00
|
||||
style F fill:#FF9800,stroke:#F57C00
|
||||
style G fill:#2196F3,stroke:#1976D2
|
||||
style H fill:#607D8B,stroke:#455A64
|
||||
style J fill:#F44336,stroke:#D32F2F
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L154-L182)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L39-L51)
|
||||
|
||||
**Section sources**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L154-L182)
|
||||
@@ -0,0 +1,394 @@
|
||||
# 项目管理
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
|
||||
- [ProManager.h](file://h/ProManager.h)
|
||||
- [Project.cpp](file://cpp/ProblemZone/Project.cpp)
|
||||
- [Project.h](file://h/Project.h)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp)
|
||||
- [TestingZone.h](file://h/TestingZone.h)
|
||||
- [opcreateprojectdlg.h](file://h/opcreateprojectdlg.h)
|
||||
- [opcreateprojectdlg.cpp](file://cpp/Views/opcreateprojectdlg.cpp)
|
||||
- [DataMngStruct.h](file://h/DataMngStruct.h)
|
||||
- [DevManager.h](file://h/DevManager.h)
|
||||
- [SptManager.h](file://h/SptManager.h)
|
||||
- [project.xml](file://CACHE/project.xml)
|
||||
- [testzone.xml](file://CACHE/testzone.xml)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [项目管理概述](#项目管理概述)
|
||||
2. [CProManager类架构与实现](#cpromanager类架构与实现)
|
||||
3. [项目数据模型与持久化](#项目数据模型与持久化)
|
||||
4. [项目与测区的层级关系](#项目与测区的层级关系)
|
||||
5. [项目配置同步到设备流程](#项目配置同步到设备流程)
|
||||
6. [项目管理API使用示例](#项目管理api使用示例)
|
||||
7. [与其他管理器的集成](#与其他管理器的集成)
|
||||
8. [多项目环境下的资源管理](#多项目环境下的资源管理)
|
||||
|
||||
## 项目管理概述
|
||||
|
||||
Geomative Studio的项目管理模块是整个系统的核心组件,负责管理地质探测项目的全生命周期。该模块通过CProManager类实现,提供了项目创建、打开、配置和删除等核心功能。每个项目包含一个或多个测区(TZ),形成清晰的层级结构。项目数据存储在数据库中,并通过XML缓存文件在本地持久化,同时支持与设备的双向同步。本模块与设备管理器、脚本管理器等组件紧密集成,确保了数据的一致性和操作的协同性。
|
||||
|
||||
## CProManager类架构与实现
|
||||
|
||||
CProManager类是项目管理的核心实现,负责协调项目和测区的创建、查询和删除操作。该类通过数据库连接管理项目数据,并与设备进行通信以实现数据同步。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CProManager {
|
||||
+ShowProList(dwDevHandle, proList) bool
|
||||
+ShowTzList(dwProHandle, tzList) bool
|
||||
+GetDMS(dwHandle) CDataMngStruct*
|
||||
+CreateProjectInDB(dwID) UINT
|
||||
+CreateProjectInDev(dwID, pDev) UINT
|
||||
+CreateTzInDB(dwID, dwPrID) UINT
|
||||
+CreateTzInDev(dwID, pDev) UINT
|
||||
+DeleteProjectInDB(dwID) void
|
||||
+DeleteProjectInDev(szMac, szPrCN, pDev) UINT
|
||||
+DeleteTzInDB(dwID) void
|
||||
+DeleteTzInDev(szPrCN, szTzCN, pDev) UINT
|
||||
+InsertDefaultTzToProject(dwProjectID) UINT
|
||||
+CreateDefaultTzInDev(dwProID, pDev) UINT
|
||||
}
|
||||
class CDataMngStruct {
|
||||
+ShowDetailInfo(dmsDetailList) bool
|
||||
}
|
||||
class CProject {
|
||||
+ShowDetailInfo(proDetailList) bool
|
||||
}
|
||||
class CTestingZone {
|
||||
+ShowDetailInfo(tzDetailList) bool
|
||||
}
|
||||
CProManager --> CDataMngStruct : "管理"
|
||||
CDataMngStruct <|-- CProject : "继承"
|
||||
CDataMngStruct <|-- CTestingZone : "继承"
|
||||
CProManager --> CLinkList : "m_dmsLinkList"
|
||||
CProManager --> CHandleProcessor : "m_handleProcessor"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [ProManager.h](file://h/ProManager.h#L30-L74)
|
||||
- [Project.h](file://h/Project.h#L16-L38)
|
||||
- [TestingZone.h](file://h/TestingZone.h#L14-L30)
|
||||
- [DataMngStruct.h](file://h/DataMngStruct.h#L14-L20)
|
||||
|
||||
**本节来源**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L32-L80)
|
||||
- [ProManager.h](file://h/ProManager.h#L30-L74)
|
||||
|
||||
## 项目数据模型与持久化
|
||||
|
||||
项目数据模型包含多个关键字段,这些字段在数据库和XML缓存文件中保持一致。项目数据首先存储在数据库的project表中,然后通过XML文件在本地缓存。
|
||||
|
||||
### 项目数据模型字段
|
||||
|
||||
| 字段名 | 中文名称 | 数据类型 | 描述 |
|
||||
|-------|--------|--------|------|
|
||||
| CN | 项目编号 | 字符串 | 项目的唯一标识符,使用GUID生成 |
|
||||
| PRname | 项目名称 | 字符串 | 项目的名称,用户可读 |
|
||||
| PRdesc | 项目描述 | 字符串 | 项目的详细描述信息 |
|
||||
| location | 位置 | 字符串 | 项目实施的地理位置 |
|
||||
| PRdate | 创建日期 | 日期 | 项目的创建日期 |
|
||||
| duration | 持续时间 | 字符串 | 项目预计的持续时间 |
|
||||
| PS | 项目负责人 | 字符串 | 项目的主要负责人 |
|
||||
| CS | 客户名称 | 字符串 | 项目的客户或委托方 |
|
||||
| PM | 项目经理 | 字符串 | 项目的管理负责人 |
|
||||
| QAS | 质量保证 | 字符串 | 质量保证相关人员 |
|
||||
| standard | 标准 | 字符串 | 项目遵循的技术标准 |
|
||||
|
||||
### XML缓存持久化机制
|
||||
|
||||
项目数据通过XML文件在CACHE目录下持久化存储。系统使用CMarkup库创建和解析XML文件,确保数据的可读性和可移植性。
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="ansi"?>
|
||||
<project>
|
||||
<project_name>test project</project_name>
|
||||
<cn>63EFC4AB5B284FC8B1B46F0CEB8F9DA4</cn>
|
||||
<description />
|
||||
<location />
|
||||
<create_date>2016-05-17</create_date>
|
||||
<create_time>00:00:00</create_time>
|
||||
<test_date>2020-04-11</test_date>
|
||||
<test_time>11:53:06</test_time>
|
||||
<duration>10</duration>
|
||||
<PS />
|
||||
<CS />
|
||||
<PM />
|
||||
<QA />
|
||||
<standard />
|
||||
<testzone_count>0</testzone_count>
|
||||
<testzones>
|
||||
<testzone TYPE="3">A9F3D38BDCF84401B8C3050D583BCBEE</testzone>
|
||||
</testzones>
|
||||
</project>
|
||||
```
|
||||
|
||||
当创建新项目时,系统会自动生成XML文件并存储在`CACHE\projects\<项目编号>\`目录下。这种持久化机制确保了即使在离线状态下,项目数据也能被访问和管理。
|
||||
|
||||
**本节来源**
|
||||
- [Project.h](file://h/Project.h#L26-L37)
|
||||
- [project.xml](file://CACHE/project.xml)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L397-L426)
|
||||
|
||||
## 项目与测区的层级关系
|
||||
|
||||
项目与测区之间存在明确的层级关系,一个项目可以包含多个测区,形成树状结构。这种设计符合地质探测的实际工作流程,允许用户在同一个项目下管理多个不同位置或类型的探测区域。
|
||||
|
||||
### 层级结构实现
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[项目] --> B[测区1]
|
||||
A --> C[测区2]
|
||||
A --> D[测区3]
|
||||
B --> E[1D VES \| 2D ERI]
|
||||
C --> F[3D ERT]
|
||||
D --> G[All Type]
|
||||
```
|
||||
|
||||
在数据模型中,项目(Project)和测区(TestingZone)都继承自CDataMngStruct基类,实现了多态性。CProManager通过m_dmsLinkList链表管理所有项目和测区对象,使用句柄(Handle)机制进行高效访问。
|
||||
|
||||
测区类型通过TZtype字段表示:
|
||||
- 类型1或0:1D VES | 2D ERI(一维垂直电测深或二维电阻率成像)
|
||||
- 类型2:3D ERT(三维电阻率断层扫描)
|
||||
- 类型3:默认测区
|
||||
|
||||
每个项目创建时会自动包含一个默认测区,确保项目结构的完整性。用户可以通过GUI界面或API创建额外的测区来满足不同的探测需求。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant GUI as GUI界面
|
||||
participant ProManager as CProManager
|
||||
participant DB as 数据库
|
||||
participant XML as XML缓存
|
||||
GUI->>ProManager : 创建项目请求
|
||||
ProManager->>DB : 在数据库创建项目记录
|
||||
DB-->>ProManager : 返回项目ID
|
||||
ProManager->>DB : 为项目插入默认测区
|
||||
ProManager->>XML : 创建project.xml文件
|
||||
ProManager->>XML : 创建testzone.xml文件
|
||||
ProManager-->>GUI : 返回创建结果
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L319-L341)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L61-L73)
|
||||
- [testzone.xml](file://CACHE/testzone.xml)
|
||||
|
||||
**本节来源**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L319-L341)
|
||||
- [TestingZone.cpp](file://cpp/ProblemZone/TestingZone.cpp#L61-L73)
|
||||
- [testzone.xml](file://CACHE/testzone.xml)
|
||||
|
||||
## 项目配置同步到设备流程
|
||||
|
||||
项目配置同步到设备是项目管理的关键功能,确保了现场设备与工作站的数据一致性。该流程涉及多个步骤,包括数据准备、文件传输和状态更新。
|
||||
|
||||
### 同步流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始同步] --> B{项目已存在?}
|
||||
B --> |否| C[在设备中创建项目]
|
||||
B --> |是| D[跳过创建]
|
||||
C --> E[生成项目XML文件]
|
||||
E --> F[创建本地缓存目录]
|
||||
F --> G[传输文件到设备]
|
||||
G --> H{传输成功?}
|
||||
H --> |是| I[更新数据库同步状态]
|
||||
H --> |否| J[显示错误信息]
|
||||
J --> K[回滚操作]
|
||||
I --> L[创建默认测区]
|
||||
L --> M[生成测区XML文件]
|
||||
M --> N[传输测区文件到设备]
|
||||
N --> O{传输成功?}
|
||||
O --> |是| P[更新数据库同步状态]
|
||||
O --> |否| Q[显示错误信息]
|
||||
Q --> R[删除已创建的项目]
|
||||
P --> S[同步完成]
|
||||
```
|
||||
|
||||
同步流程的具体实现如下:
|
||||
1. 首先检查项目是否已存在于设备中,避免重复创建
|
||||
2. 从数据库读取项目配置信息
|
||||
3. 使用CMarkup库生成project.xml文件
|
||||
4. 创建本地缓存目录`CACHE\projects\<项目编号>\`
|
||||
5. 调用设备的SendFile方法将文件传输到设备的/SD/projects/目录
|
||||
6. 如果传输成功,更新数据库中的同步状态;如果失败,执行回滚操作
|
||||
|
||||
此流程确保了数据同步的原子性和一致性,防止了部分同步导致的数据不一致问题。
|
||||
|
||||
**图表来源**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L343-L483)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L485-L707)
|
||||
|
||||
**本节来源**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L343-L707)
|
||||
|
||||
## 项目管理API使用示例
|
||||
|
||||
项目管理模块提供了丰富的API,支持通过GUI界面和后台代码进行项目操作。以下是常见的使用示例。
|
||||
|
||||
### GUI界面操作
|
||||
|
||||
通过GUI界面创建项目的流程:
|
||||
1. 用户点击"新建项目"按钮
|
||||
2. 系统弹出COpCreateProjectDlg对话框
|
||||
3. 用户填写项目信息(名称、描述、位置等)
|
||||
4. 系统验证项目名称的唯一性
|
||||
5. 调用CProManager::CreateProjectInDB方法在数据库中创建项目
|
||||
|
||||
```cpp
|
||||
// GUI创建项目的核心代码流程
|
||||
COpCreateProjectDlg opCreateProDlg;
|
||||
INT_PTR lRet = opCreateProDlg.DoModal();
|
||||
if (IDOK == lRet) {
|
||||
UINT uExecCode = theApp.m_pProManager->CreateProjectInDB(dwID);
|
||||
if (APP_SUCCESS == uExecCode) {
|
||||
// 更新UI显示
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 后台代码操作
|
||||
|
||||
通过后台代码创建和管理项目的示例:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as 应用程序
|
||||
participant DataOperator as DataOperator
|
||||
participant ProManager as CProManager
|
||||
participant DB as 数据库
|
||||
App->>DataOperator : CreateProjectInDB(pNavDataView)
|
||||
DataOperator->>ProManager : CreateProjectInDB(dwID)
|
||||
ProManager->>DB : 检查项目名称是否存在
|
||||
DB-->>ProManager : 返回检查结果
|
||||
ProManager->>DB : 插入项目记录
|
||||
DB-->>ProManager : 返回项目ID
|
||||
ProManager->>ProManager : InsertDefaultTzToProject
|
||||
ProManager-->>DataOperator : 返回执行代码
|
||||
DataOperator->>DB : 开始事务
|
||||
DataOperator->>DB : 提交事务
|
||||
DataOperator-->>App : 返回结果
|
||||
```
|
||||
|
||||
后台操作的关键特点是使用了数据库事务,确保了操作的原子性。如果任何步骤失败,整个事务将被回滚,保持数据的一致性。
|
||||
|
||||
**图表来源**
|
||||
- [opcreateprojectdlg.cpp](file://cpp/Views/opcreateprojectdlg.cpp#L21-L37)
|
||||
- [DataOperator.cpp](file://cpp/Operator/DataOperator.cpp#L618-L667)
|
||||
|
||||
**本节来源**
|
||||
- [opcreateprojectdlg.h](file://h/opcreateprojectdlg.h#L15-L36)
|
||||
- [opcreateprojectdlg.cpp](file://cpp/Views/opcreateprojectdlg.cpp#L21-L37)
|
||||
- [DataOperator.cpp](file://cpp/Operator/DataOperator.cpp#L618-L667)
|
||||
|
||||
## 与其他管理器的集成
|
||||
|
||||
项目管理器与设备管理器、脚本管理器等组件紧密集成,形成了完整的系统架构。这种集成确保了各模块之间的数据一致性和操作协同性。
|
||||
|
||||
### 与设备管理器的集成
|
||||
|
||||
项目管理器与设备管理器通过设备句柄和序列号进行通信。当需要将项目同步到设备时,项目管理器会调用设备管理器获取设备对象,然后执行文件传输操作。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CProManager {
|
||||
+CreateProjectInDev(dwID, pDev) UINT
|
||||
+CreateTzInDev(dwID, pDev) UINT
|
||||
}
|
||||
class CDevManager {
|
||||
+GetDevice(dwHandle) CDevice*
|
||||
+GetDevice(szDevSN) CDevice*
|
||||
}
|
||||
class CDevice {
|
||||
+SendFile(szHostPath, szLocalPath, szFileName) BOOL
|
||||
+m_szDevSN CString
|
||||
}
|
||||
CProManager --> CDevice : "使用"
|
||||
CDevManager --> CDevice : "管理"
|
||||
CProManager ..> CDevManager : "依赖"
|
||||
```
|
||||
|
||||
这种设计实现了关注点分离,项目管理器专注于项目数据的管理,而设备管理器负责设备的连接和通信。
|
||||
|
||||
### 与脚本管理器的集成
|
||||
|
||||
项目管理器与脚本管理器的集成主要体现在测区与脚本的关系上。每个测区可以关联多个探测脚本,这些脚本由脚本管理器管理。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[CProManager] --> |获取| B[CDevManager]
|
||||
B --> |提供| C[CDevice]
|
||||
C --> |用于| D[文件传输]
|
||||
A --> |创建| E[project.xml]
|
||||
A --> |创建| F[testzone.xml]
|
||||
E --> |包含| G[项目元数据]
|
||||
F --> |包含| H[测区元数据]
|
||||
F --> |引用| I[脚本文件]
|
||||
I --> |由| J[CSptManager]
|
||||
J --> |管理| K[脚本生命周期]
|
||||
```
|
||||
|
||||
脚本管理器负责脚本的创建、编辑和删除,而项目管理器确保这些脚本与正确的测区关联。这种分工使得系统更加模块化,易于维护和扩展。
|
||||
|
||||
**图表来源**
|
||||
- [DevManager.h](file://h/DevManager.h#L16-L68)
|
||||
- [SptManager.h](file://h/SptManager.h#L27-L87)
|
||||
- [ProManager.h](file://h/ProManager.h#L30-L74)
|
||||
|
||||
**本节来源**
|
||||
- [DevManager.h](file://h/DevManager.h#L16-L68)
|
||||
- [SptManager.h](file://h/SptManager.h#L27-L87)
|
||||
|
||||
## 多项目环境下的资源管理
|
||||
|
||||
在多项目环境下,系统需要高效管理内存和文件资源,避免资源泄漏和性能下降。CProManager类通过链表和句柄机制实现了高效的资源管理。
|
||||
|
||||
### 内存管理策略
|
||||
|
||||
CProManager使用CLinkList模板类管理所有项目和测区对象。每个对象通过唯一句柄访问,实现了对象的延迟加载和缓存机制。
|
||||
|
||||
```cpp
|
||||
// 对象获取的伪代码
|
||||
CDataMngStruct* CProManager::GetDMS(DWORD dwHandle) {
|
||||
CDataMngStruct* pDMS = m_dmsLinkList.Get(dwHandle);
|
||||
if (NULL == pDMS) {
|
||||
// 按需创建对象
|
||||
pDMS = new CProject(dwID, m_pConnection);
|
||||
m_dmsLinkList.Add(dwHandle, pDMS);
|
||||
}
|
||||
return pDMS;
|
||||
}
|
||||
```
|
||||
|
||||
这种策略的优点:
|
||||
- **延迟加载**:只有在需要时才从数据库加载数据,减少启动时间和内存占用
|
||||
- **对象缓存**:重复访问同一对象时直接从缓存获取,提高性能
|
||||
- **内存控制**:通过链表管理对象生命周期,避免内存泄漏
|
||||
|
||||
### 资源清理机制
|
||||
|
||||
系统在析构时会清理所有管理的对象:
|
||||
|
||||
```cpp
|
||||
CProManager::~CProManager() {
|
||||
int iDMSIndex = 0;
|
||||
while (NULL != m_dmsLinkList.Find(iDMSIndex)) {
|
||||
delete m_dmsLinkList.Find(iDMSIndex);
|
||||
iDMSIndex++;
|
||||
}
|
||||
m_dmsLinkList.DeleteAll();
|
||||
}
|
||||
```
|
||||
|
||||
此外,系统还提供了DeleteObjInMem方法,允许在运行时显式删除不再需要的对象,进一步优化内存使用。
|
||||
|
||||
**本节来源**
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L39-L51)
|
||||
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L155-L182)
|
||||
- [ProManager.h](file://h/ProManager.h#L72-L73)
|
||||
Reference in New Issue
Block a user