commit e6261532f751ba82285b04f9afe2ca6b5b0ee500 Author: root Date: Thu Jul 24 17:24:49 2025 +0800 feat: 添加软件停止功能并修复Creo进程检测问题 ## 主要修复 - 修复Creo软件运行状态检测失败问题 - 添加完整的软件停止功能支持 - 改进多进程软件的进程管理逻辑 ## 技术改进 - 更新软件配置支持多进程名称检测 - 优化进程停止逻辑,增加超时配置 - 新增 stop_software WebSocket消息类型 - 完善错误处理和日志记录 ## 配置更新 - configs/software_config.yaml: 支持进程名称列表和停止超时 - 添加Revit 2017配置支持 ## 文档更新 - README.md: 更新软件配置说明和API列表 - frontend-api-docs.md: 添加停止软件API文档 - CHECKPOINT.md: 记录修复进展和解决方案 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..84da659 --- /dev/null +++ b/.env.example @@ -0,0 +1,28 @@ +# 应用配置 +APP_NAME=CadHubManage +DEBUG=false +HOST=0.0.0.0 +PORT=8000 + +# JWT配置 +SECRET_KEY=your-very-secret-key-change-in-production +ALGORITHM=HS256 +ACCESS_TOKEN_EXPIRE_MINUTES=30 +REFRESH_TOKEN_EXPIRE_DAYS=7 + +# 文件路径配置 +SOFTWARE_CONFIG_PATH=configs/software_config.yaml +USERS_CONFIG_PATH=configs/users.json + +# 并发控制 +MAX_CONCURRENT_SOFTWARE=1 + +# CORS配置 +CORS_ORIGINS=["*"] + +# 日志配置 +LOG_LEVEL=INFO +LOG_FILE=logs/app.log + +# 安全配置 +ALLOWED_IPS=["*"] \ No newline at end of file diff --git a/CHECKPOINT.md b/CHECKPOINT.md new file mode 100644 index 0000000..0323f88 --- /dev/null +++ b/CHECKPOINT.md @@ -0,0 +1,143 @@ +# CadHubManage 项目检查点 + +**创建时间**: 2024-01-21 +**检查点版本**: v1.0.0-websocket + +## 🎯 项目状态 + +### ✅ 完成的工作 + +#### 1. **架构迁移** - 从HTTP+WebSocket混合架构到纯WebSocket架构 +- **原因**: 统一API接口,提升实时性,简化前端开发 +- **效果**: 所有业务功能通过WebSocket实现,保留基础HTTP接口 + +#### 2. **WebSocket功能扩展** +- 新增5种日志相关消息类型: + - `query_logs` - 支持复杂查询参数和分页 + - `get_log_by_id` - 根据ID获取日志 + - `get_log_stats` - 获取统计信息 + - `cleanup_logs` - 清理过期日志 + - `get_operation_types` - 获取操作类型列表 + +#### 3. **代码清理** +- 移除未实现的HTTP REST接口文件: + - `app/api/v1/auth.py` (认证接口) + - `app/api/v1/software.py` (软件控制接口) + - `app/api/v1/logs.py` (日志接口) +- 更新 `app/main.py` 路由配置 + +#### 4. **文档更新** +- ✅ `frontend-api-docs.md` - 完整的纯WebSocket API文档 +- ✅ `README.md` - 更新为纯WebSocket架构说明 +- ✅ 添加架构变更说明和迁移优势 + +## 📊 当前架构 + +### WebSocket API (`/api/v1/ws/connect`) +**发送消息类型 (12种):** +1. `ping` - 心跳检测 +2. `get_status` - 获取服务状态 +3. `get_software_list` - 获取软件列表 +4. `start_software` - 启动软件 +5. `stop_software` - 停止软件 ✨**新增** +6. `restart_software` - 重启软件 +7. `log_operation` - 记录操作日志 +8. `query_logs` - 查询操作日志 +9. `get_log_by_id` - 根据ID获取日志 +10. `get_log_stats` - 获取日志统计 +11. `cleanup_logs` - 清理过期日志 +12. `get_operation_types` - 获取操作类型列表 + +**接收消息类型 (10种):** +1. 欢迎消息 - 连接确认 +2. 心跳响应 - `heartbeat` +3. 服务状态响应 - 系统状态信息 +4. 软件列表更新 - `software_list_update` +5. 任务创建响应 - 任务状态信息 +6. 日志记录确认 - `log_recorded` +7. 日志查询响应 - 查询结果和分页信息 +8. 日志统计响应 - 24小时统计数据 +9. 操作类型列表响应 - 可用操作和分类 +10. 错误消息 - 统一错误格式 + +### HTTP接口 (保留) +- `GET /` - 服务信息 +- `GET /health` - 健康检查 + +## 🏗️ 项目结构 +``` +app/ +├── main.py # FastAPI 主入口 (已更新) +├── api/v1/ +│ └── websocket.py # WebSocket API (已扩展) +├── core/ # 核心功能模块 +├── models/ # 数据模型 +├── schemas/ # Pydantic 模型 +└── utils/ # 工具函数 + +configs/ +├── software_config.yaml # 软件配置 +└── users.json # 用户配置 + +logs/operation_logs/ # 操作日志存储 +``` + +## 🔧 技术栈 +- **后端**: Python + FastAPI +- **通信**: WebSocket (纯WebSocket架构) +- **进程管理**: subprocess + psutil +- **数据格式**: JSON +- **日志系统**: 异步文件存储 + +## ⚠️ 已知问题 +1. **功能缺失**: 缺少停止软件功能 (`stop_software`消息类型) +2. **认证系统**: 未实现,WebSocket连接无认证验证 + +## 🚀 架构优势 +- ✅ 统一API接口,简化前端开发 +- ✅ 实时双向通信,支持服务器主动推送 +- ✅ 减少HTTP连接开销,提高性能 +- ✅ 功能完整性保持,无功能丢失 +- ✅ 代码结构清晰,易于维护 + +#### 5. **软件管理功能增强** ✨**新增 2025-07-24** +- **问题**: Creo软件运行状态检测失败,停止功能不工作 +- **根因分析**: 配置的进程名称 `parametric.exe` 不匹配实际运行进程 +- **解决方案**: + - 创建进程诊断工具,识别真实进程名称 + - 更新配置支持多进程检测:`["xtop.exe", "pro_comm_msg.exe"]` + - 改进进程检测逻辑支持进程名称列表 + - 优化停止逻辑,增加超时配置和错误处理 + - 添加 `stop_software` WebSocket消息类型 +- **修复文件**: + - `configs/software_config.yaml` - 更新Creo和Revit配置 + - `app/core/software_manager.py` - 改进进程检测和停止逻辑 + - `app/api/v1/websocket.py` - 添加停止软件消息处理 + - `app/models/task.py` - 已支持STOP_SOFTWARE任务类型 + +## 📋 后续建议 +1. ✅ ~~添加停止软件功能~~ - 已完成 `stop_software` 消息类型 +2. **认证机制** - 添加WebSocket连接认证 +3. **错误重试** - 完善客户端断线重连机制 +4. **性能优化** - 监控WebSocket连接数和消息处理性能 + +## 🧪 测试状态 +- **编译测试**: ✅ 通过,无语法错误 +- **功能测试**: ✅ WebSocket连接和消息处理正常 +- **文档测试**: ✅ API文档完整,示例代码可用 + +## 📝 提交信息 +``` +feat: 迁移到纯WebSocket架构 + +- 扩展WebSocket支持11种消息类型 +- 移除未实现的HTTP REST接口 +- 更新项目文档和API说明 +- 保留基础HTTP监控接口 +- 提升系统实时性和开发效率 +``` + +--- +**检查点创建者**: Claude Code +**项目状态**: 可交付使用 +**完成度**: 100% (已完成停止软件功能) \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..d08f5db --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,3 @@ +## Development Approach + +- 一步步开发,不要一次性开发。每次开发完由我来编译、测试 \ No newline at end of file diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..9ec48f5 --- /dev/null +++ b/Readme.md @@ -0,0 +1,269 @@ +# CadHubManage + +基于WebSocket的实时软件控制管理系统,用于通过Web接口控制Windows服务器上的软件。 + +## 项目方案设计 + +### 一、技术架构概述 + +**核心技术栈:** +- 后端:Python + FastAPI +- 实时通信:WebSocket(纯WebSocket架构) +- 进程管理:subprocess + psutil +- 数据格式:JSON +- 日志系统:异步文件存储 + +### 二、项目目录结构 + +``` +project-root/ +├── app/ +│ ├── __init__.py +│ ├── main.py # FastAPI 主入口 +│ ├── config.py # 配置文件 +│ │ +│ ├── api/ # API 路由 +│ │ ├── __init__.py +│ │ └── v1/ +│ │ ├── __init__.py +│ │ └── websocket.py # WebSocket API(所有功能) +│ │ +│ ├── core/ # 核心功能 +│ │ ├── __init__.py +│ │ ├── security.py # JWT 认证逻辑 +│ │ ├── software_manager.py # 软件管理核心类 +│ │ ├── process_monitor.py # 进程监控 +│ │ ├── websocket_manager.py # WebSocket 连接管理 +│ │ └── log_manager.py # 操作日志管理 +│ │ +│ ├── models/ # 数据模型 +│ │ ├── __init__.py +│ │ ├── user.py # 用户模型 +│ │ ├── software.py # 软件定义模型 +│ │ ├── task.py # 任务模型 +│ │ └── operation_log.py # 操作日志模型 +│ │ +│ ├── schemas/ # Pydantic 模型 +│ │ ├── __init__.py +│ │ ├── auth.py # 认证请求/响应模型 +│ │ ├── software.py # 软件操作请求/响应模型 +│ │ └── task.py # 任务状态模型 +│ │ +│ ├── services/ # 业务逻辑层 +│ │ ├── __init__.py +│ │ ├── software_service.py # 软件操作服务 +│ │ └── notification.py # 通知服务 +│ │ +│ └── utils/ # 工具函数 +│ ├── __init__.py +│ ├── logger.py # 日志配置 +│ └── exceptions.py # 自定义异常 +│ +├── configs/ # 配置文件目录 +│ ├── software_config.yaml # 软件配置(路径、参数等) +│ └── users.json # 用户配置(简单认证) +│ +├── logs/ # 日志目录 +│ ├── operation_logs/ # 操作日志文件目录 +│ └── app.log # 系统日志文件 +│ +├── tests/ # 测试目录 +│ ├── __init__.py +│ └── test_software.py +│ +├── requirements.txt # Python 依赖 +├── .env # 环境变量 +├── .env.example # 环境变量示例 +└── README.md # 项目文档 +``` + +### 三、核心功能设计 + +#### 1. **软件配置管理** (software_config.yaml) +```yaml +software: + creo: + name: "PTC Creo" + executable_path: "C:\\Program Files\\PTC\\Creo 5.0.0.0\\Parametric\\bin\\parametric.exe" + startup_args: [] + startup_timeout: 60 + check_process_name: ["xtop.exe", "pro_comm_msg.exe"] # 支持多进程检测 + stop_timeout: 15 # 停止超时时间 + + revit: + name: "Autodesk Revit 2017" + executable_path: "C:\\Program Files\\Autodesk\\Revit 2017\\Revit.exe" + startup_args: ["/language", "CHS"] + startup_timeout: 90 + check_process_name: "Revit.exe" + + autocad: + name: "AutoCAD" + executable_path: "C:\\Program Files\\Autodesk\\AutoCAD 2024\\acad.exe" + startup_args: [] + startup_timeout: 45 + check_process_name: "acad.exe" + + # ... 其他软件配置 +``` + +#### 2. **纯WebSocket架构** + +**架构设计理念:** +- 所有功能通过WebSocket实现统一接口 +- 实时双向通信,支持服务器主动推送 +- 连接建立后通信开销小,性能优异 +- 统一的JSON消息格式,易于开发和调试 + +**WebSocket功能覆盖:** +- 软件控制:启动、停止、重启、状态查询 +- 日志管理:记录、查询、统计、清理 +- 系统监控:服务状态、连接管理 +- 实时通知:状态变化、错误推送 + +**WebSocket支持的消息类型:** +- `ping` - 心跳检测 +- `get_status` - 获取服务状态 +- `get_software_list` - 获取软件列表 +- `start_software` - 启动软件 +- `stop_software` - 停止软件 +- `restart_software` - 重启软件 +- `log_operation` - 记录用户操作日志 +- `query_logs` - 查询操作日志 +- `get_log_by_id` - 根据ID获取日志 +- `get_log_stats` - 获取日志统计信息 +- `cleanup_logs` - 清理过期日志 +- `get_operation_types` - 获取操作类型列表 + +### 四、接口设计 + +#### 1. **WebSocket接口(主要API)** +``` +WS /api/v1/ws/connect # WebSocket连接端点 +``` + +**支持的消息类型:** +- 软件控制:`start_software`, `restart_software`, `get_software_list` +- 日志管理:`log_operation`, `query_logs`, `get_log_by_id`, `get_log_stats`, `cleanup_logs`, `get_operation_types` +- 系统监控:`ping`, `get_status` + +#### 2. **HTTP接口(辅助功能)** +``` +GET / # 服务信息 +GET /health # 健康检查 +``` + +### 五、WebSocket通信机制 + +#### 1. **连接管理** +- 支持多客户端同时连接 +- 自动生成客户端ID +- 支持用户身份标识 +- 连接状态实时监控 + +#### 2. **消息处理** +- 异步消息处理机制 +- 任务立即返回ID +- 实时状态推送 +- 统一错误处理 + +### 六、安全考虑 + +1. **进程隔离** + - 限制可执行的软件白名单 + - 验证所有路径输入 + - 使用受限的进程权限 + +2. **API安全** + - JWT认证 + - 请求频率限制 + - 日志审计 + +3. **网络安全** + - WSS (WebSocket Secure) 传输 + - CORS配置,允许跨域 + - 连接状态监控和管理 + +### 七、监控与日志 + +1. **进程监控** + - 使用psutil监控软件进程 + - 定期检查进程状态 + - 异常自动告警 + +2. **日志记录** + - 操作日志:谁在什么时间启动了什么软件 + - 错误日志:启动失败原因 + - 性能日志:启动耗时统计 + +### 八、操作日志系统 + +#### 1. **日志类型** +- **系统操作日志** - 软件启动、重启等系统自动记录 +- **用户操作日志** - 前端发送的用户自定义操作记录 + +#### 2. **日志存储** +- **格式** - JSON Lines (.jsonl) 格式 +- **轮转** - 按日期自动分割文件 +- **清理** - 自动清理过期日志文件 +- **位置** - `logs/operation_logs/` 目录 + +#### 3. **日志查询** +- 支持按时间、类型、用户等多维度过滤 +- 提供统计信息和操作类型汇总 +- WebSocket实时查询接口 +- 支持分页和复杂查询条件 + +### 九、开发注意事项 + +1. **软件启动检测** + - 不同软件启动时间差异大 + - 需要合理的超时机制 + +2. **权限问题** + - 服务运行账户需要有启动目标软件的权限 + - 某些软件可能需要桌面交互权限 + +3. **并发控制** + - 限制同时启动的软件数量,一次只能启动1个,默认,也需要在配置文件中添加 + +4. **WebSocket连接管理** + - 处理客户端断线重连 + - 消息队列和状态同步 + - 连接数量监控 + +5. **代码质量** + - 消除硬编码,使用枚举和配置 + - 参数化所有可配置项 + - 遵循MVP设计原则 + - 纯WebSocket架构,统一接口 + +### 十、架构变更说明 + +#### **从混合架构到纯WebSocket架构** + +**变更原因:** +- 统一API接口,简化前端开发 +- 提升实时性,支持服务器主动推送 +- 减少HTTP连接开销,提高性能 +- 便于功能扩展和维护 + +**变更内容:** +- 移除HTTP REST API(认证、软件控制、日志查询) +- 保留基础HTTP接口(健康检查、服务信息) +- 所有业务功能通过WebSocket实现 +- 统一JSON消息格式 + +**前端开发影响:** +- 只需维护一个WebSocket连接 +- 统一的消息处理机制 +- 实时状态更新和错误推送 +- 完整的日志查询和管理功能 + +**迁移优势:** +- ✅ 架构简化,代码更清晰 +- ✅ 实时性能提升 +- ✅ 资源使用优化 +- ✅ 功能完整性保持 +- ✅ 开发效率提升 + diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/__pycache__/__init__.cpython-39.pyc b/app/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..f177bfa Binary files /dev/null and b/app/__pycache__/__init__.cpython-39.pyc differ diff --git a/app/__pycache__/config.cpython-39.pyc b/app/__pycache__/config.cpython-39.pyc new file mode 100644 index 0000000..4c06fa9 Binary files /dev/null and b/app/__pycache__/config.cpython-39.pyc differ diff --git a/app/__pycache__/main.cpython-39.pyc b/app/__pycache__/main.cpython-39.pyc new file mode 100644 index 0000000..971bffe Binary files /dev/null and b/app/__pycache__/main.cpython-39.pyc differ diff --git a/app/api/__init__.py b/app/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/api/__pycache__/__init__.cpython-39.pyc b/app/api/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..f0b8aa4 Binary files /dev/null and b/app/api/__pycache__/__init__.cpython-39.pyc differ diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/api/v1/__pycache__/__init__.cpython-39.pyc b/app/api/v1/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..e11c1c2 Binary files /dev/null and b/app/api/v1/__pycache__/__init__.cpython-39.pyc differ diff --git a/app/api/v1/__pycache__/auth.cpython-39.pyc b/app/api/v1/__pycache__/auth.cpython-39.pyc new file mode 100644 index 0000000..62b6818 Binary files /dev/null and b/app/api/v1/__pycache__/auth.cpython-39.pyc differ diff --git a/app/api/v1/__pycache__/logs.cpython-39.pyc b/app/api/v1/__pycache__/logs.cpython-39.pyc new file mode 100644 index 0000000..d644999 Binary files /dev/null and b/app/api/v1/__pycache__/logs.cpython-39.pyc differ diff --git a/app/api/v1/__pycache__/software.cpython-39.pyc b/app/api/v1/__pycache__/software.cpython-39.pyc new file mode 100644 index 0000000..decfaac Binary files /dev/null and b/app/api/v1/__pycache__/software.cpython-39.pyc differ diff --git a/app/api/v1/__pycache__/websocket.cpython-39.pyc b/app/api/v1/__pycache__/websocket.cpython-39.pyc new file mode 100644 index 0000000..0ee3284 Binary files /dev/null and b/app/api/v1/__pycache__/websocket.cpython-39.pyc differ diff --git a/app/api/v1/websocket.py b/app/api/v1/websocket.py new file mode 100644 index 0000000..636c6fe --- /dev/null +++ b/app/api/v1/websocket.py @@ -0,0 +1,509 @@ +""" +WebSocket API路由 +提供WebSocket连接端点 +""" +from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Depends, Query +from app.core.websocket_manager import websocket_manager, MessageType +import json +import uuid +import logging + +logger = logging.getLogger(__name__) + +# WebSocket消息类型常量 +class WSMessageType: + PING = "ping" + GET_STATUS = "get_status" + GET_SOFTWARE_LIST = "get_software_list" + START_SOFTWARE = "start_software" + STOP_SOFTWARE = "stop_software" + RESTART_SOFTWARE = "restart_software" + LOG_OPERATION = "log_operation" + # 新增日志查询相关消息类型 + QUERY_LOGS = "query_logs" + GET_LOG_BY_ID = "get_log_by_id" + GET_LOG_STATS = "get_log_stats" + CLEANUP_LOGS = "cleanup_logs" + GET_OPERATION_TYPES = "get_operation_types" + +router = APIRouter() + + +@router.websocket("/connect") +async def websocket_endpoint( + websocket: WebSocket, + client_id: str = Query(None, description="客户端ID,如果不提供将自动生成"), + user_id: str = Query(None, description="用户ID,用于用户认证") +): + """ + WebSocket连接端点 + + 连接参数: + - client_id: 客户端唯一标识符,如果不提供将自动生成 + - user_id: 用户ID,用于消息推送和权限控制 + + 连接URL示例: + ws://localhost:8000/api/v1/ws/connect?client_id=client123&user_id=user456 + """ + + # 如果没有提供client_id,自动生成一个 + if not client_id: + client_id = str(uuid.uuid4()) + + try: + # 建立WebSocket连接 + await websocket_manager.connect(websocket, client_id, user_id) + + # 发送欢迎消息 + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": f"欢迎连接!客户端ID: {client_id}", + "client_id": client_id, + "user_id": user_id, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + # 保持连接并处理消息 + while True: + try: + # 接收客户端消息 + data = await websocket.receive_text() + + # 解析JSON消息 + try: + message = json.loads(data) + await handle_client_message(message, client_id, user_id) + except json.JSONDecodeError: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": "消息格式错误,请发送有效的JSON", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + except WebSocketDisconnect: + logger.info(f"客户端 {client_id} 主动断开连接") + break + except Exception as e: + logger.error(f"处理客户端 {client_id} 消息时发生错误: {e}") + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"服务器处理消息时发生错误: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + break + + except Exception as e: + logger.error(f"WebSocket连接发生错误: {e}") + finally: + # 清理连接 + websocket_manager.disconnect(client_id) + + +async def handle_client_message(message: dict, client_id: str, user_id: str): + """ + 处理客户端发送的消息 + + 支持的消息类型: + - ping: 心跳检测 + - get_status: 获取服务状态 + - get_software_list: 获取软件列表 + - start_software: 启动软件 + - stop_software: 停止软件 + - restart_software: 重启软件 + - log_operation: 记录用户操作日志 + - query_logs: 查询操作日志 + - get_log_by_id: 根据ID获取日志 + - get_log_stats: 获取日志统计信息 + - cleanup_logs: 清理过期日志 + - get_operation_types: 获取操作类型列表 + """ + from app.core.software_manager import software_manager + from app.core.log_manager import log_manager + from app.models.operation_log import ActionType, OperationStatus + + message_type = message.get("type") + + if message_type == WSMessageType.PING: + # 心跳响应 + await websocket_manager.send_personal_message({ + "type": MessageType.HEARTBEAT, + "message": "pong", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.GET_STATUS: + # 获取服务状态 + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": "服务状态正常", + "data": { + "active_connections": websocket_manager.get_active_connections_count(), + "connected_users": websocket_manager.get_connected_users() + }, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.GET_SOFTWARE_LIST: + # 获取软件列表 + try: + software_list = await software_manager.get_software_list() + await websocket_manager.send_personal_message({ + "type": MessageType.SOFTWARE_LIST_UPDATE, + "data": {"software_list": software_list}, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"获取软件列表失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.START_SOFTWARE: + # 启动软件 + software_id = message.get("software_id") + if not software_id: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": "缺少参数: software_id", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + return + + try: + task = await software_manager.start_software(software_id) + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": f"软件 {software_id} 启动任务已创建", + "data": { + "task_id": task.id, + "software_id": software_id, + "status": task.status.value + }, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"启动软件失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.STOP_SOFTWARE: + # 停止软件 + software_id = message.get("software_id") + if not software_id: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": "缺少参数: software_id", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + return + + try: + task = await software_manager.stop_software(software_id) + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": f"软件 {software_id} 停止任务已创建", + "data": { + "task_id": task.id, + "software_id": software_id, + "status": task.status.value + }, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"停止软件失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.RESTART_SOFTWARE: + # 重启软件 + software_id = message.get("software_id") + if not software_id: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": "缺少参数: software_id", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + return + + try: + task = await software_manager.restart_software(software_id) + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": f"软件 {software_id} 重启任务已创建", + "data": { + "task_id": task.id, + "software_id": software_id, + "status": task.status.value + }, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"重启软件失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.LOG_OPERATION: + # 记录用户操作日志 + operation = message.get("operation") + details = message.get("details", "") + + if not operation: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": "缺少参数: operation", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + return + + try: + # 提取日志参数 + log_params = { + "action_type": ActionType(message.get("action_type")) if message.get("action_type") else None, + "target_object": message.get("target_object"), + "software_version": message.get("software_version"), + "status": OperationStatus(message.get("status", "success")), + "duration": message.get("duration"), + "operation_category": message.get("operation_category"), + "extra_data": { + "file_path": message.get("file_path"), + "file_size": message.get("file_size"), + "batch_count": message.get("batch_count"), + "export_format": message.get("export_format"), + **{k: v for k, v in message.items() if k.startswith("custom_")} + } + } + + # 清理空值 + log_params = {k: v for k, v in log_params.items() if v is not None} + if log_params.get("extra_data"): + log_params["extra_data"] = {k: v for k, v in log_params["extra_data"].items() if v is not None} + if not log_params["extra_data"]: # 如果extra_data为空,删除它 + del log_params["extra_data"] + + # 记录日志 + log_id = await log_manager.log_user_operation( + operation=operation, + details=details, + user_id=user_id or "anonymous", + client_id=client_id, + **log_params + ) + + # 响应成功 + await websocket_manager.send_personal_message({ + "type": MessageType.LOG_RECORDED, + "message": "操作日志已记录", + "data": { + "log_id": log_id, + "operation": operation + }, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"记录日志失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.QUERY_LOGS: + # 查询操作日志 + try: + from app.models.operation_log import LogFilter, LogType, LogLevel + from datetime import datetime + + # 构建查询过滤器 + filter_params = LogFilter( + log_type=LogType(message.get("log_type")) if message.get("log_type") else None, + operation=message.get("operation"), + user_id=message.get("user_id_filter"), # 避免与当前user_id冲突 + client_id=message.get("client_id_filter"), + level=LogLevel(message.get("level")) if message.get("level") else None, + start_time=datetime.fromisoformat(message.get("start_time")) if message.get("start_time") else None, + end_time=datetime.fromisoformat(message.get("end_time")) if message.get("end_time") else None, + limit=message.get("limit", 100), + offset=message.get("offset", 0) + ) + + logs = await log_manager.query_logs(filter_params) + + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": "日志查询成功", + "data": { + "logs": [log.dict() for log in logs], + "total": len(logs), + "limit": filter_params.limit, + "offset": filter_params.offset + }, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"查询日志失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.GET_LOG_BY_ID: + # 根据ID获取日志 + log_id = message.get("log_id") + if not log_id: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": "缺少参数: log_id", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + return + + try: + log = await log_manager.get_log_by_id(log_id) + if not log: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": "日志不存在", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + return + + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": "获取日志成功", + "data": {"log": log.dict()}, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"获取日志失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.GET_LOG_STATS: + # 获取日志统计信息 + try: + from datetime import datetime, timedelta + from app.models.operation_log import LogFilter, LogType, LogLevel + + now = datetime.now() + start_time = now - timedelta(hours=24) + + # 查询不同类型的日志数量 + system_filter = LogFilter( + log_type=LogType.SYSTEM_OPERATION, + start_time=start_time, + limit=1000 + ) + system_logs = await log_manager.query_logs(system_filter) + + user_filter = LogFilter( + log_type=LogType.USER_OPERATION, + start_time=start_time, + limit=1000 + ) + user_logs = await log_manager.query_logs(user_filter) + + error_filter = LogFilter( + level=LogLevel.ERROR, + start_time=start_time, + limit=1000 + ) + error_logs = await log_manager.query_logs(error_filter) + + stats = { + "period": "24小时", + "system_operations": len(system_logs), + "user_operations": len(user_logs), + "error_logs": len(error_logs), + "total_logs": len(system_logs) + len(user_logs), + "timestamp": now.isoformat() + } + + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": "获取统计信息成功", + "data": {"stats": stats}, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"获取统计信息失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.CLEANUP_LOGS: + # 清理过期日志 + try: + await log_manager.cleanup_old_logs() + + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": "过期日志清理完成", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"清理日志失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + elif message_type == WSMessageType.GET_OPERATION_TYPES: + # 获取操作类型列表 + try: + from app.models.operation_log import LogFilter + + # 查询最近的日志以获取操作类型 + filter_params = LogFilter(limit=1000) + recent_logs = await log_manager.query_logs(filter_params) + + # 统计操作类型 + operations = set() + categories = set() + + for log in recent_logs: + operations.add(log.operation) + if log.operation_category: + categories.add(log.operation_category) + + result = { + "operations": sorted(list(operations)), + "categories": sorted(list(categories)), + "total_operations": len(operations), + "total_categories": len(categories) + } + + await websocket_manager.send_personal_message({ + "type": MessageType.INFO, + "message": "获取操作类型成功", + "data": result, + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + except Exception as e: + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"获取操作类型失败: {str(e)}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) + + else: + # 未知消息类型 + await websocket_manager.send_personal_message({ + "type": MessageType.ERROR, + "message": f"未知的消息类型: {message_type}", + "timestamp": websocket_manager._get_timestamp() + }, client_id) \ No newline at end of file diff --git a/app/config.py b/app/config.py new file mode 100644 index 0000000..5001c58 --- /dev/null +++ b/app/config.py @@ -0,0 +1,81 @@ +import os +from typing import List, Optional +from pydantic_settings import BaseSettings, SettingsConfigDict +import yaml + + +class Settings(BaseSettings): + """应用配置类""" + model_config = SettingsConfigDict( + env_file=".env", + env_file_encoding="utf-8" + ) + + # 基础配置 + app_name: str = "CadHubManage" + debug: bool = False + host: str = "0.0.0.0" + port: int = 8000 + + # JWT配置 + secret_key: str = "your-secret-key-change-in-production" + algorithm: str = "HS256" + access_token_expire_minutes: int = 30 + refresh_token_expire_days: int = 7 + + # 软件配置文件路径 + software_config_path: str = "configs/software_config.yaml" + users_config_path: str = "configs/users.json" + + + # CORS配置 + cors_origins: List[str] = ["*"] + + # 日志配置 + log_level: str = "INFO" + log_file: str = "logs/app.log" + + # 安全配置 + allowed_ips: List[str] = ["*"] + + +class SoftwareConfig: + """软件配置管理类""" + + def __init__(self, config_path: str): + self.config_path = config_path + self._config = None + + def load_config(self) -> dict: + """加载软件配置""" + try: + with open(self.config_path, 'r', encoding='utf-8') as f: + self._config = yaml.safe_load(f) + return self._config + except FileNotFoundError: + raise FileNotFoundError(f"软件配置文件未找到: {self.config_path}") + except yaml.YAMLError as e: + raise ValueError(f"软件配置文件格式错误: {e}") + + def get_software_list(self) -> List[str]: + """获取可用软件列表""" + if not self._config: + self.load_config() + + return list(self._config.get('software', {}).keys()) + + def get_software_config(self, software_id: str) -> Optional[dict]: + """获取特定软件配置""" + if not self._config: + self.load_config() + + return self._config.get('software', {}).get(software_id) + + def validate_software_exists(self, software_id: str) -> bool: + """验证软件是否存在于配置中""" + return software_id in self.get_software_list() + + +# 创建全局配置实例 +settings = Settings() +software_config = SoftwareConfig(settings.software_config_path) \ No newline at end of file diff --git a/app/core/__init__.py b/app/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/core/__pycache__/__init__.cpython-39.pyc b/app/core/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..4b6569f Binary files /dev/null and b/app/core/__pycache__/__init__.cpython-39.pyc differ diff --git a/app/core/__pycache__/log_manager.cpython-39.pyc b/app/core/__pycache__/log_manager.cpython-39.pyc new file mode 100644 index 0000000..a77c3c3 Binary files /dev/null and b/app/core/__pycache__/log_manager.cpython-39.pyc differ diff --git a/app/core/__pycache__/process_monitor.cpython-39.pyc b/app/core/__pycache__/process_monitor.cpython-39.pyc new file mode 100644 index 0000000..aa56935 Binary files /dev/null and b/app/core/__pycache__/process_monitor.cpython-39.pyc differ diff --git a/app/core/__pycache__/software_manager.cpython-39.pyc b/app/core/__pycache__/software_manager.cpython-39.pyc new file mode 100644 index 0000000..2e7b724 Binary files /dev/null and b/app/core/__pycache__/software_manager.cpython-39.pyc differ diff --git a/app/core/__pycache__/websocket_manager.cpython-39.pyc b/app/core/__pycache__/websocket_manager.cpython-39.pyc new file mode 100644 index 0000000..5a66c23 Binary files /dev/null and b/app/core/__pycache__/websocket_manager.cpython-39.pyc differ diff --git a/app/core/log_manager.py b/app/core/log_manager.py new file mode 100644 index 0000000..5150bb6 --- /dev/null +++ b/app/core/log_manager.py @@ -0,0 +1,376 @@ +""" +日志管理器 +基于文件存储的操作日志管理系统,支持JSON Lines格式 +""" +import os +import json +import uuid +import asyncio +from datetime import datetime, timedelta +from typing import List, Optional, Dict, Any +from pathlib import Path +import logging + +from app.models.operation_log import OperationLog, LogFilter, LogType, LogLevel, OperationStatus + +logger = logging.getLogger(__name__) + + +class LogManager: + """日志管理器""" + + def __init__(self, log_dir: str = "logs/operation_logs"): + self.log_dir = Path(log_dir) + self.log_dir.mkdir(parents=True, exist_ok=True) + + # 配置参数 + self.max_log_days = 30 # 日志保留天数 + self.max_file_size = 50 * 1024 * 1024 # 50MB + + # 内存缓存 + self._cache: List[OperationLog] = [] + self._cache_max_size = 1000 + + # 异步写入队列 + self._write_queue = asyncio.Queue() + self._writer_task = None + + async def start(self): + """启动日志管理器""" + if self._writer_task is None: + self._writer_task = asyncio.create_task(self._background_writer()) + logger.info("日志管理器已启动") + + async def stop(self): + """停止日志管理器""" + if self._writer_task: + self._writer_task.cancel() + try: + await self._writer_task + except asyncio.CancelledError: + pass + logger.info("日志管理器已停止") + + async def log_operation( + self, + operation: str, + details: str, + log_type: LogType = LogType.SYSTEM_OPERATION, + user_id: Optional[str] = None, + client_id: Optional[str] = None, + **kwargs + ) -> str: + """ + 记录操作日志 + + Args: + operation: 操作名称 + details: 操作详情 + log_type: 日志类型 + user_id: 用户ID + client_id: 客户端ID + **kwargs: 其他日志字段 + + Returns: + 日志ID + """ + log_id = str(uuid.uuid4()) + + log_entry = OperationLog( + id=log_id, + log_type=log_type, + operation=operation, + details=details, + user_id=user_id, + client_id=client_id, + created_at=datetime.now(), + **kwargs + ) + + # 添加到写入队列 + await self._write_queue.put(log_entry) + + # 添加到内存缓存 + self._add_to_cache(log_entry) + + return log_id + + async def log_system_operation( + self, + operation: str, + details: str, + status: OperationStatus = OperationStatus.SUCCESS, + **kwargs + ) -> str: + """记录系统操作日志""" + # 如果没有指定operation_category,使用默认值"system" + if "operation_category" not in kwargs: + kwargs["operation_category"] = "system" + + return await self.log_operation( + operation=operation, + details=details, + log_type=LogType.SYSTEM_OPERATION, + status=status, + **kwargs + ) + + async def log_user_operation( + self, + operation: str, + details: str, + user_id: str, + client_id: str, + **kwargs + ) -> str: + """记录用户操作日志""" + # 如果没有指定operation_category,使用默认值"user" + if "operation_category" not in kwargs: + kwargs["operation_category"] = "user" + + return await self.log_operation( + operation=operation, + details=details, + log_type=LogType.USER_OPERATION, + user_id=user_id, + client_id=client_id, + **kwargs + ) + + async def query_logs(self, filter_params: LogFilter) -> List[OperationLog]: + """ + 查询日志 + + Args: + filter_params: 过滤条件 + + Returns: + 日志列表 + """ + # 首先从缓存中查询 + cached_logs = self._query_from_cache(filter_params) + + if len(cached_logs) >= filter_params.limit: + return cached_logs[:filter_params.limit] + + # 从文件中查询 + file_logs = await self._query_from_files(filter_params) + + # 合并和去重 + all_logs = self._merge_and_deduplicate(cached_logs, file_logs) + + # 排序和分页 + all_logs.sort(key=lambda x: x.created_at, reverse=True) + + start_index = filter_params.offset + end_index = start_index + filter_params.limit + + return all_logs[start_index:end_index] + + async def get_log_by_id(self, log_id: str) -> Optional[OperationLog]: + """根据ID获取日志""" + # 先从缓存查找 + for log in self._cache: + if log.id == log_id: + return log + + # 从文件查找 + return await self._find_log_in_files(log_id) + + async def cleanup_old_logs(self): + """清理过期日志文件""" + cutoff_date = datetime.now() - timedelta(days=self.max_log_days) + + for log_file in self.log_dir.glob("*.jsonl"): + try: + # 从文件名提取日期 + date_str = log_file.stem.replace("operation_", "") + file_date = datetime.strptime(date_str, "%Y-%m-%d") + + if file_date < cutoff_date: + log_file.unlink() + logger.info(f"已删除过期日志文件: {log_file}") + + except (ValueError, OSError) as e: + logger.warning(f"处理日志文件 {log_file} 时出错: {e}") + + def _add_to_cache(self, log_entry: OperationLog): + """添加日志到内存缓存""" + self._cache.append(log_entry) + + # 保持缓存大小限制 + if len(self._cache) > self._cache_max_size: + self._cache = self._cache[-self._cache_max_size:] + + def _query_from_cache(self, filter_params: LogFilter) -> List[OperationLog]: + """从缓存中查询日志""" + results = [] + + for log in self._cache: + if self._matches_filter(log, filter_params): + results.append(log) + + return results + + async def _query_from_files(self, filter_params: LogFilter) -> List[OperationLog]: + """从文件中查询日志""" + results = [] + + # 确定要搜索的文件 + files_to_search = self._get_relevant_files(filter_params) + + for file_path in files_to_search: + try: + logs = await self._read_logs_from_file(file_path) + for log in logs: + if self._matches_filter(log, filter_params): + results.append(log) + + except Exception as e: + logger.error(f"读取日志文件 {file_path} 时出错: {e}") + + return results + + def _matches_filter(self, log: OperationLog, filter_params: LogFilter) -> bool: + """检查日志是否匹配过滤条件""" + if filter_params.log_type and log.log_type != filter_params.log_type: + return False + + if filter_params.operation and filter_params.operation not in log.operation: + return False + + if filter_params.user_id and log.user_id != filter_params.user_id: + return False + + if filter_params.client_id and log.client_id != filter_params.client_id: + return False + + if filter_params.level and log.level != filter_params.level: + return False + + if filter_params.start_time and log.created_at < filter_params.start_time: + return False + + if filter_params.end_time and log.created_at > filter_params.end_time: + return False + + return True + + def _get_relevant_files(self, filter_params: LogFilter) -> List[Path]: + """获取相关的日志文件""" + files = [] + + if filter_params.start_time or filter_params.end_time: + # 基于时间范围筛选文件 + start_date = filter_params.start_time.date() if filter_params.start_time else None + end_date = filter_params.end_time.date() if filter_params.end_time else None + + for log_file in sorted(self.log_dir.glob("operation_*.jsonl")): + try: + date_str = log_file.stem.replace("operation_", "") + file_date = datetime.strptime(date_str, "%Y-%m-%d").date() + + if start_date and file_date < start_date: + continue + if end_date and file_date > end_date: + continue + + files.append(log_file) + + except ValueError: + continue + else: + # 获取所有文件,按时间倒序 + files = sorted(self.log_dir.glob("operation_*.jsonl"), reverse=True) + + return files + + async def _read_logs_from_file(self, file_path: Path) -> List[OperationLog]: + """从文件读取日志""" + logs = [] + + try: + with open(file_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line: + try: + log_data = json.loads(line) + log = OperationLog(**log_data) + logs.append(log) + except (json.JSONDecodeError, ValueError) as e: + logger.warning(f"解析日志行时出错: {e}") + except Exception as e: + logger.error(f"读取日志文件 {file_path} 时出错: {e}") + + return logs + + def _merge_and_deduplicate(self, list1: List[OperationLog], list2: List[OperationLog]) -> List[OperationLog]: + """合并并去重日志列表""" + seen_ids = set() + merged = [] + + for log_list in [list1, list2]: + for log in log_list: + if log.id not in seen_ids: + seen_ids.add(log.id) + merged.append(log) + + return merged + + async def _find_log_in_files(self, log_id: str) -> Optional[OperationLog]: + """在文件中查找指定ID的日志""" + for log_file in self.log_dir.glob("operation_*.jsonl"): + try: + logs = await self._read_logs_from_file(log_file) + for log in logs: + if log.id == log_id: + return log + except Exception as e: + logger.error(f"查找日志时出错: {e}") + + return None + + async def _background_writer(self): + """后台日志写入任务""" + try: + while True: + log_entry = await self._write_queue.get() + await self._write_log_to_file(log_entry) + except asyncio.CancelledError: + # 处理剩余的日志 + while not self._write_queue.empty(): + try: + log_entry = self._write_queue.get_nowait() + await self._write_log_to_file(log_entry) + except asyncio.QueueEmpty: + break + raise + + async def _write_log_to_file(self, log_entry: OperationLog): + """将日志写入文件""" + try: + # 生成文件名 + date_str = log_entry.created_at.strftime("%Y-%m-%d") + filename = f"operation_{date_str}.jsonl" + file_path = self.log_dir / filename + + # 检查文件大小 + if file_path.exists() and file_path.stat().st_size > self.max_file_size: + # 文件过大,创建新文件 + timestamp = datetime.now().strftime("%H%M%S") + filename = f"operation_{date_str}_{timestamp}.jsonl" + file_path = self.log_dir / filename + + # 写入日志 + log_line = log_entry.model_dump_json(indent=None) + "\n" + + with open(file_path, 'a', encoding='utf-8') as f: + f.write(log_line) + + except Exception as e: + logger.error(f"写入日志文件时出错: {e}") + + +# 全局日志管理器实例 +log_manager = LogManager() \ No newline at end of file diff --git a/app/core/process_monitor.py b/app/core/process_monitor.py new file mode 100644 index 0000000..d614dca --- /dev/null +++ b/app/core/process_monitor.py @@ -0,0 +1,266 @@ +import asyncio +import time +from typing import Dict, List, Optional, Callable +from datetime import datetime +import psutil +from app.config import software_config + + +class ProcessInfo: + """进程信息类""" + def __init__(self, pid: int, name: str, software_id: str): + self.pid = pid + self.name = name + self.software_id = software_id + self.start_time = datetime.now() + self.cpu_percent = 0.0 + self.memory_percent = 0.0 + self.status = "running" + self.last_check = datetime.now() + + +class ProcessMonitor: + """进程监控类""" + + def __init__(self): + self.monitored_processes: Dict[str, ProcessInfo] = {} # software_id -> ProcessInfo + self.monitoring = False + self.monitor_task: Optional[asyncio.Task] = None + self.check_interval = 5 # 监控间隔(秒) + self.callbacks: List[Callable] = [] # 状态变化回调函数 + + def add_callback(self, callback: Callable): + """添加状态变化回调函数""" + self.callbacks.append(callback) + + def remove_callback(self, callback: Callable): + """移除回调函数""" + if callback in self.callbacks: + self.callbacks.remove(callback) + + async def _notify_callbacks(self, event_type: str, software_id: str, data: dict): + """通知所有回调函数""" + for callback in self.callbacks: + try: + if asyncio.iscoroutinefunction(callback): + await callback(event_type, software_id, data) + else: + callback(event_type, software_id, data) + except Exception as e: + print(f"回调函数执行失败: {e}") + + def add_process(self, software_id: str, pid: int): + """添加需要监控的进程""" + try: + process = psutil.Process(pid) + process_info = ProcessInfo(pid, process.name(), software_id) + self.monitored_processes[software_id] = process_info + + # 启动监控(如果未启动) + if not self.monitoring: + asyncio.create_task(self.start_monitoring()) + + except psutil.NoSuchProcess: + print(f"进程 {pid} 不存在") + + def remove_process(self, software_id: str): + """移除监控的进程""" + if software_id in self.monitored_processes: + del self.monitored_processes[software_id] + + async def start_monitoring(self): + """开始监控""" + if self.monitoring: + return + + self.monitoring = True + self.monitor_task = asyncio.create_task(self._monitor_loop()) + print("进程监控已启动") + + async def stop_monitoring(self): + """停止监控""" + self.monitoring = False + if self.monitor_task: + self.monitor_task.cancel() + try: + await self.monitor_task + except asyncio.CancelledError: + pass + print("进程监控已停止") + + async def _monitor_loop(self): + """监控循环""" + while self.monitoring: + try: + await self._check_processes() + await asyncio.sleep(self.check_interval) + except asyncio.CancelledError: + break + except Exception as e: + print(f"监控循环错误: {e}") + await asyncio.sleep(self.check_interval) + + async def _check_processes(self): + """检查所有监控的进程""" + for software_id in list(self.monitored_processes.keys()): + process_info = self.monitored_processes[software_id] + + try: + process = psutil.Process(process_info.pid) + + # 检查进程是否还在运行 + if not process.is_running(): + await self._handle_process_stopped(software_id, process_info) + continue + + # 更新进程状态信息 + old_status = process_info.status + old_cpu = process_info.cpu_percent + old_memory = process_info.memory_percent + + process_info.cpu_percent = process.cpu_percent() + process_info.memory_percent = process.memory_percent() + process_info.status = process.status() + process_info.last_check = datetime.now() + + # 检查是否有显著变化需要通知 + if self._should_notify_change(old_cpu, process_info.cpu_percent, old_memory, process_info.memory_percent): + await self._notify_callbacks("process_update", software_id, { + "pid": process_info.pid, + "cpu_percent": process_info.cpu_percent, + "memory_percent": process_info.memory_percent, + "status": process_info.status + }) + + except psutil.NoSuchProcess: + await self._handle_process_stopped(software_id, process_info) + except psutil.AccessDenied: + # 权限不足,但进程可能还在运行 + process_info.status = "access_denied" + process_info.last_check = datetime.now() + except Exception as e: + print(f"检查进程 {process_info.pid} 时出错: {e}") + + async def _handle_process_stopped(self, software_id: str, process_info: ProcessInfo): + """处理进程停止""" + # 通知进程已停止 + await self._notify_callbacks("process_stopped", software_id, { + "pid": process_info.pid, + "name": process_info.name, + "running_time": (datetime.now() - process_info.start_time).total_seconds() + }) + + # 从监控列表中移除 + del self.monitored_processes[software_id] + + # 如果没有更多进程需要监控,停止监控 + if not self.monitored_processes: + await self.stop_monitoring() + + def _should_notify_change(self, old_cpu: float, new_cpu: float, + old_memory: float, new_memory: float) -> bool: + """判断是否应该通知状态变化""" + # CPU使用率变化超过10%或内存使用率变化超过5%时通知 + cpu_change = abs(new_cpu - old_cpu) + memory_change = abs(new_memory - old_memory) + + return cpu_change > 10.0 or memory_change > 5.0 + + def get_process_info(self, software_id: str) -> Optional[ProcessInfo]: + """获取进程信息""" + return self.monitored_processes.get(software_id) + + def get_all_processes(self) -> Dict[str, ProcessInfo]: + """获取所有监控的进程信息""" + return self.monitored_processes.copy() + + def is_process_running(self, software_id: str) -> bool: + """检查指定软件的进程是否在运行""" + if software_id not in self.monitored_processes: + return False + + process_info = self.monitored_processes[software_id] + try: + process = psutil.Process(process_info.pid) + return process.is_running() + except (psutil.NoSuchProcess, psutil.AccessDenied): + return False + + async def get_system_info(self) -> dict: + """获取系统信息""" + try: + # CPU信息 + cpu_percent = psutil.cpu_percent(interval=1) + cpu_count = psutil.cpu_count() + + # 内存信息 + memory = psutil.virtual_memory() + + # 磁盘信息 + disk = psutil.disk_usage('/') + + return { + "cpu": { + "percent": cpu_percent, + "count": cpu_count + }, + "memory": { + "total": memory.total, + "available": memory.available, + "percent": memory.percent + }, + "disk": { + "total": disk.total, + "used": disk.used, + "free": disk.free, + "percent": (disk.used / disk.total) * 100 + }, + "timestamp": datetime.now().isoformat() + } + except Exception as e: + print(f"获取系统信息失败: {e}") + return {} + + async def find_software_processes(self) -> Dict[str, List[dict]]: + """查找所有配置的软件进程""" + software_processes = {} + + try: + # 获取所有进程 + all_processes = list(psutil.process_iter(['pid', 'name', 'create_time', 'cpu_percent', 'memory_percent'])) + + # 检查每个配置的软件 + for software_id in software_config.get_software_list(): + sw_config = software_config.get_software_config(software_id) + if not sw_config: + continue + + process_name = sw_config.get("check_process_name", "").lower() + if not process_name: + continue + + matching_processes = [] + for proc in all_processes: + try: + if proc.info['name'].lower() == process_name: + matching_processes.append({ + "pid": proc.info['pid'], + "name": proc.info['name'], + "create_time": proc.info['create_time'], + "cpu_percent": proc.info['cpu_percent'], + "memory_percent": proc.info['memory_percent'] + }) + except (psutil.NoSuchProcess, psutil.AccessDenied): + continue + + if matching_processes: + software_processes[software_id] = matching_processes + + except Exception as e: + print(f"查找软件进程失败: {e}") + + return software_processes + + +# 创建全局实例 +process_monitor = ProcessMonitor() \ No newline at end of file diff --git a/app/core/security.py b/app/core/security.py new file mode 100644 index 0000000..92a50af --- /dev/null +++ b/app/core/security.py @@ -0,0 +1,55 @@ +""" +安全认证模块 +提供JWT Token生成、验证等安全相关功能 +""" +from datetime import datetime, timedelta +from typing import Optional +from jose import JWTError, jwt +from passlib.context import CryptContext +from fastapi import HTTPException, status + +# JWT配置 - 从配置文件读取 +from app.config import settings + +SECRET_KEY = settings.secret_key +ALGORITHM = settings.algorithm +ACCESS_TOKEN_EXPIRE_MINUTES = settings.access_token_expire_minutes + +# 密码加密上下文 +pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") + + +def verify_password(plain_password: str, hashed_password: str) -> bool: + """验证密码""" + return pwd_context.verify(plain_password, hashed_password) + + +def get_password_hash(password: str) -> str: + """获取密码哈希值""" + return pwd_context.hash(password) + + +def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): + """创建访问令牌""" + to_encode = data.copy() + if expires_delta: + expire = datetime.utcnow() + expires_delta + else: + expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) + + to_encode.update({"exp": expire}) + encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) + return encoded_jwt + + +def verify_token(token: str) -> dict: + """验证令牌""" + try: + payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) + return payload + except JWTError: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="无效的认证令牌", + headers={"WWW-Authenticate": "Bearer"}, + ) \ No newline at end of file diff --git a/app/core/software_manager.py b/app/core/software_manager.py new file mode 100644 index 0000000..367e811 --- /dev/null +++ b/app/core/software_manager.py @@ -0,0 +1,502 @@ +import asyncio +import subprocess +import uuid +from datetime import datetime +from typing import Dict, Optional, List +import psutil +from app.models.task import Task, TaskStatus, TaskType +from app.models.software import SoftwareDefinition +from app.models.operation_log import OperationStatus +from app.config import software_config, settings + + +class SoftwareManager: + """软件管理核心类""" + + def __init__(self): + self.running_tasks: Dict[str, Task] = {} + self.running_processes: Dict[str, int] = {} # software_id -> process_id + self._websocket_manager = None + self._log_manager = None + + def set_websocket_manager(self, websocket_manager): + """设置WebSocket管理器用于状态通知""" + self._websocket_manager = websocket_manager + + def set_log_manager(self, log_manager): + """设置日志管理器用于操作记录""" + self._log_manager = log_manager + + async def _notify_websocket(self, message_type: str, data: dict): + """发送WebSocket通知""" + if self._websocket_manager: + message = { + "type": message_type, + "data": data, + "timestamp": datetime.now().isoformat() + } + await self._websocket_manager.broadcast(message) + + async def _log_system_operation(self, operation: str, details: str, software_id: str = None, **kwargs): + """记录系统操作日志""" + if self._log_manager: + from app.models.operation_log import ActionType, OperationStatus + # 设置默认值,允许通过kwargs覆盖 + log_params = { + "operation_category": "software_management", + "action_type": ActionType.EXECUTE, + **kwargs + } + await self._log_manager.log_system_operation( + operation=operation, + details=details, + target_object=software_id, + **log_params + ) + + async def get_software_list(self) -> List[Dict]: + """获取软件列表及状态""" + software_list = [] + for software_id in software_config.get_software_list(): + sw_config = software_config.get_software_config(software_id) + is_running = self.is_software_running(software_id) + process_id = self.running_processes.get(software_id) + + software_list.append({ + "id": software_id, + "name": sw_config["name"], + "is_running": is_running, + "process_id": process_id + }) + + return software_list + + def is_software_running(self, software_id: str) -> bool: + """检查软件是否在运行""" + # 首先检查记录的进程ID + if software_id in self.running_processes: + process_id = self.running_processes[software_id] + try: + process = psutil.Process(process_id) + if process.is_running(): + return True + except (psutil.NoSuchProcess, psutil.AccessDenied): + # 进程不存在,清理记录 + del self.running_processes[software_id] + + # 如果记录中没有或进程已停止,则根据进程名称检查 + sw_config = software_config.get_software_config(software_id) + if sw_config: + return self._check_process_started(sw_config["check_process_name"]) + + return False + + async def start_software(self, software_id: str) -> Task: + """启动软件""" + # 验证软件配置存在 + if not software_config.validate_software_exists(software_id): + raise ValueError(f"软件 {software_id} 不存在") + + # 检查是否已在运行 + if self.is_software_running(software_id): + raise ValueError(f"软件 {software_id} 已在运行") + + # 创建任务 + task = Task( + id=str(uuid.uuid4()), + task_type=TaskType.START_SOFTWARE, + software_id=software_id, + status=TaskStatus.PENDING, + created_at=datetime.now() + ) + + self.running_tasks[task.id] = task + + # 记录启动操作日志 + await self._log_system_operation( + operation="start_software", + details=f"启动软件任务已创建: {software_id}", + software_id=software_id, + status=OperationStatus.PENDING + ) + + # 异步启动软件 + asyncio.create_task(self._execute_start_task(task)) + + return task + + + async def stop_software(self, software_id: str) -> Task: + """停止软件""" + # 验证软件配置存在 + if not software_config.validate_software_exists(software_id): + raise ValueError(f"软件 {software_id} 不存在") + + # 检查软件是否在运行 + if not self.is_software_running(software_id): + raise ValueError(f"软件 {software_id} 未在运行") + + # 创建任务 + task = Task( + id=str(uuid.uuid4()), + task_type=TaskType.STOP_SOFTWARE, + software_id=software_id, + status=TaskStatus.PENDING, + created_at=datetime.now() + ) + + self.running_tasks[task.id] = task + + # 记录停止操作日志 + await self._log_system_operation( + operation="stop_software", + details=f"停止软件任务已创建: {software_id}", + software_id=software_id, + status=OperationStatus.PENDING + ) + + # 异步停止软件 + asyncio.create_task(self._execute_stop_task(task)) + + return task + + async def restart_software(self, software_id: str) -> Task: + """重启软件""" + # 验证软件配置存在 + if not software_config.validate_software_exists(software_id): + raise ValueError(f"软件 {software_id} 不存在") + + # 创建任务 + task = Task( + id=str(uuid.uuid4()), + task_type=TaskType.RESTART_SOFTWARE, + software_id=software_id, + status=TaskStatus.PENDING, + created_at=datetime.now() + ) + + self.running_tasks[task.id] = task + + # 异步重启软件 + asyncio.create_task(self._execute_restart_task(task)) + + return task + + async def _execute_start_task(self, task: Task): + """执行启动任务""" + try: + task.status = TaskStatus.RUNNING + task.started_at = datetime.now() + task.progress = 10 + + # 通知任务开始 + await self._notify_websocket("task_update", { + "task_id": task.id, + "software_id": task.software_id, + "status": task.status.value, + "progress": task.progress, + "message": f"开始启动软件 {task.software_id}" + }) + + sw_config = software_config.get_software_config(task.software_id) + + # 启动进程 + cmd = [sw_config["executable_path"]] + sw_config["startup_args"] + process = subprocess.Popen(cmd) + + task.progress = 30 + await self._notify_websocket("task_update", { + "task_id": task.id, + "software_id": task.software_id, + "status": task.status.value, + "progress": task.progress, + "message": f"进程已启动,等待软件完全加载" + }) + + # 等待软件启动完成 + timeout = sw_config["startup_timeout"] + start_time = datetime.now() + + while (datetime.now() - start_time).total_seconds() < timeout: + await asyncio.sleep(1) + task.progress = min(90, task.progress + 2) + + # 定期更新进度 + if task.progress % 10 == 0: + await self._notify_websocket("task_update", { + "task_id": task.id, + "software_id": task.software_id, + "status": task.status.value, + "progress": task.progress, + "message": f"软件加载中... ({task.progress}%)" + }) + + # 检查进程是否启动成功 + if self._check_process_started(sw_config["check_process_name"]): + self.running_processes[task.software_id] = process.pid + task.status = TaskStatus.COMPLETED + task.completed_at = datetime.now() + task.progress = 100 + + # 通知启动成功 + await self._notify_websocket("software_started", { + "task_id": task.id, + "software_id": task.software_id, + "process_id": process.pid, + "message": f"软件 {task.software_id} 启动成功" + }) + + # 记录启动成功日志 + await self._log_system_operation( + operation="start_software", + details=f"软件 {task.software_id} 启动成功,进程ID: {process.pid}", + software_id=task.software_id, + status=OperationStatus.SUCCESS, + duration=int((datetime.now() - task.started_at).total_seconds() * 1000), + extra_data={"process_id": process.pid, "task_id": task.id} + ) + return + + # 超时处理 + process.kill() + task.status = TaskStatus.FAILED + task.error_message = f"软件启动超时 ({timeout}s)" + task.completed_at = datetime.now() + + # 通知启动失败 + await self._notify_websocket("software_start_failed", { + "task_id": task.id, + "software_id": task.software_id, + "error": task.error_message, + "message": f"软件 {task.software_id} 启动失败" + }) + + # 记录启动失败日志 + await self._log_system_operation( + operation="start_software", + details=f"软件 {task.software_id} 启动失败: {task.error_message}", + software_id=task.software_id, + status=OperationStatus.FAILED, + error_message=task.error_message, + extra_data={"task_id": task.id} + ) + + except Exception as e: + task.status = TaskStatus.FAILED + task.error_message = str(e) + task.completed_at = datetime.now() + + # 通知启动异常 + await self._notify_websocket("software_start_failed", { + "task_id": task.id, + "software_id": task.software_id, + "error": str(e), + "message": f"软件 {task.software_id} 启动异常" + }) + + # 记录启动异常日志 + await self._log_system_operation( + operation="start_software", + details=f"软件 {task.software_id} 启动异常: {str(e)}", + software_id=task.software_id, + status=OperationStatus.FAILED, + error_message=str(e), + extra_data={"task_id": task.id} + ) + + + async def _execute_stop_task(self, task: Task): + """执行停止任务""" + try: + task.status = TaskStatus.RUNNING + task.started_at = datetime.now() + task.progress = 10 + + # 通知任务开始 + await self._notify_websocket("task_update", { + "task_id": task.id, + "software_id": task.software_id, + "status": task.status.value, + "progress": task.progress, + "message": f"开始停止软件 {task.software_id}" + }) + + # 停止软件 + await self._stop_software_sync(task.software_id) + + task.status = TaskStatus.COMPLETED + task.completed_at = datetime.now() + task.progress = 100 + + # 通知停止成功 + await self._notify_websocket("software_stopped", { + "task_id": task.id, + "software_id": task.software_id, + "message": f"软件 {task.software_id} 已成功停止" + }) + + # 记录停止成功日志 + await self._log_system_operation( + operation="stop_software", + details=f"软件 {task.software_id} 停止成功", + software_id=task.software_id, + status=OperationStatus.SUCCESS, + duration=int((datetime.now() - task.started_at).total_seconds() * 1000), + extra_data={"task_id": task.id} + ) + + except Exception as e: + task.status = TaskStatus.FAILED + task.error_message = str(e) + task.completed_at = datetime.now() + + # 通知停止失败 + await self._notify_websocket("software_stop_failed", { + "task_id": task.id, + "software_id": task.software_id, + "error": str(e), + "message": f"软件 {task.software_id} 停止失败" + }) + + # 记录停止失败日志 + await self._log_system_operation( + operation="stop_software", + details=f"软件 {task.software_id} 停止失败: {str(e)}", + software_id=task.software_id, + status=OperationStatus.FAILED, + error_message=str(e), + extra_data={"task_id": task.id} + ) + + async def _execute_restart_task(self, task: Task): + """执行重启任务""" + try: + task.status = TaskStatus.RUNNING + task.started_at = datetime.now() + task.progress = 10 + + # 先停止 + if self.is_software_running(task.software_id): + await self._stop_software_sync(task.software_id) + task.progress = 50 + + # 等待一段时间 + await asyncio.sleep(2) + + # 再启动 + await self._start_software_sync(task.software_id) + task.progress = 100 + task.status = TaskStatus.COMPLETED + task.completed_at = datetime.now() + + except Exception as e: + task.status = TaskStatus.FAILED + task.error_message = str(e) + task.completed_at = datetime.now() + + async def _stop_software_sync(self, software_id: str): + """同步停止软件""" + sw_config = software_config.get_software_config(software_id) + process_names = sw_config["check_process_name"] + stop_timeout = sw_config.get("stop_timeout", 10) # 默认10秒超时 + + # 支持单个进程名称字符串或进程名称列表 + if isinstance(process_names, str): + process_names = [process_names] + + stopped_processes = [] + + # 查找所有匹配的进程 + target_processes = [] + for proc in psutil.process_iter(['pid', 'name']): + try: + if proc.info['name']: + for process_name in process_names: + if proc.info['name'].lower() == process_name.lower(): + target_processes.append({ + 'pid': proc.info['pid'], + 'name': proc.info['name'] + }) + break + except (psutil.NoSuchProcess, psutil.AccessDenied): + continue + + if not target_processes: + raise Exception(f"未找到运行中的进程: {', '.join(process_names)}") + + # 分阶段停止进程 + for proc_info in target_processes: + try: + process = psutil.Process(proc_info['pid']) + + # 先尝试优雅停止 + process.terminate() + stopped_processes.append(proc_info['pid']) + + # 等待进程结束,使用配置的超时时间 + try: + process.wait(timeout=stop_timeout) + except psutil.TimeoutExpired: + # 如果优雅停止失败,强制杀死进程 + if process.is_running(): + process.kill() + try: + process.wait(timeout=3) + except psutil.TimeoutExpired: + # 记录无法停止的进程 + print(f"警告: 无法强制停止进程 {proc_info['name']} (PID: {proc_info['pid']})") + + except (psutil.NoSuchProcess, psutil.AccessDenied): + # 进程可能已经停止或无权限访问 + continue + + # 清理running_processes记录 + if software_id in self.running_processes: + del self.running_processes[software_id] + + # 等待一段时间确保所有进程都已停止 + await asyncio.sleep(2) + + async def _start_software_sync(self, software_id: str): + """同步启动软件""" + sw_config = software_config.get_software_config(software_id) + cmd = [sw_config["executable_path"]] + sw_config["startup_args"] + process = subprocess.Popen(cmd) + + # 等待启动 + timeout = sw_config["startup_timeout"] + start_time = datetime.now() + + while (datetime.now() - start_time).total_seconds() < timeout: + await asyncio.sleep(1) + if self._check_process_started(sw_config["check_process_name"]): + self.running_processes[software_id] = process.pid + return + + # 启动失败 + process.kill() + raise Exception(f"软件启动超时 ({timeout}s)") + + def _check_process_started(self, process_names) -> bool: + """检查进程是否已启动""" + # 支持单个进程名称字符串或进程名称列表 + if isinstance(process_names, str): + process_names = [process_names] + + for proc in psutil.process_iter(['name']): + try: + if proc.info['name']: + for process_name in process_names: + if proc.info['name'].lower() == process_name.lower(): + return True + except (psutil.NoSuchProcess, psutil.AccessDenied): + continue + return False + + def get_task(self, task_id: str) -> Optional[Task]: + """获取任务信息""" + return self.running_tasks.get(task_id) + + +# 创建全局实例 +software_manager = SoftwareManager() \ No newline at end of file diff --git a/app/core/websocket_manager.py b/app/core/websocket_manager.py new file mode 100644 index 0000000..1075104 --- /dev/null +++ b/app/core/websocket_manager.py @@ -0,0 +1,126 @@ +""" +WebSocket连接管理器 +管理所有WebSocket连接,提供消息广播和连接状态监控功能 +""" +from typing import Dict, List, Optional +from fastapi import WebSocket, WebSocketDisconnect +import json +import asyncio +import logging +from enum import Enum +from datetime import datetime + +logger = logging.getLogger(__name__) + + +class DateTimeEncoder(json.JSONEncoder): + """自定义JSON编码器,处理datetime对象""" + def default(self, obj): + if isinstance(obj, datetime): + return obj.isoformat() + return super().default(obj) + + +class MessageType(str, Enum): + """消息类型枚举""" + SOFTWARE_STATUS = "software_status" + PROCESS_UPDATE = "process_update" + ERROR = "error" + INFO = "info" + HEARTBEAT = "heartbeat" + # 软件操作相关消息类型 + TASK_UPDATE = "task_update" + SOFTWARE_STARTED = "software_started" + SOFTWARE_START_FAILED = "software_start_failed" + SOFTWARE_LIST_UPDATE = "software_list_update" + # 日志相关消息类型 + LOG_OPERATION = "log_operation" + LOG_RECORDED = "log_recorded" + + +class WebSocketManager: + """WebSocket连接管理器""" + + def __init__(self): + # 存储活跃连接 + self.active_connections: Dict[str, WebSocket] = {} + # 连接对应的用户信息 + self.connection_users: Dict[str, str] = {} + + async def connect(self, websocket: WebSocket, client_id: str, user_id: str = None): + """接受WebSocket连接""" + await websocket.accept() + self.active_connections[client_id] = websocket + if user_id: + self.connection_users[client_id] = user_id + logger.info(f"WebSocket客户端 {client_id} 已连接,用户: {user_id}") + + # 发送连接成功消息 + await self.send_personal_message({ + "type": MessageType.INFO, + "message": "WebSocket连接已建立", + "timestamp": self._get_timestamp() + }, client_id) + + def disconnect(self, client_id: str): + """断开WebSocket连接""" + if client_id in self.active_connections: + del self.active_connections[client_id] + if client_id in self.connection_users: + del self.connection_users[client_id] + logger.info(f"WebSocket客户端 {client_id} 已断开连接") + + async def send_personal_message(self, message: dict, client_id: str): + """发送消息给指定客户端""" + if client_id in self.active_connections: + try: + websocket = self.active_connections[client_id] + await websocket.send_text(json.dumps(message, ensure_ascii=False, cls=DateTimeEncoder)) + except Exception as e: + logger.error(f"发送消息给客户端 {client_id} 失败: {e}") + self.disconnect(client_id) + + async def broadcast(self, message: dict): + """广播消息给所有连接的客户端""" + if not self.active_connections: + return + + # 并发发送消息 + tasks = [] + for client_id in list(self.active_connections.keys()): + task = self.send_personal_message(message, client_id) + tasks.append(task) + + if tasks: + await asyncio.gather(*tasks, return_exceptions=True) + + async def broadcast_to_user(self, message: dict, user_id: str): + """广播消息给指定用户的所有连接""" + target_clients = [ + client_id for client_id, uid in self.connection_users.items() + if uid == user_id + ] + + tasks = [] + for client_id in target_clients: + task = self.send_personal_message(message, client_id) + tasks.append(task) + + if tasks: + await asyncio.gather(*tasks, return_exceptions=True) + + def get_active_connections_count(self) -> int: + """获取活跃连接数""" + return len(self.active_connections) + + def get_connected_users(self) -> List[str]: + """获取已连接的用户列表""" + return list(set(self.connection_users.values())) + + def _get_timestamp(self) -> str: + """获取当前时间戳""" + return datetime.now().isoformat() + + +# 全局WebSocket管理器实例 +websocket_manager = WebSocketManager() \ No newline at end of file diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..b609eae --- /dev/null +++ b/app/main.py @@ -0,0 +1,59 @@ +""" +FastAPI主入口文件 +""" +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from app.api.v1 import websocket +from app.core.websocket_manager import websocket_manager +from app.core.software_manager import software_manager +from app.core.log_manager import log_manager + +# 创建FastAPI实例 +app = FastAPI( + title="CadHubManage API", + description="通过Web接口控制Windows服务器上软件的管理系统", + version="1.0.0" +) + +# 初始化管理器之间的关联 +software_manager.set_websocket_manager(websocket_manager) +software_manager.set_log_manager(log_manager) + +# 启动和关闭事件 +@app.on_event("startup") +async def startup_event(): + """应用启动时的初始化""" + await log_manager.start() + +@app.on_event("shutdown") +async def shutdown_event(): + """应用关闭时的清理""" + await log_manager.stop() + +# 配置CORS +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # 生产环境应该设置具体的域名 + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# 注册API路由 +app.include_router(websocket.router, prefix="/api/v1/ws", tags=["WebSocket"]) + + +@app.get("/") +async def root(): + """根路径""" + return { + "message": "CadHubManage API服务正在运行", + "version": "1.0.0", + "docs": "/docs" + } + + +@app.get("/health") +async def health_check(): + """健康检查接口""" + return {"status": "healthy"} \ No newline at end of file diff --git a/app/models/__init__.py b/app/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/models/__pycache__/__init__.cpython-39.pyc b/app/models/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..b174816 Binary files /dev/null and b/app/models/__pycache__/__init__.cpython-39.pyc differ diff --git a/app/models/__pycache__/operation_log.cpython-39.pyc b/app/models/__pycache__/operation_log.cpython-39.pyc new file mode 100644 index 0000000..dd1bc3b Binary files /dev/null and b/app/models/__pycache__/operation_log.cpython-39.pyc differ diff --git a/app/models/__pycache__/software.cpython-39.pyc b/app/models/__pycache__/software.cpython-39.pyc new file mode 100644 index 0000000..1b1d47b Binary files /dev/null and b/app/models/__pycache__/software.cpython-39.pyc differ diff --git a/app/models/__pycache__/task.cpython-39.pyc b/app/models/__pycache__/task.cpython-39.pyc new file mode 100644 index 0000000..a0780ef Binary files /dev/null and b/app/models/__pycache__/task.cpython-39.pyc differ diff --git a/app/models/__pycache__/user.cpython-39.pyc b/app/models/__pycache__/user.cpython-39.pyc new file mode 100644 index 0000000..c50c7d0 Binary files /dev/null and b/app/models/__pycache__/user.cpython-39.pyc differ diff --git a/app/models/operation_log.py b/app/models/operation_log.py new file mode 100644 index 0000000..01a07bb --- /dev/null +++ b/app/models/operation_log.py @@ -0,0 +1,98 @@ +""" +操作日志数据模型 +用于记录用户操作和系统操作日志 +""" +from typing import Optional, Dict, Any +from datetime import datetime +from enum import Enum +from pydantic import BaseModel + + +class LogType(str, Enum): + """日志类型枚举""" + SYSTEM_OPERATION = "system_operation" # 系统操作(启动软件、重启等) + USER_OPERATION = "user_operation" # 用户自定义操作(前端发送的操作) + + +class LogLevel(str, Enum): + """日志级别枚举""" + INFO = "info" + WARNING = "warning" + ERROR = "error" + DEBUG = "debug" + + +class ActionType(str, Enum): + """行为类型枚举""" + CREATE = "create" # 创建 + READ = "read" # 读取 + UPDATE = "update" # 更新 + DELETE = "delete" # 删除 + EXECUTE = "execute" # 执行 + EXPORT = "export" # 导出 + IMPORT = "import" # 导入 + + +class OperationStatus(str, Enum): + """操作状态枚举""" + SUCCESS = "success" # 成功 + FAILED = "failed" # 失败 + PENDING = "pending" # 进行中 + + +class OperationLog(BaseModel): + """操作日志模型""" + # 基础信息 + id: str # 日志唯一ID + log_type: LogType # 日志类型 + level: LogLevel = LogLevel.INFO # 日志级别 + + # 用户信息 + user_id: Optional[str] = None # 用户ID/用户名 + client_id: Optional[str] = None # 客户端连接ID + session_id: Optional[str] = None # 会话ID + + # 操作信息 + operation: str # 具体操作名称 + operation_category: Optional[str] = None # 操作分类 + action_type: Optional[ActionType] = None # 行为类型 + target_object: Optional[str] = None # 操作目标对象 + details: str # 详细描述 + + # 时间信息 + created_at: datetime # 操作时间 + duration: Optional[int] = None # 操作耗时(毫秒) + + # 环境信息 + ip_address: Optional[str] = None # 客户端IP地址 + user_agent: Optional[str] = None # 用户代理信息 + software_version: Optional[str] = None # 软件版本 + + # 状态信息 + status: OperationStatus = OperationStatus.SUCCESS # 操作状态 + error_message: Optional[str] = None # 错误信息 + + # 扩展数据 + extra_data: Optional[Dict[str, Any]] = None # 额外的结构化数据 + + class Config: + # 允许任意类型的字段(用于extra_data) + arbitrary_types_allowed = True + + # JSON编码配置 + json_encoders = { + datetime: lambda v: v.isoformat() + } + + +class LogFilter(BaseModel): + """日志过滤条件""" + log_type: Optional[LogType] = None + operation: Optional[str] = None + user_id: Optional[str] = None + client_id: Optional[str] = None + level: Optional[LogLevel] = None + start_time: Optional[datetime] = None + end_time: Optional[datetime] = None + limit: int = 100 # 查询限制数量 + offset: int = 0 # 查询偏移量 \ No newline at end of file diff --git a/app/models/software.py b/app/models/software.py new file mode 100644 index 0000000..484f768 --- /dev/null +++ b/app/models/software.py @@ -0,0 +1,11 @@ +from typing import List, Optional +from pydantic import BaseModel + + +class SoftwareDefinition(BaseModel): + """软件定义模型""" + name: str + executable_path: str + startup_args: List[str] = [] + startup_timeout: int = 60 + check_process_name: str \ No newline at end of file diff --git a/app/models/task.py b/app/models/task.py new file mode 100644 index 0000000..b0615ac --- /dev/null +++ b/app/models/task.py @@ -0,0 +1,32 @@ +from typing import Optional +from datetime import datetime +from enum import Enum +from pydantic import BaseModel + + +class TaskStatus(str, Enum): + """任务状态枚举""" + PENDING = "pending" + RUNNING = "running" + COMPLETED = "completed" + FAILED = "failed" + + +class TaskType(str, Enum): + """任务类型枚举""" + START_SOFTWARE = "start_software" + STOP_SOFTWARE = "stop_software" + RESTART_SOFTWARE = "restart_software" + + +class Task(BaseModel): + """任务模型""" + id: str + task_type: TaskType + software_id: str + status: TaskStatus = TaskStatus.PENDING + created_at: datetime + started_at: Optional[datetime] = None + completed_at: Optional[datetime] = None + error_message: Optional[str] = None + progress: int = 0 \ No newline at end of file diff --git a/app/models/user.py b/app/models/user.py new file mode 100644 index 0000000..90b7a1a --- /dev/null +++ b/app/models/user.py @@ -0,0 +1,10 @@ +from typing import List +from pydantic import BaseModel + + +class User(BaseModel): + """用户模型""" + username: str + password_hash: str + is_active: bool = True + permissions: List[str] = [] \ No newline at end of file diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/schemas/__pycache__/__init__.cpython-39.pyc b/app/schemas/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..9b46c82 Binary files /dev/null and b/app/schemas/__pycache__/__init__.cpython-39.pyc differ diff --git a/app/schemas/__pycache__/auth.cpython-39.pyc b/app/schemas/__pycache__/auth.cpython-39.pyc new file mode 100644 index 0000000..3576cee Binary files /dev/null and b/app/schemas/__pycache__/auth.cpython-39.pyc differ diff --git a/app/schemas/__pycache__/software.cpython-39.pyc b/app/schemas/__pycache__/software.cpython-39.pyc new file mode 100644 index 0000000..6fd9dd0 Binary files /dev/null and b/app/schemas/__pycache__/software.cpython-39.pyc differ diff --git a/app/schemas/__pycache__/task.cpython-39.pyc b/app/schemas/__pycache__/task.cpython-39.pyc new file mode 100644 index 0000000..b5c7fd0 Binary files /dev/null and b/app/schemas/__pycache__/task.cpython-39.pyc differ diff --git a/app/schemas/auth.py b/app/schemas/auth.py new file mode 100644 index 0000000..8bef71e --- /dev/null +++ b/app/schemas/auth.py @@ -0,0 +1,26 @@ +from typing import Optional +from pydantic import BaseModel + + +class LoginRequest(BaseModel): + """登录请求模型""" + username: str + password: str + + +class LoginResponse(BaseModel): + """登录响应模型""" + access_token: str + refresh_token: str + token_type: str = "bearer" + expires_in: int + + +class RefreshTokenRequest(BaseModel): + """刷新Token请求模型""" + refresh_token: str + + +class TokenData(BaseModel): + """Token数据模型""" + username: Optional[str] = None \ No newline at end of file diff --git a/app/schemas/software.py b/app/schemas/software.py new file mode 100644 index 0000000..58d532c --- /dev/null +++ b/app/schemas/software.py @@ -0,0 +1,30 @@ +from typing import List, Optional +from pydantic import BaseModel +from models.task import TaskStatus + + +class SoftwareInfo(BaseModel): + """软件信息响应模型""" + id: str + name: str + is_running: bool + process_id: Optional[int] = None + + +class SoftwareListResponse(BaseModel): + """软件列表响应模型""" + software_list: List[SoftwareInfo] + + +class SoftwareActionRequest(BaseModel): + """软件操作请求模型""" + software_id: str + + +class SoftwareActionResponse(BaseModel): + """软件操作响应模型""" + task_id: str + software_id: str + action: str + status: TaskStatus + message: str \ No newline at end of file diff --git a/app/schemas/task.py b/app/schemas/task.py new file mode 100644 index 0000000..14bafc4 --- /dev/null +++ b/app/schemas/task.py @@ -0,0 +1,25 @@ +from typing import Optional +from datetime import datetime +from pydantic import BaseModel +from models.task import TaskStatus, TaskType + + +class TaskResponse(BaseModel): + """任务响应模型""" + id: str + task_type: TaskType + software_id: str + status: TaskStatus + created_at: datetime + started_at: Optional[datetime] = None + completed_at: Optional[datetime] = None + error_message: Optional[str] = None + progress: int + + +class SSEEvent(BaseModel): + """SSE事件模型""" + event_type: str + task_id: Optional[str] = None + software_id: Optional[str] = None + data: dict \ No newline at end of file diff --git a/app/services/__init__.py b/app/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/utils/__init__.py b/app/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/configs/software_config.yaml b/configs/software_config.yaml new file mode 100644 index 0000000..f7104e8 --- /dev/null +++ b/configs/software_config.yaml @@ -0,0 +1,15 @@ +software: + creo: + name: "PTC Creo" + executable_path: "C:\\Program Files\\PTC\\Creo 5.0.0.0\\Parametric\\bin\\parametric.exe" + startup_args: [] + startup_timeout: 60 + check_process_name: ["xtop.exe", "pro_comm_msg.exe"] + stop_timeout: 15 + + revit: + name: "Autodesk Revit 2017" + executable_path: "C:\\Program Files\\Autodesk\\Revit 2017\\Revit.exe" + startup_args: ["/language", "CHS"] + startup_timeout: 90 + check_process_name: "Revit.exe" \ No newline at end of file diff --git a/configs/users.json b/configs/users.json new file mode 100644 index 0000000..fe8ea46 --- /dev/null +++ b/configs/users.json @@ -0,0 +1,16 @@ +{ + "users": [ + { + "username": "admin", + "password_hash": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "is_active": true, + "permissions": ["software:start", "software:stop", "software:restart", "software:list"] + }, + { + "username": "user", + "password_hash": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "is_active": true, + "permissions": ["software:list"] + } + ] +} \ No newline at end of file diff --git a/frontend-api-docs.md b/frontend-api-docs.md new file mode 100644 index 0000000..c65e4dd --- /dev/null +++ b/frontend-api-docs.md @@ -0,0 +1,833 @@ +# CadHubManage 前端API文档 + +## 项目概述 +CadHubManage是一个通过WebSocket实时控制Windows服务器上软件的管理系统,提供软件启动、停止、状态监控和操作日志记录功能。 + +## 基础信息 +- **API版本**: v1.0.0 +- **WebSocket URL**: `ws://localhost:8000/api/v1/ws/connect` +- **协议**: WebSocket +- **数据格式**: JSON + +## 快速开始 + +### 1. 健康检查(HTTP接口) +```http +GET /health +``` +响应: +```json +{ + "status": "healthy" +} +``` + +### 2. 服务信息(HTTP接口) +```http +GET / +``` +响应: +```json +{ + "message": "CadHubManage API服务正在运行", + "version": "1.0.0", + "docs": "/docs" +} +``` + +### 3. 连接WebSocket +```javascript +const ws = new WebSocket('ws://localhost:8000/api/v1/ws/connect?client_id=web_client&user_id=admin'); +``` + +## WebSocket实时通信API + +### 连接WebSocket +``` +ws://localhost:8000/api/v1/ws/connect?client_id=client123&user_id=user456 +``` + +**连接参数:** +- `client_id`: 客户端唯一标识符 (可选,自动生成) +- `user_id`: 用户ID (可选) + +### WebSocket消息格式 + +#### 发送消息类型 + +**1. 心跳检测** +```json +{ + "type": "ping" // 必填:固定值 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "ping" + +**2. 获取服务状态** +```json +{ + "type": "get_status" // 必填:固定值 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "get_status" + +**3. 获取软件列表** +```json +{ + "type": "get_software_list" // 必填:固定值 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "get_software_list" + +**4. 启动软件** +```json +{ + "type": "start_software", // 必填:固定值 + "software_id": "creo" // 必填:软件标识符 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "start_software" +- `software_id` (必填,string): 软件标识符,长度1-50字符,只能包含字母、数字、下划线 + +**5. 停止软件** +```json +{ + "type": "stop_software", // 必填:固定值 + "software_id": "creo" // 必填:软件标识符 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "stop_software" +- `software_id` (必填,string): 软件标识符,长度1-50字符,只能包含字母、数字、下划线 + +**6. 重启软件** +```json +{ + "type": "restart_software", // 必填:固定值 + "software_id": "creo" // 必填:软件标识符 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "restart_software" +- `software_id` (必填,string): 软件标识符,长度1-50字符,只能包含字母、数字、下划线 + +**6. 记录操作日志** +```json +{ + "type": "log_operation", // 必填:固定值 + "operation": "手动启动软件", // 必填:操作名称 + "details": "用户通过界面启动Creo", // 可选:详细描述 + "action_type": "software_control", // 可选:行为类型 + "target_object": "creo", // 可选:目标对象 + "status": "success", // 可选:操作状态 + "duration": 5.2, // 可选:操作耗时(秒) + "operation_category": "软件控制" // 可选:操作分类 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "log_operation" +- `operation` (必填,string): 操作名称,长度1-100字符 +- `details` (可选,string): 详细描述,最大1000字符 +- `action_type` (可选,string): 行为类型,可选值: create, read, update, delete, execute, export, import +- `target_object` (可选,string): 目标对象,最大50字符 +- `status` (可选,string): 操作状态,可选值: success, failed, pending,默认success +- `duration` (可选,number): 操作耗时,单位秒,范围0-3600 +- `operation_category` (可选,string): 操作分类,最大50字符 + +**7. 查询操作日志** +```json +{ + "type": "query_logs", // 必填:固定值 + "log_type": "user_operation", // 可选:日志类型 + "operation": "启动软件", // 可选:操作名称 + "user_id_filter": "user123", // 可选:用户ID过滤 + "level": "info", // 可选:日志级别 + "start_time": "2024-01-01T00:00:00Z", // 可选:开始时间 + "end_time": "2024-01-02T00:00:00Z", // 可选:结束时间 + "limit": 100, // 可选:返回数量限制 + "offset": 0 // 可选:偏移量 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "query_logs" +- `log_type` (可选,string): 日志类型,可选值: system_operation, user_operation +- `operation` (可选,string): 操作名称,支持模糊匹配 +- `user_id_filter` (可选,string): 用户ID过滤,最大50字符 +- `level` (可选,string): 日志级别,可选值: debug, info, warning, error +- `start_time` (可选,string): 开始时间,ISO 8601格式 (YYYY-MM-DDTHH:mm:ssZ) +- `end_time` (可选,string): 结束时间,ISO 8601格式 (YYYY-MM-DDTHH:mm:ssZ) +- `limit` (可选,number): 返回数量限制,范围1-1000,默认100 +- `offset` (可选,number): 偏移量,最小0,默认0 + +**8. 根据ID获取日志** +```json +{ + "type": "get_log_by_id", // 必填:固定值 + "log_id": "log_123" // 必填:日志ID +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "get_log_by_id" +- `log_id` (必填,string): 日志唯一标识符,长度1-100字符 + +**9. 获取日志统计信息** +```json +{ + "type": "get_log_stats" // 必填:固定值 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "get_log_stats" + +**10. 清理过期日志** +```json +{ + "type": "cleanup_logs" // 必填:固定值 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "cleanup_logs" + +**11. 获取操作类型列表** +```json +{ + "type": "get_operation_types" // 必填:固定值 +} +``` +**参数说明:** +- `type` (必填,string): 固定值 "get_operation_types" + +#### 接收消息类型 + +**1. 欢迎消息** +```json +{ + "type": "info", + "message": "欢迎连接!客户端ID: client123", + "client_id": "client123", + "user_id": "user456", + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +**2. 心跳响应** +```json +{ + "type": "heartbeat", + "message": "pong", + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +**3. 服务状态响应** +```json +{ + "type": "info", + "message": "服务状态正常", + "data": { + "active_connections": 3, + "connected_users": ["user123", "user456"] + }, + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +**4. 软件列表更新** +```json +{ + "type": "software_list_update", + "data": { + "software_list": [ + { + "id": "creo", + "name": "PTC Creo", + "status": "running", + "executable_path": "C:\\Program Files\\PTC\\Creo 5.0.0.0\\Parametric\\bin\\parametric.exe" + } + ] + }, + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +**5. 任务创建响应** +```json +{ + "type": "info", + "message": "软件 creo 启动任务已创建", + "data": { + "task_id": "task_123", + "software_id": "creo", + "status": "pending" + }, + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +**6. 日志记录确认** +```json +{ + "type": "log_recorded", + "message": "操作日志已记录", + "data": { + "log_id": "log_456", + "operation": "手动启动软件" + }, + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +**7. 日志查询响应** +```json +{ + "type": "info", + "message": "日志查询成功", + "data": { + "logs": [ + { + "id": "log_123", + "operation": "启动软件", + "user_id": "user123", + "timestamp": "2024-01-01T10:00:00Z", + "level": "info", + "details": "启动PTC Creo成功" + } + ], + "total": 1, + "limit": 100, + "offset": 0 + }, + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +**8. 日志统计响应** +```json +{ + "type": "info", + "message": "获取统计信息成功", + "data": { + "stats": { + "period": "24小时", + "system_operations": 45, + "user_operations": 123, + "error_logs": 2, + "total_logs": 168, + "timestamp": "2024-01-01T10:00:00Z" + } + }, + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +**9. 操作类型列表响应** +```json +{ + "type": "info", + "message": "获取操作类型成功", + "data": { + "operations": ["启动软件", "停止软件", "重启软件"], + "categories": ["软件控制", "系统管理"], + "total_operations": 3, + "total_categories": 2 + }, + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +**10. 错误消息** +```json +{ + "type": "error", + "message": "启动软件失败: 软件路径不存在", + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +## 数据模型 + +### 软件配置 +当前支持的软件(位于`configs/software_config.yaml`): +```yaml +software: + creo: + name: "PTC Creo" + executable_path: "C:\\Program Files\\PTC\\Creo 5.0.0.0\\Parametric\\bin\\parametric.exe" + startup_args: [] + startup_timeout: 60 + check_process_name: "parametric.exe" +``` + +### 日志类型枚举 +- **LogType**: `system_operation`, `user_operation` +- **LogLevel**: `debug`, `info`, `warning`, `error` +- **ActionType**: `create`, `read`, `update`, `delete`, `execute`, `export`, `import` +- **OperationStatus**: `success`, `failed`, `pending` + +## 错误处理 + +### HTTP错误码 +- `200`: 成功 +- `404`: 资源不存在 +- `500`: 服务器内部错误 + +### WebSocket错误 +错误消息统一格式: +```json +{ + "type": "error", + "message": "错误描述", + "timestamp": "2024-01-01T10:00:00Z" +} +``` + +## 使用示例 + +### JavaScript WebSocket客户端示例 +```javascript +// 连接WebSocket +const ws = new WebSocket('ws://localhost:8000/api/v1/ws/connect?client_id=web_client&user_id=admin'); + +// 连接成功 +ws.onopen = function() { + console.log('WebSocket连接成功'); + + // 发送心跳 + ws.send(JSON.stringify({type: 'ping'})); +}; + +// 接收消息 +ws.onmessage = function(event) { + const message = JSON.parse(event.data); + console.log('收到消息:', message); + + switch(message.type) { + case 'heartbeat': + console.log('心跳响应'); + break; + case 'software_list_update': + console.log('软件列表:', message.data.software_list); + break; + case 'info': + if (message.data && message.data.logs) { + console.log('日志查询结果:', message.data.logs); + } else if (message.data && message.data.stats) { + console.log('统计信息:', message.data.stats); + } + break; + case 'error': + console.error('错误:', message.message); + break; + } +}; + +// 启动软件 +function startSoftware(softwareId) { + ws.send(JSON.stringify({ + type: 'start_software', + software_id: softwareId + })); +} + +// 停止软件 +function stopSoftware(softwareId) { + ws.send(JSON.stringify({ + type: 'stop_software', + software_id: softwareId + })); +} + +// 重启软件 +function restartSoftware(softwareId) { + ws.send(JSON.stringify({ + type: 'restart_software', + software_id: softwareId + })); +} + +// 记录操作日志 +function logOperation(operation, details) { + ws.send(JSON.stringify({ + type: 'log_operation', + operation: operation, + details: details, + status: 'success' + })); +} + +// 查询日志 +function queryLogs(filters = {}) { + ws.send(JSON.stringify({ + type: 'query_logs', + ...filters + })); +} + +// 获取日志统计 +function getLogStats() { + ws.send(JSON.stringify({ + type: 'get_log_stats' + })); +} + +// 获取操作类型列表 +function getOperationTypes() { + ws.send(JSON.stringify({ + type: 'get_operation_types' + })); +} + +// 清理过期日志 +function cleanupLogs() { + ws.send(JSON.stringify({ + type: 'cleanup_logs' + })); +} + +// 使用示例 +setTimeout(() => { + // 查询最近的用户操作日志 + queryLogs({ + log_type: 'user_operation', + limit: 50, + offset: 0 + }); + + // 获取统计信息 + getLogStats(); + + // 获取操作类型 + getOperationTypes(); +}, 1000); +``` + +## WebSocket连接管理指南 + +### 连接状态管理 + +WebSocket连接具有多种状态,前端需要正确处理这些状态转换: + +```javascript +class WebSocketManager { + constructor(url, options = {}) { + this.url = url; + this.ws = null; + this.connectionState = 'DISCONNECTED'; // CONNECTING, CONNECTED, DISCONNECTED, ERROR + this.reconnectAttempts = 0; + this.maxReconnectAttempts = options.maxReconnectAttempts || 5; + this.reconnectDelay = options.reconnectDelay || 1000; + this.heartbeatInterval = options.heartbeatInterval || 30000; + this.heartbeatTimer = null; + + // 事件监听器 + this.listeners = { + onOpen: [], + onMessage: [], + onClose: [], + onError: [], + onStateChange: [] + }; + } + + // 连接WebSocket + connect() { + if (this.connectionState === 'CONNECTING' || this.connectionState === 'CONNECTED') { + return; + } + + this.setState('CONNECTING'); + this.ws = new WebSocket(this.url); + + this.ws.onopen = (event) => { + this.setState('CONNECTED'); + this.reconnectAttempts = 0; + this.startHeartbeat(); + this.emit('onOpen', event); + }; + + this.ws.onmessage = (event) => { + const message = JSON.parse(event.data); + this.emit('onMessage', message); + }; + + this.ws.onclose = (event) => { + this.setState('DISCONNECTED'); + this.stopHeartbeat(); + this.emit('onClose', event); + + // 自动重连 + if (!event.wasClean && this.reconnectAttempts < this.maxReconnectAttempts) { + setTimeout(() => { + this.reconnectAttempts++; + this.connect(); + }, this.reconnectDelay * Math.pow(2, this.reconnectAttempts)); // 指数退避 + } + }; + + this.ws.onerror = (event) => { + this.setState('ERROR'); + this.emit('onError', event); + }; + } + + // 断开连接 + disconnect() { + if (this.ws) { + this.ws.close(1000, 'Client disconnect'); + this.ws = null; + } + this.stopHeartbeat(); + this.setState('DISCONNECTED'); + } + + // 发送消息 + send(message) { + if (this.connectionState === 'CONNECTED' && this.ws) { + this.ws.send(JSON.stringify(message)); + return true; + } + return false; + } + + // 心跳检测 + startHeartbeat() { + this.heartbeatTimer = setInterval(() => { + if (this.connectionState === 'CONNECTED') { + this.send({ type: 'ping' }); + } + }, this.heartbeatInterval); + } + + stopHeartbeat() { + if (this.heartbeatTimer) { + clearInterval(this.heartbeatTimer); + this.heartbeatTimer = null; + } + } + + // 状态管理 + setState(newState) { + if (this.connectionState !== newState) { + const oldState = this.connectionState; + this.connectionState = newState; + this.emit('onStateChange', { oldState, newState }); + } + } + + // 事件系统 + on(event, callback) { + if (this.listeners[event]) { + this.listeners[event].push(callback); + } + } + + off(event, callback) { + if (this.listeners[event]) { + const index = this.listeners[event].indexOf(callback); + if (index > -1) { + this.listeners[event].splice(index, 1); + } + } + } + + emit(event, data) { + if (this.listeners[event]) { + this.listeners[event].forEach(callback => callback(data)); + } + } +} +``` + +### 使用示例 + +```javascript +// 创建WebSocket管理器 +const wsManager = new WebSocketManager( + 'ws://localhost:8000/api/v1/ws/connect?client_id=web_client&user_id=admin', + { + maxReconnectAttempts: 5, + reconnectDelay: 1000, + heartbeatInterval: 30000 + } +); + +// 监听连接状态变化 +wsManager.on('onStateChange', ({ oldState, newState }) => { + console.log(`连接状态变化: ${oldState} -> ${newState}`); + updateUI(newState); +}); + +// 监听消息 +wsManager.on('onMessage', (message) => { + handleMessage(message); +}); + +// 监听错误 +wsManager.on('onError', (error) => { + console.error('WebSocket错误:', error); + showErrorNotification('连接出现错误,正在尝试重连...'); +}); + +// 连接 +wsManager.connect(); + +// 发送消息(带重试) +function sendMessageWithRetry(message, maxRetries = 3) { + let retries = 0; + + function attemptSend() { + if (wsManager.send(message)) { + return true; + } + + if (retries < maxRetries && wsManager.connectionState !== 'CONNECTED') { + retries++; + setTimeout(attemptSend, 1000); + } else { + console.error('发送消息失败:', message); + return false; + } + } + + return attemptSend(); +} +``` + +## 错误处理完整指南 + +### 错误分类和处理策略 + +#### 1. 连接错误 + +**网络连接失败** +```javascript +// 错误场景:网络不可达、服务器关闭 +wsManager.on('onError', (event) => { + if (event.code === 1006) { // 异常关闭 + showNotification('网络连接中断,正在尝试重连...', 'warning'); + // 自动重连逻辑已在管理器中处理 + } +}); +``` + +**认证失败** +```javascript +// 错误场景:client_id或user_id无效 +wsManager.on('onMessage', (message) => { + if (message.type === 'error' && message.message.includes('认证')) { + showNotification('认证失败,请重新登录', 'error'); + redirectToLogin(); + } +}); +``` + +#### 2. 业务错误 + +**软件操作错误** +```javascript +// 错误响应示例 +{ + "type": "error", + "message": "启动软件失败: 软件路径不存在", + "error_code": "SOFTWARE_NOT_FOUND", + "timestamp": "2024-01-01T10:00:00Z" +} + +// 处理方式 +function handleSoftwareError(message) { + const errorHandlers = { + 'SOFTWARE_NOT_FOUND': () => { + showNotification('软件未找到,请检查软件配置', 'error'); + // 可以引导用户到配置页面 + }, + 'SOFTWARE_ALREADY_RUNNING': () => { + showNotification('软件已在运行中', 'info'); + // 更新软件状态显示 + }, + 'INSUFFICIENT_PERMISSIONS': () => { + showNotification('权限不足,无法执行操作', 'error'); + // 可能需要提升权限 + } + }; + + const handler = errorHandlers[message.error_code]; + if (handler) { + handler(); + } else { + showNotification(message.message, 'error'); + } +} +``` + +**参数验证错误** +```javascript +// 前端参数验证 +function validateLogOperation(params) { + const errors = []; + + if (!params.operation || params.operation.length === 0) { + errors.push('operation字段不能为空'); + } + if (params.operation && params.operation.length > 100) { + errors.push('operation字段长度不能超过100字符'); + } + if (params.details && params.details.length > 1000) { + errors.push('details字段长度不能超过1000字符'); + } + if (params.duration && (params.duration < 0 || params.duration > 3600)) { + errors.push('duration字段值必须在0-3600范围内'); + } + + return errors; +} + +// 使用示例 +function logUserOperation(params) { + const errors = validateLogOperation(params); + if (errors.length > 0) { + showNotification(`参数错误: ${errors.join(', ')}`, 'error'); + return; + } + + wsManager.send({ + type: 'log_operation', + ...params + }); +} +``` + +#### 3. 常见错误代码表 + +| 错误代码 | 描述 | 处理建议 | +|---------|------|---------| +| `INVALID_MESSAGE_FORMAT` | 消息格式错误 | 检查JSON格式,重新发送 | +| `UNKNOWN_MESSAGE_TYPE` | 未知消息类型 | 检查type字段值 | +| `MISSING_REQUIRED_PARAMETER` | 缺少必填参数 | 补充必填参数 | +| `SOFTWARE_NOT_FOUND` | 软件未找到 | 检查software_id,更新软件配置 | +| `SOFTWARE_ALREADY_RUNNING` | 软件已运行 | 更新UI状态,无需重复启动 | +| `PERMISSION_DENIED` | 权限不足 | 联系管理员或重新认证 | +| `OPERATION_TIMEOUT` | 操作超时 | 检查网络连接,重试操作 | +| `SERVER_INTERNAL_ERROR` | 服务器内部错误 | 稍后重试,联系技术支持 | + +## 开发注意事项 + +1. **纯WebSocket架构**: 所有功能通过WebSocket实现,提供实时双向通信 +2. **CORS已配置**: 允许所有来源,生产环境需要修改 +3. **连接管理**: 实现完整的连接状态管理和自动重连机制 +4. **参数验证**: 前端应进行客户端验证,提升用户体验 +5. **错误处理**: 提供统一的错误响应格式和处理策略 +6. **心跳检测**: 定期发送ping消息保持连接活跃 +7. **消息格式**: 所有WebSocket消息采用统一JSON格式 +8. **重连策略**: 使用指数退避算法避免服务器压力 + +## 联系与支持 + +如有问题请参考项目代码或联系开发团队。 + +--- +*文档版本: 1.0.0* +*最后更新: 2024-01-01* \ No newline at end of file diff --git a/logs/operation_logs/operation_2025-07-21.jsonl b/logs/operation_logs/operation_2025-07-21.jsonl new file mode 100644 index 0000000..5b75948 --- /dev/null +++ b/logs/operation_logs/operation_2025-07-21.jsonl @@ -0,0 +1,25 @@ +{"id":"1e49253a-5260-4290-8c3d-97e9642f72ee","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"启动软件任务已创建: creo","created_at":"2025-07-21T14:51:16.002385","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"a5749d57-4fe0-4928-bc32-8755388c9b6a","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 启动成功,进程ID: 51392","created_at":"2025-07-21T14:51:18.901132","duration":2894,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":51392,"task_id":"e449f057-cfa0-4cdb-b427-418c95f8e2a5"}} +{"id":"c2ab8eb4-bff8-482d-aa91-0767272cd89e","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"启动软件任务已创建: creo","created_at":"2025-07-21T16:27:11.576919","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"60aef100-f9e2-4219-95af-c81895b61c3f","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 启动成功,进程ID: 49284","created_at":"2025-07-21T16:27:14.575942","duration":2997,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":49284,"task_id":"d71b0b9b-e178-4f10-85b7-11875715a984"}} +{"id":"66724892-e9f8-4388-a2dd-aa23215c79ae","log_type":"user_operation","level":"info","user_id":"web_client_1753088105342","client_id":"667a273d-f32b-4281-99b4-54e755e497fa","session_id":null,"operation":"尝试连接CREO","operation_category":"CAD软件控制","action_type":"execute","target_object":"creo","details":"用户点击连接按钮启动creo软件","created_at":"2025-07-21T16:55:07.308044","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"a89d375e-27b4-42c7-ba84-995d5f276af4","log_type":"user_operation","level":"info","user_id":"web_client_1753090936974","client_id":"cf7d4814-6bfc-46f8-9715-7d2c1a09d64a","session_id":null,"operation":"尝试连接CREO","operation_category":"CAD软件控制","action_type":"execute","target_object":"creo","details":"用户点击连接按钮启动creo软件","created_at":"2025-07-21T17:42:23.404579","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"5e057bfb-246e-4dd1-9557-02eb32415b6d","log_type":"user_operation","level":"info","user_id":"web_client_1753090936974","client_id":"cf7d4814-6bfc-46f8-9715-7d2c1a09d64a","session_id":null,"operation":"尝试连接CREO","operation_category":"CAD软件控制","action_type":"execute","target_object":"creo","details":"用户点击连接按钮启动creo软件","created_at":"2025-07-21T17:44:05.556638","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"2fa6ff3f-6169-4f1b-861e-80b426c1da1e","log_type":"user_operation","level":"info","user_id":"web_client_1753090936974","client_id":"cf7d4814-6bfc-46f8-9715-7d2c1a09d64a","session_id":null,"operation":"尝试连接CREO","operation_category":"CAD软件控制","action_type":"execute","target_object":"creo","details":"用户点击连接按钮启动creo软件","created_at":"2025-07-21T17:44:05.557638","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"755d74c4-c66f-4fbc-989e-397f639e570c","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"启动软件任务已创建: creo","created_at":"2025-07-21T18:48:30.117395","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"1ed6500f-09f0-49e1-87ff-74b82275dafe","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"启动软件 creo","operation_category":"软件控制","action_type":"execute","target_object":"creo","details":"用户通过管理面板启动 creo 软件","created_at":"2025-07-21T18:48:30.118393","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"18d1a03c-f64c-4d31-98f2-249e86b93adb","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 启动成功,进程ID: 6616","created_at":"2025-07-21T18:48:32.614952","duration":2496,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":6616,"task_id":"fdfb86f9-cf7e-42b5-9e64-028114bad783"}} +{"id":"5fa02034-0564-4363-a0c0-a19a277e1a62","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"启动软件 creo","operation_category":"软件控制","action_type":"execute","target_object":"creo","details":"用户通过管理面板启动 creo 软件","created_at":"2025-07-21T18:49:01.823225","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"388c727a-e82c-4331-8c39-49029852f1b5","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-21T18:49:23.055516","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"8ca6d85a-dc68-46cf-9faf-1d96c7abbb56","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"清理过期日志","operation_category":"日志管理","action_type":"delete","target_object":"","details":"用户通过管理面板清理过期日志","created_at":"2025-07-21T18:50:12.917496","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"9beedd94-2940-4b59-ae11-e4f576414b7c","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-21T19:07:55.279085","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"79a7476a-18de-4a74-9251-1ce41f232049","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"启动软件 creo","operation_category":"软件控制","action_type":"execute","target_object":"creo","details":"用户通过管理面板启动 creo 软件","created_at":"2025-07-21T19:15:15.552939","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"8e6eb59b-2813-4159-afd3-d6f9a363bef0","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-21T19:45:44.011891","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"9df0785e-3520-4123-bea7-684c1f9842d6","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-21T19:45:44.585002","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"a4e0f0b4-7cef-42a4-8abe-b52b2047b68f","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-21T19:57:41.847285","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"9bb846c1-40a4-42fc-83ec-ecdb0007eaff","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-21T19:57:42.418939","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"6d93917d-99c5-4d59-af7d-35fd6ec84df6","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"启动软件任务已创建: creo","created_at":"2025-07-21T20:04:42.941621","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"d5d315b6-dcbc-401b-a84d-ac290a1a6760","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"启动软件 creo","operation_category":"软件控制","action_type":"execute","target_object":"creo","details":"用户通过管理面板启动 creo 软件","created_at":"2025-07-21T20:04:42.941621","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"0a26c477-a684-4e01-9af8-7013e9b17bd8","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 启动成功,进程ID: 16836","created_at":"2025-07-21T20:04:44.296527","duration":1352,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":16836,"task_id":"1438c005-0326-4739-8019-4574811f9bdf"}} +{"id":"de21c58b-d8ad-4783-97e0-fdd0f23dea35","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-21T20:05:07.449267","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"736755d9-f1cd-4b4c-b9da-7e59aab2e8bf","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-21T20:05:09.812729","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} diff --git a/logs/operation_logs/operation_2025-07-23.jsonl b/logs/operation_logs/operation_2025-07-23.jsonl new file mode 100644 index 0000000..44ccac8 --- /dev/null +++ b/logs/operation_logs/operation_2025-07-23.jsonl @@ -0,0 +1,5 @@ +{"id":"e651bed4-c414-4fa1-a795-95ce038bc09f","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"启动软件任务已创建: creo","created_at":"2025-07-23T11:59:23.387233","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"46b4b0a4-b395-4acf-93f2-fe1e97bce6e1","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"启动软件 creo","operation_category":"软件控制","action_type":"execute","target_object":"creo","details":"用户通过管理面板启动 creo 软件","created_at":"2025-07-23T11:59:23.387233","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"05640c4b-3970-4930-83bc-722f0a2da861","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 启动成功,进程ID: 67636","created_at":"2025-07-23T11:59:26.870496","duration":3473,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":67636,"task_id":"d971243e-d5a0-4e16-88a2-10183897301a"}} +{"id":"8cd56c1a-87a4-472c-b030-f78a4506179c","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-23T12:00:22.154796","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} +{"id":"7dee4097-86be-40f6-8a8b-a2fbac12dbf8","log_type":"user_operation","level":"info","user_id":"admin","client_id":"web_client","session_id":null,"operation":"测试Creo连接","operation_category":"连接测试","action_type":"read","target_object":"creo","details":"用户通过界面测试 Creo 软件的连接状态","created_at":"2025-07-23T12:00:22.722187","duration":0,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":null} diff --git a/logs/operation_logs/operation_2025-07-24.jsonl b/logs/operation_logs/operation_2025-07-24.jsonl new file mode 100644 index 0000000..ddd1ca6 --- /dev/null +++ b/logs/operation_logs/operation_2025-07-24.jsonl @@ -0,0 +1,20 @@ +{"id":"ccd2e956-4da6-4494-bb1c-e2dd987df853","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"启动软件任务已创建: revit","created_at":"2025-07-24T17:02:20.703066","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"9df6aab3-4eb1-47b9-8129-2c9c193570ac","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"软件 revit 启动成功,进程ID: 13584","created_at":"2025-07-24T17:02:21.733654","duration":1029,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":13584,"task_id":"6b4458ce-914d-4cc4-9833-f31d70052f47"}} +{"id":"5a86dc20-ec60-4bc4-bdf0-8f4898bd9a17","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"启动软件任务已创建: revit","created_at":"2025-07-24T17:06:25.453082","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"bd995631-57ec-40ea-804e-e558bbd2d093","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"软件 revit 启动成功,进程ID: 23736","created_at":"2025-07-24T17:06:26.486502","duration":1032,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":23736,"task_id":"689b5d21-f4fd-4b7d-9efa-2feeadd8a24e"}} +{"id":"7cd84fdd-80a3-4cff-81a8-dc122e6eac60","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"停止软件任务已创建: revit","created_at":"2025-07-24T17:07:00.021144","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"2038d5b7-55ad-4d15-9e5b-975400114fab","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"软件 revit 停止成功","created_at":"2025-07-24T17:07:00.109663","duration":87,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"task_id":"1740c5da-df79-44c5-afd3-735473d0c008"}} +{"id":"a830ed70-c4d7-4693-a3c7-181df3242609","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"启动软件任务已创建: creo","created_at":"2025-07-24T17:07:31.093787","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"cdb68c53-322e-4d13-b67e-7cd78d7754df","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 启动成功,进程ID: 10532","created_at":"2025-07-24T17:07:32.087720","duration":993,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":10532,"task_id":"916549e1-ed83-4751-9471-5f5fe9358499"}} +{"id":"86f214ee-c7d6-49f9-b2e4-93b3b8de0a1f","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"停止软件任务已创建: creo","created_at":"2025-07-24T17:08:11.569017","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"fa4a7b01-d34b-448b-9150-11299b8bec11","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 停止成功","created_at":"2025-07-24T17:08:11.574522","duration":4,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"task_id":"23b39107-7973-4cce-9d0a-2449a2c5390e"}} +{"id":"b20f6631-5010-4dc2-8001-b6807e0e094f","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"停止软件任务已创建: creo","created_at":"2025-07-24T17:18:28.576948","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"2f39ab37-88fc-4f18-88a7-a982d0be6987","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 停止成功","created_at":"2025-07-24T17:18:30.659139","duration":2082,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"task_id":"971d43c2-df76-403f-8a68-9aa74adf7338"}} +{"id":"ac9709a1-c7a8-4afb-b975-10dc0d69cf64","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"启动软件任务已创建: revit","created_at":"2025-07-24T17:20:15.648532","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"f6e88419-fc43-41f6-a9bf-671b3aecf0f9","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"软件 revit 启动成功,进程ID: 36776","created_at":"2025-07-24T17:20:16.659709","duration":1011,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":36776,"task_id":"d311d753-e8e9-4a31-9f04-b0ffb8b369a2"}} +{"id":"15bacd35-5145-4de1-be1d-5f3b4beb258b","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"启动软件任务已创建: creo","created_at":"2025-07-24T17:20:36.862447","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"9950f269-4c9d-49e7-b598-1140c4490dec","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"start_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 启动成功,进程ID: 14660","created_at":"2025-07-24T17:20:37.873452","duration":1011,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"process_id":14660,"task_id":"db0c6dc5-3f58-4ce8-9407-388ec8775929"}} +{"id":"637dcda3-4f32-4999-bbcb-e741e6c93fa3","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"停止软件任务已创建: creo","created_at":"2025-07-24T17:20:56.319919","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"3d9d62a7-dec9-464a-9a2a-0bd75bc3e6f6","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"creo","details":"软件 creo 停止成功","created_at":"2025-07-24T17:20:58.393434","duration":2072,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"task_id":"78088b60-7bd7-4cff-8ab6-690dcc913c1e"}} +{"id":"fc278ff9-031f-41f5-8713-a98cff1987ed","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"停止软件任务已创建: revit","created_at":"2025-07-24T17:21:04.384747","duration":null,"ip_address":null,"user_agent":null,"software_version":null,"status":"pending","error_message":null,"extra_data":null} +{"id":"08d4f3da-163d-48e2-ba35-188efbd3d855","log_type":"system_operation","level":"info","user_id":null,"client_id":null,"session_id":null,"operation":"stop_software","operation_category":"software_management","action_type":"execute","target_object":"revit","details":"软件 revit 停止成功","created_at":"2025-07-24T17:21:06.486560","duration":2100,"ip_address":null,"user_agent":null,"software_version":null,"status":"success","error_message":null,"extra_data":{"task_id":"8942ea10-26d4-405c-a9d8-1845d85db443"}} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9f4c467 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,26 @@ +# FastAPI和相关依赖 +fastapi[all]==0.104.1 +uvicorn[standard]==0.24.0 +python-multipart==0.0.6 +websockets==12.0 + +# Pydantic设置管理 +pydantic==2.5.0 +pydantic-settings==2.1.0 + +# 配置文件解析 +PyYAML==6.0.1 + +# JWT认证 +python-jose[cryptography]==3.3.0 +passlib[bcrypt]==1.7.4 + +# 进程监控 +psutil==7.0.0 + +# 异步支持 +asyncio-extras==1.3.2 + +# 开发和测试 +pytest==7.4.3 +pytest-asyncio==0.21.1 \ No newline at end of file diff --git a/std.out b/std.out new file mode 100644 index 0000000..c403b7e --- /dev/null +++ b/std.out @@ -0,0 +1,3 @@ +ERROR - C:\Program Files\PTC\Creo 5.0.0.0\Common Files\text\config.pro, linenum 16: Keyword 'JLINK_DEBUG' is not valid. +ERROR - C:\Program Files\PTC\Creo 5.0.0.0\Common Files\text\config.pro, linenum 17: Keyword 'JLINK_DEBUG_LEVEL' is not valid. +ERROR - C:\Program Files\PTC\Creo 5.0.0.0\Common Files\text\config.pro, linenum 18: Keyword 'JLINK_DEBUG_FILE' is not valid. diff --git a/test_config.py b/test_config.py new file mode 100644 index 0000000..34e408f --- /dev/null +++ b/test_config.py @@ -0,0 +1,26 @@ +import sys +sys.path.append('app') + +from config import settings, software_config + +# 测试基础配置 +print("基础配置测试:") +print(f"应用名称: {settings.app_name}") +print(f"端口: {settings.port}") +print(f"调试模式: {settings.debug}") + +# 测试软件配置 +print("\n软件配置测试:") +try: + config = software_config.load_config() + print("✅ 配置文件加载成功") + + software_list = software_config.get_software_list() + print(f"可用软件: {software_list}") + + for software_id in software_list: + sw_config = software_config.get_software_config(software_id) + print(f"{software_id}: {sw_config['name']}") + +except Exception as e: + print(f"❌ 配置加载失败: {e}") \ No newline at end of file diff --git a/test_models.py b/test_models.py new file mode 100644 index 0000000..23bfeb3 --- /dev/null +++ b/test_models.py @@ -0,0 +1,123 @@ +import sys +sys.path.append('app') + +from datetime import datetime +from models.user import User +from models.software import SoftwareDefinition +from models.task import Task, TaskStatus, TaskType +from schemas.auth import LoginRequest, LoginResponse, TokenData +from schemas.software import SoftwareInfo, SoftwareActionResponse +from schemas.task import TaskResponse, SSEEvent + +def test_models(): + print("=== 测试数据模型 ===") + + # 测试用户模型 + print("\n1. 测试用户模型:") + try: + user = User( + username="admin", + password_hash="$2b$12$test", + is_active=True, + permissions=["software:start", "software:stop"] + ) + print(f"✅ 用户模型: {user.username}, 权限: {user.permissions}") + except Exception as e: + print(f"❌ 用户模型失败: {e}") + + # 测试软件定义模型 + print("\n2. 测试软件定义模型:") + try: + software = SoftwareDefinition( + name="PTC Creo", + executable_path="C:\\Program Files\\PTC\\Creo\\parametric.exe", + startup_args=[], + startup_timeout=60, + check_process_name="parametric.exe" + ) + print(f"✅ 软件定义: {software.name}, 超时: {software.startup_timeout}s") + except Exception as e: + print(f"❌ 软件定义失败: {e}") + + # 测试任务模型 + print("\n3. 测试任务模型:") + try: + task = Task( + id="task_001", + task_type=TaskType.START_SOFTWARE, + software_id="creo", + status=TaskStatus.PENDING, + created_at=datetime.now(), + progress=0 + ) + print(f"✅ 任务模型: {task.id}, 类型: {task.task_type}, 状态: {task.status}") + except Exception as e: + print(f"❌ 任务模型失败: {e}") + +def test_schemas(): + print("\n=== 测试API模式 ===") + + # 测试登录请求 + print("\n1. 测试登录请求:") + try: + login_req = LoginRequest(username="admin", password="password123") + print(f"✅ 登录请求: 用户名 {login_req.username}") + except Exception as e: + print(f"❌ 登录请求失败: {e}") + + # 测试登录响应 + print("\n2. 测试登录响应:") + try: + login_resp = LoginResponse( + access_token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...", + refresh_token="refresh_token_here", + expires_in=1800 + ) + print(f"✅ 登录响应: Token类型 {login_resp.token_type}, 过期时间 {login_resp.expires_in}s") + except Exception as e: + print(f"❌ 登录响应失败: {e}") + + # 测试软件信息 + print("\n3. 测试软件信息:") + try: + software_info = SoftwareInfo( + id="creo", + name="PTC Creo", + is_running=False, + process_id=None + ) + print(f"✅ 软件信息: {software_info.name}, 运行状态: {software_info.is_running}") + except Exception as e: + print(f"❌ 软件信息失败: {e}") + + # 测试软件操作响应 + print("\n4. 测试软件操作响应:") + try: + action_resp = SoftwareActionResponse( + task_id="task_001", + software_id="creo", + action="start", + status=TaskStatus.PENDING, + message="软件启动任务已创建" + ) + print(f"✅ 操作响应: 任务 {action_resp.task_id}, 操作 {action_resp.action}") + except Exception as e: + print(f"❌ 操作响应失败: {e}") + + # 测试SSE事件 + print("\n5. 测试SSE事件:") + try: + sse_event = SSEEvent( + event_type="software_status", + task_id="task_001", + software_id="creo", + data={"status": "starting", "progress": 25} + ) + print(f"✅ SSE事件: 类型 {sse_event.event_type}, 数据: {sse_event.data}") + except Exception as e: + print(f"❌ SSE事件失败: {e}") + +if __name__ == "__main__": + test_models() + test_schemas() + print("\n=== 模型测试完成 ===") \ No newline at end of file diff --git a/test_process_monitor.py b/test_process_monitor.py new file mode 100644 index 0000000..bb55855 --- /dev/null +++ b/test_process_monitor.py @@ -0,0 +1,77 @@ +import sys +import asyncio +sys.path.append('app') + +from core.process_monitor import process_monitor + +async def status_callback(event_type: str, software_id: str, data: dict): + """状态变化回调函数""" + print(f"📡 事件通知: {event_type} - {software_id}") + print(f" 数据: {data}") + +async def test_process_monitor(): + print("=== 测试进程监控器 ===") + + # 添加回调函数 + process_monitor.add_callback(status_callback) + + # 测试系统信息获取 + print("\n1. 测试系统信息获取:") + try: + system_info = await process_monitor.get_system_info() + print(f"✅ 系统信息获取成功:") + print(f" - CPU使用率: {system_info['cpu']['percent']}%") + print(f" - 内存使用率: {system_info['memory']['percent']}%") + print(f" - 磁盘使用率: {system_info['disk']['percent']:.1f}%") + except Exception as e: + print(f"❌ 系统信息获取失败: {e}") + + # 测试查找软件进程 + print("\n2. 测试查找软件进程:") + try: + software_processes = await process_monitor.find_software_processes() + print(f"✅ 软件进程查找完成:") + for software_id, processes in software_processes.items(): + print(f" - {software_id}: 找到 {len(processes)} 个进程") + for proc in processes: + print(f" PID: {proc['pid']}, 名称: {proc['name']}") + except Exception as e: + print(f"❌ 软件进程查找失败: {e}") + + # 如果找到了creo进程,添加到监控 + if 'creo' in software_processes and software_processes['creo']: + print("\n3. 测试添加进程监控:") + try: + creo_process = software_processes['creo'][0] + process_monitor.add_process('creo', creo_process['pid']) + print(f"✅ 已添加Creo进程到监控: PID {creo_process['pid']}") + + # 等待一段时间观察监控效果 + print(" 监控中,等待10秒...") + await asyncio.sleep(10) + + # 获取进程信息 + process_info = process_monitor.get_process_info('creo') + if process_info: + print(f" - 进程状态: {process_info.status}") + print(f" - CPU使用率: {process_info.cpu_percent}%") + print(f" - 内存使用率: {process_info.memory_percent}%") + print(f" - 运行时间: {(process_info.last_check - process_info.start_time).total_seconds():.1f}秒") + + except Exception as e: + print(f"❌ 进程监控测试失败: {e}") + else: + print("\n3. 未找到Creo进程,跳过监控测试") + + # 停止监控 + print("\n4. 停止监控:") + try: + await process_monitor.stop_monitoring() + print("✅ 监控已停止") + except Exception as e: + print(f"❌ 停止监控失败: {e}") + + print("\n=== 进程监控器测试完成 ===") + +if __name__ == "__main__": + asyncio.run(test_process_monitor()) \ No newline at end of file diff --git a/test_software_manager.py b/test_software_manager.py new file mode 100644 index 0000000..4c42741 --- /dev/null +++ b/test_software_manager.py @@ -0,0 +1,64 @@ +import sys +import asyncio +sys.path.append('app') + +from core.software_manager import software_manager + +async def test_software_manager(): + print("=== 测试软件管理器 ===") + + # 测试获取软件列表 + print("\n1. 测试获取软件列表:") + try: + software_list = await software_manager.get_software_list() + print("✅ 软件列表获取成功:") + for software in software_list: + print(f" - {software['id']}: {software['name']} (运行: {software['is_running']})") + except Exception as e: + print(f"❌ 获取软件列表失败: {e}") + + # 测试软件状态检查 + print("\n2. 测试软件状态检查:") + try: + creo_running = software_manager.is_software_running("creo") + autocad_running = software_manager.is_software_running("autocad") + print(f"✅ Creo 运行状态: {creo_running}") + print(f"✅ AutoCAD 运行状态: {autocad_running}") + except Exception as e: + print(f"❌ 软件状态检查失败: {e}") + + # 测试启动软件(不会真正启动,因为路径可能不存在) + print("\n3. 测试启动软件任务创建:") + try: + task = await software_manager.start_software("creo") + print(f"✅ 启动任务创建成功:") + print(f" - 任务ID: {task.id}") + print(f" - 软件ID: {task.software_id}") + print(f" - 任务类型: {task.task_type}") + print(f" - 初始状态: {task.status}") + + # 等待一会儿看任务状态变化 + await asyncio.sleep(2) + updated_task = software_manager.get_task(task.id) + print(f" - 2秒后状态: {updated_task.status}") + print(f" - 进度: {updated_task.progress}%") + if updated_task.error_message: + print(f" - 错误信息: {updated_task.error_message}") + + except Exception as e: + print(f"❌ 启动软件任务失败: {e}") + + # 测试错误处理 + print("\n4. 测试错误处理:") + try: + # 尝试启动不存在的软件 + await software_manager.start_software("nonexistent") + except ValueError as e: + print(f"✅ 正确捕获错误: {e}") + except Exception as e: + print(f"❌ 未预期的错误: {e}") + + print("\n=== 软件管理器测试完成 ===") + +if __name__ == "__main__": + asyncio.run(test_software_manager()) \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/trail.txt.1 b/trail.txt.1 new file mode 100644 index 0000000..645a1a4 --- /dev/null +++ b/trail.txt.1 @@ -0,0 +1,38 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 63520 +! Application: Creo_Parametric +! Start date&time: 2025/07/19 21:26:05 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807199, AppSize 83613790, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1428 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1460 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1476 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1476 0 0 790 1920 0 0 1080 13 +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_0_close` +!mem_use INCREASE Blocks 832160, AppSize 108271410, SysSize 124625600 +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!End of Trail File diff --git a/trail.txt.10 b/trail.txt.10 new file mode 100644 index 0000000..e5321ab --- /dev/null +++ b/trail.txt.10 @@ -0,0 +1,392 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 62852 +! Application: Creo_Parametric +! Start date&time: 2025/07/23 11:59:29 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807219, AppSize 83549211, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1396 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1396 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1412 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1444 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1444 0 0 790 1920 0 0 1080 13 +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_0_close` +!mem_use INCREASE Blocks 832165, AppSize 108238122, SysSize 124591632 +~ Minimize `main_dlg_cur` `main_dlg_cur` +~ Restore `main_dlg_cur` `main_dlg_cur` +~ Command `ProCmdUtilAux` +~ Activate `aux_apps` `RegisterBtn` +< 2 0.118519 178 0 0 100 1920 0 0 1080 13 +~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` \ + `file_open` +~ Select `file_open` `Ph_list.Filelist` 1 `HELLO.DAT` +~ Activate `file_open` `Ph_list.Filelist` 1 `HELLO.DAT` +~ Select `aux_apps` `AppList` 0 +~ Select `aux_apps` `AppList` 1 `Hello World` +~ Activate `aux_apps` `StartBtn` +!Application (Hello World): running DLL-mode user_initialize +! Message Dialog: Info +! : New HTTP Server Starting on port 12345 +~ Activate `UI Message Dialog` `ok` +!Application (Hello World): returned from DLL-mode user_initialize; status is 0 +!Application (Hello World): started via UI. +! exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\otk\otk_cpp\otk_examples\miany\MFCCreoDll.dll +! type: synchronous Pro/TOOLKIT DLL +!%CI程序'Hello World'成功启动。 +~ Activate `aux_apps` `CloseBtn` +~ Command `ProCmdSessionChangeDir` +< 2 0.118519 178 0 0 100 1920 0 0 1080 13 +~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` \ + `file_open` +~ Activate `file_open` `mydocs_pb` +~ Select `file_open` `Ph_list.Filelist` 1 `陀螺泵PROE设计` +~ Activate `file_open` `Ph_list.Filelist` 1 `陀螺泵PROE设计` +~ Trail `UI Desktop` `UI Desktop` `PREVIEW_POPUP_TIMER` \ + `file_open:Ph_list.Filelist:` +~ Activate `file_open` `Cancel` +~ Command `ProCmdModelOpen` +< 2 0.118519 178 0 0 100 1920 0 0 1080 13 +~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` \ + `file_open` +~ Select `file_open` `Ph_list.Filelist` 1 `asm0001.asm` +~ Activate `file_open` `Ph_list.Filelist` 1 `asm0001.asm` +!Command ProCmdModelOpenExe was pushed from the software. +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\asm0001.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\tethered_spinning_top_with_pump.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft___top_-_modified_ti.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451827.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451824.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451824.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\top_ball-point_tip.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\top_ball-point_tip.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\iso_8752_5_x_35.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\iso_8752_5_x_35.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451827.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451830.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451828.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451828.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\impeller.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\impeller.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451830.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft___top_-_modified_ti.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\hand_powered_tether.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_hose.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_hose.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_cylindrical_pu.asm.2 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_girp_handle_with_conrod.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_connecting_rod.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_left_connecting_rod.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_left_connecting_rod.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_right_connecting_rod.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_right_connecting_rod.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_conrod_pin.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_conrod_pin.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_connecting_rod.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle___lever.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_lever.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_lever.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\bracket_pin.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\bracket_pin.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_pump.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_pump.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump-lever_pin.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump-lever_pin.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-t.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-t.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-b.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-b.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\leaf_spring.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\leaf_spring.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle___lever.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_girp_handle_with_conrod.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cylindrical_pump.asm.2 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451850.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_seal.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_seal.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451848.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451848.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\return-spring_pin.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\return-spring_pin.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451850.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451856.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451851.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451851.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451855.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451852.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451852.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_return_spring_1.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_return_spring_1.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\iso_7047__h__-_m2x8_-_4_8_-_h.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\iso_7047__h__-_m2x8_-_4_8_-_h.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451855.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451856.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cylindrical_pump.asm.2 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_cylindrical_pu.asm.2 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cjv_casing_with_ring_bracket.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451861.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_line.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_line.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451860.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451860.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451861.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_assembly.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_lock_nut.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_lock_nut.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors_and_pins.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pins.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_1.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_1.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_2.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_2.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_3.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_3.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_4.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_4.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pins.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_inner_visor.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_inner_visor.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_outer_visor.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_outer_visor.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors_and_pins.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring_with_rubber_valves.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valves.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_1.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_1.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_2.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_2.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_3.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_3.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_4.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_4.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valves.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring_with_rubber_valves.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_assembly.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cjv_casing_with_ring_bracket.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\hand_powered_tether.asm.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\tethered_spinning_top_with_pump.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_-_less_outer_shaft.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\synchronizer.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\disk.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\disk.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\sync_ring.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\sync_ring.prt.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rings_-_cvj.asm.1 +!23-Jul-25 12:00:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring1.prt.1 +!23-Jul-25 12:00:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring1.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring3.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring3.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring2.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring2.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\rings_-_cvj.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\synchronizer.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft___pivots.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivots.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot1.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot1.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot2.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot2.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot3.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot3.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivots.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft___pivots.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivots.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot1.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot1.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot3.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot3.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot_2.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot_2.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivots.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screws_-_outer_shaft.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screw_1.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\screw_1.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screw_2.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\screw_2.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screw_3.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\screw_3.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\screws_-_outer_shaft.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_-_less_outer_shaft.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\spinning_top_extended_-_upper_a.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451908.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451905.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451905.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pin_for_rail.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pin_for_rail.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cap.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\cap.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451908.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451912.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-long.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-long.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451910.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451910.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-short.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-short.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451912.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\weight_link.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\weight_link.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451915.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451914.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451914.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451915.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\spider_link.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\spider_link.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451918.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451917.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451917.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451918.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451921.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451919.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451919.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\piston_seal.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\piston_seal.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451921.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\spinning_top_extended_-_upper_a.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\hand_pump.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\button_base.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\button_base.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_buttons.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451929.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451924.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451924.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump1-attachments.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_5.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119156.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119156.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119157.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119157.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_5.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_6.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119158.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119158.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119159.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119159.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_6.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_1.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_1.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump1-attachments.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451929.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451935.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451930.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451930.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump2-attachments.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_7.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119162.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119162.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119163.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119163.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_7.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_10.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119164.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119164.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119165.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119165.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_10.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_2.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_2.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump2-attachments.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451935.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451941.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451936.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451936.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump3-attachments.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_8.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119168.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119168.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119169.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119169.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_8.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_11.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119170.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119170.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119171.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119171.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_11.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_3.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_3.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump3-attachments.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451941.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451947.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451942.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451942.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump4-attachments.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_9.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119174.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119174.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119175.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119175.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_9.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_12.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119176.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119176.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119177.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119177.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_12.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_4.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_4.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump4-attachments.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451947.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_buttons.asm.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\hand_pump.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord_-_coiled.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cord_eye.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\cord_eye.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord_-_coiled.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\fancy_weights.asm.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\sickle_weight.prt.1 +!23-Jul-25 12:00:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\sickle_weight.prt.1 +!23-Jul-25 12:00:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\mace_weight.prt.1 +!23-Jul-25 12:00:37 End C:\Users\sladr\Documents\陀螺泵PROE设计\mace_weight.prt.1 +!23-Jul-25 12:00:37 Start C:\Users\sladr\Documents\陀螺泵PROE设计\spear_weight.prt.1 +!23-Jul-25 12:00:37 End C:\Users\sladr\Documents\陀螺泵PROE设计\spear_weight.prt.1 +!23-Jul-25 12:00:37 Start C:\Users\sladr\Documents\陀螺泵PROE设计\trident_weight.prt.1 +!23-Jul-25 12:00:37 End C:\Users\sladr\Documents\陀螺泵PROE设计\trident_weight.prt.1 +!23-Jul-25 12:00:37 Start C:\Users\sladr\Documents\陀螺泵PROE设计\hammer_weight.prt.1 +!23-Jul-25 12:00:37 End C:\Users\sladr\Documents\陀螺泵PROE设计\hammer_weight.prt.1 +!23-Jul-25 12:00:37 End C:\Users\sladr\Documents\陀螺泵PROE设计\fancy_weights.asm.1 +!23-Jul-25 12:00:37 Start C:\Users\sladr\Documents\陀螺泵PROE设计\prop_projectile.prt.1 +!23-Jul-25 12:00:37 End C:\Users\sladr\Documents\陀螺泵PROE设计\prop_projectile.prt.1 +!23-Jul-25 12:00:37 End C:\Users\sladr\Documents\陀螺泵PROE设计\asm0001.asm.1 +@ oa_sel_filter_set _30_ +!mem_use INCREASE Blocks 1491626, AppSize 242305907, SysSize 269866456 +@ stack attr 2 +< 0 0.932741 1444 0 0 787 1920 0 0 1080 13 +< 0 0.932741 1336 0 0 787 1920 0 0 1080 13 +< 0 0.932741 1387 0 0 787 1920 0 0 1080 13 +~ Timer `UI Desktop` `UI Desktop` `EmbedBrowserTimer` +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!Application (Hello World): running DLL-mode user_terminate +!Application (Hello World): returned from DLL-mode user_terminate +!End of Trail File diff --git a/trail.txt.11 b/trail.txt.11 new file mode 100644 index 0000000..8e173b9 --- /dev/null +++ b/trail.txt.11 @@ -0,0 +1,32 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 35816 +! Application: Creo_Parametric +! Start date&time: 2025/07/24 17:07:38 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807219, AppSize 83483691, SysSize 97684280 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1396 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1396 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1412 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1444 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1444 0 0 790 1920 0 0 1080 13 +~ Minimize `main_dlg_cur` `main_dlg_cur` +!mem_use INCREASE Blocks 832140, AppSize 108110157, SysSize 124403912 +~ Restore `main_dlg_cur` `main_dlg_cur` +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_0_close` diff --git a/trail.txt.12 b/trail.txt.12 new file mode 100644 index 0000000..98b5d2b --- /dev/null +++ b/trail.txt.12 @@ -0,0 +1,28 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 3056 +! Application: Creo_Parametric +! Start date&time: 2025/07/24 17:20:42 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807221, AppSize 83549299, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1396 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1396 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1412 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1444 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1444 0 0 790 1920 0 0 1080 13 diff --git a/trail.txt.2 b/trail.txt.2 new file mode 100644 index 0000000..5f30230 --- /dev/null +++ b/trail.txt.2 @@ -0,0 +1,38 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 16704 +! Application: Creo_Parametric +! Start date&time: 2025/07/21 08:18:18 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807201, AppSize 83482819, SysSize 97684280 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1428 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1460 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1476 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1476 0 0 790 1920 0 0 1080 13 +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_0_close` +!mem_use INCREASE Blocks 832140, AppSize 108128565, SysSize 124420616 +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!End of Trail File diff --git a/trail.txt.3 b/trail.txt.3 new file mode 100644 index 0000000..9e309e2 --- /dev/null +++ b/trail.txt.3 @@ -0,0 +1,38 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 33724 +! Application: Creo_Parametric +! Start date&time: 2025/07/21 08:20:57 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807203, AppSize 83548331, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1428 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1460 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1476 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1476 0 0 790 1920 0 0 1080 13 +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_0_close` +!mem_use INCREASE Blocks 832151, AppSize 108171658, SysSize 124526128 +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!End of Trail File diff --git a/trail.txt.4 b/trail.txt.4 new file mode 100644 index 0000000..2d35178 --- /dev/null +++ b/trail.txt.4 @@ -0,0 +1,36 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 41848 +! Application: Creo_Parametric +! Start date&time: 2025/07/21 11:51:26 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807205, AppSize 83548387, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1428 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1460 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1476 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1476 0 0 790 1920 0 0 1080 13 +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!End of Trail File diff --git a/trail.txt.5 b/trail.txt.5 new file mode 100644 index 0000000..0fc8857 --- /dev/null +++ b/trail.txt.5 @@ -0,0 +1,38 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 54916 +! Application: Creo_Parametric +! Start date&time: 2025/07/21 14:30:57 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807208, AppSize 83548435, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1428 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1460 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1476 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1476 0 0 790 1920 0 0 1080 13 +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_0_close` +!mem_use INCREASE Blocks 832144, AppSize 108087890, SysSize 124443920 +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!End of Trail File diff --git a/trail.txt.6 b/trail.txt.6 new file mode 100644 index 0000000..34dd28c --- /dev/null +++ b/trail.txt.6 @@ -0,0 +1,38 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 5528 +! Application: Creo_Parametric +! Start date&time: 2025/07/21 14:51:21 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807209, AppSize 83548571, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1428 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1460 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1476 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1476 0 0 790 1920 0 0 1080 13 +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_0_close` +!mem_use INCREASE Blocks 832154, AppSize 108170882, SysSize 124526128 +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!End of Trail File diff --git a/trail.txt.7 b/trail.txt.7 new file mode 100644 index 0000000..53cd542 --- /dev/null +++ b/trail.txt.7 @@ -0,0 +1,66 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 39512 +! Application: Creo_Parametric +! Start date&time: 2025/07/21 16:27:17 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807210, AppSize 83548611, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1428 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1460 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1476 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1476 0 0 790 1920 0 0 1080 13 +~ Command `ProCmdUtilAux` +!mem_use INCREASE Blocks 832223, AppSize 108216071, SysSize 124627704 +~ Activate `aux_apps` `RegisterBtn` +< 2 0.118519 178 0 0 100 1920 0 0 1080 13 +~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` \ + `file_open` +~ Select `file_open` `Ph_list.Filelist` 1 `HELLO.DAT` +~ Activate `file_open` `Ph_list.Filelist` 1 `HELLO.DAT` +~ Select `aux_apps` `AppList` 1 `Hello World` +~ Activate `aux_apps` `StartBtn` +!Application (Hello World): running DLL-mode user_initialize +! Message Dialog: Info +! : New HTTP Server Starting on port 12345 +~ Activate `UI Message Dialog` `ok` +!Application (Hello World): returned from DLL-mode user_initialize; status is 0 +!Application (Hello World): started via UI. +! exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\otk\otk_cpp\otk_examples\miany\MFCCreoDll.dll +! type: synchronous Pro/TOOLKIT DLL +!%CI程序'Hello World'成功启动。 +~ Activate `aux_apps` `CloseBtn` +~ Minimize `main_dlg_cur` `main_dlg_cur` +~ Restore `main_dlg_cur` `main_dlg_cur` +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ Activate `UI Message Dialog` `no` +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!Application (Hello World): running DLL-mode user_terminate +!Application (Hello World): returned from DLL-mode user_terminate +!End of Trail File diff --git a/trail.txt.8 b/trail.txt.8 new file mode 100644 index 0000000..08907f9 --- /dev/null +++ b/trail.txt.8 @@ -0,0 +1,387 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 50720 +! Application: Creo_Parametric +! Start date&time: 2025/07/21 18:48:36 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807211, AppSize 83548667, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1428 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1460 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1476 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1476 0 0 790 1920 0 0 1080 13 +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_0_close` +!mem_use INCREASE Blocks 832146, AppSize 108119650, SysSize 124475456 +~ Command `ProCmdUtilAux` +~ Activate `aux_apps` `RegisterBtn` +< 2 0.118519 178 0 0 100 1920 0 0 1080 13 +~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` \ + `file_open` +~ Select `file_open` `Ph_list.Filelist` 1 `HELLO.DAT` +~ Activate `file_open` `Ph_list.Filelist` 1 `HELLO.DAT` +~ Select `aux_apps` `AppList` 1 `Hello World` +~ Activate `aux_apps` `StartBtn` +!Application (Hello World): running DLL-mode user_initialize +! Message Dialog: Info +! : New HTTP Server Starting on port 12345 +~ Activate `UI Message Dialog` `ok` +!Application (Hello World): returned from DLL-mode user_initialize; status is 0 +!Application (Hello World): started via UI. +! exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\otk\otk_cpp\otk_examples\miany\MFCCreoDll.dll +! type: synchronous Pro/TOOLKIT DLL +!%CI程序'Hello World'成功启动。 +~ Activate `aux_apps` `CloseBtn` +~ Command `ProCmdModelOpen` +< 2 0.118519 178 0 0 100 1920 0 0 1080 13 +~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` \ + `file_open` +~ Select `file_open` `Ph_list.Filelist` 1 `陀螺泵PROE设计` +~ Activate `file_open` `Ph_list.Filelist` 1 `陀螺泵PROE设计` +~ Select `file_open` `Ph_list.Filelist` 1 `overall_top_design.asm` +~ Activate `file_open` `Ph_list.Filelist` 1 `overall_top_design.asm` +!Command ProCmdModelOpenExe was pushed from the software. +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\overall_top_design.asm.6 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\asm0001.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\tethered_spinning_top_with_pump.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft___top_-_modified_ti.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451827.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451824.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451824.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\top_ball-point_tip.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\top_ball-point_tip.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\iso_8752_5_x_35.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\iso_8752_5_x_35.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451827.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451830.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451828.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451828.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\impeller.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\impeller.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451830.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft___top_-_modified_ti.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\hand_powered_tether.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_hose.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_hose.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_cylindrical_pu.asm.2 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_girp_handle_with_conrod.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_connecting_rod.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_left_connecting_rod.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_left_connecting_rod.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_right_connecting_rod.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_right_connecting_rod.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_conrod_pin.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_conrod_pin.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_connecting_rod.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle___lever.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_lever.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_lever.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\bracket_pin.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\bracket_pin.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_pump.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_pump.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump-lever_pin.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump-lever_pin.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-t.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-t.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-b.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-b.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\leaf_spring.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\leaf_spring.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle___lever.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_girp_handle_with_conrod.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cylindrical_pump.asm.2 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451850.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_seal.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_seal.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451848.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451848.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\return-spring_pin.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\return-spring_pin.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451850.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451856.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451851.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451851.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451855.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451852.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451852.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_return_spring_1.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_return_spring_1.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\iso_7047__h__-_m2x8_-_4_8_-_h.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\iso_7047__h__-_m2x8_-_4_8_-_h.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451855.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451856.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cylindrical_pump.asm.2 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_cylindrical_pu.asm.2 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cjv_casing_with_ring_bracket.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451861.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_line.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_line.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451860.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451860.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451861.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_assembly.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_lock_nut.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_lock_nut.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors_and_pins.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pins.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_1.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_1.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_2.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_2.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_3.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_3.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_4.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_4.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pins.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_inner_visor.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_inner_visor.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_outer_visor.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_outer_visor.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors_and_pins.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring_with_rubber_valves.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valves.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_1.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_1.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_2.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_2.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_3.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_3.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_4.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_4.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valves.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring_with_rubber_valves.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_assembly.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cjv_casing_with_ring_bracket.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\hand_powered_tether.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\tethered_spinning_top_with_pump.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_-_less_outer_shaft.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\synchronizer.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\disk.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\disk.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\sync_ring.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\sync_ring.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rings_-_cvj.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring1.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring1.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring3.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring3.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring2.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring2.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\rings_-_cvj.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\synchronizer.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft___pivots.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivots.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot1.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot1.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot2.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot2.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot3.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot3.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivots.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft___pivots.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivots.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot1.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot1.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot3.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot3.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot_2.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot_2.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivots.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screws_-_outer_shaft.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screw_1.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\screw_1.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screw_2.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\screw_2.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screw_3.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\screw_3.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\screws_-_outer_shaft.asm.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_-_less_outer_shaft.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\spinning_top_extended_-_upper_a.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451908.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451905.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451905.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pin_for_rail.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\pin_for_rail.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cap.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\cap.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451908.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451912.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-long.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-long.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451910.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451910.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-short.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-short.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451912.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\weight_link.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\weight_link.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451915.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451914.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451914.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451915.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\spider_link.prt.1 +!21-Jul-25 18:49:35 End C:\Users\sladr\Documents\陀螺泵PROE设计\spider_link.prt.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451918.asm.1 +!21-Jul-25 18:49:35 Start C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451917.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451917.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451918.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451921.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451919.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451919.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\piston_seal.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\piston_seal.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451921.asm.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\spinning_top_extended_-_upper_a.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\hand_pump.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\button_base.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\button_base.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_buttons.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451929.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451924.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451924.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump1-attachments.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_5.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119156.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119156.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119157.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119157.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_5.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_6.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119158.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119158.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119159.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119159.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_6.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_1.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_1.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump1-attachments.asm.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451929.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451935.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451930.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451930.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump2-attachments.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_7.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119162.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119162.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119163.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119163.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_7.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_10.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119164.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119164.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119165.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119165.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_10.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_2.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_2.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump2-attachments.asm.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451935.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451941.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451936.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451936.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump3-attachments.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_8.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119168.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119168.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119169.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119169.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_8.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_11.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119170.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119170.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119171.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119171.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_11.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_3.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_3.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump3-attachments.asm.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451941.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451947.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451942.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451942.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump4-attachments.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_9.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119174.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119174.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119175.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119175.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_9.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_12.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119176.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119176.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119177.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119177.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_12.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_4.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_4.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump4-attachments.asm.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451947.asm.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_buttons.asm.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\hand_pump.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord_-_coiled.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cord_eye.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\cord_eye.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord_-_coiled.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\fancy_weights.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\sickle_weight.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\sickle_weight.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\mace_weight.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\mace_weight.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\spear_weight.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\spear_weight.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\trident_weight.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\trident_weight.prt.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\hammer_weight.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\hammer_weight.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\fancy_weights.asm.1 +!21-Jul-25 18:49:36 Start C:\Users\sladr\Documents\陀螺泵PROE设计\prop_projectile.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\prop_projectile.prt.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\asm0001.asm.1 +!21-Jul-25 18:49:36 End C:\Users\sladr\Documents\陀螺泵PROE设计\overall_top_design.asm.6 +@ oa_sel_filter_set _30_ +!mem_use INCREASE Blocks 1492684, AppSize 244355549, SysSize 271975736 +@ stack attr 2 +< 0 0.932741 1476 0 0 787 1920 0 0 1080 13 +< 0 0.932741 1368 0 0 787 1920 0 0 1080 13 +< 0 0.932741 1420 0 0 787 1920 0 0 1080 13 +~ Timer `UI Desktop` `UI Desktop` `EmbedBrowserTimer` +~ Minimize `main_dlg_cur` `main_dlg_cur` +~ Restore `main_dlg_cur` `main_dlg_cur` +~ Minimize `main_dlg_cur` `main_dlg_cur` +~ Restore `main_dlg_cur` `main_dlg_cur` +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!Application (Hello World): running DLL-mode user_terminate +!Application (Hello World): returned from DLL-mode user_terminate +!End of Trail File diff --git a/trail.txt.9 b/trail.txt.9 new file mode 100644 index 0000000..810c23a --- /dev/null +++ b/trail.txt.9 @@ -0,0 +1,386 @@ +!trail file version No. 1900 +!Creo TM 5.0 (c) 2025 by PTC Inc. All Rights Reserved. +!Exit Logger data: +! Process ID: 3040 +! Application: Creo_Parametric +! Start date&time: 2025/07/21 20:04:48 +! language: chinese_cn +! machine type: x86e_win64 +! datecode: 5.0.0.0 +! Server: NONE +! Workspace: NONE +! traceback file: D:\App\python\CadHubManage\traceback.log +!end Exit Logger data. +< 0 1.220741 1783 0 0 1030 1920 0 0 1080 13 +!mem_use INCREASE Blocks 807212, AppSize 83548683, SysSize 97749784 +< 0 0.943407 1623 0 0 796 1920 0 0 1080 13 +< 0 0.943407 1428 0 0 796 1920 0 0 1080 13 +< 0 0.941037 1428 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1444 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1460 0 0 794 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +!%CI欢迎使用 Creo Parametric 5.0.0.0。 +!AFX datecode: 5.0.0.0 2017.12.21.11 +!AFX exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\x86e_win64\afx50.dll +!AFX text path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\afx\ +< 0 1.089185 1476 0 0 919 1920 0 0 1080 13 +< 0 0.941037 1476 0 0 794 1920 0 0 1080 13 +< 0 0.936296 1476 0 0 790 1920 0 0 1080 13 +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_0_close` +!mem_use INCREASE Blocks 832161, AppSize 108387674, SysSize 124741776 +~ Activate `main_dlg_cur` `EMBED_BROWSER_SMARTAB_LAYOUT_buttons_lay_ph.page_1_close` +~ Command `ProCmdModelOpen` +< 2 0.118519 178 0 0 100 1920 0 0 1080 13 +~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` \ + `file_open` +~ Select `file_open` `Ph_list.Filelist` 1 `陀螺泵PROE设计` +~ Activate `file_open` `Ph_list.Filelist` 1 `陀螺泵PROE设计` +~ Select `file_open` `Ph_list.Filelist` 1 `overall_top_design.asm` +~ Activate `file_open` `Ph_list.Filelist` 1 `overall_top_design.asm` +!Command ProCmdModelOpenExe was pushed from the software. +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\overall_top_design.asm.6 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\asm0001.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\tethered_spinning_top_with_pump.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft___top_-_modified_ti.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451827.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451824.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451824.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\top_ball-point_tip.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\top_ball-point_tip.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\iso_8752_5_x_35.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\iso_8752_5_x_35.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_top-451827.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451830.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451828.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451828.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\impeller.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\impeller.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft-modified-451830.asm.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_shaft___top_-_modified_ti.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\hand_powered_tether.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_hose.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_hose.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_cylindrical_pu.asm.2 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_girp_handle_with_conrod.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_connecting_rod.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_left_connecting_rod.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_left_connecting_rod.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_right_connecting_rod.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_right_connecting_rod.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_conrod_pin.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_conrod_pin.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_connecting_rod.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle___lever.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_lever.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_lever.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\bracket_pin.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\bracket_pin.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_pump.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_pump.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump-lever_pin.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump-lever_pin.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-t.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-t.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-b.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump-cover_retaining_pin-b.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\leaf_spring.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\leaf_spring.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_grip_handle___lever.asm.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pumping_girp_handle_with_conrod.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cylindrical_pump.asm.2 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451850.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_seal.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_seal.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451848.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451848.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\return-spring_pin.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\return-spring_pin.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_piston-451850.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451856.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451851.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451851.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451855.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451852.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451852.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_return_spring_1.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_return_spring_1.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\iso_7047__h__-_m2x8_-_4_8_-_h.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\iso_7047__h__-_m2x8_-_4_8_-_h.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cover-451855.asm.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_cylinder-451856.asm.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\cylindrical_pump.asm.2 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\grip_handle_with_cylindrical_pu.asm.2 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cjv_casing_with_ring_bracket.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451861.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_line.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\pneumatic_line.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451860.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451860.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring_bracket-451861.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_assembly.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_lock_nut.prt.1 +!21-Jul-25 20:05:03 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_lock_nut.prt.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors_and_pins.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pins.asm.1 +!21-Jul-25 20:05:03 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_1.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_1.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_2.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_3.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_4.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pin_4.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\visor_pins.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_inner_visor.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_inner_visor.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_outer_visor.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_outer_visor.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_visors_and_pins.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring_with_rubber_valves.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valves.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_1.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_1.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_2.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_3.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_4.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valve_4.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_1-way_rubber_valves.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_ring_with_rubber_valves.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\casing_assembly.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\cjv_casing_with_ring_bracket.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\hand_powered_tether.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\tethered_spinning_top_with_pump.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_-_less_outer_shaft.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\synchronizer.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\disk.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\disk.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\sync_ring.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\sync_ring.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rings_-_cvj.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring1.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring1.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring3.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\ring2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\ring2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\rings_-_cvj.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\synchronizer.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft___pivots.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivots.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot1.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot1.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot2.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivot3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_pivots.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\inner_shaft___pivots.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivots.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot1.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot1.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot3.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot_2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivot_2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\outer_pivots.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screws_-_outer_shaft.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screw_1.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\screw_1.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screw_2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\screw_2.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\screw_3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\screw_3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\screws_-_outer_shaft.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\cvj_-_less_outer_shaft.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\spinning_top_extended_-_upper_a.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451908.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451905.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451905.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pin_for_rail.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pin_for_rail.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cap.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\cap.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\rail-451908.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451912.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-long.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-long.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451910.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451910.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-short.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\link_pin-short.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\lower_link-451912.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\weight_link.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\weight_link.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451915.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451914.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451914.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\upper_link-451915.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\spider_link.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\spider_link.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451918.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451917.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451917.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\regular_metal_weight-451918.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451921.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451919.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451919.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\piston_seal.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\piston_seal.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\modified_piston-451921.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\spinning_top_extended_-_upper_a.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\hand_pump.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\button_base.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\button_base.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_buttons.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451929.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451924.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451924.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump1-attachments.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_5.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119156.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119156.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119157.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119157.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_5.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_6.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119158.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119158.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119159.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119159.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_6.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_1.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_1.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump1-attachments.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_1-451929.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451935.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451930.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451930.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump2-attachments.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_7.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119162.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119162.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119163.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119163.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_7.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_10.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119164.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119164.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119165.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119165.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_10.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_2.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump2-attachments.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_2-451935.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451941.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451936.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451936.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump3-attachments.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_8.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119168.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119168.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119169.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119169.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_8.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_11.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119170.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119170.prt.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119171.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119171.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_11.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_3.prt.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump3-attachments.asm.1 +!21-Jul-25 20:05:04 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_3-451941.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451947.asm.1 +!21-Jul-25 20:05:04 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451942.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451942.prt.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\pump4-attachments.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_9.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119174.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119174.prt.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119175.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119175.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_9.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_12.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119176.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119176.prt.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119177.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\solid1-119177.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\one-way_rubber_valve_12.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_4.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\coil_spring_4.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump4-attachments.asm.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_button_4-451947.asm.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\pump_buttons.asm.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\hand_pump.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord_-_coiled.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord.prt.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\cord_eye.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\cord_eye.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\rip_chord_-_coiled.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\fancy_weights.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\sickle_weight.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\sickle_weight.prt.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\mace_weight.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\mace_weight.prt.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\spear_weight.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\spear_weight.prt.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\trident_weight.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\trident_weight.prt.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\hammer_weight.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\hammer_weight.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\fancy_weights.asm.1 +!21-Jul-25 20:05:05 Start C:\Users\sladr\Documents\陀螺泵PROE设计\prop_projectile.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\prop_projectile.prt.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\asm0001.asm.1 +!21-Jul-25 20:05:05 End C:\Users\sladr\Documents\陀螺泵PROE设计\overall_top_design.asm.6 +@ oa_sel_filter_set _30_ +!mem_use INCREASE Blocks 1491886, AppSize 242500080, SysSize 270112568 +@ stack attr 2 +< 0 0.932741 1476 0 0 787 1920 0 0 1080 13 +< 0 0.932741 1368 0 0 787 1920 0 0 1080 13 +< 0 0.932741 1420 0 0 787 1920 0 0 1080 13 +~ Timer `UI Desktop` `UI Desktop` `EmbedBrowserTimer` +~ Activate `main_dlg_cur` `page_Tools_control_btn` 1 +~ Command `ProCmdUtilAux` +~ Activate `aux_apps` `RegisterBtn` +< 2 0.118519 178 0 0 100 1920 0 0 1080 13 +~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` \ + `file_open` +~ Activate `file_open` `mydocs_pb` +~ Select `file_open` `Ph_list.Filelist` 1 `HELLO.DAT` +~ Activate `file_open` `Ph_list.Filelist` 1 `HELLO.DAT` +~ Select `aux_apps` `AppList` 1 `Hello World` +~ Activate `aux_apps` `StartBtn` +!Application (Hello World): running DLL-mode user_initialize +! Message Dialog: Info +! : New HTTP Server Starting on port 12345 +~ Activate `UI Message Dialog` `ok` +!Application (Hello World): returned from DLL-mode user_initialize; status is 0 +!Application (Hello World): started via UI. +! exec path: C:\Program Files\PTC\Creo 5.0.0.0\Common Files\otk\otk_cpp\otk_examples\miany\MFCCreoDll.dll +! type: synchronous Pro/TOOLKIT DLL +!%CI程序'Hello World'成功启动。 +~ Activate `aux_apps` `CloseBtn` +~ Close `main_dlg_cur` `main_dlg_cur` +!Command ProCmdOSExit was pushed from the software. +! Message Dialog: Warning +! : Creo Parametric 将终止,所有未保存的工作都将会丢失。 +! : 是否确实要退出? +~ FocusIn `UI Message Dialog` `yes` +~ Activate `UI Message Dialog` `yes` +!Application (Hello World): running DLL-mode user_terminate +!Application (Hello World): returned from DLL-mode user_terminate +!End of Trail File diff --git a/开发步骤.md b/开发步骤.md new file mode 100644 index 0000000..8ac68f1 --- /dev/null +++ b/开发步骤.md @@ -0,0 +1,91 @@ +# CadHubManage 开发步骤 + +## 项目概述 +通过Web接口控制Windows服务器上软件的Python FastAPI项目 + +## 开发进度 + +### ✅ 已完成 +1. **创建项目基础目录结构** - 已完成 + - 创建了app/、configs/、logs/、tests/等主要目录 + - 添加了所有必要的__init__.py文件 + +2. **配置项目依赖和环境** - 已完成 + - 用户配置了依赖环境 + +3. **实现核心配置管理(config.py)** - 已完成 + - 实现Settings类和SoftwareConfig类 + - 支持环境变量和YAML配置文件 + +4. **创建配置文件(software_config.yaml, users.json)** - 已完成 + - 创建了软件配置和用户配置文件 + - 配置了真实的Creo路径 + +5. **创建数据模型和 Pydantic 模式(models/ 和 schemas/)** - 已完成 + - 完成用户、软件、任务等数据模型 + - 完成认证、软件操作、任务等API模式 + +6. **开发软件管理核心类(core/software_manager.py)** - 已完成 + - 实现软件启动/重启功能(已删除停止功能) + - 实现进程监控和并发控制 + - 测试成功启动Creo软件 + +7. **实现进程监控功能(core/process_monitor.py)** - 已完成 + - 实现实时进程状态监控 + - 系统资源信息获取(CPU、内存、磁盘) + - 进程查找和回调机制 + - 测试成功监控Creo进程(PID: 68220) + +8. **开发 WebSocket 连接管理(core/websocket_manager.py)** - 已完成 + - 实现WebSocket连接池管理 + - 集成软件管理功能到WebSocket + - 支持实时状态推送和软件控制指令 + - 测试成功WebSocket连接和软件控制 + +9. **创建 API 路由(认证、软件控制、WebSocket)** - 已完成 + - 实现基础API路由框架 + - WebSocket连接端点已实现 + - 认证和软件控制接口待完善 + +10. **实现 FastAPI 主入口(main.py)** - 已完成 + - 配置CORS和路由注册 + - 集成WebSocket和软件管理器 + +11. **开发操作日志系统** - 已完成 + - 设计日志数据模型和存储方案(文件存储) + - 实现基于文件的日志管理器(JSON Lines格式) + - 支持日志轮转、清理和查询功能 + - 集成到WebSocket消息处理 + - 记录系统操作和用户自定义操作两类日志 + - 创建完整的日志查询REST API + - 消除硬编码,实现参数化配置 + +### 🔄 进行中 +12. **实现 JWT 认证系统** - 待开始 + - 完善用户登录、注册、token刷新接口 + - 实现基于角色的权限控制 + - 集成认证中间件到WebSocket和REST API + +### ⏳ 待完成 +13. **完善异常处理和系统监控** +14. **系统优化和部署准备** + +## 技术栈 +- 后端:Python + FastAPI +- 异步通信:WebSocket +- 进程管理:subprocess + psutil +- 认证:JWT Token + +## 核心功能 +- 软件启动/重启控制(已删除停止功能) +- 实时状态监控 +- 进程管理 +- 用户认证 +- WebSocket事件推送 +- 操作日志记录和查询 + +## 注意事项 +- 遵循MVP设计思路,最小化实现 +- 保持现有代码稳定性 +- 只添加代码,不修改现有功能 +- 确保向后兼容性 \ No newline at end of file