14 KiB
项目管理
**本文档引用的文件** - [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)目录
项目管理概述
Geomative Studio的项目管理模块是整个系统的核心组件,负责管理地质探测项目的全生命周期。该模块通过CProManager类实现,提供了项目创建、打开、配置和删除等核心功能。每个项目包含一个或多个测区(TZ),形成清晰的层级结构。项目数据存储在数据库中,并通过XML缓存文件在本地持久化,同时支持与设备的双向同步。本模块与设备管理器、脚本管理器等组件紧密集成,确保了数据的一致性和操作的协同性。
CProManager类架构与实现
CProManager类是项目管理的核心实现,负责协调项目和测区的创建、查询和删除操作。该类通过数据库连接管理项目数据,并与设备进行通信以实现数据同步。
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"
图表来源
本节来源
项目数据模型与持久化
项目数据模型包含多个关键字段,这些字段在数据库和XML缓存文件中保持一致。项目数据首先存储在数据库的project表中,然后通过XML文件在本地缓存。
项目数据模型字段
| 字段名 | 中文名称 | 数据类型 | 描述 |
|---|---|---|---|
| CN | 项目编号 | 字符串 | 项目的唯一标识符,使用GUID生成 |
| PRname | 项目名称 | 字符串 | 项目的名称,用户可读 |
| PRdesc | 项目描述 | 字符串 | 项目的详细描述信息 |
| location | 位置 | 字符串 | 项目实施的地理位置 |
| PRdate | 创建日期 | 日期 | 项目的创建日期 |
| duration | 持续时间 | 字符串 | 项目预计的持续时间 |
| PS | 项目负责人 | 字符串 | 项目的主要负责人 |
| CS | 客户名称 | 字符串 | 项目的客户或委托方 |
| PM | 项目经理 | 字符串 | 项目的管理负责人 |
| QAS | 质量保证 | 字符串 | 质量保证相关人员 |
| standard | 标准 | 字符串 | 项目遵循的技术标准 |
XML缓存持久化机制
项目数据通过XML文件在CACHE目录下持久化存储。系统使用CMarkup库创建和解析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\<项目编号>\目录下。这种持久化机制确保了即使在离线状态下,项目数据也能被访问和管理。
本节来源
项目与测区的层级关系
项目与测区之间存在明确的层级关系,一个项目可以包含多个测区,形成树状结构。这种设计符合地质探测的实际工作流程,允许用户在同一个项目下管理多个不同位置或类型的探测区域。
层级结构实现
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创建额外的测区来满足不同的探测需求。
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 : 返回创建结果
图表来源
本节来源
项目配置同步到设备流程
项目配置同步到设备是项目管理的关键功能,确保了现场设备与工作站的数据一致性。该流程涉及多个步骤,包括数据准备、文件传输和状态更新。
同步流程
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[同步完成]
同步流程的具体实现如下:
- 首先检查项目是否已存在于设备中,避免重复创建
- 从数据库读取项目配置信息
- 使用CMarkup库生成project.xml文件
- 创建本地缓存目录
CACHE\projects\<项目编号>\ - 调用设备的SendFile方法将文件传输到设备的/SD/projects/目录
- 如果传输成功,更新数据库中的同步状态;如果失败,执行回滚操作
此流程确保了数据同步的原子性和一致性,防止了部分同步导致的数据不一致问题。
图表来源
本节来源
项目管理API使用示例
项目管理模块提供了丰富的API,支持通过GUI界面和后台代码进行项目操作。以下是常见的使用示例。
GUI界面操作
通过GUI界面创建项目的流程:
- 用户点击"新建项目"按钮
- 系统弹出COpCreateProjectDlg对话框
- 用户填写项目信息(名称、描述、位置等)
- 系统验证项目名称的唯一性
- 调用CProManager::CreateProjectInDB方法在数据库中创建项目
// GUI创建项目的核心代码流程
COpCreateProjectDlg opCreateProDlg;
INT_PTR lRet = opCreateProDlg.DoModal();
if (IDOK == lRet) {
UINT uExecCode = theApp.m_pProManager->CreateProjectInDB(dwID);
if (APP_SUCCESS == uExecCode) {
// 更新UI显示
}
}
后台代码操作
通过后台代码创建和管理项目的示例:
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 : 返回结果
后台操作的关键特点是使用了数据库事务,确保了操作的原子性。如果任何步骤失败,整个事务将被回滚,保持数据的一致性。
图表来源
本节来源
与其他管理器的集成
项目管理器与设备管理器、脚本管理器等组件紧密集成,形成了完整的系统架构。这种集成确保了各模块之间的数据一致性和操作协同性。
与设备管理器的集成
项目管理器与设备管理器通过设备句柄和序列号进行通信。当需要将项目同步到设备时,项目管理器会调用设备管理器获取设备对象,然后执行文件传输操作。
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 : "依赖"
这种设计实现了关注点分离,项目管理器专注于项目数据的管理,而设备管理器负责设备的连接和通信。
与脚本管理器的集成
项目管理器与脚本管理器的集成主要体现在测区与脚本的关系上。每个测区可以关联多个探测脚本,这些脚本由脚本管理器管理。
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[脚本生命周期]
脚本管理器负责脚本的创建、编辑和删除,而项目管理器确保这些脚本与正确的测区关联。这种分工使得系统更加模块化,易于维护和扩展。
图表来源
本节来源
多项目环境下的资源管理
在多项目环境下,系统需要高效管理内存和文件资源,避免资源泄漏和性能下降。CProManager类通过链表和句柄机制实现了高效的资源管理。
内存管理策略
CProManager使用CLinkList模板类管理所有项目和测区对象。每个对象通过唯一句柄访问,实现了对象的延迟加载和缓存机制。
// 对象获取的伪代码
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;
}
这种策略的优点:
- 延迟加载:只有在需要时才从数据库加载数据,减少启动时间和内存占用
- 对象缓存:重复访问同一对象时直接从缓存获取,提高性能
- 内存控制:通过链表管理对象生命周期,避免内存泄漏
资源清理机制
系统在析构时会清理所有管理的对象:
CProManager::~CProManager() {
int iDMSIndex = 0;
while (NULL != m_dmsLinkList.Find(iDMSIndex)) {
delete m_dmsLinkList.Find(iDMSIndex);
iDMSIndex++;
}
m_dmsLinkList.DeleteAll();
}
此外,系统还提供了DeleteObjInMem方法,允许在运行时显式删除不再需要的对象,进一步优化内存使用。
本节来源