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,294 @@
# 1D项目创建
<cite>
**本文引用的文件**
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp)
- [DialNew1DTask.h](file://h/DialNew1DTask.h)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
- [TaskDataOper.h](file://h/TaskDataOper.h)
- [GeoMative.rc](file://GeoMative.rc)
- [DialTaskManager.cpp](file://cpp/Views/DialTaskManager.cpp)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件系统性地文档化1D项目创建流程,覆盖任务名称、测试位置、测试类型(电阻率/激电/自电)、装置类型、测试脚本、迭代次数、发射波形和发射周期等参数的配置;解释DialNew1DTask对话框的UI控件布局、数据验证逻辑与CTaskDataOper服务的交互机制;阐述不同测试类型对发射周期选项的动态影响,以及装置类型与脚本之间的关联查询逻辑;并为开发者提供界面元素扩展、参数验证规则定制与错误提示本地化的实现方法。
## 项目结构
1D项目创建涉及三个关键层次:
- 视图层:DialNew1DTask对话框负责用户输入与参数校验,并调用服务层接口创建任务。
- 服务层:CTaskDataOper封装数据库操作与业务逻辑,包括任务参数持久化、脚本与装置类型的关联查询等。
- 资源层:GeoMative.rc定义对话框控件布局与标签文本,支持多语言显示。
```mermaid
graph TB
subgraph "视图层"
D1["DialNew1DTask<br/>对话框"]
end
subgraph "服务层"
S1["CTaskDataOper<br/>任务数据操作"]
end
subgraph "资源层"
R1["GeoMative.rc<br/>控件布局/标签"]
end
D1 --> S1
D1 --- R1
```
图表来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L1-L120)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
- [GeoMative.rc](file://GeoMative.rc#L906-L929)
章节来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L1-L120)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
- [GeoMative.rc](file://GeoMative.rc#L906-L929)
## 核心组件
- DialNew1DTask:1D任务创建对话框,包含任务名称、测试地点、测试类型、装置类型、测试脚本、迭代次数、发射波形、发射周期等输入项;负责基础校验与调用服务层创建任务。
- CTaskDataOper:封装任务创建、脚本与装置类型关联查询、默认测区获取等逻辑;负责将任务参数写入数据库并返回新任务ID。
- GeoMative.rc:定义对话框控件ID与布局,支持中英文标签切换。
章节来源
- [DialNew1DTask.h](file://h/DialNew1DTask.h#L13-L71)
- [TaskDataOper.h](file://h/TaskDataOper.h#L12-L37)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
- [GeoMative.rc](file://GeoMative.rc#L906-L929)
## 架构总览
1D任务创建的端到端流程如下:
- 用户在DialNew1DTask中填写参数并点击“创建”。
- 对话框执行参数校验,组装ST1DTaskParam结构体。
- 调用CTaskDataOper::CreateTaskCN生成任务编号,再调用CTaskDataOper::Create1DTask持久化任务。
- 创建成功后返回新任务ID,对话框关闭。
```mermaid
sequenceDiagram
participant U as "用户"
participant V as "DialNew1DTask"
participant S as "CTaskDataOper"
participant DB as "数据库"
U->>V : 输入任务参数并点击“创建”
V->>V : 参数校验名称、测试类型、装置类型、脚本、迭代次数、发射周期
V->>S : CreateTaskCN(测试类型)
S-->>V : 返回任务编号
V->>S : Create1DTask(参数, 任务编号)
S->>DB : 插入td、tdchannel、td1dcon、gr等记录
DB-->>S : 返回新任务ID
S-->>V : 新任务ID
V-->>U : 关闭对话框
```
图表来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L239-L366)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
章节来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L239-L366)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
## 详细组件分析
### DialNew1DTask对话框
- 控件布局与标签
- 任务名称、测试地点、测试类型、装置类型、测试脚本、迭代次数、发射波形、发射周期。
- 支持中英文双语标签切换。
- 初始化逻辑
- 测试类型下拉框初始化为电阻率/激电/自电(中文或英文)。
- 装置类型下拉框通过CTaskDataOper::QueryMediumInfo加载介质信息。
- 发射波形默认固定为0+0-,不可编辑。
- 发射周期下拉框按2的幂次生成(1S、2S、4S、8S、16S、32S、64S),其中“自动”对应1S。
- 事件处理
- 装置类型变化:触发脚本下拉框重载,基于所选装置类型与脚本类型查询关联脚本。
- 测试类型变化:根据选择动态调整发射波形与发射周期可用性与内容。
- “创建”按钮:执行参数校验,组装ST1DTaskParam,调用服务层创建任务。
- 参数校验
- 任务名称非空。
- 必须选择测试类型。
- 必须选择装置类型。
- 必须选择测试脚本。
- 迭代次数必须为1~255整数。
- 电阻率/激电需选择发射周期;自电不启用发射周期。
- 采样间隔范围校验(0~30000)。
```mermaid
flowchart TD
Start(["进入对话框"]) --> Init["初始化控件<br/>加载测试类型/装置类型/发射周期"]
Init --> SelArray["选择装置类型"]
SelArray --> LoadSpt["查询关联脚本并填充下拉"]
SelArray --> ChangeType["选择测试类型"]
ChangeType --> DynaWave["动态设置发射波形"]
DynaWave --> DynaPeriod["动态设置发射周期项<br/>电阻率/激电可选;自电禁用"]
DynaPeriod --> ClickOK["点击“创建”"]
ClickOK --> Validate["参数校验<br/>名称/类型/装置/脚本/迭代次数/采样间隔"]
Validate --> Valid{"校验通过?"}
Valid -- 否 --> ShowErr["弹出错误提示并终止"]
Valid -- 是 --> CallSvc["调用服务层创建任务"]
CallSvc --> Done(["完成"])
```
图表来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L66-L165)
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L167-L237)
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L239-L366)
- [GeoMative.rc](file://GeoMative.rc#L906-L929)
章节来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L66-L165)
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L167-L237)
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L239-L366)
- [GeoMative.rc](file://GeoMative.rc#L906-L929)
### CTaskDataOper服务
- 任务创建
- CreateTaskCN:生成任务编号(含设备序列号与时间戳)。
- Create1DTask:插入td、tdchannel、td1dcon、gr等记录,返回新任务ID。
- 装置类型与脚本关联
- QuerySptByAR:根据装置类型ID与脚本类型查询可用脚本列表。
- QueryMediumInfo:查询介质(装置类型)列表。
- 默认测区
- GetDefaultTzID:获取默认测区ID。
```mermaid
classDiagram
class CTaskDataOper {
+CreateTaskCN(iTestType) CString
+Create1DTask(stTaskParam, strTaskCN) int
+QuerySptByAR(iAR, vtRes, iSptType) void
+QueryMediumInfo(iSptType, vtRes) void
+GetDefaultTzID() int
}
class ST1DTaskParam {
+strTDName
+strTestPlace
+iTestType
+iAR
+iSptID
+strSptName
+iSptType
+iStacking
+iTxWave
+iTxPeriod
+iSAInterval
}
CTaskDataOper --> ST1DTaskParam : "使用"
```
图表来源
- [TaskDataOper.h](file://h/TaskDataOper.h#L12-L37)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L774-L791)
章节来源
- [TaskDataOper.h](file://h/TaskDataOper.h#L12-L37)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L774-L791)
### 不同测试类型对发射周期的影响
- 电阻率:发射波形为0+0-,发射周期可选(1S、2S、4S、8S、16S、32S、64S),其中“自动”映射为1S。
- 激电:发射波形为+0-0,发射周期可选(1S、2S、4S、8S、16S、32S、64S)。
- 自电:发射波形为0,发射周期禁用且不选择。
章节来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L186-L237)
### 装置类型与脚本的关联查询逻辑
- 当用户选择装置类型后,对话框清空并重新加载脚本下拉框。
- 服务层根据装置类型ID与脚本类型查询关联脚本,填充下拉列表。
- 该逻辑确保仅展示与当前装置类型匹配的脚本。
章节来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L167-L184)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L774-L791)
### 与任务管理器的集成
- DialTaskManager在创建任务时,会将DialNew1DTask中的参数打包到任务参数结构中,随后调用服务层创建任务。
章节来源
- [DialTaskManager.cpp](file://cpp/Views/DialTaskManager.cpp#L253-L266)
## 依赖关系分析
- DialNew1DTask依赖CTaskDataOper进行数据查询与任务创建。
- 服务层依赖数据库连接与ADO记录集进行数据持久化。
- 资源层通过资源脚本定义控件布局与标签文本,支持多语言。
```mermaid
graph LR
D1["DialNew1DTask"] --> S1["CTaskDataOper"]
S1 --> DB["数据库"]
D1 --- RC["GeoMative.rc"]
```
图表来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L1-L40)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
- [GeoMative.rc](file://GeoMative.rc#L906-L929)
章节来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L1-L40)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
- [GeoMative.rc](file://GeoMative.rc#L906-L929)
## 性能考量
- 下拉框数据加载:装置类型与脚本查询应避免重复请求,建议在对话框初始化时一次性加载并缓存。
- 数据库事务:任务创建采用事务提交,异常回滚,保证一致性。
- UI响应:参数校验应在用户输入过程中及时反馈,减少无效提交。
## 故障排查指南
- 常见错误
- 未选择测试类型/装置类型/脚本:弹出相应提示并阻止提交。
- 迭代次数不在1~255范围内:提示范围错误。
- 采样间隔不在0~30000范围内:提示范围错误。
- 电阻率/激电未选择发射周期:提示必选项。
- 自电类型不启用发射周期:保持禁用状态。
- 服务端错误
- 查询脚本信息失败:提示查询失败并返回负值。
- 默认测区ID获取失败:提示获取失败。
- 数据库异常:捕获COM异常并回滚事务。
章节来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L239-L366)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L199)
## 结论
DialNew1DTask通过清晰的UI布局与严格的参数校验,结合CTaskDataOper的服务能力,实现了1D项目的标准化创建流程。测试类型对发射周期的动态控制与装置类型到脚本的关联查询,确保了参数的一致性与可执行性。开发者可在现有基础上扩展界面元素、定制验证规则与增强本地化提示。
## 附录
### 开发者指南:界面元素扩展
- 在资源脚本中添加新的控件ID与布局,参考现有控件命名规范。
- 在对话框类中声明控件变量并在DoDataExchange中绑定。
- 在OnInitDialog中初始化控件状态与默认值。
- 在消息映射中添加事件处理函数,必要时调用服务层查询数据。
章节来源
- [GeoMative.rc](file://GeoMative.rc#L906-L929)
- [DialNew1DTask.h](file://h/DialNew1DTask.h#L13-L47)
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L43-L65)
### 开发者指南:参数验证规则定制
- 在OnOK中增加自定义校验分支,如范围检查、格式校验、互斥条件判断。
- 使用本地化字符串资源统一提示文案,便于多语言维护。
章节来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L239-L366)
### 开发者指南:错误提示本地化
- 将提示文案集中到资源脚本或字符串常量,通过语言标识切换显示。
- 统一使用消息框接口输出提示,确保用户体验一致。
章节来源
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L246-L251)
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L256-L262)
@@ -0,0 +1,157 @@
# 2D项目创建
<cite>
**本文档引用的文件**
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp)
- [DialNew2DTask.h](file://h/DialNew2DTask.h)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
- [TaskDataOper.h](file://h/TaskDataOper.h)
</cite>
## 目录
1. [简介](#简介)
2. [参数配置](#参数配置)
3. [控件交互逻辑](#控件交互逻辑)
4. [跨孔测量模式约束](#跨孔测量模式约束)
5. [测试脚本选择机制](#测试脚本选择机制)
6. [接地电阻测试选项](#接地电阻测试选项)
## 简介
2D项目创建功能是Geomative Studio软件中的核心功能之一,用于配置和创建二维地球物理勘探任务。该功能通过`DialNew2DTask`对话框实现,允许用户设置任务的各种参数,包括装置类型、电缆布线方式、电极间距、孔间距(跨孔测量)、起始/结束电极、采样间隔等。本文档详细说明了该功能的实现细节和交互逻辑。
**Section sources**
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L1-L665)
- [DialNew2DTask.h](file://h/DialNew2DTask.h#L1-L92)
## 参数配置
2D项目创建对话框提供了多个参数的配置选项,主要包括:
- **任务名称**:用户定义的任务标识名称
- **测试地点**:勘探任务的地理位置描述
- **测试方式**:包括电阻率(RES)、激电(IP)和自电(SP)三种模式
- **装置类型**:定义电极排列方式,如温纳、施伦贝谢等
- **测试脚本**:预定义的测量序列和参数配置
- **迭代次数**:测量数据的叠加次数,用于提高信噪比
- **发射周期**:电流发射的时间周期
- **电缆布线方式**:电缆的连接和部署方式
- **电极间距**:相邻电极之间的距离
- **采样间隔**:数据采集的时间间隔(毫秒)
这些参数共同定义了2D勘探任务的测量配置,确保数据采集的准确性和一致性。
**Section sources**
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L80-L237)
- [TaskDataOper.h](file://h/TaskDataOper.h#L40-L82)
## 控件交互逻辑
`DialNew2DTask`对话框中的控件具有复杂的交互逻辑,特别是装置类型变化时对脚本和电缆布线方式的动态过滤机制。
### 装置类型变化事件
当用户选择不同的装置类型时,系统会触发`OnSelchangeCombo2dArray`事件处理函数,该函数执行以下操作:
1. 清空测试脚本下拉框
2. 根据选定的装置类型查询可用的测试脚本
3. 动态填充测试脚本下拉框
4. 根据装置类型显示或隐藏孔间距输入框
```mermaid
flowchart TD
A[用户选择装置类型] --> B{装置类型为跨孔测量?}
B --> |是| C[显示孔间距输入框]
B --> |否| D[隐藏孔间距输入框]
E[查询对应装置类型的测试脚本] --> F[填充测试脚本下拉框]
G{装置类型为Geomative跨孔?} --> |是| H[禁用起始/结束电极输入]
G --> |否| I[启用起始/结束电极输入]
```
**Diagram sources**
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L239-L274)
### 测试方式变化事件
当测试方式(电阻率、激电、自电)发生变化时,系统会动态过滤电缆布线方式和发射周期选项:
- 电阻率模式:过滤掉激电专用的布线方式
- 激电模式:过滤掉电阻率专用的布线方式
- 自电模式:显示所有布线方式但禁用发射周期
```mermaid
flowchart TD
A[用户选择测试方式] --> B{测试方式为激电?}
B --> |是| C[过滤电阻率布线方式]
B --> |否| D{测试方式为电阻率?}
D --> |是| E[过滤激电布线方式]
D --> |否| F[显示所有布线方式]
G[更新发射周期选项] --> H[根据测试方式启用/禁用]
```
**Diagram sources**
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L312-L411)
## 跨孔测量模式约束
在跨孔测量模式下,系统对孔间距与电极间距存在严格的约束关系:
1. 当装置类型为跨孔测量(AR_CROSS_HOLE_TYPE)时,孔间距输入框会被显示
2. 系统会验证孔间距必须大于电极间距
3. 如果孔间距小于或等于电极间距,系统会弹出错误提示
```mermaid
flowchart TD
A["用户选择跨孔装置类型"] --> B["显示孔间距输入框"]
C["用户输入孔间距和电极间距"] --> D{"孔间距 > 电极间距?"}
D --> |是| E["参数有效,继续"]
D --> |否| F["显示错误提示: \"孔间距必须大于电极间距\""]
```
这种约束确保了跨孔测量的物理可行性,防止用户配置不合理的参数。
**Section sources**
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L530-L560)
## 测试脚本选择机制
当用户选择测试脚本后,系统会自动填充电极范围和层数,实现原理如下:
1. 调用`Query2DSptInfo`函数查询脚本的最小和最大层
2. 调用`QuerySptElecTpMount`函数查询脚本的电极数量和测量点数
3. 自动设置起始电极为1,结束电极为最大电极数
4. 填充起始层和结束层的值
```mermaid
sequenceDiagram
participant User as 用户
participant Dialog as DialNew2DTask对话框
participant TaskOper as CTaskDataOper
User->>Dialog : 选择测试脚本
Dialog->>TaskOper : Query2DSptInfo(iSptID)
TaskOper-->>Dialog : 返回最小/最大层
Dialog->>TaskOper : QuerySptElecTpMount(iSptID)
TaskOper-->>Dialog : 返回电极数量
Dialog->>Dialog : 设置起始电极为1
Dialog->>Dialog : 设置结束电极为最大电极数
Dialog->>Dialog : 填充层范围
```
**Diagram sources**
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L276-L309)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L986-L1019)
## 接地电阻测试选项
接地电阻测试选项具有以下默认行为和可配置性:
- **默认行为**:默认启用接地电阻测试(`((CButton*)GetDlgItem(IDC_IF_TEST_GR))->SetCheck(TRUE);`
- **用户可配置性**:用户可以通过复选框启用或禁用接地电阻测试
- **参数传递**:选中状态会作为`ucTestGRFlag`参数传递给任务创建函数
```mermaid
flowchart TD
A[对话框初始化] --> B[默认选中接地电阻测试]
C[用户操作] --> D{用户取消选中?}
D --> |是| E[ucTestGRFlag = 0]
D --> |否| F[ucTestGRFlag = 1]
G[创建任务] --> H[将ucTestGRFlag写入任务参数]
```
这种设计既保证了常规情况下进行接地电阻测试,又允许用户根据实际需求关闭该功能。
**Section sources**
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L233-L235)
- [TaskDataOper.h](file://h/TaskDataOper.h#L66-L80)
@@ -0,0 +1,317 @@
# 3D项目创建
<cite>
**本文引用的文件**
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp)
- [DialNew3DTask.h](file://h/DialNew3DTask.h)
- [TaskDataOper.h](file://h/TaskDataOper.h)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
- [DialTaskManager.cpp](file://cpp/Views/DialTaskManager.cpp)
- [DialCreateNew3DSpt.cpp](file://cpp/Views/DialCreateNew3DSpt.cpp)
- [DialCreateNew3DSpt.h](file://h/DialCreateNew3DSpt.h)
- [Script3D.cpp](file://cpp/ProblemZone/Script3D.cpp)
- [GeoMative.rc](file://GeoMative.rc)
- [Resource.h](file://Resource.h)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件系统性地文档化Geomative Studio中“3D项目创建”流程,重点覆盖:
- 三维网格信息(X/Y方向电极数量、电极步长、电极间距等)的配置与来源
- DialNew3DTask对话框如何基于选定的测试脚本自动计算并展示网格尺寸信息
- 三维测量中电缆布线方式的特殊要求与适配
- 发射周期、迭代次数等通用参数的继承与适配策略
- 三维测量任务参数结构体(ST3DTaskParam)与数据库存储的映射关系
- 任务创建成功后的ID返回机制
## 项目结构
围绕3D项目创建的关键文件组织如下:
- 视图层:DialNew3DTask3D任务创建对话框)、DialCreateNew3DSpt3D脚本创建对话框)
- 操作层:TaskDataOper(任务数据操作,含Create3DTask
- 脚本层:Script3D(脚本信息查询与展示)
- 资源与控件:GeoMative.rc、Resource.h(包含3D相关控件ID
```mermaid
graph TB
subgraph "视图层"
DNT["DialNew3DTask<br/>3D任务创建对话框"]
DCNS["DialCreateNew3DSpt<br/>3D脚本创建对话框"]
end
subgraph "操作层"
TDO["CTaskDataOper<br/>任务数据操作"]
end
subgraph "脚本层"
S3D["CScript3D<br/>脚本信息查询"]
end
subgraph "资源与控件"
RC["GeoMative.rc<br/>资源定义"]
RH["Resource.h<br/>控件ID常量"]
end
DNT --> TDO
DCNS --> S3D
DNT --> RC
DNT --> RH
DCNS --> RC
DCNS --> RH
```
图表来源
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L1-L120)
- [DialCreateNew3DSpt.cpp](file://cpp/Views/DialCreateNew3DSpt.cpp#L1-L120)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
- [Script3D.cpp](file://cpp/ProblemZone/Script3D.cpp#L1-L120)
- [GeoMative.rc](file://GeoMative.rc#L1662-L1681)
- [Resource.h](file://Resource.h#L759-L789)
章节来源
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L1-L120)
- [DialCreateNew3DSpt.cpp](file://cpp/Views/DialCreateNew3DSpt.cpp#L1-L120)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
- [Script3D.cpp](file://cpp/ProblemZone/Script3D.cpp#L1-L120)
- [GeoMative.rc](file://GeoMative.rc#L1662-L1681)
- [Resource.h](file://Resource.h#L759-L789)
## 核心组件
- DialNew3DTask:负责3D任务创建的用户交互,包括测试方式、装置类型、脚本选择、电缆布线方式、发射周期、采样间隔、迭代次数等,并将参数封装为ST3DTaskParam后交由CTaskDataOper执行创建。
- CTaskDataOper:提供Create3DTask接口,完成数据库插入、生成任务ID、写入td与tdchannel表、导入脚本点位信息等。
- CScript3D:提供脚本查询能力,用于获取脚本的Rect、PoleStep、PoleDistance、LineDirection等网格与布线相关信息。
- DialCreateNew3DSpt3D脚本创建对话框,承载X/Y网格大小、电极间距、迭代数、电缆方向等输入与绘制预览。
- 资源与控件:通过GeoMative.rc与Resource.h定义3D相关控件ID,确保UI一致性。
章节来源
- [DialNew3DTask.h](file://h/DialNew3DTask.h#L1-L51)
- [TaskDataOper.h](file://h/TaskDataOper.h#L85-L112)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
- [Script3D.cpp](file://cpp/ProblemZone/Script3D.cpp#L1-L120)
- [DialCreateNew3DSpt.h](file://h/DialCreateNew3DSpt.h#L83-L108)
- [GeoMative.rc](file://GeoMative.rc#L1662-L1681)
- [Resource.h](file://Resource.h#L759-L789)
## 架构总览
下图展示了3D任务创建从UI到数据库的端到端流程。
```mermaid
sequenceDiagram
participant 用户 as "用户"
participant DNT as "DialNew3DTask"
participant TDO as "CTaskDataOper"
participant DB as "数据库"
participant S3D as "CScript3D"
用户->>DNT : 选择测试方式/装置/脚本/布线方式/周期/采样间隔/迭代次数
DNT->>S3D : 查询脚本网格信息(Rect/PoleStep/PoleDistance/LineDirection)
S3D-->>DNT : 返回网格尺寸与步长/间距/方向
DNT->>DNT : 自动计算并显示网格信息
DNT->>TDO : Create3DTask(ST3DTaskParam, TaskCN)
TDO->>DB : 插入td表(含Rect/RectLoc/Espace/Edistance/Clayout等)
TDO->>DB : 插入tdchannel表
TDO->>DB : 批量导入脚本3D点位到td3dcon
TDO-->>DNT : 返回新任务ID
DNT-->>用户 : 创建成功并返回任务ID
```
图表来源
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L216-L306)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
- [Script3D.cpp](file://cpp/ProblemZone/Script3D.cpp#L1-L120)
章节来源
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L216-L306)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
- [Script3D.cpp](file://cpp/ProblemZone/Script3D.cpp#L1-L120)
## 详细组件分析
### DialNew3DTask3D任务创建对话框
- 功能要点
- 测试方式、装置类型、脚本、布线方式、发射周期、采样间隔、迭代次数等参数收集
- 基于脚本查询自动填充网格尺寸(X/Y方向电极数量、步长、间距、方向)
- 将参数封装为ST3DTaskParam并调用CTaskDataOper::Create3DTask
- 成功后返回新任务ID并在任务管理器中使用
- 关键逻辑路径
- 脚本选择事件:OnSelchangeCombo3dScript
- 通过QuerySptRectByARandSCname获取Rect、PoleStep、PoleDistance、LineDirection
- 解析并填充m_rcGridSize、m_fXElecStep、m_fYElecStep、m_fXElecDistance、m_fYElecDistance、m_byLineDirection
- 更新界面显示网络尺寸(X: right+1, Y: bottom+1
- OK事件:OnOK
- 参数校验(步长、任务名、测试方式、布线方式、迭代次数、发射周期、采样间隔)
- 组装ST3DTaskParam并调用Create3DTask
- 记录新任务ID并返回
- 三维网格参数映射
- X/Y方向电极数量:来自Rect解析后的right、bottom加一
- 电极步长:来自PoleStep(X、Y方向)
- 电极间距:来自PoleDistanceX、Y方向)
- 测线方向:来自LineDirection0:X方向,1:Y方向)
章节来源
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L216-L306)
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L411-L569)
- [DialNew3DTask.h](file://h/DialNew3DTask.h#L1-L51)
### CTaskDataOper3D任务创建与数据库映射
- Create3DTask流程
- 查询脚本基础信息(Eamount、TPamount、Rect、RectLoc、PoleStep、PoleDistance、CN、LineDirection
- 生成任务CN并开启事务
- 插入td表(含TDname、TDCN、Tlocation、TZID、SCID、SCCN、Sname、Stype、Ttype、Eamount、TPamount、CHamount、N、TRwave、TRfrequency、SAfrequency、Clayout、SkipCable、Espace、Edistance、rect、rect_loc、Cdate、Ctime、DESN、STime、ETime、TTimer、TdStatus、TestGRFlag、LineDirection、CreateTime
- 插入tdchannel表(TDID、CHnumber、AR
- 批量导入脚本3D点位到td3dcon
- 提交事务并返回任务ID
- 数据库字段与ST3DTaskParam映射要点
- ST3DTaskParam中的iSptID、iSptType、iTestType、iAR、iCableLayout、iStacking、iTxWave、iTxPeriod、iSAInterval、ucTestGRFlag等直接映射到td表对应字段
- 脚本查询返回的Rect、PoleStep、PoleDistance、LineDirection写入td表的rect、rect_loc、Espace、Edistance、LineDirection
- 任务ID通过查询td表最大ID返回
章节来源
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
- [TaskDataOper.h](file://h/TaskDataOper.h#L85-L112)
### DialCreateNew3DSpt3D脚本创建与网格输入
- 功能要点
- 输入X/Y网格大小、电极间距、迭代数、电缆方向等
- 初始化绘图板,根据输入更新X/Y电极数量、间距,并重绘
- 支持不同测量方法与装置类型的组合显示
- 关键参数
- m_uiXGridSize、m_uiYGridSizeX/Y方向电极数量
- m_fXPoleDistance、m_fYPoleDistanceX/Y方向电极间距
- m_uiIterationNumber:迭代次数
- m_comCableDirection:电缆方向(X或Y
章节来源
- [DialCreateNew3DSpt.cpp](file://cpp/Views/DialCreateNew3DSpt.cpp#L1-L200)
- [DialCreateNew3DSpt.cpp](file://cpp/Views/DialCreateNew3DSpt.cpp#L957-L966)
- [DialCreateNew3DSpt.h](file://h/DialCreateNew3DSpt.h#L83-L108)
### 3D脚本信息查询(CScript3D
- 作用:提供脚本Rect、PoleStep、PoleDistance、LineDirection等信息,供DialNew3DTask自动计算网格尺寸
- 影响:直接影响DialNew3DTask对话框中网格尺寸的显示与验证
章节来源
- [Script3D.cpp](file://cpp/ProblemZone/Script3D.cpp#L1-L120)
### 3D任务参数结构体(ST3DTaskParam)与数据库映射
- 结构体字段(节选)
- strTDName、strTestPlace、iTestType、iCableLayout、iAR、iSptID、strSptName、iSptType、iSkipCable、iStacking、iTxWave、iTxPeriod、iSAInterval、ucTestGRFlag
- 数据库存储映射
- td表字段与ST3DTaskParam字段一一对应,包括但不限于:Ttype、Clayout、N、TRwave、TRfrequency、SAfrequency、Espace、Edistance、rect、rect_loc、LineDirection、TestGRFlag、CreateTime等
- 任务ID返回
- 通过查询td表的最大ID返回新任务ID
章节来源
- [TaskDataOper.h](file://h/TaskDataOper.h#L85-L112)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
### DialTaskManager:参数继承与适配
- 在任务类型选择为3D时,DialTaskManager从DialNew3DTask读取参数并写入任务参数结构
- 关键参数继承
- 测试类型、发射周期、脚本ID、装置类型、布线方式、采样间隔、迭代次数
- 三维特有的电极步长、电极间距、网格尺寸、测线方向也从DialNew3DTask传递
章节来源
- [DialTaskManager.cpp](file://cpp/Views/DialTaskManager.cpp#L300-L341)
## 依赖分析
- DialNew3DTask依赖TaskDataOper进行脚本查询与任务创建
- TaskDataOper依赖数据库连接与ADO Recordset进行数据持久化
- DialCreateNew3DSpt与DialNew3DTask共同影响最终的网格与布线参数
- 资源文件GeoMative.rc与Resource.h为3D相关控件提供ID与布局
```mermaid
graph LR
DNT["DialNew3DTask"] --> TDO["CTaskDataOper"]
DNT --> S3D["CScript3D"]
DCNS["DialCreateNew3DSpt"] --> DNT
TDO --> DB["数据库"]
RC["GeoMative.rc"] --> DNT
RH["Resource.h"] --> DNT
```
图表来源
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L216-L306)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
- [Script3D.cpp](file://cpp/ProblemZone/Script3D.cpp#L1-L120)
- [GeoMative.rc](file://GeoMative.rc#L1662-L1681)
- [Resource.h](file://Resource.h#L759-L789)
章节来源
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L216-L306)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
- [Script3D.cpp](file://cpp/ProblemZone/Script3D.cpp#L1-L120)
- [GeoMative.rc](file://GeoMative.rc#L1662-L1681)
- [Resource.h](file://Resource.h#L759-L789)
## 性能考量
- 脚本查询与数据库访问
- DialNew3DTask在脚本切换时进行一次脚本信息查询,建议避免频繁重复查询
- TaskDataOper在Create3DTask中使用事务,减少多次提交带来的开销
- 网格尺寸计算
- 仅基于脚本返回的Rect/PoleStep/PoleDistance/LineDirection进行简单解析与显示,复杂度低
- UI更新
- DialCreateNew3DSpt在参数变化时触发重绘,建议在大量参数变更时合并更新以降低刷新频率
[本节为通用指导,无需特定文件引用]
## 故障排查指南
- 步长为空或格式错误
- 现象:OnOK中对步长进行非空与范围校验,若为空或越界会弹窗提示
- 处理:检查脚本PoleStep格式(X,Y),确保输入合法
- 任务名为空
- 现象:必填项校验失败
- 处理:填写任务名称后重试
- 测试方式/布线方式/脚本未选择
- 现象:必选项未选择导致校验失败
- 处理:按提示选择相应项
- 迭代次数越界
- 现象:范围校验失败
- 处理:将迭代次数调整至1~255范围内
- 发射周期未选择(电阻率/激电)
- 现象:测试方式切换时周期控件启用状态变化
- 处理:根据当前测试方式正确选择周期
- 采样间隔越界
- 现象:范围校验失败
- 处理:将采样间隔调整至0~30000范围内
- 任务创建失败
- 现象:Create3DTask返回负值
- 处理:检查数据库连接、事务回滚日志,确认脚本ID有效且数据库权限正常
章节来源
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L411-L569)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L549-L748)
## 结论
- 3D项目创建流程以DialNew3DTask为核心入口,结合脚本查询自动填充网格尺寸,确保X/Y方向电极数量、步长、间距与测线方向的一致性
- 电缆布线方式在不同测试方式下进行过滤与适配,保证三维测量的可行性
- 通用参数(发射周期、采样间隔、迭代次数)在对话框中进行严格校验,并在任务管理器中继承到最终任务参数
- ST3DTaskParam与数据库字段映射清晰,Create3DTask通过事务保障数据一致性,返回新任务ID供后续使用
[本节为总结,无需特定文件引用]
## 附录
### 3D网格参数与UI控件对照
- X方向电极数量:来自Rect解析后的right+1
- Y方向电极数量:来自Rect解析后的bottom+1
- X方向电极步长:来自PoleStep的X分量
- Y方向电极步长:来自PoleStep的Y分量
- X方向电极间距:来自PoleDistance的X分量
- Y方向电极间距:来自PoleDistance的Y分量
- 测线方向:来自LineDirection0:X方向,1:Y方向)
- 电缆方向:COMBOBOX控件(X或Y
章节来源
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L216-L306)
- [GeoMative.rc](file://GeoMative.rc#L1662-L1681)
- [Resource.h](file://Resource.h#L759-L789)
@@ -0,0 +1,405 @@
# 项目创建与管理
<cite>
**本文档引用的文件**
- [GeoMative.cpp](file://cpp/Main/GeoMative.cpp)
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp)
- [Project.cpp](file://cpp/ProblemZone/Project.cpp)
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp)
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp)
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp)
- [opcreateprojectdlg.cpp](file://cpp/Views/opcreateprojectdlg.cpp)
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp)
- [DataOperator.cpp](file://cpp/Operator/DataOperator.cpp)
</cite>
## 目录
1. [项目创建流程](#项目创建流程)
2. [项目类型对话框实现机制](#项目类型对话框实现机制)
3. [项目参数设置与测区定义](#项目参数设置与测区定义)
4. [项目数据模型与内存组织](#项目数据模型与内存组织)
5. [XML缓存与数据库同步](#xml缓存与数据库同步)
6. [项目类型扩展技术路径](#项目类型扩展技术路径)
## 项目创建流程
Geomative Studio的项目创建流程始于应用程序初始化阶段,在`GeoMative.cpp`中通过`InitInstance()`方法完成。系统首先建立与数据库的连接,然后初始化项目管理器(`CProManager`)、设备管理器(`CDevManager`)等核心组件。项目创建的核心入口是`CProManager::CreateProjectInDB()`方法,该方法通过显示`COpCreateProjectDlg`对话框收集用户输入的项目基本信息。
项目创建过程遵循严格的验证机制,首先检查项目名称是否已存在,若存在则提示用户"工程名称已经存在!"。项目信息包括工程编号(CN)、名称、描述、位置、日期、持续时间、监督员、管理员、负责人、品质保证员和标准等字段。系统支持自动生成唯一标识码(GUID)作为工程编号,确保项目标识的唯一性。
项目创建成功后,系统会自动为新项目创建默认测区(DefaultTestZone),并初始化相应的数据库记录。整个创建过程采用事务处理机制,确保数据的一致性和完整性。项目创建完成后,相关信息会被同步到缓存目录(CACHE/projects/)下的XML文件中,实现本地缓存与数据库的双重存储。
**Section sources**
- [GeoMative.cpp](file://cpp/Main/GeoMative.cpp#L159-L442)
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L249-L341)
- [opcreateprojectdlg.cpp](file://cpp/Views/opcreateprojectdlg.cpp#L79-L115)
## 项目类型对话框实现机制
系统为不同维度的测量项目提供了专门的对话框实现,包括`DialNew1DTask``DialNew2DTask``DialNew3DTask`三个类,分别处理一维、二维和三维测量任务的创建。这些对话框类继承自MFC的`CDialog`基类,通过资源文件定义用户界面布局,并在运行时动态填充数据。
### 一维项目对话框(DialNew1DTask
`DialNew1DTask`对话框为用户提供了一维测量任务的配置界面。在`OnInitDialog()`方法中,系统初始化测试类型下拉框(电阻率、激电、自电),并从数据库查询可用的测量装置类型(AR)。用户选择装置类型后,系统会自动加载关联的测试脚本。发射周期选项支持从"自动"到64秒的多种选择,满足不同测量需求。
```mermaid
classDiagram
class CDialNew1DTask {
+m_strTaskName string
+m_strTestPlace string
+m_strSptName string
+m_iTestType int
+m_iAR int
+m_iSptID int
+m_iStacking int
+m_iTxWave int
+m_iTxPeriod int
+OnInitDialog() bool
+OnSelchangeCombo1dArray() void
+OnSelchangeCombo1dTestType() void
+OnOK() void
}
class CTaskDataOper {
+QueryMediumInfo() void
+QuerySptByAR() void
+Create1DTask() int
}
CDialNew1DTask --> CTaskDataOper : "uses"
```
**Diagram sources **
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L1-L381)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L200)
### 二维项目对话框(DialNew2DTask
`DialNew2DTask`对话框提供了更复杂的二维测量配置功能。除了基本的测试参数外,还包含电缆布线方式、电极间距、孔间距等专业设置。系统根据选择的测试类型动态调整可用的电缆布线选项,例如电阻率测量和激电测量有不同的布线要求。对于交叉孔(Cross Hole)类型的测量,系统会显示孔间距设置字段。
```mermaid
classDiagram
class CDialNew2DTask {
+m_iCableLayout int
+m_iStatrLayer int
+m_iEndLayer int
+m_iStartElec int
+m_iEndElec int
+m_fEelcSpace float
+m_iSkipCable int
+m_iRollCnt int
+OnInitDialog() bool
+OnSelchangeCombo2dArray() void
+OnSelchangeCombo2dScript() void
+OnSelchangeCombo2dTestType() void
+OnOK() void
}
class CTaskDataOper {
+QueryCmInfo() void
+Query2DSptInfo() bool
+QuerySptElecTpMount() bool
+Create2DTask() int
}
CDialNew2DTask --> CTaskDataOper : "uses"
```
**Diagram sources **
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L1-L665)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L202-L400)
### 三维项目对话框(DialNew3DTask
`DialNew3DTask`对话框专为三维测量任务设计,提供了网格信息、步长设置等高级功能。用户选择测试脚本后,系统会自动解析并显示网格尺寸信息(X和Y方向的电极数量)。三维测量支持复杂的电极步长和距离设置,允许用户定义非均匀网格布局。
```mermaid
classDiagram
class CDialNew3DTask {
+m_rcGridSize CRect
+m_fXElecStep float
+m_fYElecStep float
+m_fXElecDistance float
+m_fYElecDistance float
+m_byLineDirection byte
+OnInitDialog() bool
+OnSelchangeCombo3dArray() void
+OnSelchangeCombo3dScript() void
+OnSelchangeCombo3dTestType() void
+OnOK() void
}
class CTaskDataOper {
+QuerySptRectByARandSCname() void
+Create3DTask() int
}
CDialNew3DTask --> CTaskDataOper : "uses"
```
**Diagram sources **
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L1-L570)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L402-L600)
**Section sources**
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L1-L381)
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L1-L665)
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L1-L570)
## 项目参数设置与测区定义
项目参数设置是测量任务创建过程中的关键环节,系统通过一系列验证规则确保输入数据的有效性。每个对话框的`OnOK()`方法都包含完整的参数验证逻辑,对必填字段进行空值检查,对数值范围进行边界验证。
### 参数验证规则
系统实施严格的参数验证机制:
- **任务名称**:不能为空,长度限制50个字符
- **迭代次数**:必须在1-255范围内
- **电极间距**:必须大于零
- **采样间隔**:必须在0-30000毫秒范围内
- **孔间距**:必须大于电极间距(仅交叉孔测量)
当用户输入不符合要求时,系统会弹出相应的错误提示,如"任务名不能为空"、"迭代次数的取值范围为1到255"等,并阻止任务创建过程继续执行。
### 测区定义机制
测区(Testing Zone)是项目的基本组成单元,系统通过`COpCreateTzDlg`对话框管理测区的创建。每个项目创建时都会自动包含一个默认测区。测区定义包含名称、位置、描述和创建日期等基本信息。系统在`ProManager.cpp`中通过`InsertDefaultTzToProject()`方法实现默认测区的自动创建。
测区与测量任务之间存在层级关系,一个项目可以包含多个测区,每个测区可以包含多个测量任务。这种层次结构通过数据库中的外键关系(PRID、TZID)来维护,确保数据的完整性和一致性。
```mermaid
flowchart TD
Start([开始创建任务]) --> ValidateInput["验证输入参数"]
ValidateInput --> InputValid{"参数有效?"}
InputValid --> |否| ReturnError["显示错误信息"]
InputValid --> |是| CheckDependencies["检查依赖项"]
CheckDependencies --> DependenciesValid{"依赖项有效?"}
DependenciesValid --> |否| HandleDependencyError["处理依赖错误"]
DependenciesValid --> |是| CreateTaskRecord["创建任务数据库记录"]
CreateTaskRecord --> CreateChannelRecord["创建通道记录"]
CreateChannelRecord --> ImportScriptData["导入脚本数据"]
ImportScriptData --> InsertGroundResistance["插入接地电阻信息"]
InsertGroundResistance --> CommitTransaction["提交事务"]
CommitTransaction --> End([任务创建完成])
ReturnError --> End
HandleDependencyError --> End
```
**Diagram sources **
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L200)
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L91)
**Section sources**
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L239-L365)
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L414-L664)
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L411-L568)
- [opcreatetzdlg.cpp](file://cpp/Views/opcreatetzdlg.cpp#L54-L91)
## 项目数据模型与内存组织
系统的项目数据模型基于面向对象设计,核心类包括`CProject``CTestingZone``CTask`等。这些类通过`CProManager`进行统一管理,并在内存中形成层次化的数据结构。
### 核心数据结构
`CProject`类封装了项目的所有属性,包括工程编号(CN)、名称、描述、位置、日期、持续时间、监督员、管理员、负责人、品质保证员和标准等。这些属性在构造函数中从数据库查询并初始化:
```mermaid
classDiagram
class CProject {
+m_szCN string
+m_szPRname string
+m_szDesc string
+m_szLocation string
+m_szPRdate string
+m_szDuration string
+m_szPS string
+m_szCS string
+m_szPM string
+m_szQAS string
+m_szStandard string
+m_dwID DWORD
+CProject(DWORD, _ConnectionPtr&) constructor
+~CProject() destructor
+ShowDetailInfo(CListCtrl&) bool
}
class CTestingZone {
+m_szCN string
+m_szTZname string
+m_szDesc string
+m_szLocation string
+m_szCdate string
+m_dwID DWORD
+m_dwPRID DWORD
+CTestingZone(DWORD, _ConnectionPtr&) constructor
+~CTestingZone() destructor
}
class CTask {
+m_strTDName string
+m_strTDCN string
+m_strTestPlace string
+m_iTZID int
+m_iSCID int
+m_strSCCN string
+m_strSptName string
+m_ucStype byte
+m_ucTtype byte
+m_iEamount int
+m_iTPmount int
+m_ucCHamount byte
+m_iN int
+m_ucTRwave byte
+m_ucTRfrequency byte
+m_iSAfrequency int
+m_strCdate string
+m_strCtime string
+m_tCreateTime time_t
+CTask(DWORD, _ConnectionPtr&) constructor
+~CTask() destructor
}
CProject --> CTestingZone : "1..*"
CTestingZone --> CTask : "1..*"
```
**Diagram sources **
- [Project.cpp](file://cpp/ProblemZone/Project.cpp#L1-L81)
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L153-L182)
### 内存管理机制
系统采用智能缓存机制管理项目数据,通过`m_dmsLinkList`链表存储已加载的项目、测区和任务对象。`CProManager::GetDMS()`方法实现了对象的延迟加载和缓存重用:
1. 当请求特定数据对象时,首先在缓存链表中查找
2. 如果找到则直接返回缓存对象
3. 如果未找到则从数据库加载并创建新对象,然后加入缓存链表
这种机制避免了重复的数据库查询,提高了系统性能。同时,系统在应用程序退出时通过析构函数清理所有缓存对象,防止内存泄漏。
**Section sources**
- [Project.cpp](file://cpp/ProblemZone/Project.cpp#L1-L81)
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L153-L182)
## XML缓存与数据库同步
系统采用XML文件作为本地缓存机制,与中央数据库保持同步。这种双重存储策略既保证了数据的持久性,又提高了本地访问性能。
### 缓存文件结构
项目相关的XML缓存文件存储在`CACHE/`目录下,主要包含:
- `project.xml`:项目基本信息
- `testzone.xml`:测区配置信息
- 任务特定的XML文件:测量任务参数
`project.xml`文件采用标准的XML格式,包含项目名称、编号、描述、位置、创建日期等元数据:
```xml
<?xml version="1.0" encoding="ansi"?>
<project>
<project_name>示例项目</project_name>
<cn>PRJ-2023-001</cn>
<description>项目描述</description>
<location>测量地点</location>
<create_date>2023-01-01</create_date>
<create_time>00:00:00</create_time>
<test_date>2023-01-01</test_date>
<test_time>00:00:00</test_time>
<duration>30</duration>
<PS>监督员姓名</PS>
<CS>管理员姓名</CS>
<PM>负责人姓名</PM>
<QA>品质保证员姓名</QA>
<standard>标准名称</standard>
<testzone_count>1</testzone_count>
<testzones/>
</project>
```
### 同步策略
系统在项目创建和修改时执行同步操作:
1. 首先在数据库中创建记录
2. 然后生成对应的XML缓存文件
3. 最后将文件传输到设备(如果连接)
同步过程采用事务控制,确保数据库和缓存的一致性。如果文件传输失败,系统会回滚数据库操作,保持数据完整性。`CreateProjectInDev()`方法负责处理项目到设备的同步,包括创建目录结构、生成XML文件和文件传输等步骤。
```mermaid
sequenceDiagram
participant User as "用户"
participant Dialog as "创建对话框"
participant TaskDataOper as "TaskDataOper"
participant Database as "数据库"
participant FileSystem as "文件系统"
User->>Dialog : 提交任务参数
Dialog->>TaskDataOper : 调用CreateXDTTask()
TaskDataOper->>Database : 开始事务
Database-->>TaskDataOper : 事务开始
TaskDataOper->>Database : 插入任务记录
Database-->>TaskDataOper : 记录ID
TaskDataOper->>Database : 插入通道记录
TaskDataOper->>Database : 导入脚本数据
TaskDataOper->>Database : 插入接地电阻
TaskDataOper->>FileSystem : 生成XML缓存
FileSystem-->>TaskDataOper : 文件创建成功
TaskDataOper->>Database : 提交事务
Database-->>TaskDataOper : 事务提交
TaskDataOper-->>Dialog : 返回任务ID
Dialog-->>User : 创建成功
```
**Diagram sources **
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L383-L447)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L148-L197)
**Section sources**
- [ProManager.cpp](file://cpp/Managers/ProManager.cpp#L383-L447)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L148-L197)
## 项目类型扩展技术路径
系统设计具有良好的可扩展性,开发者可以通过以下路径扩展项目类型和功能。
### 新增项目模板
要添加新的项目模板,需要执行以下步骤:
1. 在数据库的`medium`表中添加新的测量装置类型
2. 在相应的脚本表(`script1d``script2d``script3d`)中添加配套的测量脚本
3. 修改`QueryMediumInfo()`方法的查询逻辑,确保新模板能被正确检索
### 自定义参数字段
扩展自定义参数字段需要:
1. 修改数据库表结构,添加新的字段列
2. 更新`STXDTTaskParam`结构体,添加对应的成员变量
3. 在对话框资源文件中添加新的UI控件
4.`DoDataExchange()`方法中绑定新控件
5.`OnOK()`方法中添加参数验证逻辑
### 项目验证规则
自定义验证规则的实现方式:
1. 在对话框类中添加新的验证方法
2.`OnOK()`方法中调用验证方法
3. 使用`AfxMessageBox()``MessageBoxEx()`显示验证错误信息
4. 返回前阻止基类的`OnOK()`调用
### 扩展示例
以下是一个添加温度补偿参数的扩展示例:
```mermaid
classDiagram
class CDialNew2DTask {
+m_fTemperature float
+m_iCompensationMethod int
+AddTemperatureControls() void
+ValidateTemperature() bool
}
class ST2DTaskParam {
+fTemperature float
+iCompensationMethod int
}
CDialNew2DTask --> ST2DTaskParam : "包含"
```
开发者可以基于现有架构,通过类似的模式添加各种专业测量参数和验证规则,满足特定应用场景的需求。
**Section sources**
- [DialNew1DTask.cpp](file://cpp/Views/DialNew1DTask.cpp#L239-L365)
- [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L414-L664)
- [DialNew3DTask.cpp](file://cpp/Views/DialNew3DTask.cpp#L411-L568)
- [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L97-L200)