实现Creo模型关闭功能接口

- 添加关闭模型API端点 POST /api/model/close
- 支持安全关闭和强制关闭两种模式
- 实现修改状态检查防止数据丢失
- 添加详细的关闭结果反馈
- 完善的异常处理和错误信息

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root 2025-07-22 08:32:19 +08:00
parent 872a68d5be
commit aa66f3ddc0
4 changed files with 207 additions and 10 deletions

View File

@ -277,12 +277,52 @@ MFCCreoDll/
**API端点**
- `POST /api/creo/analysis/shell` - 薄壳化分析接口
#### 模块7: 关闭模型功能 (完成)
**功能:** 安全关闭当前Creo模型支持修改状态检查和强制关闭
**文件:** CreoManager.h, CreoManager.cpp, MFCCreoDll.cpp
**测试状态:** ✅ 开发完成,待编译测试
**API端点**
- `POST /api/model/close` - 关闭模型接口
**技术细节:**
- 使用OTK `pfcOutline3D` API进行真实几何包络盒计算
- 实现基于边界识别法的外壳特征白名单构建
- 支持零件和装配体的薄壳化分析
- 真实几何分析替代所有模拟数据和猜测逻辑
- 完善的置信度计算算法和特征安全性评估
- 使用OTK `pfcModel::Erase()` API执行模型关闭操作
- 使用 `pfcModel::GetIsModified()` 检查模型修改状态
- 支持安全关闭(检查修改)和强制关闭(忽略修改)两种模式
- 完善的异常处理和错误反馈机制
- 返回详细的关闭结果信息(模型名称、修改状态、关闭时间)
**API请求格式**
```json
{
"software_type": "creo",
"force_close": false
}
```
**API响应格式**
```json
{
"success": true,
"data": {
"model_name": "assembly.asm",
"was_modified": false,
"close_time": "2024-01-15T10:30:00Z"
},
"error": null
}
```
**已解决的技术问题:**
1. **OTK API正确性** - 使用正确的 `GetIsModified()` 方法检查模型修改状态
2. **安全关闭逻辑** - 实现修改状态检查,防止意外的数据丢失
3. **强制关闭选项** - 提供 `force_close` 参数允许忽略未保存修改
4. **详细错误信息** - 当模型有未保存修改时提供清晰的错误提示
5. **状态反馈完整性** - 返回关闭操作的完整状态信息
**关键技术突破:**
- 实现了安全的模型关闭机制,平衡了用户便利性和数据安全性
- 提供了灵活的关闭选项,适应不同的使用场景
- 建立了标准的模型生命周期管理API模式
**API请求格式**
```json
@ -341,7 +381,7 @@ MFCCreoDll/
### 🔄 待实现模块(按优先级排序)
#### 模块7: WebSocket服务 (高优先级)
#### 模块8: WebSocket服务 (高优先级)
**目标:** 实现双向实时通信,支持长时间操作
**预计文件:** WebSocketServer.h, WebSocketServer.cpp
**主要功能:**
@ -350,7 +390,7 @@ MFCCreoDll/
- 长操作进度反馈
- 客户端连接管理
#### 模块8: Creo长操作接口 (中优先级)
#### 模块9: Creo长操作接口 (中优先级)
**目标:** 实现模型加载、特征删除、多格式导出等操作
**预计文件:** ModelAnalyzer.h, ModelAnalyzer.cpp
**主要功能:**
@ -359,7 +399,7 @@ MFCCreoDll/
- 多格式导出STL、IGES等
- 操作进度监控
#### 模块9: 日志系统 (低优先级)
#### 模块10: 日志系统 (低优先级)
**目标:** 统一的日志记录和错误追踪
**预计文件:** Logger.h, Logger.cpp
**主要功能:**
@ -368,7 +408,7 @@ MFCCreoDll/
- 文件和控制台输出
- 调试信息记录
#### 模块10: 用户认证 (最低优先级)
#### 模块11: 用户认证 (最低优先级)
**目标:** 简单的用户识别和访问控制
**预计文件:** AuthManager.h, AuthManager.cpp
**主要功能:**
@ -387,6 +427,7 @@ Web前端 -> HTTP API (12345端口) -> MFC DLL -> OTK -> Creo
层级分析接口 -> HierarchyAnalysis -> 装配体结构分析
层级删除接口 -> HierarchyDelete -> 组件安全删除
薄壳化分析接口 -> ShellAnalysis -> 几何边界特征识别
关闭模型接口 -> CloseModel -> 安全模型关闭
```
**目标架构:**
@ -422,10 +463,14 @@ Web前端 -> HTTP API (快速查询) -> CreoManager -> Creo
13. **薄壳化分析算法** - 实现了基于真实几何边界的薄壳化特征识别
14. **假数据彻底清除** - 移除所有模拟计算实现纯OTK API的几何分析
15. **特征置信度算法** - 实现了标准的特征删除安全性评估机制
16. **模型关闭API设计** - 实现了安全的模型关闭机制,平衡用户便利性和数据安全性
17. **OTK模型状态检查** - 使用正确的`GetIsModified()`API检查模型修改状态
18. **强制关闭选项** - 提供灵活的关闭选项,适应不同使用场景
19. **模型生命周期管理** - 建立了标准的模型生命周期管理API模式
### 下一步计划
建议继续实现模块7WebSocket服务为后续长操作和实时通信奠定基础。核心分析功能层级分析、层级删除、薄壳化分析已经完成现在可以专注于实时通信和用户体验优化。
建议继续实现模块8WebSocket服务为后续长操作和实时通信奠定基础。核心分析功能层级分析、层级删除、薄壳化分析、模型关闭)已经完成,现在可以专注于实时通信和用户体验优化。
## 测试记录

View File

@ -136,6 +136,14 @@ ModelStatus CreoManager::GetModelStatus() {
status.file_size = "Exception getting file size";
}
// 检查模型是否已修改
try {
status.is_modified = current_model->GetIsModified();
}
catch (...) {
status.is_modified = false; // 默认值:未修改
}
// 获取真实的零件数量和装配体层级
if (status.is_assembly) {
try {
@ -655,6 +663,64 @@ SaveResult CreoManager::SaveModel() {
return result;
}
// 关闭模型功能实现
CloseResult CreoManager::CloseModel(bool force_close) {
CloseResult result;
SessionInfo sessionInfo = GetSessionInfo();
if (!sessionInfo.is_valid) {
result.error_message = "Creo session not available";
return result;
}
try {
pfcModel_ptr current_model = sessionInfo.session->GetCurrentModel();
if (!current_model) {
result.error_message = "No current model loaded";
return result;
}
// 获取模型信息
xstring model_name_xstr = current_model->GetFileName();
result.model_name = XStringToString(model_name_xstr);
// 检查模型是否已修改
result.was_modified = current_model->GetIsModified();
// 如果模型已修改且不是强制关闭,则需要处理
if (result.was_modified && !force_close) {
result.error_message = "Model has unsaved changes. Use force_close=true to close without saving.";
return result;
}
// 执行关闭操作
current_model->Erase();
// 设置成功结果
result.close_time = GetCurrentTimeStringISO();
result.success = true;
}
catch (const pfcXToolkitBadInputs&) {
result.error_message = "Bad input parameters";
}
catch (const pfcXToolkitGeneralError&) {
result.error_message = "Creo toolkit error";
}
catch (const pfcXToolkitInvalidName&) {
result.error_message = "Invalid model name";
}
catch (const std::exception& e) {
result.error_message = "Standard error: " + std::string(e.what());
}
catch (...) {
result.error_message = "Unknown error during close operation";
}
return result;
}
// 层级分析主方法
HierarchyAnalysisResult CreoManager::AnalyzeModelHierarchy(const HierarchyAnalysisRequest& request) {
HierarchyAnalysisResult result;

View File

@ -45,6 +45,7 @@ struct ModelStatus {
std::string file_size;
std::string connection_status;
std::string open_time;
bool is_modified = false; // 模型是否已修改(未保存)
};
// 导出结果结构
@ -71,6 +72,15 @@ struct SaveResult {
std::string error_message;
};
// 关闭结果结构
struct CloseResult {
bool success = false;
std::string model_name;
bool was_modified = false;
std::string close_time;
std::string error_message;
};
// 层级分析组件信息结构
struct ComponentInfo {
std::string id;
@ -136,6 +146,9 @@ public:
// 保存功能
SaveResult SaveModel();
// 关闭功能
CloseResult CloseModel(bool force_close = false);
// 层级分析功能
HierarchyAnalysisResult AnalyzeModelHierarchy(const HierarchyAnalysisRequest& request);

View File

@ -857,6 +857,78 @@ HttpResponse SaveModelHandler(const HttpRequest& request) {
return response;
}
// 关闭模型路由处理器
HttpResponse CloseModelHandler(const HttpRequest& request) {
HttpResponse response;
if (request.method != "POST") {
response.status_code = 405;
response.body = "{\"success\": false, \"error\": \"Method not allowed\"}";
return response;
}
try {
// 解析JSON请求参数
std::string software_type = ExtractJsonValue(request.body, "software_type");
std::string force_close_str = ExtractJsonValue(request.body, "force_close");
// 参数验证
if (software_type.empty()) {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Missing required parameter: software_type\"}";
return response;
}
if (software_type != "creo") {
response.status_code = 400;
response.body = "{\"success\": false, \"error\": \"Invalid software_type, must be 'creo'\"}";
return response;
}
// 解析force_close参数
bool force_close = (force_close_str == "true");
// 执行关闭操作
CloseResult result = CreoManager::Instance().CloseModel(force_close);
if (result.success) {
// 构建成功响应
std::ostringstream json;
json << "{"
<< "\"success\": true,"
<< "\"data\": {"
<< "\"model_name\": \"" << EscapeJsonString(result.model_name) << "\","
<< "\"was_modified\": " << (result.was_modified ? "true" : "false") << ","
<< "\"close_time\": \"" << EscapeJsonString(result.close_time) << "\""
<< "},"
<< "\"error\": null"
<< "}";
response.body = json.str();
} else {
// 构建错误响应
std::ostringstream json;
json << "{"
<< "\"success\": false,"
<< "\"data\": null,"
<< "\"error\": \"" << EscapeJsonString(result.error_message) << "\""
<< "}";
response.status_code = 500;
response.body = json.str();
}
} catch (const std::exception& e) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"JSON parsing error: " + std::string(e.what()) + "\"}";
} catch (...) {
response.status_code = 500;
response.body = "{\"success\": false, \"data\": null, \"error\": \"Unknown error during close operation\"}";
}
return response;
}
extern "C" int user_initialize(
int argc,
@ -886,6 +958,7 @@ extern "C" int user_initialize(
g_http_server->SetRouteHandler("/api/creo/hierarchy/delete", HierarchyDeleteHandler);
g_http_server->SetRouteHandler("/api/analysis/shell-analysis", ShellAnalysisHandler);
g_http_server->SetRouteHandler("/api/model/save", SaveModelHandler);
g_http_server->SetRouteHandler("/api/model/close", CloseModelHandler);
if (g_http_server->Start()) {