Files
autoAiWorkSys/api/middleware/schedule/services/accountValidator.js
张成 65833dd32d 11
2025-12-30 15:46:18 +08:00

200 lines
6.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const db = require('../../dbProxy');
const authorizationService = require('../../../services/authorization_service');
const deviceManager = require('../core/deviceManager');
/**
* 账户验证服务
* 统一处理账户启用状态、授权状态、在线状态的检查
*/
class AccountValidator {
/**
* 检查账户是否启用
* @param {string} sn_code - 设备序列号
* @returns {Promise<{enabled: boolean, reason?: string}>}
*/
async checkEnabled(sn_code) {
try {
const pla_account = db.getModel('pla_account');
const account = await pla_account.findOne({
where: { sn_code, is_delete: 0 },
attributes: ['is_enabled', 'name']
});
if (!account) {
return { enabled: false, reason: '账户不存在' };
}
if (!account.is_enabled) {
return { enabled: false, reason: '账户未启用' };
}
return { enabled: true };
} catch (error) {
console.error(`[账户验证] 检查启用状态失败 (${sn_code}):`, error);
return { enabled: false, reason: '检查失败' };
}
}
/**
* 检查账户授权状态
* @param {string} sn_code - 设备序列号
* @returns {Promise<{authorized: boolean, days?: number, reason?: string}>}
*/
async checkAuthorization(sn_code) {
try {
const result = await authorizationService.checkAuthorization(sn_code);
if (!result.is_authorized) {
return {
authorized: false,
days: result.days_remaining || 0,
reason: result.message || '授权已过期'
};
}
return {
authorized: true,
days: result.days_remaining
};
} catch (error) {
console.error(`[账户验证] 检查授权状态失败 (${sn_code}):`, error);
return { authorized: false, reason: '授权检查失败' };
}
}
/**
* 检查设备是否在线
* @param {string} sn_code - 设备序列号
* @param {number} offlineThreshold - 离线阈值(毫秒)
* @returns {{online: boolean, lastHeartbeat?: number, reason?: string}}
*/
checkOnline(sn_code, offlineThreshold = 3 * 60 * 1000) {
const device = deviceManager.devices.get(sn_code);
if (!device) {
return { online: false, reason: '设备从未发送心跳' };
}
const now = Date.now();
const lastHeartbeat = device.lastHeartbeat || 0;
const elapsed = now - lastHeartbeat;
if (elapsed > offlineThreshold) {
const minutes = Math.round(elapsed / (60 * 1000));
return {
online: false,
lastHeartbeat,
reason: `设备离线(最后心跳: ${minutes}分钟前)`
};
}
if (!device.isOnline) {
return { online: false, lastHeartbeat, reason: '设备标记为离线' };
}
return { online: true, lastHeartbeat };
}
/**
* 综合验证(启用 + 授权 + 在线)
* @param {string} sn_code - 设备序列号
* @param {object} options - 验证选项
* @param {boolean} options.checkEnabled - 是否检查启用状态(默认 true
* @param {boolean} options.checkAuth - 是否检查授权(默认 true
* @param {boolean} options.checkOnline - 是否检查在线(默认 true
* @param {number} options.offlineThreshold - 离线阈值(默认 3分钟
* @returns {Promise<{valid: boolean, reason?: string, details?: object}>}
*/
async validate(sn_code, options = {}) {
const {
checkEnabled = true,
checkAuth = true,
checkOnline = true,
offlineThreshold = 3 * 60 * 1000
} = options;
const details = {};
// 检查启用状态
if (checkEnabled) {
const enabledResult = await this.checkEnabled(sn_code);
details.enabled = enabledResult;
if (!enabledResult.enabled) {
return {
valid: false,
reason: enabledResult.reason,
details
};
}
}
// 检查授权状态
if (checkAuth) {
const authResult = await this.checkAuthorization(sn_code);
details.authorization = authResult;
if (!authResult.authorized) {
return {
valid: false,
reason: authResult.reason,
details
};
}
}
// 检查在线状态
if (checkOnline) {
const onlineResult = this.checkOnline(sn_code, offlineThreshold);
details.online = onlineResult;
if (!onlineResult.online) {
return {
valid: false,
reason: onlineResult.reason,
details
};
}
}
return { valid: true, details };
}
/**
* 批量验证多个账户
* @param {string[]} sn_codes - 设备序列号数组
* @param {object} options - 验证选项
* @returns {Promise<{valid: string[], invalid: Array<{sn_code: string, reason: string}>}>}
*/
async validateBatch(sn_codes, options = {}) {
const valid = [];
const invalid = [];
for (const sn_code of sn_codes) {
const result = await this.validate(sn_code, options);
if (result.valid) {
valid.push(sn_code);
} else {
invalid.push({ sn_code, reason: result.reason });
}
}
return { valid, invalid };
}
/**
* 检查账户是否已登录(通过心跳数据)
* @param {string} sn_code - 设备序列号
* @returns {boolean}
*/
checkLoggedIn(sn_code) {
const device = deviceManager.devices.get(sn_code);
return device?.isLoggedIn || false;
}
}
// 导出单例
const accountValidator = new AccountValidator();
module.exports = accountValidator;