diff --git a/CLAUDE.md b/CLAUDE.md
index de33c01..0b6e7b0 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -142,6 +142,8 @@ const handleOperation = async () => {
- ✅ Creo专属页面框架(模型分析、导出工具)
- ✅ 通用格式转换页面框架
- ✅ 智能薄壳化分析接口(startShellAnalysis)
+- ✅ WebSocket日志系统完整接入
+- ✅ 信息面板实时日志显示和软件状态同步
## 页面添加标准流程
@@ -153,13 +155,29 @@ const handleOperation = async () => {
- 添加页面切换处理方法
4. **组件间通信** - 使用emit事件,不用router.push
+## 日志系统实现总结
+
+### ✅ 完成内容
+1. **API钩子集成** - 所有CAD操作自动通过WebSocket记录日志到后台
+2. **实时状态同步** - CAD连接成功后自动更新信息面板软件状态
+3. **字段名修复** - 修复了后台返回`is_running`字段与前端`status`字段不匹配的问题
+4. **分页逻辑修复** - 修复了翻页时重复调用后台接口导致的分页错乱
+5. **日志实时显示** - 信息面板实时接收并按时间排序显示操作日志
+
+### 🔧 关键修改
+- **apiClient.js**: 添加WebSocket日志记录钩子和CAD连接成功时的状态同步
+- **InfoManagementPanel.vue**: 修复软件状态字段名和分页逻辑
+- **websocketService.js**: 连接时主动获取历史日志,清理调试输出
+
+### 💡 数据流
+`CAD操作` → `API调用` → `后处理钩子` → `WebSocket记录` → `后台存储` → `实时推送` → `信息面板显示`
+
## 待开发功能
- Creo模型分析、导出工具具体功能实现
- 通用格式转换具体功能实现
- Revit和PDMS集成
- 3D模型查看器
-- 实时日志系统
---
diff --git a/src/components/layout/InfoManagementPanel.vue b/src/components/layout/InfoManagementPanel.vue
index ba1a09b..3ca9abe 100644
--- a/src/components/layout/InfoManagementPanel.vue
+++ b/src/components/layout/InfoManagementPanel.vue
@@ -63,21 +63,21 @@
{{ software.name || software.id }}
-
- {{ getStatusText(software.status) }}
+
+ {{ software.is_running ? '运行中' : '已停止' }}
@@ -236,8 +243,8 @@ const operationFilter = ref('')
const currentPage = ref(1)
const logsPerPage = 10
-// 过滤后的日志
-const filteredLogs = computed(() => {
+// 过滤后的完整日志
+const allFilteredLogs = computed(() => {
let filtered = logs.value
if (logTypeFilter.value) {
@@ -252,14 +259,19 @@ const filteredLogs = computed(() => {
)
}
+ return filtered
+})
+
+// 当前页显示的日志
+const filteredLogs = computed(() => {
const start = (currentPage.value - 1) * logsPerPage
const end = start + logsPerPage
- return filtered.slice(start, end)
+ return allFilteredLogs.value.slice(start, end)
})
// 总页数
const totalPages = computed(() => {
- return Math.ceil(logs.value.length / logsPerPage)
+ return Math.ceil(allFilteredLogs.value.length / logsPerPage)
})
// WebSocket事件监听器管理
@@ -283,9 +295,10 @@ const initListeners = () => {
// 监听日志更新
const onLogUpdate = (logData) => {
if (Array.isArray(logData)) {
- logs.value = logData
+ // 新日志添加到顶部,保持最新日志在前
+ logs.value = [...logData].sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
} else if (logData.logs) {
- logs.value = logData.logs
+ logs.value = [...logData.logs].sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
}
}
websocketService.on('onLogUpdate', onLogUpdate)
@@ -433,14 +446,12 @@ const formatTime = (timestamp) => {
const prevPage = () => {
if (currentPage.value > 1) {
currentPage.value--
- refreshLogs()
}
}
const nextPage = () => {
if (currentPage.value < totalPages.value) {
currentPage.value++
- refreshLogs()
}
}
diff --git a/src/services/apiClient.js b/src/services/apiClient.js
index 66673ed..3bce57b 100644
--- a/src/services/apiClient.js
+++ b/src/services/apiClient.js
@@ -2,7 +2,9 @@
// 包含拦截器、日志记录和后处理能力
import { getDefaultRequestConfig, getNotificationConfig } from '@/config/cad'
+import cadConfig from '@/config/cad'
import { ElNotification, ElLoading } from 'element-plus'
+import websocketService from './websocketService'
// 日志记录系统
class ApiLogger {
@@ -59,6 +61,7 @@ class ApiClient {
// 设置通知处理器
setupNotificationHandler() {
+ // 通知处理器
PostProcessManager.addHandler(async (response, context) => {
// 默认显示通知,可通过配置关闭
if (context.showNotification !== false && context.operationContext) {
@@ -84,6 +87,35 @@ class ApiClient {
}
}
})
+
+ // WebSocket日志记录处理器
+ PostProcessManager.addHandler(async (response, context) => {
+ if (context.operationContext) {
+ const { software, operation } = context.operationContext
+ const status = response.ok ? 'success' : 'failed'
+ const details = response.ok ?
+ `${software} ${operation}执行成功` :
+ `${software} ${operation}执行失败: ${response.statusText || '未知错误'}`
+
+ // 发送到WebSocket后台记录
+ websocketService.logOperation(
+ `${software} - ${operation}`,
+ details,
+ {
+ action_type: 'execute',
+ target_object: context.url,
+ status: status,
+ duration: context.duration || 0,
+ operation_category: 'CAD操作'
+ }
+ )
+
+ // CAD连接成功时同步更新信息面板软件状态
+ if (response.ok && operation === '连接测试') {
+ websocketService.getSoftwareList()
+ }
+ }
+ })
}
// 核心请求方法
diff --git a/src/services/websocketService.js b/src/services/websocketService.js
index 28dfca0..eb4ef9d 100644
--- a/src/services/websocketService.js
+++ b/src/services/websocketService.js
@@ -31,7 +31,6 @@ class WebSocketService {
onOperationTypesUpdate: []
}
- console.log('WebSocketService 初始化完成')
}
// 获取WebSocket连接URL
@@ -47,12 +46,10 @@ class WebSocketService {
}
const url = this.getConnectionUrl()
- console.log('开始连接统一管理后台:', url)
this.setState('CONNECTING')
this.ws = new WebSocket(url)
this.ws.onopen = (event) => {
- console.log('统一管理后台连接成功')
this.setState('CONNECTED')
this.reconnectAttempts = 0
this.startHeartbeat()
@@ -63,13 +60,13 @@ class WebSocketService {
this.getSoftwareList()
this.getLogStats()
this.getOperationTypes()
+ this.queryLogs()
}, 500)
}
this.ws.onmessage = (event) => {
try {
const message = JSON.parse(event.data)
- console.log('收到管理后台消息:', message)
this.handleMessage(message)
this.emit('onMessage', message)
} catch (error) {
@@ -78,7 +75,6 @@ class WebSocketService {
}
this.ws.onclose = (event) => {
- console.log('统一管理后台连接关闭:', event)
this.setState('DISCONNECTED')
this.stopHeartbeat()
this.emit('onClose', event)
@@ -86,7 +82,6 @@ class WebSocketService {
// 自动重连
if (!event.wasClean && this.reconnectAttempts < this.config.RECONNECT_ATTEMPTS) {
const delay = this.config.RECONNECT_DELAY * Math.pow(2, this.reconnectAttempts)
- console.log(`统一管理后台将在 ${delay}ms 后重连,第 ${this.reconnectAttempts + 1} 次尝试`)
setTimeout(() => {
this.reconnectAttempts++
this.connect()
@@ -95,7 +90,6 @@ class WebSocketService {
}
this.ws.onerror = (event) => {
- console.error('统一管理后台连接错误:', event)
this.setState('ERROR')
this.emit('onError', event)
}
@@ -103,7 +97,6 @@ class WebSocketService {
// 断开连接
disconnect() {
- console.log('主动断开统一管理后台连接')
if (this.ws) {
this.ws.close(1000, 'Client disconnect')
this.ws = null
@@ -116,11 +109,9 @@ class WebSocketService {
send(message) {
if (this.connectionState === 'CONNECTED' && this.ws) {
const jsonMessage = JSON.stringify(message)
- console.log('发送管理后台消息:', message)
this.ws.send(jsonMessage)
return true
} else {
- console.warn('统一管理后台未连接,消息发送失败:', message)
return false
}
}
@@ -132,13 +123,17 @@ class WebSocketService {
this.handleInfoMessage(message)
break
case 'heartbeat':
- console.log('收到心跳响应')
break
case 'software_list_update':
this.handleSoftwareListUpdate(message)
break
case 'log_recorded':
- console.log('操作日志已记录:', message.data)
+ break
+ case 'software_started':
+ case 'software_stopped':
+ case 'software_restarted':
+ // 软件状态变更后自动刷新软件列表
+ this.getSoftwareList()
break
case 'error':
console.error('管理后台错误:', message.message)
@@ -181,7 +176,6 @@ class WebSocketService {
handleSoftwareListUpdate(message) {
if (message.data && message.data.software_list) {
this.softwareList = message.data.software_list
- console.log('软件列表已更新:', this.softwareList)
this.emit('onSoftwareUpdate', this.softwareList)
}
}
@@ -208,7 +202,6 @@ class WebSocketService {
return false
}
- console.log('启动软件:', softwareId)
return this.send({
type: 'start_software',
software_id: softwareId
@@ -222,7 +215,6 @@ class WebSocketService {
return false
}
- console.log('停止软件:', softwareId)
return this.send({
type: 'stop_software',
software_id: softwareId
@@ -236,7 +228,6 @@ class WebSocketService {
return false
}
- console.log('重启软件:', softwareId)
return this.send({
type: 'restart_software',
software_id: softwareId
@@ -261,7 +252,6 @@ class WebSocketService {
operation_category: options.operation_category || '软件控制'
}
- console.log('记录操作日志:', logData)
return this.send(logData)
}
@@ -281,7 +271,6 @@ class WebSocketService {
if (filters.start_time) queryData.start_time = filters.start_time
if (filters.end_time) queryData.end_time = filters.end_time
- console.log('查询操作日志:', queryData)
return this.send(queryData)
}
@@ -300,19 +289,16 @@ class WebSocketService {
// API方法 - 获取日志统计信息
getLogStats() {
- console.log('获取日志统计信息')
return this.send({ type: 'get_log_stats' })
}
// API方法 - 清理过期日志
cleanupLogs() {
- console.log('清理过期日志')
return this.send({ type: 'cleanup_logs' })
}
// API方法 - 获取操作类型列表
getOperationTypes() {
- console.log('获取操作类型列表')
return this.send({ type: 'get_operation_types' })
}
@@ -337,7 +323,6 @@ class WebSocketService {
if (this.connectionState !== newState) {
const oldState = this.connectionState
this.connectionState = newState
- console.log(`统一管理后台状态变化: ${oldState} -> ${newState}`)
this.emit('onStateChange', { oldState, newState })
}
}