完善保险项目和养殖端小程序

This commit is contained in:
xuqiuyun
2025-09-26 18:45:42 +08:00
parent 00dfa83fd1
commit ec3f472641
58 changed files with 4866 additions and 2233 deletions

View File

@@ -276,43 +276,43 @@ export const useDataStore = defineStore('data', () => {
}
// 实时数据更新方法WebSocket调用
function updateDeviceRealtime(deviceData) {
const index = devices.value.findIndex(device => device.id === deviceData.id)
if (index !== -1) {
// 更新现有设备数据
devices.value[index] = { ...devices.value[index], ...deviceData }
console.log(`设备 ${deviceData.id} 实时数据已更新`)
} else {
// 如果是新设备,添加到列表
devices.value.push(deviceData)
console.log(`新设备 ${deviceData.id} 已添加`)
}
}
// function updateDeviceRealtime(deviceData) {
// const index = devices.value.findIndex(device => device.id === deviceData.id)
// if (index !== -1) {
// // 更新现有设备数据
// devices.value[index] = { ...devices.value[index], ...deviceData }
// console.log(`设备 ${deviceData.id} 实时数据已更新`)
// } else {
// // 如果是新设备,添加到列表
// devices.value.push(deviceData)
// console.log(`新设备 ${deviceData.id} 已添加`)
// }
// }
function addNewAlert(alertData) {
// 添加新预警到列表顶部
alerts.value.unshift(alertData)
console.log(`新预警 ${alertData.id} 已添加`)
}
// function addNewAlert(alertData) {
// // 添加新预警到列表顶部
// alerts.value.unshift(alertData)
// console.log(`新预警 ${alertData.id} 已添加`)
// }
function updateAnimalRealtime(animalData) {
const index = animals.value.findIndex(animal => animal.id === animalData.id)
if (index !== -1) {
// 更新现有动物数据
animals.value[index] = { ...animals.value[index], ...animalData }
console.log(`动物 ${animalData.id} 实时数据已更新`)
} else {
// 如果是新动物记录,添加到列表
animals.value.push(animalData)
console.log(`新动物记录 ${animalData.id} 已添加`)
}
}
// function updateAnimalRealtime(animalData) {
// const index = animals.value.findIndex(animal => animal.id === animalData.id)
// if (index !== -1) {
// // 更新现有动物数据
// animals.value[index] = { ...animals.value[index], ...animalData }
// console.log(`动物 ${animalData.id} 实时数据已更新`)
// } else {
// // 如果是新动物记录,添加到列表
// animals.value.push(animalData)
// console.log(`新动物记录 ${animalData.id} 已添加`)
// }
// }
function updateStatsRealtime(statsData) {
// 更新统计数据
stats.value = { ...stats.value, ...statsData }
console.log('系统统计数据已实时更新')
}
// function updateStatsRealtime(statsData) {
// // 更新统计数据
// stats.value = { ...stats.value, ...statsData }
// console.log('系统统计数据已实时更新')
// }
function updateAlertStatus(alertId, status) {
const index = alerts.value.findIndex(alert => alert.id === alertId)
@@ -360,10 +360,10 @@ export const useDataStore = defineStore('data', () => {
fetchAllData,
// 实时数据更新方法
updateDeviceRealtime,
addNewAlert,
updateAnimalRealtime,
updateStatsRealtime,
// updateDeviceRealtime,
// addNewAlert,
// updateAnimalRealtime,
// updateStatsRealtime,
updateAlertStatus
}
})

View File

@@ -71,7 +71,7 @@ export const useUserStore = defineStore('user', () => {
localStorage.setItem('user', JSON.stringify(userData.value));
// 建立WebSocket连接
await connectWebSocket();
// await connectWebSocket();
}
return result;
@@ -87,42 +87,42 @@ export const useUserStore = defineStore('user', () => {
}
// WebSocket连接状态
const isWebSocketConnected = ref(false)
// const isWebSocketConnected = ref(false)
// 建立WebSocket连接
async function connectWebSocket() {
if (!token.value) {
console.log('无token跳过WebSocket连接')
return
}
// async function connectWebSocket() {
// if (!token.value) {
// console.log('无token跳过WebSocket连接')
// return
// }
try {
const webSocketService = await import('../utils/websocketService')
webSocketService.default.connect(token.value)
isWebSocketConnected.value = true
console.log('WebSocket连接已建立')
} catch (error) {
console.error('WebSocket连接失败:', error)
isWebSocketConnected.value = false
}
}
// try {
// const webSocketService = await import('../utils/websocketService')
// webSocketService.default.connect(token.value)
// isWebSocketConnected.value = true
// console.log('WebSocket连接已建立')
// } catch (error) {
// console.error('WebSocket连接失败:', error)
// isWebSocketConnected.value = false
// }
// }
// 断开WebSocket连接
async function disconnectWebSocket() {
try {
const webSocketService = await import('../utils/websocketService')
webSocketService.default.disconnect()
isWebSocketConnected.value = false
console.log('WebSocket连接已断开')
} catch (error) {
console.error('断开WebSocket连接失败:', error)
}
}
// async function disconnectWebSocket() {
// try {
// const webSocketService = await import('../utils/websocketService')
// webSocketService.default.disconnect()
// isWebSocketConnected.value = false
// console.log('WebSocket连接已断开')
// } catch (error) {
// console.error('断开WebSocket连接失败:', error)
// }
// }
// 登出操作
async function logout() {
// 断开WebSocket连接
await disconnectWebSocket()
// await disconnectWebSocket()
token.value = ''
userData.value = null
@@ -222,14 +222,14 @@ export const useUserStore = defineStore('user', () => {
token,
userData,
isLoggedIn,
isWebSocketConnected,
// isWebSocketConnected,
checkLoginStatus,
validateToken,
login,
logout,
updateUserInfo,
connectWebSocket,
disconnectWebSocket,
// connectWebSocket,
// disconnectWebSocket,
hasPermission,
hasRole,
canAccessMenu,

View File

@@ -1,379 +0,0 @@
/**
* WebSocket实时通信服务
* @file websocketService.js
* @description 前端WebSocket客户端处理实时数据接收
*/
import { io } from 'socket.io-client';
import { useUserStore } from '../stores/user';
import { useDataStore } from '../stores/data';
import { message, notification } from 'ant-design-vue';
class WebSocketService {
constructor() {
this.socket = null;
this.isConnected = false;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectInterval = 3000; // 3秒重连间隔
this.userStore = null;
this.dataStore = null;
}
/**
* 连接WebSocket服务器
* @param {string} token JWT认证令牌
*/
connect(token) {
if (this.socket && this.isConnected) {
console.log('WebSocket已连接无需重复连接');
return;
}
// 初始化store
this.userStore = useUserStore();
this.dataStore = useDataStore();
const serverUrl = import.meta.env.VITE_API_URL || 'http://localhost:5350';
console.log('正在连接WebSocket服务器:', serverUrl);
this.socket = io(serverUrl, {
auth: {
token: token
},
transports: ['websocket', 'polling'],
timeout: 20000,
reconnection: true,
reconnectionAttempts: this.maxReconnectAttempts,
reconnectionDelay: this.reconnectInterval
});
this.setupEventListeners();
}
/**
* 设置事件监听器
*/
setupEventListeners() {
if (!this.socket) return;
// 连接成功
this.socket.on('connect', () => {
this.isConnected = true;
this.reconnectAttempts = 0;
console.log('WebSocket连接成功连接ID:', this.socket.id);
message.success('实时数据连接已建立');
});
// 连接确认
this.socket.on('connected', (data) => {
console.log('收到服务器连接确认:', data);
});
// 设备状态更新
this.socket.on('device_update', (data) => {
console.log('收到设备状态更新:', data);
this.handleDeviceUpdate(data);
});
// 预警更新
this.socket.on('alert_update', (data) => {
console.log('收到预警更新:', data);
this.handleAlertUpdate(data);
});
// 紧急预警
this.socket.on('urgent_alert', (data) => {
console.log('收到紧急预警:', data);
this.handleUrgentAlert(data);
});
// 动物健康状态更新
this.socket.on('animal_update', (data) => {
console.log('收到动物健康状态更新:', data);
this.handleAnimalUpdate(data);
});
// 系统统计数据更新
this.socket.on('stats_update', (data) => {
console.log('收到系统统计数据更新:', data);
this.handleStatsUpdate(data);
});
// 性能监控数据(仅管理员)
this.socket.on('performance_update', (data) => {
console.log('收到性能监控数据:', data);
this.handlePerformanceUpdate(data);
});
// 连接断开
this.socket.on('disconnect', (reason) => {
this.isConnected = false;
console.log('WebSocket连接断开:', reason);
if (reason === 'io server disconnect') {
// 服务器主动断开,需要重新连接
this.reconnect();
}
});
// 连接错误
this.socket.on('connect_error', (error) => {
console.error('WebSocket连接错误:', error);
if (error.message.includes('认证失败') || error.message.includes('未提供认证令牌')) {
message.error('实时连接认证失败,请重新登录');
this.userStore.logout();
} else {
this.handleReconnect();
}
});
// 心跳响应
this.socket.on('pong', (data) => {
console.log('收到心跳响应:', data);
});
}
/**
* 处理设备状态更新
* @param {Object} data 设备数据
*/
handleDeviceUpdate(data) {
// 更新数据存储中的设备状态
if (this.dataStore) {
this.dataStore.updateDeviceRealtime(data.data);
}
// 如果设备状态异常,显示通知
if (data.data.status === 'offline') {
notification.warning({
message: '设备状态变化',
description: `设备 ${data.data.name} 已离线`,
duration: 4.5,
});
} else if (data.data.status === 'maintenance') {
notification.info({
message: '设备状态变化',
description: `设备 ${data.data.name} 进入维护模式`,
duration: 4.5,
});
}
}
/**
* 处理预警更新
* @param {Object} data 预警数据
*/
handleAlertUpdate(data) {
// 更新数据存储中的预警数据
if (this.dataStore) {
this.dataStore.addNewAlert(data.data);
}
// 显示预警通知
const alertLevel = data.data.level;
let notificationType = 'info';
if (alertLevel === 'critical') {
notificationType = 'error';
} else if (alertLevel === 'high') {
notificationType = 'warning';
}
notification[notificationType]({
message: '新预警',
description: `${data.data.farm_name}: ${data.data.message}`,
duration: 6,
});
}
/**
* 处理紧急预警
* @param {Object} data 紧急预警数据
*/
handleUrgentAlert(data) {
// 紧急预警使用模态框显示
notification.error({
message: '🚨 紧急预警',
description: `${data.alert.farm_name}: ${data.alert.message}`,
duration: 0, // 不自动关闭
style: {
backgroundColor: '#fff2f0',
border: '1px solid #ffccc7'
}
});
// 播放警报声音(如果浏览器支持)
this.playAlertSound();
}
/**
* 处理动物健康状态更新
* @param {Object} data 动物数据
*/
handleAnimalUpdate(data) {
// 更新数据存储
if (this.dataStore) {
this.dataStore.updateAnimalRealtime(data.data);
}
// 如果动物健康状态异常,显示通知
if (data.data.health_status === 'sick') {
notification.warning({
message: '动物健康状态变化',
description: `${data.data.farm_name}${data.data.type}出现健康问题`,
duration: 5,
});
} else if (data.data.health_status === 'quarantined') {
notification.error({
message: '动物健康状态变化',
description: `${data.data.farm_name}${data.data.type}已隔离`,
duration: 6,
});
}
}
/**
* 处理系统统计数据更新
* @param {Object} data 统计数据
*/
handleStatsUpdate(data) {
// 更新数据存储中的统计信息
if (this.dataStore) {
this.dataStore.updateStatsRealtime(data.data);
}
}
/**
* 处理性能监控数据更新
* @param {Object} data 性能数据
*/
handlePerformanceUpdate(data) {
// 只有管理员才能看到性能数据
if (this.userStore?.user?.roles?.includes('admin')) {
console.log('收到性能监控数据:', data);
// 可以通过事件总线通知性能监控组件更新
window.dispatchEvent(new CustomEvent('performance_update', { detail: data }));
}
}
/**
* 播放警报声音
*/
playAlertSound() {
try {
// 创建音频上下文
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
// 生成警报音
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.frequency.setValueAtTime(800, audioContext.currentTime);
gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
oscillator.start();
oscillator.stop(audioContext.currentTime + 0.5);
} catch (error) {
console.log('无法播放警报声音:', error);
}
}
/**
* 订阅农场数据
* @param {number} farmId 农场ID
*/
subscribeFarm(farmId) {
if (this.socket && this.isConnected) {
this.socket.emit('subscribe_farm', farmId);
console.log(`已订阅农场 ${farmId} 的实时数据`);
}
}
/**
* 取消订阅农场数据
* @param {number} farmId 农场ID
*/
unsubscribeFarm(farmId) {
if (this.socket && this.isConnected) {
this.socket.emit('unsubscribe_farm', farmId);
console.log(`已取消订阅农场 ${farmId} 的实时数据`);
}
}
/**
* 订阅设备数据
* @param {number} deviceId 设备ID
*/
subscribeDevice(deviceId) {
if (this.socket && this.isConnected) {
this.socket.emit('subscribe_device', deviceId);
console.log(`已订阅设备 ${deviceId} 的实时数据`);
}
}
/**
* 发送心跳
*/
sendHeartbeat() {
if (this.socket && this.isConnected) {
this.socket.emit('ping');
}
}
/**
* 处理重连
*/
handleReconnect() {
this.reconnectAttempts++;
if (this.reconnectAttempts <= this.maxReconnectAttempts) {
console.log(`尝试重连WebSocket (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
setTimeout(() => {
this.reconnect();
}, this.reconnectInterval * this.reconnectAttempts);
} else {
message.error('实时连接已断开,请刷新页面重试');
}
}
/**
* 重新连接
*/
reconnect() {
if (this.userStore?.token) {
this.connect(this.userStore.token);
}
}
/**
* 断开连接
*/
disconnect() {
if (this.socket) {
this.socket.disconnect();
this.socket = null;
this.isConnected = false;
console.log('WebSocket连接已断开');
}
}
/**
* 获取连接状态
* @returns {boolean} 连接状态
*/
getConnectionStatus() {
return this.isConnected;
}
}
// 创建单例实例
const webSocketService = new WebSocketService();
export default webSocketService;