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 <noreply@anthropic.com>
This commit is contained in:
root 2025-07-24 17:24:49 +08:00
commit e6261532f7
76 changed files with 5490 additions and 0 deletions

28
.env.example Normal file
View File

@ -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=["*"]

143
CHECKPOINT.md Normal file
View File

@ -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% (已完成停止软件功能)

3
CLAUDE.md Normal file
View File

@ -0,0 +1,3 @@
## Development Approach
- 一步步开发,不要一次性开发。每次开发完由我来编译、测试

269
Readme.md Normal file
View File

@ -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连接
- 统一的消息处理机制
- 实时状态更新和错误推送
- 完整的日志查询和管理功能
**迁移优势:**
- ✅ 架构简化,代码更清晰
- ✅ 实时性能提升
- ✅ 资源使用优化
- ✅ 功能完整性保持
- ✅ 开发效率提升

0
app/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

0
app/api/__init__.py Normal file
View File

Binary file not shown.

0
app/api/v1/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

509
app/api/v1/websocket.py Normal file
View File

@ -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)

81
app/config.py Normal file
View File

@ -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)

0
app/core/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

376
app/core/log_manager.py Normal file
View File

@ -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()

266
app/core/process_monitor.py Normal file
View File

@ -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()

55
app/core/security.py Normal file
View File

@ -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"},
)

View File

@ -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()

View File

@ -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()

59
app/main.py Normal file
View File

@ -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"}

0
app/models/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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 # 查询偏移量

11
app/models/software.py Normal file
View File

@ -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

32
app/models/task.py Normal file
View File

@ -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

10
app/models/user.py Normal file
View File

@ -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] = []

0
app/schemas/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

26
app/schemas/auth.py Normal file
View File

@ -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

30
app/schemas/software.py Normal file
View File

@ -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

25
app/schemas/task.py Normal file
View File

@ -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

0
app/services/__init__.py Normal file
View File

0
app/utils/__init__.py Normal file
View File

View File

@ -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"

16
configs/users.json Normal file
View File

@ -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"]
}
]
}

833
frontend-api-docs.md Normal file
View File

@ -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*

View File

@ -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}

View File

@ -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}

View File

@ -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"}}

26
requirements.txt Normal file
View File

@ -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

3
std.out Normal file
View File

@ -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.

26
test_config.py Normal file
View File

@ -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}")

123
test_models.py Normal file
View File

@ -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=== 模型测试完成 ===")

77
test_process_monitor.py Normal file
View File

@ -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())

64
test_software_manager.py Normal file
View File

@ -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())

0
tests/__init__.py Normal file
View File

38
trail.txt.1 Normal file
View File

@ -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

392
trail.txt.10 Normal file
View File

@ -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:<NULL>`
~ 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

32
trail.txt.11 Normal file
View File

@ -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`

28
trail.txt.12 Normal file
View File

@ -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

38
trail.txt.2 Normal file
View File

@ -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

38
trail.txt.3 Normal file
View File

@ -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

36
trail.txt.4 Normal file
View File

@ -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

38
trail.txt.5 Normal file
View File

@ -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

38
trail.txt.6 Normal file
View File

@ -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

66
trail.txt.7 Normal file
View File

@ -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

387
trail.txt.8 Normal file
View File

@ -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

386
trail.txt.9 Normal file
View File

@ -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

91
开发步骤.md Normal file
View File

@ -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设计思路最小化实现
- 保持现有代码稳定性
- 只添加代码,不修改现有功能
- 确保向后兼容性