This commit is contained in:
张成
2025-12-22 16:26:59 +08:00
parent aa2d03ee30
commit e17d5610f5
54 changed files with 11735 additions and 3 deletions

230
app/mixins/authMixin.js Normal file
View File

@@ -0,0 +1,230 @@
/**
* 用户认证管理 Mixin
*/
import { getToken } from '../utils/api';
export default {
data() {
return {
phone: '',
password: '',
isLoggedIn: false,
loginButtonText: '登录',
userName: '',
remainingDays: null,
snCode: '',
deviceId: '-',
listenChannel: '-',
userMenuInfo: {
userName: '',
snCode: ''
}
};
},
methods: {
async loadSavedConfig() {
try {
// 从 store 加载保存的手机号
if (this.$store) {
const savedPhone = this.$store.state.config.phone || this.$store.state.auth.phone;
if (savedPhone) {
this.phone = savedPhone;
}
}
// 注意:现在数据都在 store 中,通过持久化插件自动恢复
// 如果需要从主进程同步数据,可以在这里调用,但通常不需要
// 因为登录成功后已经通过 syncUserInfo 同步到主进程了
} catch (error) {
console.error('加载配置失败:', error);
if (this.addLog) {
this.addLog('error', `加载配置失败: ${error.message}`);
}
}
},
// checkActivationStatus 方法已移除
// 现在登录状态由 Vuex Store 管理,通过持久化插件自动恢复
// 不再需要从主进程获取状态
// 用户登录(只调用主进程接口,业务逻辑由主进程处理)
async userLogin(password, rememberMe = true) {
// 基本验证
if (!this.phone) {
if (this.addLog) {
this.addLog('error', '请输入手机号');
}
return { success: false, error: '请输入手机号' };
}
if (!password) {
if (this.addLog) {
this.addLog('error', '请输入密码');
}
return { success: false, error: '请输入密码' };
}
if (!window.electronAPI) {
if (this.addLog) {
this.addLog('error', 'Electron API不可用');
}
return { success: false, error: 'Electron API不可用' };
}
try {
if (this.addLog) {
this.addLog('info', `正在使用手机号 ${this.phone} 登录...`);
}
const result = await window.electronAPI.invoke('auth:login', {
phone: this.phone,
password: password
});
if (result.success && result.data) {
// 登录成功,通过 store 更新状态(业务逻辑由主进程处理)
if (this.$store) {
await this.$store.dispatch('auth/login', {
phone: this.phone,
password: password,
deviceId: result.data.device_id || ''
});
if (rememberMe) {
this.$store.dispatch('config/setRememberMe', true);
this.$store.dispatch('config/setPhone', this.phone);
}
}
// MQTT 连接由主进程自动处理,这里只检查状态
if (this.checkMQTTStatus) {
setTimeout(() => {
this.checkMQTTStatus();
}, 1000);
}
// 开始获取任务状态
if (this.startTaskStatusUpdate) {
this.startTaskStatusUpdate();
}
return { success: true, data: result.data };
} else {
if (this.addLog) {
this.addLog('error', `登录失败: ${result.error || '未知错误'}`);
}
return { success: false, error: result.error || '未知错误' };
}
} catch (error) {
if (this.addLog) {
this.addLog('error', `登录过程中发生错误: ${error.message}`);
}
return { success: false, error: error.message };
}
},
async tryAutoLogin() {
try {
if (!this.$store) {
return false;
}
// 从 store 检查是否有保存的登录信息
const savedPhone = this.$store.state.config.phone || this.$store.state.auth.phone;
const userLoggedOut = this.$store.state.config.userLoggedOut || this.$store.state.auth.userLoggedOut;
// 如果用户手动退出,不自动登录
if (userLoggedOut) {
return false;
}
if (!savedPhone) {
return false;
}
// 检查 store 中是否有有效的登录信息token 和用户信息)
const token = getToken();
const storeSnCode = this.$store ? this.$store.state.auth.snCode : '';
const storeUserName = this.$store ? this.$store.state.auth.userName : '';
// 如果有 token 和用户信息,说明已登录(数据已通过持久化插件恢复)
if (token && (storeSnCode || storeUserName)) {
// 更新登录状态
this.$store.commit('auth/SET_LOGGED_IN', true);
this.$store.commit('auth/SET_LOGIN_BUTTON_TEXT', '注销登录');
if (this.addLog) {
this.addLog('info', '自动登录成功');
}
// 连接MQTT
// MQTT 连接由主进程自动处理,这里只检查状态
if (this.checkMQTTStatus) {
setTimeout(() => {
this.checkMQTTStatus();
}, 1000);
}
return true; // 自动登录成功
}
return false; // 未登录
} catch (error) {
console.error('自动登录失败:', error);
if (this.addLog) {
this.addLog('error', `自动登录失败: ${error.message}`);
}
return false;
}
},
// 注销登录(只调用主进程接口,业务逻辑由主进程处理)
async logoutDevice() {
if (!window.electronAPI) {
if (this.addLog) {
this.addLog('error', 'Electron API不可用');
}
return;
}
try {
if (this.addLog) {
this.addLog('info', '正在注销登录...');
}
await window.electronAPI.invoke('auth:logout');
// 停止任务状态更新
if (this.stopTaskStatusUpdate) {
this.stopTaskStatusUpdate();
}
// 更新 store 状态
if (this.$store) {
this.$store.dispatch('auth/logout');
this.$store.dispatch('config/setUserLoggedOut', true);
}
if (this.addLog) {
this.addLog('success', '注销登录成功');
}
// 触发跳转到登录页面
if (this.$emit) {
this.$emit('logout-success');
}
} catch (error) {
if (this.addLog) {
this.addLog('error', `注销登录异常: ${error.message}`);
}
}
}
},
watch: {
snCode(newVal) {
this.userMenuInfo.snCode = newVal;
}
}
};

View File

@@ -0,0 +1,178 @@
/**
* 事件监听器管理 Mixin
*/
import platformMixin from './platformMixin.js';
export default {
mixins: [platformMixin],
data() {
return {
// 存储已注册的事件监听器,用于清理
_registeredEventListeners: []
};
},
methods: {
setupEventListeners() {
console.log('[事件监听] setupEventListeners 开始执行');
if (!window.electronAPI || !window.electronEvents) {
console.error('[事件监听] Electron API不可用', {
hasElectronAPI: !!window.electronAPI,
hasElectronEvents: !!window.electronEvents
});
if (this.addLog) {
this.addLog('error', 'Electron API不可用');
}
return;
}
const electronEvents = window.electronEvents;
console.log('[事件监听] electronEvents 对象:', electronEvents);
// 定义需要注册的事件监听器
const listeners = [
// MQTT 事件
{ channel: 'mqtt:connected', handler: (data) => {
console.log('[事件监听] 收到 mqtt:connected 事件,数据:', data);
this.onMQTTConnected(data);
}},
{ channel: 'mqtt:disconnected', handler: (data) => {
console.log('[事件监听] 收到 mqtt:disconnected 事件,数据:', data);
this.onMQTTDisconnected(data);
}},
{ channel: 'mqtt:message', handler: (data) => {
console.log('[事件监听] 收到 mqtt:message 事件');
this.onMQTTMessage(data);
}},
{ channel: 'mqtt:status', handler: (data) => {
console.log('[事件监听] 收到 mqtt:status 事件,数据:', data);
this.onMQTTStatusChange(data);
}},
// 指令执行结果
{ channel: 'command:result', handler: (data) => {
if (this.addLog) {
if (data.success) {
this.addLog('success', `指令执行成功 : ${JSON.stringify(data.data).length}字符`);
} else {
this.addLog('error', `指令执行失败: ${data.error}`);
}
}
}},
// 系统信息
{ channel: 'system:info', handler: (data) => this.updateSystemInfo(data) },
{ channel: 'log:message', handler: (data) => {
console.log('[事件监听] 收到 log:message 事件,数据:', data);
if (this.addLog) {
this.addLog(data.level, data.message);
}
}},
// 通知
{ channel: 'notification', handler: (data) => {
if (this.showNotification) {
this.showNotification(data.title, data.body);
}
}},
// 更新相关
{ channel: 'update:available', handler: (updateInfo) => this.onUpdateAvailable(updateInfo) },
{ channel: 'update:progress', handler: (progressData) => this.onUpdateProgress(progressData) },
{ channel: 'update:downloaded', handler: (data) => this.onUpdateDownloaded(data) },
{ channel: 'update:error', handler: (errorData) => this.onUpdateError(errorData) },
// 设备工作状态
{
channel: 'device:work-status',
handler: (workStatus) => {
this.onDeviceWorkStatus(workStatus);
}
},
// 平台登录状态
{ channel: 'platform:login-status-updated', handler: (data) => {
// 优先使用组件中定义的方法
if (this.onPlatformLoginStatusUpdated) {
this.onPlatformLoginStatusUpdated(data);
} else {
console.warn('[事件监听] 无法更新平台登录状态:组件未定义 onPlatformLoginStatusUpdated 且 store 不可用');
}
}}
];
// 注册所有事件监听器
listeners.forEach(({ channel, handler }) => {
electronEvents.on(channel, handler);
// 保存到清理列表
this._registeredEventListeners.push({ channel, handler });
});
console.log('[事件监听] 所有事件监听器已设置完成');
// 优先使用 store 的 dispatch 方法添加日志
if (this.$store && this.$store.dispatch) {
this.$store.dispatch('log/addLog', { level: 'info', message: '事件监听器设置完成' });
console.log('[事件监听] 已通过 store.dispatch 添加日志');
} else if (this.addLog) {
this.addLog('info', '事件监听器设置完成');
console.log('[事件监听] 已通过 addLog 方法添加日志');
} else {
console.log('[事件监听] 日志系统暂不可用,将在组件完全初始化后记录');
}
},
/**
* 清理所有已注册的事件监听器
*/
cleanupEventListeners() {
console.log('[事件监听] 开始清理事件监听器');
if (!window.electronEvents || !this._registeredEventListeners) {
return;
}
// 移除所有已注册的监听器
this._registeredEventListeners.forEach(({ channel, handler }) => {
try {
window.electronEvents.off(channel, handler);
} catch (error) {
console.warn(`[事件监听] 移除监听器失败: ${channel}`, error);
}
});
// 清空列表
this._registeredEventListeners = [];
console.log('[事件监听] 事件监听器清理完成');
},
showNotification(title, body) {
if ('Notification' in window) {
if (Notification.permission === 'granted') {
new Notification(title, {
body: body,
icon: '/assets/icon.png'
});
} else if (Notification.permission !== 'denied') {
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
new Notification(title, {
body: body,
icon: '/assets/icon.png'
});
}
});
}
}
if (this.addLog) {
this.addLog('info', `[通知] ${title}: ${body}`);
}
}
},
};

48
app/mixins/logMixin.js Normal file
View File

@@ -0,0 +1,48 @@
/**
* 日志管理 Mixin
* 直接使用 store 中的 log 状态
*/
export default {
methods: {
/**
* 添加日志
* @param {string} level - 日志级别: 'info', 'success', 'warn', 'error'
* @param {string} message - 日志消息
*/
addLog(level, message) {
if (this.$store) {
this.$store.dispatch('log/addLog', { level, message });
}
},
/**
* 清空日志
*/
clearLogs() {
if (this.$store) {
this.$store.dispatch('log/clearLogs');
}
},
/**
* 导出日志
*/
exportLogs() {
if (this.$store) {
this.$store.dispatch('log/exportLogs');
}
}
},
computed: {
/**
* 获取日志条目(从 store 获取)
*/
logEntries() {
if (this.$store) {
return this.$store.getters['log/logEntries'] || [];
}
return [];
}
}
};

97
app/mixins/mqttMixin.js Normal file
View File

@@ -0,0 +1,97 @@
/**
* MQTT 管理 Mixin
*/
export default {
computed: {
isConnected() {
return this.$store ? this.$store.state.mqtt.isConnected : false;
},
mqttStatus() {
return this.$store ? this.$store.state.mqtt.mqttStatus : '未连接';
}
},
methods: {
// MQTT 连接已由主进程自动处理,客户端不再需要手动连接
// 只保留状态查询方法
async checkMQTTStatus() {
try {
if (!window.electronAPI) {
return;
}
const statusResult = await window.electronAPI.invoke('mqtt:status');
if (statusResult && typeof statusResult.isConnected !== 'undefined') {
if (this.$store) {
this.$store.dispatch('mqtt/setConnected', statusResult.isConnected);
}
}
} catch (error) {
console.warn('查询MQTT状态失败:', error);
}
},
async disconnectMQTT() {
try {
if (!window.electronAPI) {
return;
}
await window.electronAPI.invoke('mqtt:disconnect');
if (this.addLog) {
this.addLog('info', '服务断开连接指令已发送');
}
} catch (error) {
if (this.addLog) {
this.addLog('error', `断开服务连接异常: ${error.message}`);
}
}
},
onMQTTConnected(data) {
console.log('[MQTT] onMQTTConnected 被调用,数据:', data);
if (this.$store) {
this.$store.dispatch('mqtt/setConnected', true);
console.log('[MQTT] 状态已更新为已连接');
}
if (this.addLog) {
this.addLog('success', 'MQTT 服务已连接');
}
},
onMQTTDisconnected(data) {
if (this.$store) {
this.$store.dispatch('mqtt/setConnected', false);
}
if (this.addLog) {
this.addLog('warn', `服务连接断开: ${data.reason || '未知原因'}`);
}
},
onMQTTMessage(data) {
const action = data.payload?.action || 'unknown';
if (this.addLog) {
this.addLog('info', `收到远程指令: ${action}`);
}
},
onMQTTStatusChange(data) {
console.log('[MQTT] onMQTTStatusChange 被调用,数据:', data);
// 根据状态数据更新连接状态
if (data && typeof data.isConnected !== 'undefined') {
if (this.$store) {
this.$store.dispatch('mqtt/setConnected', data.isConnected);
console.log('[MQTT] 通过 isConnected 更新状态:', data.isConnected);
}
} else if (data && data.status) {
// 如果数据中有 status 字段,根据状态字符串判断
const isConnected = data.status === 'connected' || data.status === '已连接';
if (this.$store) {
this.$store.dispatch('mqtt/setConnected', isConnected);
console.log('[MQTT] 通过 status 更新状态:', isConnected);
}
}
}
}
};

View File

@@ -0,0 +1,65 @@
/**
* 平台信息管理 Mixin
*/
export default {
computed: {
currentPlatform() {
return this.$store ? this.$store.state.platform.currentPlatform : '-';
},
platformLoginStatus() {
return this.$store ? this.$store.state.platform.platformLoginStatus : '-';
},
platformLoginStatusColor() {
return this.$store ? this.$store.state.platform.platformLoginStatusColor : '#FF9800';
},
isPlatformLoggedIn() {
return this.$store ? this.$store.state.platform.isPlatformLoggedIn : false;
}
},
methods: {
// 接收主进程推送的平台登录状态(不做处理,直接更新 store
onPlatformLoginStatusUpdated(data) {
console.log('[PlatformMixin] 收到平台登录状态更新:', data);
if (this.$store && data) {
// 直接使用主进程提供的格式化数据
if (data.platform !== undefined) {
this.$store.dispatch('platform/updatePlatform', data.platform);
}
// 修复:确保正确处理 isLoggedIn 状态
const isLoggedIn = data.isLoggedIn !== undefined ? data.isLoggedIn : false;
this.$store.dispatch('platform/updatePlatformLoginStatus', {
status: data.status || (isLoggedIn ? '已登录' : '未登录'),
color: data.color || (isLoggedIn ? '#4CAF50' : '#FF9800'),
isLoggedIn: isLoggedIn
});
}
},
/**
* 主动检查平台登录状态
* 调用主进程接口检查状态,主进程会自动更新并通知前端
*/
async checkPlatformLoginStatus() {
if (!window.electronAPI || !window.electronAPI.invoke) {
console.warn('[PlatformMixin] electronAPI 不可用,无法检查平台登录状态');
return;
}
try {
const result = await window.electronAPI.invoke('auth:platform-login-status');
if (result && result.success) {
// 主进程已经通过 platform:login-status-updated 事件通知前端了
// 这里不需要再次更新 store因为事件处理已经更新了
console.log('[PlatformMixin] 平台登录状态检查完成:', {
platform: result.platformType,
isLoggedIn: result.isLoggedIn
});
}
} catch (error) {
console.error('[PlatformMixin] 检查平台登录状态失败:', error);
}
}
}
};

220
app/mixins/qrCodeMixin.js Normal file
View File

@@ -0,0 +1,220 @@
/**
* 二维码管理 Mixin
* 二维码刷新逻辑在渲染层处理,主进程只负责执行获取二维码的操作
*/
export default {
data() {
return {
qrCodeAutoRefreshInterval: null, // 二维码自动刷新定时器
qrCodeCountdownInterval: null, // 倒计时定时器
};
},
computed: {
qrCodeUrl() {
return this.$store ? this.$store.state.qrCode.qrCodeUrl : null;
},
qrCodeCountdown() {
return this.$store ? this.$store.state.qrCode.qrCodeCountdown : 0;
},
qrCodeCountdownActive() {
return this.$store ? this.$store.state.qrCode.qrCodeCountdownActive : false;
},
qrCodeExpired() {
return this.$store ? this.$store.state.qrCode.qrCodeExpired : false;
},
qrCodeRefreshCount() {
return this.$store ? this.$store.state.qrCode.qrCodeRefreshCount : 0;
},
isPlatformLoggedIn() {
return this.$store ? this.$store.state.platform.isPlatformLoggedIn : false;
}
},
methods: {
/**
* 获取二维码
*/
async getQrCode() {
try {
if (!window.electronAPI || !window.electronAPI.invoke) {
console.error('[二维码] electronAPI 不可用');
return;
}
const result = await window.electronAPI.invoke('command:execute', {
platform: 'boss',
action: 'get_login_qr_code',
data: { type: 'app' },
source: 'renderer'
});
if (result.success && result.data) {
const qrCodeUrl = result.data.qrCodeUrl || result.data.qr_code_url || result.data.oos_url || result.data.imageData;
const qrCodeOosUrl = result.data.qrCodeOosUrl || result.data.oos_url || null;
if (qrCodeUrl && this.$store) {
this.$store.dispatch('qrCode/setQrCode', { url: qrCodeUrl, oosUrl: qrCodeOosUrl });
if (this.addLog) {
this.addLog('success', '二维码已获取');
}
return true;
}
} else {
console.error('[二维码] 获取失败:', result.error || '未知错误');
if (this.addLog) {
this.addLog('error', `获取二维码失败: ${result.error || '未知错误'}`);
}
}
} catch (error) {
console.error('[二维码] 获取失败:', error);
if (this.addLog) {
this.addLog('error', `获取二维码失败: ${error.message}`);
}
}
return false;
},
/**
* 启动二维码自动刷新
*/
startQrCodeAutoRefresh() {
// 如果定时器已存在,不重复启动
if (this.qrCodeAutoRefreshInterval) {
return;
}
// 如果平台已登录,不启动自动刷新
if (this.isPlatformLoggedIn) {
return;
}
const QR_CODE_REFRESH_INTERVAL = 25000; // 25秒
const MAX_REFRESH_COUNT = 3; // 最大刷新次数
// 重置刷新次数
if (this.$store) {
this.$store.dispatch('qrCode/setQrCodeCountdown', {
countdown: 25,
isActive: true,
refreshCount: 0,
isExpired: false
});
}
// 立即获取一次二维码
this.getQrCode();
// 启动定时器每25秒刷新一次
this.qrCodeAutoRefreshInterval = setInterval(async () => {
// 检查平台登录状态
if (this.isPlatformLoggedIn) {
this.stopQrCodeAutoRefresh();
return;
}
// 检查刷新次数
const refreshCount = this.qrCodeRefreshCount;
if (refreshCount >= MAX_REFRESH_COUNT) {
// 已达到最大次数
if (this.$store) {
this.$store.dispatch('qrCode/setQrCodeCountdown', {
countdown: 0,
isActive: false,
refreshCount: refreshCount,
isExpired: true
});
}
this.stopQrCodeAutoRefresh();
return;
}
// 刷新二维码
const success = await this.getQrCode();
if (success) {
// 更新刷新次数
if (this.$store) {
this.$store.dispatch('qrCode/setQrCodeCountdown', {
countdown: 25,
isActive: true,
refreshCount: refreshCount + 1,
isExpired: false
});
}
}
}, QR_CODE_REFRESH_INTERVAL);
// 启动倒计时
this.startQrCodeCountdown();
},
/**
* 停止二维码自动刷新
*/
stopQrCodeAutoRefresh() {
if (this.qrCodeAutoRefreshInterval) {
clearInterval(this.qrCodeAutoRefreshInterval);
this.qrCodeAutoRefreshInterval = null;
}
this.stopQrCodeCountdown();
if (this.$store) {
this.$store.dispatch('qrCode/setQrCodeCountdown', {
countdown: 0,
isActive: false,
refreshCount: this.qrCodeRefreshCount,
isExpired: this.qrCodeExpired
});
}
},
/**
* 启动二维码倒计时
*/
startQrCodeCountdown() {
// 如果倒计时定时器已存在,不重复启动
if (this.qrCodeCountdownInterval) {
return;
}
// 每秒更新一次倒计时
this.qrCodeCountdownInterval = setInterval(() => {
if (this.qrCodeCountdownActive && this.qrCodeCountdown > 0) {
const newCountdown = this.qrCodeCountdown - 1;
if (this.$store) {
this.$store.dispatch('qrCode/setQrCodeCountdown', {
countdown: newCountdown,
isActive: true,
refreshCount: this.qrCodeRefreshCount,
isExpired: false
});
}
} else {
// 倒计时结束
this.stopQrCodeCountdown();
}
}, 1000);
},
/**
* 停止二维码倒计时
*/
stopQrCodeCountdown() {
if (this.qrCodeCountdownInterval) {
clearInterval(this.qrCodeCountdownInterval);
this.qrCodeCountdownInterval = null;
}
},
},
watch: {
// 监听平台登录状态,如果已登录则停止刷新
isPlatformLoggedIn(newVal) {
if (newVal) {
this.stopQrCodeAutoRefresh();
}
}
},
beforeUnmount() {
// 组件销毁时清理定时器
this.stopQrCodeAutoRefresh();
}
};

View File

@@ -0,0 +1,48 @@
/**
* 系统信息管理 Mixin
*/
export default {
computed: {
uptime() {
return this.$store ? this.$store.state.system.uptime : '0分钟';
},
cpuUsage() {
return this.$store ? this.$store.state.system.cpuUsage : '0%';
},
memUsage() {
return this.$store ? this.$store.state.system.memUsage : '0MB';
},
deviceId() {
return this.$store ? this.$store.state.system.deviceId : '-';
}
},
methods: {
// 更新运行时间(仅计算,不请求)
startSystemInfoUpdate() {
const updateUptime = () => {
if (this.$store && this.startTime) {
const elapsed = Math.floor((Date.now() - this.startTime) / 1000 / 60);
this.$store.dispatch('system/updateUptime', `${elapsed}分钟`);
}
};
updateUptime();
setInterval(updateUptime, 5000);
},
// 接收主进程推送的系统信息(不做处理,直接更新 store
updateSystemInfo(data) {
if (this.$store && data) {
if (data.cpu !== undefined) {
this.$store.dispatch('system/updateCpuUsage', data.cpu);
}
if (data.memory !== undefined) {
this.$store.dispatch('system/updateMemUsage', data.memory);
}
if (data.deviceId !== undefined) {
this.$store.dispatch('system/updateDeviceId', data.deviceId);
}
}
}
}
};

61
app/mixins/taskMixin.js Normal file
View File

@@ -0,0 +1,61 @@
/**
* 设备工作状态管理 Mixin
*/
export default {
computed: {
displayText() {
return this.$store ? this.$store.state.task.displayText : null;
},
nextExecuteTimeText() {
return this.$store ? this.$store.state.task.nextExecuteTimeText : null;
},
currentActivity() {
return this.$store ? this.$store.state.task.currentActivity : null;
},
pendingQueue() {
return this.$store ? this.$store.state.task.pendingQueue : null;
},
deviceStatus() {
return this.$store ? this.$store.state.task.deviceStatus : null;
}
},
methods: {
startTaskStatusUpdate() {
// 设备工作状态已通过 MQTT 实时推送,不再使用接口轮询
// 设备工作状态通过 device_work_status_${snCode} 主题推送,由 mqttService 处理并发送到渲染进程
// 通过 onDeviceWorkStatus 方法接收并更新状态
console.log('[TaskMixin] 设备工作状态更新已启动,使用 MQTT 实时推送');
},
stopTaskStatusUpdate() {
if (this.$store) {
this.$store.dispatch('task/clearDeviceWorkStatus');
}
},
/**
* 处理设备工作状态通知
* 服务端已格式化好显示文本,客户端直接使用,不做复杂处理
*/
onDeviceWorkStatus(workStatus) {
if (!workStatus || !this.$store) {
console.warn('[Renderer] 收到设备工作状态但数据无效:', workStatus);
return;
}
// 直接更新设备工作状态到 store服务端已处理好所有显示逻辑
try {
this.$store.dispatch('task/updateDeviceWorkStatus', workStatus);
// 验证更新是否成功
this.$nextTick(() => {
const state = this.$store.state.task;
});
} catch (error) {
console.error('[Renderer] 更新设备工作状态失败:', error);
}
}
}
};

138
app/mixins/updateMixin.js Normal file
View File

@@ -0,0 +1,138 @@
/**
* 更新管理 Mixin
*/
export default {
computed: {
updateDialogVisible() {
return this.$store ? this.$store.state.update.updateDialogVisible : false;
},
updateInfo() {
return this.$store ? this.$store.state.update.updateInfo : null;
},
updateProgress() {
return this.$store ? this.$store.state.update.updateProgress : 0;
},
isDownloading() {
return this.$store ? this.$store.state.update.isDownloading : false;
},
downloadState() {
return this.$store ? this.$store.state.update.downloadState : {
progress: 0,
downloadedBytes: 0,
totalBytes: 0
};
}
},
methods: {
// 接收主进程推送的更新信息(不做处理,直接更新 store
onUpdateAvailable(updateInfo) {
if (!updateInfo) {
return;
}
if (this.$store) {
this.$store.dispatch('update/setUpdateInfo', updateInfo);
this.$store.dispatch('update/showUpdateDialog');
}
if (this.addLog) {
this.addLog('info', `发现新版本: ${updateInfo.version || '未知'}`);
}
},
// 接收主进程推送的更新进度(不做处理,直接更新 store
onUpdateProgress(progressData) {
if (this.$store && progressData) {
this.$store.dispatch('update/setDownloadState', {
progress: progressData.progress || 0,
downloadedBytes: progressData.downloadedBytes || 0,
totalBytes: progressData.totalBytes || 0
});
this.$store.dispatch('update/setUpdateProgress', progressData.progress || 0);
this.$store.dispatch('update/setDownloading', true);
}
},
// 接收主进程推送的下载完成通知(不做处理,直接更新 store
onUpdateDownloaded(data) {
if (this.$store) {
this.$store.dispatch('update/setDownloading', false);
this.$store.dispatch('update/setUpdateProgress', 100);
}
if (this.addLog) {
this.addLog('success', '更新包下载完成');
}
if (this.showNotification) {
this.showNotification('更新下载完成', '更新包已下载完成,是否立即安装?');
}
},
// 接收主进程推送的更新错误(不做处理,直接显示)
onUpdateError(errorData) {
if (this.$store) {
this.$store.dispatch('update/setDownloading', false);
}
const errorMsg = errorData?.error || '更新失败';
if (this.addLog) {
this.addLog('error', `更新错误: ${errorMsg}`);
}
if (this.showNotification) {
this.showNotification('更新失败', errorMsg);
}
},
closeUpdateDialog() {
if (this.$store) {
this.$store.dispatch('update/hideUpdateDialog');
}
},
// 下载更新(调用主进程接口,不做业务逻辑处理)
async startDownload() {
const updateInfoData = this.updateInfo;
if (!updateInfoData || !updateInfoData.downloadUrl) {
if (this.addLog) {
this.addLog('error', '更新信息不存在');
}
return;
}
if (!window.electronAPI) {
if (this.addLog) {
this.addLog('error', 'Electron API不可用');
}
return;
}
try {
await window.electronAPI.invoke('update:download', updateInfoData.downloadUrl);
} catch (error) {
if (this.addLog) {
this.addLog('error', `下载更新失败: ${error.message}`);
}
}
},
// 安装更新(调用主进程接口,不做业务逻辑处理)
async installUpdate() {
if (!window.electronAPI) {
if (this.addLog) {
this.addLog('error', 'Electron API不可用');
}
return;
}
try {
await window.electronAPI.invoke('update:install');
setTimeout(() => {
this.closeUpdateDialog();
}, 1000);
} catch (error) {
if (this.addLog) {
this.addLog('error', `安装更新失败: ${error.message}`);
}
}
}
}
};