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:
commit
e6261532f7
28
.env.example
Normal file
28
.env.example
Normal 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
143
CHECKPOINT.md
Normal 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
3
CLAUDE.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Development Approach
|
||||
|
||||
- 一步步开发,不要一次性开发。每次开发完由我来编译、测试
|
||||
269
Readme.md
Normal file
269
Readme.md
Normal 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
0
app/__init__.py
Normal file
BIN
app/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
app/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/config.cpython-39.pyc
Normal file
BIN
app/__pycache__/config.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/main.cpython-39.pyc
Normal file
BIN
app/__pycache__/main.cpython-39.pyc
Normal file
Binary file not shown.
0
app/api/__init__.py
Normal file
0
app/api/__init__.py
Normal file
BIN
app/api/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
app/api/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
0
app/api/v1/__init__.py
Normal file
0
app/api/v1/__init__.py
Normal file
BIN
app/api/v1/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
app/api/v1/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/api/v1/__pycache__/auth.cpython-39.pyc
Normal file
BIN
app/api/v1/__pycache__/auth.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/api/v1/__pycache__/logs.cpython-39.pyc
Normal file
BIN
app/api/v1/__pycache__/logs.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/api/v1/__pycache__/software.cpython-39.pyc
Normal file
BIN
app/api/v1/__pycache__/software.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/api/v1/__pycache__/websocket.cpython-39.pyc
Normal file
BIN
app/api/v1/__pycache__/websocket.cpython-39.pyc
Normal file
Binary file not shown.
509
app/api/v1/websocket.py
Normal file
509
app/api/v1/websocket.py
Normal 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
81
app/config.py
Normal 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
0
app/core/__init__.py
Normal file
BIN
app/core/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
app/core/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/core/__pycache__/log_manager.cpython-39.pyc
Normal file
BIN
app/core/__pycache__/log_manager.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/core/__pycache__/process_monitor.cpython-39.pyc
Normal file
BIN
app/core/__pycache__/process_monitor.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/core/__pycache__/software_manager.cpython-39.pyc
Normal file
BIN
app/core/__pycache__/software_manager.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/core/__pycache__/websocket_manager.cpython-39.pyc
Normal file
BIN
app/core/__pycache__/websocket_manager.cpython-39.pyc
Normal file
Binary file not shown.
376
app/core/log_manager.py
Normal file
376
app/core/log_manager.py
Normal 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
266
app/core/process_monitor.py
Normal 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
55
app/core/security.py
Normal 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"},
|
||||
)
|
||||
502
app/core/software_manager.py
Normal file
502
app/core/software_manager.py
Normal 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()
|
||||
126
app/core/websocket_manager.py
Normal file
126
app/core/websocket_manager.py
Normal 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
59
app/main.py
Normal 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
0
app/models/__init__.py
Normal file
BIN
app/models/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
app/models/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/models/__pycache__/operation_log.cpython-39.pyc
Normal file
BIN
app/models/__pycache__/operation_log.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/models/__pycache__/software.cpython-39.pyc
Normal file
BIN
app/models/__pycache__/software.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/models/__pycache__/task.cpython-39.pyc
Normal file
BIN
app/models/__pycache__/task.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/models/__pycache__/user.cpython-39.pyc
Normal file
BIN
app/models/__pycache__/user.cpython-39.pyc
Normal file
Binary file not shown.
98
app/models/operation_log.py
Normal file
98
app/models/operation_log.py
Normal 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
11
app/models/software.py
Normal 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
32
app/models/task.py
Normal 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
10
app/models/user.py
Normal 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
0
app/schemas/__init__.py
Normal file
BIN
app/schemas/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
app/schemas/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/schemas/__pycache__/auth.cpython-39.pyc
Normal file
BIN
app/schemas/__pycache__/auth.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/schemas/__pycache__/software.cpython-39.pyc
Normal file
BIN
app/schemas/__pycache__/software.cpython-39.pyc
Normal file
Binary file not shown.
BIN
app/schemas/__pycache__/task.cpython-39.pyc
Normal file
BIN
app/schemas/__pycache__/task.cpython-39.pyc
Normal file
Binary file not shown.
26
app/schemas/auth.py
Normal file
26
app/schemas/auth.py
Normal 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
30
app/schemas/software.py
Normal 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
25
app/schemas/task.py
Normal 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
0
app/services/__init__.py
Normal file
0
app/utils/__init__.py
Normal file
0
app/utils/__init__.py
Normal file
15
configs/software_config.yaml
Normal file
15
configs/software_config.yaml
Normal 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
16
configs/users.json
Normal 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
833
frontend-api-docs.md
Normal 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*
|
||||
25
logs/operation_logs/operation_2025-07-21.jsonl
Normal file
25
logs/operation_logs/operation_2025-07-21.jsonl
Normal 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}
|
||||
5
logs/operation_logs/operation_2025-07-23.jsonl
Normal file
5
logs/operation_logs/operation_2025-07-23.jsonl
Normal 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}
|
||||
20
logs/operation_logs/operation_2025-07-24.jsonl
Normal file
20
logs/operation_logs/operation_2025-07-24.jsonl
Normal 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
26
requirements.txt
Normal 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
3
std.out
Normal 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
26
test_config.py
Normal 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
123
test_models.py
Normal 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
77
test_process_monitor.py
Normal 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
64
test_software_manager.py
Normal 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
0
tests/__init__.py
Normal file
38
trail.txt.1
Normal file
38
trail.txt.1
Normal 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
392
trail.txt.10
Normal 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
32
trail.txt.11
Normal 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
28
trail.txt.12
Normal 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
38
trail.txt.2
Normal 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
38
trail.txt.3
Normal 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
36
trail.txt.4
Normal 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
38
trail.txt.5
Normal 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
38
trail.txt.6
Normal 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
66
trail.txt.7
Normal 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
387
trail.txt.8
Normal 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
386
trail.txt.9
Normal 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
91
开发步骤.md
Normal 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设计思路,最小化实现
|
||||
- 保持现有代码稳定性
|
||||
- 只添加代码,不修改现有功能
|
||||
- 确保向后兼容性
|
||||
Loading…
Reference in New Issue
Block a user