1
This commit is contained in:
49
app/store/index.js
Normal file
49
app/store/index.js
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Vuex Store 主入口
|
||||
*/
|
||||
import { createStore } from 'vuex';
|
||||
import app from './modules/app';
|
||||
import auth from './modules/auth';
|
||||
import mqtt from './modules/mqtt';
|
||||
import task from './modules/task';
|
||||
import system from './modules/system';
|
||||
import platform from './modules/platform';
|
||||
import qrCode from './modules/qrCode';
|
||||
import update from './modules/update';
|
||||
import delivery from './modules/delivery';
|
||||
import log from './modules/log';
|
||||
import config from './modules/config';
|
||||
import createPersistedState from 'vuex-persistedstate'
|
||||
|
||||
const store = createStore({
|
||||
modules: {
|
||||
app,
|
||||
auth,
|
||||
mqtt,
|
||||
task,
|
||||
system,
|
||||
platform,
|
||||
qrCode,
|
||||
update,
|
||||
delivery,
|
||||
log,
|
||||
config
|
||||
},
|
||||
plugins: [createPersistedState({
|
||||
key: 'boss-auto-app',
|
||||
storage: window.localStorage, // 或 sessionStorage
|
||||
paths: ['auth', 'config'] // 只持久化这些
|
||||
})]
|
||||
});
|
||||
|
||||
// 调试:输出localStorage中保存的持久化数据
|
||||
console.log('[Store] localStorage中保存的数据:', {
|
||||
'boss-auto-app': localStorage.getItem('boss-auto-app'),
|
||||
'api_token': localStorage.getItem('api_token')
|
||||
});
|
||||
|
||||
// 应用启动时,从 store 恢复登录状态
|
||||
store.dispatch('auth/restoreLoginStatus');
|
||||
|
||||
export default store;
|
||||
|
||||
28
app/store/modules/app.js
Normal file
28
app/store/modules/app.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 应用全局状态管理
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
currentVersion: '1.0.0',
|
||||
isLoading: true,
|
||||
startTime: Date.now()
|
||||
},
|
||||
mutations: {
|
||||
SET_VERSION(state, version) {
|
||||
state.currentVersion = version;
|
||||
},
|
||||
SET_LOADING(state, loading) {
|
||||
state.isLoading = loading;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setVersion({ commit }, version) {
|
||||
commit('SET_VERSION', version);
|
||||
},
|
||||
setLoading({ commit }, loading) {
|
||||
commit('SET_LOADING', loading);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
291
app/store/modules/auth.js
Normal file
291
app/store/modules/auth.js
Normal file
@@ -0,0 +1,291 @@
|
||||
/**
|
||||
* 用户认证状态管理
|
||||
*/
|
||||
import { login as apiLogin, setToken, clearToken, getToken } from '../../utils/api';
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
email: '',
|
||||
password: '',
|
||||
isLoggedIn: false,
|
||||
loginButtonText: '登录',
|
||||
userName: '',
|
||||
remainingDays: null,
|
||||
snCode: '',
|
||||
deviceId: null,
|
||||
platformType: null,
|
||||
userId: null,
|
||||
listenChannel: '-',
|
||||
userLoggedOut: false,
|
||||
rememberMe: false,
|
||||
userMenuInfo: {
|
||||
userName: '',
|
||||
snCode: ''
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
SET_EMAIL(state, email) {
|
||||
state.email = email;
|
||||
},
|
||||
SET_PASSWORD(state, password) {
|
||||
state.password = password;
|
||||
},
|
||||
SET_LOGGED_IN(state, isLoggedIn) {
|
||||
state.isLoggedIn = isLoggedIn;
|
||||
},
|
||||
SET_LOGIN_BUTTON_TEXT(state, text) {
|
||||
state.loginButtonText = text;
|
||||
},
|
||||
SET_USER_NAME(state, userName) {
|
||||
state.userName = userName;
|
||||
state.userMenuInfo.userName = userName;
|
||||
},
|
||||
SET_REMAINING_DAYS(state, days) {
|
||||
state.remainingDays = days;
|
||||
},
|
||||
SET_SN_CODE(state, snCode) {
|
||||
state.snCode = snCode;
|
||||
state.userMenuInfo.snCode = snCode;
|
||||
state.listenChannel = snCode ? `request_${snCode}` : '-';
|
||||
},
|
||||
SET_DEVICE_ID(state, deviceId) {
|
||||
state.deviceId = deviceId;
|
||||
},
|
||||
SET_PLATFORM_TYPE(state, platformType) {
|
||||
state.platformType = platformType;
|
||||
},
|
||||
SET_USER_ID(state, userId) {
|
||||
state.userId = userId;
|
||||
},
|
||||
SET_USER_LOGGED_OUT(state, value) {
|
||||
state.userLoggedOut = value;
|
||||
},
|
||||
SET_REMEMBER_ME(state, value) {
|
||||
state.rememberMe = value;
|
||||
},
|
||||
SET_USER_MENU_INFO(state, info) {
|
||||
state.userMenuInfo = { ...state.userMenuInfo, ...info };
|
||||
},
|
||||
CLEAR_AUTH(state) {
|
||||
state.isLoggedIn = false;
|
||||
state.loginButtonText = '登录';
|
||||
state.listenChannel = '-';
|
||||
state.snCode = '';
|
||||
state.deviceId = null;
|
||||
state.platformType = null;
|
||||
state.userId = null;
|
||||
state.userName = '';
|
||||
state.remainingDays = null;
|
||||
state.userMenuInfo = {
|
||||
userName: '',
|
||||
snCode: ''
|
||||
};
|
||||
state.password = '';
|
||||
state.userLoggedOut = true;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* 从 store 恢复登录状态
|
||||
* 状态已通过持久化插件从 localStorage 恢复
|
||||
*/
|
||||
async restoreLoginStatus({ commit, state }) {
|
||||
try {
|
||||
const token = getToken();
|
||||
|
||||
console.log('[Auth Store] 尝试恢复登录状态:', {
|
||||
hasToken: !!token,
|
||||
userLoggedOut: state.userLoggedOut,
|
||||
snCode: state.snCode,
|
||||
userName: state.userName,
|
||||
isLoggedIn: state.isLoggedIn,
|
||||
persistedState: {
|
||||
email: state.email,
|
||||
platformType: state.platformType,
|
||||
userId: state.userId,
|
||||
deviceId: state.deviceId
|
||||
}
|
||||
});
|
||||
|
||||
// 如果有 token 且用户没有手动退出,且有用户信息,则恢复登录状态
|
||||
if (token && !state.userLoggedOut && (state.snCode || state.userName)) {
|
||||
console.log('[Auth Store] 满足恢复登录条件,开始恢复...');
|
||||
|
||||
commit('SET_LOGGED_IN', true);
|
||||
commit('SET_LOGIN_BUTTON_TEXT', '注销登录');
|
||||
|
||||
// 恢复登录状态后,同步用户信息到主进程(确保 platform_type 等数据同步)
|
||||
if (window.electronAPI && window.electronAPI.invoke) {
|
||||
try {
|
||||
await window.electronAPI.invoke('auth:sync-user-info', {
|
||||
platform_type: state.platformType || null,
|
||||
sn_code: state.snCode || '',
|
||||
user_id: state.userId || null,
|
||||
user_name: state.userName || '',
|
||||
device_id: state.deviceId || null
|
||||
});
|
||||
console.log('[Auth Store] 用户信息已同步到主进程');
|
||||
|
||||
// 恢复登录状态后,手动连接 MQTT
|
||||
if (state.snCode) {
|
||||
try {
|
||||
const mqttResult = await window.electronAPI.invoke('mqtt:connect', state.snCode);
|
||||
console.log('[Auth Store] 恢复登录后 MQTT 连接结果:', mqttResult);
|
||||
|
||||
// 如果连接成功,立即更新MQTT状态到store
|
||||
if (mqttResult && mqttResult.success && mqttResult.isConnected) {
|
||||
commit('mqtt/SET_CONNECTED', true, { root: true });
|
||||
commit('mqtt/SET_STATUS', '已连接', { root: true });
|
||||
console.log('[Auth Store] 恢复登录后 MQTT 状态已更新到 store');
|
||||
}
|
||||
} catch (mqttError) {
|
||||
console.warn('[Auth Store] 恢复登录后 MQTT 连接失败:', mqttError);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[Auth Store] 恢复登录状态时同步用户信息到主进程失败:', error);
|
||||
}
|
||||
} else {
|
||||
console.warn('[Auth Store] electronAPI 不可用,无法同步用户信息到主进程');
|
||||
}
|
||||
|
||||
console.log('[Auth Store] 登录状态恢复完成');
|
||||
} else {
|
||||
console.log('[Auth Store] 不满足恢复登录条件,跳过恢复');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Auth Store] 恢复登录状态失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @param {Object} context Vuex context
|
||||
* @param {Object} payload 登录参数
|
||||
* @param {string} payload.email 邮箱
|
||||
* @param {string} payload.password 密码
|
||||
* @param {string} payload.deviceId 设备ID(可选)
|
||||
* @returns {Promise<Object>} 登录结果
|
||||
*/
|
||||
async login({ commit }, { email, password, deviceId = null }) {
|
||||
try {
|
||||
// 调用登录接口
|
||||
const response = await apiLogin(email, password, deviceId);
|
||||
|
||||
if (response.code === 0 && response.data) {
|
||||
// 登录成功,更新状态
|
||||
const { token, user, device_id } = response.data;
|
||||
|
||||
// token 已在 apiLogin 中设置,这里不需要重复设置
|
||||
|
||||
|
||||
|
||||
commit('SET_EMAIL', email);
|
||||
commit('SET_PASSWORD', password);
|
||||
commit('SET_LOGGED_IN', true);
|
||||
commit('SET_LOGIN_BUTTON_TEXT', '注销登录');
|
||||
commit('SET_USER_NAME', user?.name || email);
|
||||
commit('SET_REMAINING_DAYS', user?.remaining_days || null);
|
||||
commit('SET_SN_CODE', user?.sn_code || '');
|
||||
commit('SET_DEVICE_ID', device_id || deviceId);
|
||||
commit('SET_PLATFORM_TYPE', user?.platform_type || null);
|
||||
commit('SET_USER_ID', user?.id || null);
|
||||
commit('SET_USER_LOGGED_OUT', false);
|
||||
|
||||
// 登录成功后,同步更新 platform store 的显示名称
|
||||
if (user?.platform_type) {
|
||||
const platformNames = {
|
||||
'boss': 'BOSS直聘',
|
||||
'liepin': '猎聘',
|
||||
'zhilian': '智联招聘',
|
||||
'1': 'BOSS直聘'
|
||||
};
|
||||
const displayName = platformNames[user.platform_type] || user.platform_type;
|
||||
commit('platform/SET_CURRENT_PLATFORM', displayName, { root: true });
|
||||
|
||||
// 初始化平台登录状态为未登录(需要用户通过平台登录)
|
||||
commit('platform/SET_PLATFORM_LOGIN_STATUS', {
|
||||
status: '未登录',
|
||||
color: '#FF9800',
|
||||
isLoggedIn: false
|
||||
}, { root: true });
|
||||
console.log('[Auth Store] 平台信息已初始化');
|
||||
}
|
||||
|
||||
// 同步用户信息到主进程的 authService(确保主进程也能获取到 platform_type 和 token)
|
||||
if (window.electronAPI && window.electronAPI.invoke) {
|
||||
try {
|
||||
await window.electronAPI.invoke('auth:sync-user-info', {
|
||||
token: token, // 同步 token 到主进程
|
||||
platform_type: user?.platform_type || null,
|
||||
sn_code: user?.sn_code || '',
|
||||
user_id: user?.id || null,
|
||||
user_name: user?.name || email, // 修复:使用 email 而不是 phone
|
||||
device_id: device_id || deviceId
|
||||
});
|
||||
|
||||
// 登录成功后,手动连接 MQTT
|
||||
if (user?.sn_code) {
|
||||
try {
|
||||
const mqttResult = await window.electronAPI.invoke('mqtt:connect', user.sn_code);
|
||||
console.log('[Auth Store] MQTT 连接结果:', mqttResult);
|
||||
|
||||
// 如果连接成功,立即更新MQTT状态到store
|
||||
if (mqttResult && mqttResult.success && mqttResult.isConnected) {
|
||||
commit('mqtt/SET_CONNECTED', true, { root: true });
|
||||
commit('mqtt/SET_STATUS', '已连接', { root: true });
|
||||
console.log('[Auth Store] MQTT 状态已更新到 store');
|
||||
}
|
||||
} catch (mqttError) {
|
||||
console.warn('[Auth Store] MQTT 连接失败:', mqttError);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[Auth Store] 同步用户信息到主进程失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: response.data
|
||||
};
|
||||
} else {
|
||||
// 登录失败
|
||||
return {
|
||||
success: false,
|
||||
error: response.message || '登录失败'
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Auth Store] 登录失败:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error.message || '登录过程中发生错误'
|
||||
};
|
||||
}
|
||||
},
|
||||
logout({ commit }) {
|
||||
commit('CLEAR_AUTH');
|
||||
clearToken();
|
||||
},
|
||||
updateUserInfo({ commit }, userInfo) {
|
||||
if (userInfo.name) commit('SET_USER_NAME', userInfo.name);
|
||||
if (userInfo.sn_code) commit('SET_SN_CODE', userInfo.sn_code);
|
||||
if (userInfo.device_id) commit('SET_DEVICE_ID', userInfo.device_id);
|
||||
if (userInfo.remaining_days !== undefined) {
|
||||
commit('SET_REMAINING_DAYS', userInfo.remaining_days);
|
||||
}
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
isLoggedIn: state => state.isLoggedIn,
|
||||
userInfo: state => ({
|
||||
email: state.email,
|
||||
userName: state.userName,
|
||||
snCode: state.snCode,
|
||||
deviceId: state.deviceId,
|
||||
remainingDays: state.remainingDays
|
||||
})
|
||||
}
|
||||
};
|
||||
72
app/store/modules/config.js
Normal file
72
app/store/modules/config.js
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 应用配置状态管理
|
||||
* 统一管理所有配置,不再使用 localStorage
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
// 用户相关配置
|
||||
email: '',
|
||||
userLoggedOut: false,
|
||||
rememberMe: false,
|
||||
|
||||
// 应用设置
|
||||
appSettings: {
|
||||
autoStart: false,
|
||||
startOnBoot: false,
|
||||
enableNotifications: true,
|
||||
soundAlert: true
|
||||
},
|
||||
|
||||
// 设备ID(客户端生成,需要持久化)
|
||||
deviceId: null
|
||||
},
|
||||
mutations: {
|
||||
SET_EMAIL(state, email) {
|
||||
state.email = email;
|
||||
},
|
||||
SET_USER_LOGGED_OUT(state, value) {
|
||||
state.userLoggedOut = value;
|
||||
},
|
||||
SET_REMEMBER_ME(state, value) {
|
||||
state.rememberMe = value;
|
||||
},
|
||||
SET_APP_SETTINGS(state, settings) {
|
||||
state.appSettings = { ...state.appSettings, ...settings };
|
||||
},
|
||||
UPDATE_APP_SETTING(state, { key, value }) {
|
||||
state.appSettings[key] = value;
|
||||
},
|
||||
SET_DEVICE_ID(state, deviceId) {
|
||||
state.deviceId = deviceId;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setEmail({ commit }, email) {
|
||||
commit('SET_EMAIL', email);
|
||||
},
|
||||
setUserLoggedOut({ commit }, value) {
|
||||
commit('SET_USER_LOGGED_OUT', value);
|
||||
},
|
||||
setRememberMe({ commit }, value) {
|
||||
commit('SET_REMEMBER_ME', value);
|
||||
},
|
||||
updateAppSettings({ commit }, settings) {
|
||||
commit('SET_APP_SETTINGS', settings);
|
||||
},
|
||||
updateAppSetting({ commit }, { key, value }) {
|
||||
commit('UPDATE_APP_SETTING', { key, value });
|
||||
},
|
||||
setDeviceId({ commit }, deviceId) {
|
||||
commit('SET_DEVICE_ID', deviceId);
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
email: state => state.email,
|
||||
userLoggedOut: state => state.userLoggedOut,
|
||||
rememberMe: state => state.rememberMe,
|
||||
appSettings: state => state.appSettings,
|
||||
deviceId: state => state.deviceId
|
||||
}
|
||||
};
|
||||
|
||||
165
app/store/modules/delivery.js
Normal file
165
app/store/modules/delivery.js
Normal file
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* 投递配置状态管理
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
deliveryStats: {
|
||||
todayCount: 0,
|
||||
weekCount: 0,
|
||||
monthCount: 0,
|
||||
totalCount: 0,
|
||||
successCount: 0,
|
||||
failedCount: 0,
|
||||
pendingCount: 0,
|
||||
interviewCount: 0,
|
||||
successRate: 0,
|
||||
interviewRate: 0
|
||||
},
|
||||
deliveryConfig: {
|
||||
autoDelivery: false,
|
||||
interval: 30,
|
||||
minSalary: 15000,
|
||||
maxSalary: 30000,
|
||||
scrollPages: 3,
|
||||
maxPerBatch: 10,
|
||||
filterKeywords: '',
|
||||
excludeKeywords: '',
|
||||
startTime: '09:00',
|
||||
endTime: '18:00',
|
||||
workdaysOnly: true
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
SET_DELIVERY_STATS(state, stats) {
|
||||
state.deliveryStats = { ...state.deliveryStats, ...stats };
|
||||
},
|
||||
SET_DELIVERY_CONFIG(state, config) {
|
||||
state.deliveryConfig = { ...state.deliveryConfig, ...config };
|
||||
},
|
||||
UPDATE_DELIVERY_CONFIG(state, { key, value }) {
|
||||
state.deliveryConfig[key] = value;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
updateDeliveryStats({ commit }, stats) {
|
||||
commit('SET_DELIVERY_STATS', stats);
|
||||
},
|
||||
async loadDeliveryStats({ commit, rootState }) {
|
||||
try {
|
||||
const snCode = rootState.auth.snCode;
|
||||
if (!snCode) {
|
||||
console.warn('[Delivery Store] 没有 snCode,无法加载统计数据');
|
||||
return { success: false, error: '请先登录' };
|
||||
}
|
||||
|
||||
// 动态导入 API
|
||||
const applyRecordsAPI = (await import('../../api/apply_records.js')).default;
|
||||
const result = await applyRecordsAPI.getStatistics(snCode);
|
||||
|
||||
// 后端返回格式:{ code: 0, data: {...} }
|
||||
if (result && result.code === 0 && result.data) {
|
||||
commit('SET_DELIVERY_STATS', result.data);
|
||||
return { success: true };
|
||||
} else {
|
||||
const errorMsg = result?.message || '加载统计失败';
|
||||
console.error('[Delivery Store] 加载统计失败:', result);
|
||||
return { success: false, error: errorMsg };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Delivery Store] 加载统计失败:', error);
|
||||
return { success: false, error: error.message || '加载统计失败' };
|
||||
}
|
||||
},
|
||||
updateDeliveryConfig({ commit }, { key, value }) {
|
||||
commit('UPDATE_DELIVERY_CONFIG', { key, value });
|
||||
},
|
||||
setDeliveryConfig({ commit }, config) {
|
||||
commit('SET_DELIVERY_CONFIG', config);
|
||||
},
|
||||
async saveDeliveryConfig({ state, rootState }) {
|
||||
try {
|
||||
const snCode = rootState.auth.snCode;
|
||||
if (!snCode) {
|
||||
return { success: false, error: '请先登录' };
|
||||
}
|
||||
|
||||
// 将前端配置格式转换为后端格式
|
||||
const deliverConfig = {
|
||||
auto_delivery: state.deliveryConfig.autoDelivery || false,
|
||||
interval: state.deliveryConfig.interval || 30,
|
||||
min_salary: state.deliveryConfig.minSalary || 0,
|
||||
max_salary: state.deliveryConfig.maxSalary || 0,
|
||||
scroll_pages: state.deliveryConfig.scrollPages || 3,
|
||||
max_per_batch: state.deliveryConfig.maxPerBatch || 10,
|
||||
filter_keywords: state.deliveryConfig.filterKeywords || '',
|
||||
exclude_keywords: state.deliveryConfig.excludeKeywords || '',
|
||||
start_time: state.deliveryConfig.startTime || '09:00',
|
||||
end_time: state.deliveryConfig.endTime || '18:00',
|
||||
// 将布尔值转换为数字 1/0,后端期望数字类型
|
||||
workdays_only: state.deliveryConfig.workdaysOnly ? 1 : 0
|
||||
};
|
||||
|
||||
// 动态导入 API
|
||||
const deliveryConfigAPI = (await import('../../api/delivery_config.js')).default;
|
||||
const result = await deliveryConfigAPI.saveConfig(snCode, deliverConfig);
|
||||
|
||||
// 后端返回格式:{ code: 0, message: 'success', data: {...} }
|
||||
// 或者:{ success: true, ... }
|
||||
if (result && (result.code === 0 || result.success === true)) {
|
||||
return { success: true };
|
||||
} else {
|
||||
const errorMsg = result?.message || result?.error || '保存失败';
|
||||
console.error('[Delivery Store] 保存配置失败:', result);
|
||||
return { success: false, error: errorMsg };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Delivery Store] 保存配置失败:', error);
|
||||
return { success: false, error: error.message || '保存配置失败' };
|
||||
}
|
||||
},
|
||||
async loadDeliveryConfig({ commit, rootState }) {
|
||||
try {
|
||||
const snCode = rootState.auth.snCode;
|
||||
if (!snCode) {
|
||||
// 如果没有登录,使用默认配置
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
// 动态导入 API
|
||||
const deliveryConfigAPI = (await import('../../api/delivery_config.js')).default;
|
||||
const result = await deliveryConfigAPI.getConfig(snCode);
|
||||
|
||||
// 后端返回格式:{ code: 0, data: { deliver_config: {...} } }
|
||||
if (result && result.data && result.data.deliver_config) {
|
||||
const deliverConfig = result.data.deliver_config;
|
||||
// 将后端格式转换为前端格式
|
||||
const frontendConfig = {
|
||||
autoDelivery: deliverConfig.auto_delivery || false,
|
||||
interval: deliverConfig.interval || 30,
|
||||
minSalary: deliverConfig.min_salary || 0,
|
||||
maxSalary: deliverConfig.max_salary || 0,
|
||||
scrollPages: deliverConfig.scroll_pages || 3,
|
||||
maxPerBatch: deliverConfig.max_per_batch || 10,
|
||||
filterKeywords: deliverConfig.filter_keywords || '',
|
||||
excludeKeywords: deliverConfig.exclude_keywords || '',
|
||||
startTime: deliverConfig.start_time || '09:00',
|
||||
endTime: deliverConfig.end_time || '18:00',
|
||||
// 将数字 1/0 转换为布尔值,前端使用布尔值
|
||||
workdaysOnly: deliverConfig.workdays_only === 1 || deliverConfig.workdays_only === true
|
||||
};
|
||||
commit('SET_DELIVERY_CONFIG', frontendConfig);
|
||||
return { success: true };
|
||||
} else {
|
||||
// 如果获取失败,使用默认配置
|
||||
return { success: true };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Delivery Store] 加载配置失败:', error);
|
||||
// 如果加载失败,使用默认配置
|
||||
return { success: true };
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
63
app/store/modules/log.js
Normal file
63
app/store/modules/log.js
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* 日志状态管理
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
logs: [],
|
||||
maxLogs: 1000
|
||||
},
|
||||
mutations: {
|
||||
ADD_LOG(state, logEntry) {
|
||||
state.logs.push(logEntry);
|
||||
if (state.logs.length > state.maxLogs) {
|
||||
state.logs.shift();
|
||||
}
|
||||
},
|
||||
CLEAR_LOGS(state) {
|
||||
state.logs = [];
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
addLog({ commit }, { level, message }) {
|
||||
const timestamp = new Date().toLocaleString();
|
||||
const logEntry = {
|
||||
time: timestamp,
|
||||
level: level.toUpperCase(),
|
||||
message: message
|
||||
};
|
||||
commit('ADD_LOG', logEntry);
|
||||
},
|
||||
clearLogs({ commit }) {
|
||||
commit('CLEAR_LOGS');
|
||||
commit('ADD_LOG', {
|
||||
time: new Date().toLocaleString(),
|
||||
level: 'INFO',
|
||||
message: '日志已清空'
|
||||
});
|
||||
},
|
||||
exportLogs({ state, commit }) {
|
||||
const logText = state.logs.map(log =>
|
||||
`[${log.time}] [${log.level}] ${log.message}`
|
||||
).join('\n');
|
||||
|
||||
const blob = new Blob([logText], { type: 'text/plain' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `logs_${new Date().toISOString().replace(/[:.]/g, '-')}.txt`;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
|
||||
commit('ADD_LOG', {
|
||||
time: new Date().toLocaleString(),
|
||||
level: 'INFO',
|
||||
message: '日志已导出'
|
||||
});
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
logEntries: state => state.logs
|
||||
}
|
||||
};
|
||||
|
||||
25
app/store/modules/mqtt.js
Normal file
25
app/store/modules/mqtt.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* MQTT 连接状态管理
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
isConnected: false,
|
||||
mqttStatus: '未连接'
|
||||
},
|
||||
mutations: {
|
||||
SET_CONNECTED(state, isConnected) {
|
||||
state.isConnected = isConnected;
|
||||
},
|
||||
SET_STATUS(state, status) {
|
||||
state.mqttStatus = status;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setConnected({ commit }, isConnected) {
|
||||
commit('SET_CONNECTED', isConnected);
|
||||
commit('SET_STATUS', isConnected ? '已连接' : '未连接');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
31
app/store/modules/platform.js
Normal file
31
app/store/modules/platform.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 平台信息状态管理
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
currentPlatform: '-',
|
||||
platformLoginStatus: '-',
|
||||
platformLoginStatusColor: '#FF9800',
|
||||
isPlatformLoggedIn: false
|
||||
},
|
||||
mutations: {
|
||||
SET_CURRENT_PLATFORM(state, platform) {
|
||||
state.currentPlatform = platform;
|
||||
},
|
||||
SET_PLATFORM_LOGIN_STATUS(state, { status, color, isLoggedIn }) {
|
||||
state.platformLoginStatus = status;
|
||||
state.platformLoginStatusColor = color || '#FF9800';
|
||||
state.isPlatformLoggedIn = isLoggedIn || false;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
updatePlatform({ commit }, platform) {
|
||||
commit('SET_CURRENT_PLATFORM', platform);
|
||||
},
|
||||
updatePlatformLoginStatus({ commit }, { status, color, isLoggedIn }) {
|
||||
commit('SET_PLATFORM_LOGIN_STATUS', { status, color, isLoggedIn });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
42
app/store/modules/qrCode.js
Normal file
42
app/store/modules/qrCode.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 二维码状态管理
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
qrCodeUrl: null,
|
||||
qrCodeOosUrl: null,
|
||||
qrCodeCountdown: 0,
|
||||
qrCodeCountdownActive: false,
|
||||
qrCodeRefreshCount: 0,
|
||||
qrCodeExpired: false
|
||||
},
|
||||
mutations: {
|
||||
SET_QR_CODE_URL(state, { url, oosUrl }) {
|
||||
state.qrCodeUrl = url;
|
||||
state.qrCodeOosUrl = oosUrl || null;
|
||||
},
|
||||
SET_QR_CODE_COUNTDOWN(state, { countdown, isActive, refreshCount, isExpired }) {
|
||||
state.qrCodeCountdown = countdown || 0;
|
||||
state.qrCodeCountdownActive = isActive || false;
|
||||
state.qrCodeRefreshCount = refreshCount || 0;
|
||||
state.qrCodeExpired = isExpired || false;
|
||||
},
|
||||
CLEAR_QR_CODE(state) {
|
||||
state.qrCodeUrl = null;
|
||||
state.qrCodeOosUrl = null;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setQrCode({ commit }, { url, oosUrl }) {
|
||||
commit('SET_QR_CODE_URL', { url, oosUrl });
|
||||
},
|
||||
setQrCodeCountdown({ commit }, data) {
|
||||
commit('SET_QR_CODE_COUNTDOWN', data);
|
||||
},
|
||||
clearQrCode({ commit }) {
|
||||
commit('CLEAR_QR_CODE');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
41
app/store/modules/system.js
Normal file
41
app/store/modules/system.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 系统信息状态管理
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
uptime: '0分钟',
|
||||
cpuUsage: '0%',
|
||||
memUsage: '0MB',
|
||||
deviceId: '-'
|
||||
},
|
||||
mutations: {
|
||||
SET_UPTIME(state, uptime) {
|
||||
state.uptime = uptime;
|
||||
},
|
||||
SET_CPU_USAGE(state, usage) {
|
||||
state.cpuUsage = usage;
|
||||
},
|
||||
SET_MEM_USAGE(state, usage) {
|
||||
state.memUsage = usage;
|
||||
},
|
||||
SET_DEVICE_ID(state, deviceId) {
|
||||
state.deviceId = deviceId || '-';
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
updateUptime({ commit }, uptime) {
|
||||
commit('SET_UPTIME', uptime);
|
||||
},
|
||||
updateCpuUsage({ commit }, usage) {
|
||||
commit('SET_CPU_USAGE', `${usage.toFixed(1)}%`);
|
||||
},
|
||||
updateMemUsage({ commit }, usage) {
|
||||
commit('SET_MEM_USAGE', `${usage}MB`);
|
||||
},
|
||||
updateDeviceId({ commit }, deviceId) {
|
||||
commit('SET_DEVICE_ID', deviceId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
81
app/store/modules/task.js
Normal file
81
app/store/modules/task.js
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* 设备工作状态和任务统计管理
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
// 设备工作状态
|
||||
displayText: null, // 服务端格式化好的显示文本
|
||||
nextExecuteTimeText: null, // 服务端格式化好的下次执行时间文本
|
||||
currentActivity: null, // 当前活动(任务或指令)
|
||||
pendingQueue: null, // 待执行队列信息
|
||||
deviceStatus: null, // 设备状态
|
||||
|
||||
// 任务统计
|
||||
taskStats: {
|
||||
todayCount: 0,
|
||||
weekCount: 0,
|
||||
monthCount: 0,
|
||||
totalCount: 0,
|
||||
completedCount: 0,
|
||||
runningCount: 0,
|
||||
pendingCount: 0,
|
||||
failedCount: 0,
|
||||
completionRate: 0
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
SET_DEVICE_WORK_STATUS(state, workStatus) {
|
||||
state.displayText = workStatus.displayText || null;
|
||||
state.nextExecuteTimeText = workStatus.pendingQueue?.nextExecuteTimeText || null;
|
||||
state.currentActivity = workStatus.currentActivity || null;
|
||||
state.pendingQueue = workStatus.pendingQueue || null;
|
||||
state.deviceStatus = workStatus.deviceStatus || null;
|
||||
|
||||
},
|
||||
CLEAR_DEVICE_WORK_STATUS(state) {
|
||||
state.displayText = null;
|
||||
state.nextExecuteTimeText = null;
|
||||
state.currentActivity = null;
|
||||
state.pendingQueue = null;
|
||||
state.deviceStatus = null;
|
||||
},
|
||||
SET_TASK_STATS(state, stats) {
|
||||
state.taskStats = { ...state.taskStats, ...stats };
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
updateDeviceWorkStatus({ commit }, workStatus) {
|
||||
commit('SET_DEVICE_WORK_STATUS', workStatus);
|
||||
},
|
||||
clearDeviceWorkStatus({ commit }) {
|
||||
commit('CLEAR_DEVICE_WORK_STATUS');
|
||||
},
|
||||
async loadTaskStats({ commit, rootState }) {
|
||||
try {
|
||||
const snCode = rootState.auth.snCode;
|
||||
if (!snCode) {
|
||||
console.warn('[Task Store] 没有 snCode,无法加载任务统计');
|
||||
return { success: false, error: '请先登录' };
|
||||
}
|
||||
|
||||
// 调用任务统计接口
|
||||
const result = await window.electronAPI.invoke('http:get', '/task/statistics', { sn_code: snCode });
|
||||
|
||||
// 后端返回格式:{ code: 0, data: {...} }
|
||||
if (result && result.code === 0 && result.data) {
|
||||
commit('SET_TASK_STATS', result.data);
|
||||
return { success: true };
|
||||
} else {
|
||||
const errorMsg = result?.message || '加载任务统计失败';
|
||||
console.error('[Task Store] 加载任务统计失败:', result);
|
||||
return { success: false, error: errorMsg };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Task Store] 加载任务统计失败:', error);
|
||||
return { success: false, error: error.message || '加载任务统计失败' };
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
55
app/store/modules/update.js
Normal file
55
app/store/modules/update.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 更新状态管理
|
||||
*/
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
updateDialogVisible: false,
|
||||
updateInfo: null,
|
||||
updateProgress: 0,
|
||||
isDownloading: false,
|
||||
downloadState: {
|
||||
progress: 0,
|
||||
downloadedBytes: 0,
|
||||
totalBytes: 0
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
SET_UPDATE_DIALOG_VISIBLE(state, visible) {
|
||||
state.updateDialogVisible = visible;
|
||||
},
|
||||
SET_UPDATE_INFO(state, info) {
|
||||
state.updateInfo = info;
|
||||
},
|
||||
SET_UPDATE_PROGRESS(state, progress) {
|
||||
state.updateProgress = progress;
|
||||
},
|
||||
SET_DOWNLOADING(state, downloading) {
|
||||
state.isDownloading = downloading;
|
||||
},
|
||||
SET_DOWNLOAD_STATE(state, downloadState) {
|
||||
state.downloadState = { ...state.downloadState, ...downloadState };
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
showUpdateDialog({ commit }) {
|
||||
commit('SET_UPDATE_DIALOG_VISIBLE', true);
|
||||
},
|
||||
hideUpdateDialog({ commit }) {
|
||||
commit('SET_UPDATE_DIALOG_VISIBLE', false);
|
||||
},
|
||||
setUpdateInfo({ commit }, info) {
|
||||
commit('SET_UPDATE_INFO', info);
|
||||
},
|
||||
setUpdateProgress({ commit }, progress) {
|
||||
commit('SET_UPDATE_PROGRESS', progress);
|
||||
},
|
||||
setDownloading({ commit }, downloading) {
|
||||
commit('SET_DOWNLOADING', downloading);
|
||||
},
|
||||
setDownloadState({ commit }, state) {
|
||||
commit('SET_DOWNLOAD_STATE', state);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user