实现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:
parent
872a68d5be
commit
aa66f3ddc0
65
CLAUDE.md
65
CLAUDE.md
@ -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模式
|
||||
|
||||
### 下一步计划
|
||||
|
||||
建议继续实现模块7(WebSocket服务),为后续长操作和实时通信奠定基础。核心分析功能(层级分析、层级删除、薄壳化分析)已经完成,现在可以专注于实时通信和用户体验优化。
|
||||
建议继续实现模块8(WebSocket服务),为后续长操作和实时通信奠定基础。核心分析功能(层级分析、层级删除、薄壳化分析、模型关闭)已经完成,现在可以专注于实时通信和用户体验优化。
|
||||
|
||||
## 测试记录
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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()) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user