This commit is contained in:
张成
2025-12-15 22:03:01 +08:00
parent 6e5c35f144
commit 4443d43ec1
15 changed files with 776 additions and 485 deletions

View File

@@ -0,0 +1,100 @@
const Framework = require("../../framework/node-core-framework.js");
const authorizationService = require('../services/authorization_service.js');
/**
* 账号管理控制器(客户端接口)
* 提供客户端调用的账号相关接口
*/
module.exports = {
/**
* @swagger
* /api/account/check-authorization:
* post:
* summary: 检查账号授权状态
* description: 根据设备SN码检查账号的授权状态剩余天数、是否过期等
* tags: [前端-账号管理]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - sn_code
* properties:
* sn_code:
* type: string
* description: 设备SN码
* example: 'GHJU'
* responses:
* 200:
* description: 检查成功
* content:
* application/json:
* schema:
* type: object
* properties:
* code:
* type: integer
* description: 状态码0表示成功
* example: 0
* message:
* type: string
* description: 响应消息
* example: 'success'
* data:
* type: object
* properties:
* is_authorized:
* type: boolean
* description: 是否已授权
* example: true
* remaining_days:
* type: integer
* description: 剩余天数
* example: 30
* message:
* type: string
* description: 授权状态消息
* example: '授权有效,剩余 30 天'
* 400:
* description: 参数错误
* content:
* application/json:
* schema:
* type: object
* properties:
* code:
* type: integer
* example: 400
* message:
* type: string
* example: '请提供设备SN码'
* 500:
* description: 服务器错误
*/
'POST /account/check-authorization': async (ctx) => {
try {
const { sn_code } = ctx.getBody();
// 参数验证
if (!sn_code) {
return ctx.fail('请提供设备SN码');
}
// 调用授权服务检查授权状态
const result = await authorizationService.checkAuthorization(sn_code, 'sn_code');
// 返回授权检查结果
return ctx.success({
is_authorized: result.is_authorized,
remaining_days: result.remaining_days,
message: result.message
});
} catch (error) {
console.error('[账号管理] 检查授权状态失败:', error);
return ctx.fail('检查授权状态失败: ' + (error.message || '未知错误'));
}
}
};

View File

@@ -6,7 +6,7 @@ module.exports = {
* /api/user/login:
* post:
* summary: 用户登录
* description: 通过设备SN码登录返回token和用户信息
* description: 通过手机号和密码登录返回token、device_id和用户信息
* tags: [前端-用户管理]
* requestBody:
* required: true
@@ -15,17 +15,17 @@ module.exports = {
* schema:
* type: object
* required:
* - sn_code
* - device_id
* - phone
* - password
* properties:
* sn_code:
* phone:
* type: string
* description: 设备SN码
* example: 'GHJU'
* device_id:
* description: 手机号(登录名)
* example: '13800138000'
* password:
* type: string
* description: 设备ID
* example: 'device_123456'
* description: 密码
* example: 'password123'
* responses:
* 200:
* description: 登录成功
@@ -49,6 +49,10 @@ module.exports = {
* type: string
* description: 认证token
* example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
* device_id:
* type: string
* description: 设备ID
* example: 'device_123456'
* user:
* type: object
* description: 用户信息
@@ -64,20 +68,35 @@ module.exports = {
* example: 400
* message:
* type: string
* example: '用户不存在'
* example: '用户不存在或密码错误'
*/
"POST /user/login": async (ctx) => {
const { sn_code, device_id } = ctx.getBody();
const { phone, password } = ctx.getBody();
const dayjs = require('dayjs');
const crypto = require('crypto');
const { pla_account,device_status} = await Framework.getModels();
// 验证参数
if (!phone || !password) {
return ctx.fail('手机号和密码不能为空');
}
const { pla_account } = await Framework.getModels();
// 根据手机号login_name和密码查找用户
const user = await pla_account.findOne({
where: {
login_name: phone,
pwd: password
}
});
// 获取用户信息
const user = await pla_account.findOne({ where: { sn_code } });
if (!user) {
return ctx.fail('用户不存在');
return ctx.fail('手机号或密码错误');
}
// 检查账号是否启用
if (!user.is_enabled) {
return ctx.fail('账号已被禁用');
}
// 检查授权状态
@@ -95,32 +114,30 @@ module.exports = {
if (remaining_days <= 0) {
return ctx.fail('账号授权已过期,请联系管理员续费');
}
} else {
// 如果没有授权信息,检查是否允许登录(可以根据业务需求决定是否允许)
// 这里暂时允许登录,但可以添加配置项控制
}
// 更新设备状态
const device = await device_status.findOne({ where: { sn_code } });
if (device) {
await device_status.update({
device_id: device_id
}, { where: { sn_code } });
} else {
await device_status.create({
sn_code: sn_code,
device_id: device_id
});
// 生成设备ID如果不存在基于手机号和机器特征生成
let device_id = user.device_id;
if (!device_id) {
// 生成唯一设备ID
const machineInfo = `${phone}_${Date.now()}_${Math.random()}`;
device_id = crypto.createHash('sha256').update(machineInfo).digest('hex').substring(0, 32);
// 保存设备ID到账号表
await pla_account.update(
{ device_id: device_id },
{ where: { id: user.id } }
);
}
// 创建token
const token = Framework.getServices().tokenService.create({
sn_code: user.sn_code,
device_id: user.device_id
device_id: device_id,
user_id: user.id
});
// 计算剩余天数并返回
// 计算剩余天数
let remaining_days = 0;
if (authDate && authDays > 0) {
const startDate = dayjs(authDate);
@@ -132,8 +149,13 @@ module.exports = {
const userInfo = user.toJSON();
userInfo.remaining_days = remaining_days;
// 不返回密码
delete userInfo.pwd;
return ctx.success({ token, user: userInfo });
return ctx.success({
token,
device_id,
user: userInfo
});
}
}

View File

@@ -214,10 +214,10 @@ class MqttDispatcher {
console.log(`[MQTT心跳] 收到设备 ${sn_code} 的心跳消息`);
const device_status = db.getModel('device_status');
// 检查设备是否存在
let device = await device_status.findByPk(sn_code);
// 移除 device_status 模型依赖
// const device_status = db.getModel('device_status');
// let device = await device_status.findByPk(sn_code);
let device = null; // device_status 已移除,暂时设为 null
const updateData = {
isOnline: true, // 收到心跳,设备在线
@@ -250,8 +250,8 @@ class MqttDispatcher {
loginTime = new Date(platform_login_status.timestamp);
}
// 更新登录状态
const previousIsLoggedIn = device ? device.isLoggedIn : false;
// 移除 device_status 依赖previousIsLoggedIn 暂时设为 false
const previousIsLoggedIn = false; // device_status 已移除
updateData.isLoggedIn = isLoggedIn;
@@ -276,16 +276,17 @@ class MqttDispatcher {
}
}
// 更新或创建设备记录
if (device) {
await device_status.update(updateData, { where: { sn_code } });
console.log(`[MQTT心跳] 设备 ${sn_code} 状态已更新 - 在线: true, 登录: ${updateData.isLoggedIn}`);
}
else
{
logProxy.error('[MQTT心跳] 设备 ${sn_code} 不存在', { sn_code });
return;
}
// 移除 device_status 更新逻辑
// 如果需要在 pla_account 表中添加在线状态字段,可以在这里更新
console.log(`[MQTT心跳] 设备 ${sn_code} 心跳已接收 - 登录: ${updateData.isLoggedIn || false}`);
// if (device) {
// await device_status.update(updateData, { where: { sn_code } });
// console.log(`[MQTT心跳] 设备 ${sn_code} 状态已更新 - 在线: true, 登录: ${updateData.isLoggedIn}`);
// } else {
// logProxy.error('[MQTT心跳] 设备 ${sn_code} 不存在', { sn_code });
// return;
// }
// 记录心跳到设备管理器
await deviceManager.recordHeartbeat(sn_code, heartbeatData);

View File

@@ -161,6 +161,12 @@ class ScheduledJobs {
*/
async cleanupOfflineDeviceTasks() {
try {
// 移除 device_status 依赖,离线任务清理功能暂时禁用
// 如果需要在 pla_account 表中添加在线状态字段,可以重新实现此功能
console.log('[清理离线任务] device_status 已移除,功能暂时禁用');
return;
/* 原有代码已注释
const Sequelize = require('sequelize');
const { device_status, task_status, op } = db.models;
@@ -240,6 +246,7 @@ class ScheduledJobs {
if (totalCancelled > 0) {
console.log(`[清理离线任务] 共取消 ${totalCancelled} 个离线设备的任务`);
}
*/
} catch (error) {
console.error('[清理离线任务] 执行失败:', error);
}
@@ -361,27 +368,14 @@ class ScheduledJobs {
}
try {
// device_status 查询所有在线且已登录的设备
// 移除 device_status 依赖,改为直接从 pla_account 查询启用且开启自动投递的账号
const models = db.models;
const { device_status, pla_account, op } = models;
const onlineDevices = await device_status.findAll({
where: {
isOnline: true,
isLoggedIn: true
},
attributes: ['sn_code', 'accountName', 'platform']
});
if (!onlineDevices || onlineDevices.length === 0) {
console.log('[自动投递] 没有在线且已登录的设备');
return;
}
// 获取这些在线设备对应的账号配置(只获取启用且开启自动投递的账号)
const snCodes = onlineDevices.map(device => device.sn_code);
const { pla_account, op } = models;
// 直接从 pla_account 查询启用且开启自动投递的账号
// 注意:不再检查在线状态,因为 device_status 已移除
const pla_users = await pla_account.findAll({
where: {
sn_code: { [op.in]: snCodes },
is_delete: 0,
is_enabled: 1, // 只获取启用的账号
auto_deliver: 1
@@ -509,27 +503,14 @@ class ScheduledJobs {
}
try {
// device_status 查询所有在线且已登录的设备
// 移除 device_status 依赖,改为直接从 pla_account 查询启用且开启自动沟通的账号
const models = db.models;
const { device_status, pla_account, op } = models;
const onlineDevices = await device_status.findAll({
where: {
isOnline: true,
isLoggedIn: true
},
attributes: ['sn_code', 'accountName', 'platform']
});
if (!onlineDevices || onlineDevices.length === 0) {
console.log('[自动沟通] 没有在线且已登录的设备');
return;
}
// 获取这些在线设备对应的账号配置(只获取启用且开启自动沟通的账号)
const snCodes = onlineDevices.map(device => device.sn_code);
const { pla_account, op } = models;
// 直接从 pla_account 查询启用且开启自动沟通的账号
// 注意:不再检查在线状态,因为 device_status 已移除
const pla_users = await pla_account.findAll({
where: {
sn_code: { [op.in]: snCodes },
is_delete: 0,
is_enabled: 1, // 只获取启用的账号
auto_chat: 1

View File

@@ -59,9 +59,8 @@ class TaskQueue {
order: [['priority', 'DESC'], ['id', 'ASC']]
});
// 获取所有启用的账号和设备在线状态
// 获取所有启用的账号(移除 device_status 依赖,不再检查在线状态
const pla_account = db.getModel('pla_account');
const device_status = db.getModel('device_status');
const enabledAccounts = await pla_account.findAll({
where: {
@@ -72,21 +71,9 @@ class TaskQueue {
});
const enabledSnCodes = new Set(enabledAccounts.map(acc => acc.sn_code));
// 检查设备在线状态需要同时满足isOnline = true 且心跳未超时)
const heartbeatTimeout = require('./config.js').monitoring.heartbeatTimeout; // 默认5分钟
const now = new Date();
const heartbeatThreshold = new Date(now.getTime() - heartbeatTimeout);
const onlineDevices = await device_status.findAll({
where: {
isOnline: true,
lastHeartbeatTime: {
[Sequelize.Op.gte]: heartbeatThreshold // 心跳时间在阈值内
}
},
attributes: ['sn_code', 'lastHeartbeatTime']
});
const onlineSnCodes = new Set(onlineDevices.map(dev => dev.sn_code));
// 移除 device_status 依赖,不再检查设备在线状态
// 如果需要在线状态检查,可以在 pla_account 表中添加相应字段
const onlineSnCodes = new Set(); // 暂时设为空,表示不再检查在线状态
let restoredCount = 0;

158
api/model/account_config.js Normal file
View File

@@ -0,0 +1,158 @@
const Sequelize = require('sequelize');
/**
* 账号配置表模型
* 配置不同平台的账号设置
*/
module.exports = (db) => {
const account_config = db.define("account_config", {
account_id: {
comment: '账号ID关联 pla_account.id',
type: Sequelize.INTEGER,
allowNull: false,
primaryKey: true
},
platform_type: {
comment: '平台类型boss- Boss直聘, liepin- 猎聘)',
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: 'boss'
},
// 平台相关配置JSON格式
platform_config: {
comment: '平台相关配置JSON对象',
type: Sequelize.JSON(),
allowNull: true,
get: function () {
const value = this.getDataValue('platform_config');
if (!value) return null;
if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (e) {
return null;
}
}
return value;
},
set: function (value) {
if (value === null || value === undefined) {
this.setDataValue('platform_config', null);
} else if (typeof value === 'string') {
this.setDataValue('platform_config', value);
} else {
this.setDataValue('platform_config', JSON.stringify(value));
}
},
defaultValue: null
},
// 自动投递配置
auto_deliver_config: {
comment: '自动投递配置JSON对象',
type: Sequelize.JSON(),
allowNull: true,
get: function () {
const value = this.getDataValue('auto_deliver_config');
if (!value) return null;
if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (e) {
return null;
}
}
return value;
},
set: function (value) {
if (value === null || value === undefined) {
this.setDataValue('auto_deliver_config', null);
} else if (typeof value === 'string') {
this.setDataValue('auto_deliver_config', value);
} else {
this.setDataValue('auto_deliver_config', JSON.stringify(value));
}
},
defaultValue: null
},
// 自动沟通配置
auto_chat_config: {
comment: '自动沟通配置JSON对象',
type: Sequelize.JSON(),
allowNull: true,
get: function () {
const value = this.getDataValue('auto_chat_config');
if (!value) return null;
if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (e) {
return null;
}
}
return value;
},
set: function (value) {
if (value === null || value === undefined) {
this.setDataValue('auto_chat_config', null);
} else if (typeof value === 'string') {
this.setDataValue('auto_chat_config', value);
} else {
this.setDataValue('auto_chat_config', JSON.stringify(value));
}
},
defaultValue: null
},
// 自动活跃配置
auto_active_config: {
comment: '自动活跃配置JSON对象',
type: Sequelize.JSON(),
allowNull: true,
get: function () {
const value = this.getDataValue('auto_active_config');
if (!value) return null;
if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (e) {
return null;
}
}
return value;
},
set: function (value) {
if (value === null || value === undefined) {
this.setDataValue('auto_active_config', null);
} else if (typeof value === 'string') {
this.setDataValue('auto_active_config', value);
} else {
this.setDataValue('auto_active_config', JSON.stringify(value));
}
},
defaultValue: null
},
// 备注
notes: {
comment: '备注',
type: Sequelize.TEXT,
allowNull: true,
defaultValue: ''
}
}, {
timestamps: true,
createdAt: 'created_time',
updatedAt: 'last_update_time',
indexes: [
{
unique: false,
fields: ['account_id']
},
{
unique: false,
fields: ['platform_type']
}
]
});
return account_config;
};

View File

@@ -1,309 +0,0 @@
const Sequelize = require('sequelize');
/**
* 设备状态表模型
* 记录pydp客户端设备的实时状态和运行信息
*/
module.exports = (db) => {
const device_status= db.define("device_status", {
// 设备基本信息
sn_code: {
comment: '设备SN码(唯一标识)',
type: Sequelize.STRING(50),
allowNull: false,
primaryKey: true
},
device_id:{
comment: '设备ID',
type: Sequelize.STRING(200),
allowNull: false,
primaryKey: true
},
deviceName: {
comment: '设备名称',
type: Sequelize.STRING(100),
allowNull: true,
defaultValue: ''
},
deviceType: {
comment: '设备类型',
type: Sequelize.STRING(50),
allowNull: true,
defaultValue: 'pydp'
},
// 在线状态
isOnline: {
comment: '是否在线',
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: false
},
isRunning: {
comment: '是否运行中',
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: false
},
lastOnlineTime: {
comment: '最后在线时间',
type: Sequelize.DATE,
allowNull: true
},
lastOfflineTime: {
comment: '最后离线时间',
type: Sequelize.DATE,
allowNull: true
},
onlineDuration: {
comment: '在线时长(分钟)',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
// 运行状态
currentTask: {
comment: '当前执行任务',
type: Sequelize.STRING(100),
allowNull: true,
defaultValue: ''
},
currentTaskId: {
comment: '当前任务ID',
type: Sequelize.STRING(50),
allowNull: true,
defaultValue: ''
},
taskStatus: {
comment: '任务状态',
type: Sequelize.STRING(20),
allowNull: true,
defaultValue: 'idle'
},
lastTaskTime: {
comment: '最后任务时间',
type: Sequelize.DATE,
allowNull: true
},
// 平台信息
platform: {
comment: '当前使用平台: boss-Boss直聘, liepin-猎聘',
type: Sequelize.STRING(20),
allowNull: true,
defaultValue: 'boss'
},
isLoggedIn: {
comment: '是否已登录平台',
type: Sequelize.BOOLEAN,
allowNull: true,
defaultValue: false
},
loginTime: {
comment: '登录时间',
type: Sequelize.DATE,
allowNull: true
},
accountName: {
comment: '账号名称',
type: Sequelize.STRING(100),
allowNull: true,
defaultValue: ''
},
// 性能信息
cpuUsage: {
comment: 'CPU使用率(%)',
type: Sequelize.FLOAT,
allowNull: true,
defaultValue: 0
},
memoryUsage: {
comment: '内存使用率(%)',
type: Sequelize.FLOAT,
allowNull: true,
defaultValue: 0
},
diskUsage: {
comment: '磁盘使用率(%)',
type: Sequelize.FLOAT,
allowNull: true,
defaultValue: 0
},
// 网络信息
ipAddress: {
comment: 'IP地址',
type: Sequelize.STRING(50),
allowNull: true,
defaultValue: ''
},
macAddress: {
comment: 'MAC地址',
type: Sequelize.STRING(50),
allowNull: true,
defaultValue: ''
},
networkStatus: {
comment: '网络状态: good-良好, slow-缓慢, offline-离线',
type: Sequelize.STRING(20),
allowNull: true,
defaultValue: 'good'
},
// 心跳信息
lastHeartbeatTime: {
comment: '最后心跳时间',
type: Sequelize.DATE,
allowNull: true
},
heartbeatInterval: {
comment: '心跳间隔(秒)',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 30
},
missedHeartbeats: {
comment: '丢失的心跳次数',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
// 版本信息
clientVersion: {
comment: '客户端版本',
type: Sequelize.STRING(20),
allowNull: true,
defaultValue: ''
},
pythonVersion: {
comment: 'Python版本',
type: Sequelize.STRING(20),
allowNull: true,
defaultValue: ''
},
osVersion: {
comment: '操作系统版本',
type: Sequelize.STRING(100),
allowNull: true,
defaultValue: ''
},
// 统计信息
totalTasksCompleted: {
comment: '完成任务总数',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
totalTasksFailed: {
comment: '失败任务总数',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
totalJobsSearched: {
comment: '搜索岗位总数',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
totalApplies: {
comment: '投递简历总数',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
totalChats: {
comment: '聊天总数',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
// 错误信息
lastError: {
comment: '最后错误信息',
type: Sequelize.TEXT,
allowNull: true,
defaultValue: ''
},
lastErrorTime: {
comment: '最后错误时间',
type: Sequelize.DATE,
allowNull: true
},
errorCount: {
comment: '错误次数',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
// 健康状态
healthStatus: {
comment: '健康状态: healthy-健康, warning-警告, error-错误, unknown-未知',
type: Sequelize.STRING(20),
allowNull: true,
defaultValue: 'unknown'
},
healthScore: {
comment: '健康评分(0-100)',
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
// 配置信息
config: {
comment: '设备配置(JSON)',
type: Sequelize.TEXT,
allowNull: true,
defaultValue: ''
},
// 其他信息
notes: {
comment: '备注',
type: Sequelize.TEXT,
allowNull: true,
defaultValue: ''
},
}, {
timestamps: false,
indexes: [
{
unique: false,
fields: ['isOnline']
},
{
unique: false,
fields: ['isRunning']
},
{
unique: false,
fields: ['healthStatus']
},
{
unique: false,
fields: ['platform']
},
{
unique: false,
fields: ['lastHeartbeatTime']
},
]
});
// device_status.sync({ force: true });
return device_status
// device_status.sync({ force: true
};

View File

@@ -15,6 +15,12 @@ module.exports = (db) => {
allowNull: false,
defaultValue: ''
},
device_id: {
comment: '设备ID',
type: Sequelize.STRING(200),
allowNull: true,
defaultValue: ''
},
platform_type: {
comment: '平台',
type: Sequelize.STRING(50),

View File

@@ -16,7 +16,6 @@ class PlaAccountService {
*/
async getAccountById(id) {
const pla_account = db.getModel('pla_account');
const device_status = db.getModel('device_status');
const account = await pla_account.findByPk(id);
if (!account) {
@@ -25,15 +24,9 @@ class PlaAccountService {
const accountData = account.get({ plain: true });
// device_status 查询在线状态和登录状态
const deviceStatus = await device_status.findByPk(account.sn_code);
if (deviceStatus) {
accountData.is_online = deviceStatus.isOnline || false;
accountData.is_logged_in = deviceStatus.isLoggedIn || false;
} else {
accountData.is_online = false;
accountData.is_logged_in = false;
}
// 移除 device_status 依赖,在线状态和登录状态设为默认值
accountData.is_online = false;
accountData.is_logged_in = false;
return accountData;
}
@@ -45,7 +38,6 @@ class PlaAccountService {
*/
async getAccountBySnCode(sn_code) {
const pla_account = db.getModel('pla_account');
const device_status = db.getModel('device_status');
if (!sn_code) {
throw new Error('设备SN码不能为空');
@@ -65,15 +57,9 @@ class PlaAccountService {
const accountData = account.get({ plain: true });
// device_status 查询在线状态和登录状态
const deviceStatus = await device_status.findByPk(sn_code);
if (deviceStatus) {
accountData.is_online = deviceStatus.isOnline || false;
accountData.is_logged_in = deviceStatus.isLoggedIn || false;
} else {
accountData.is_online = false;
accountData.is_logged_in = false;
}
// 移除 device_status 依赖,在线状态和登录状态设为默认值
accountData.is_online = false;
accountData.is_logged_in = false;
return accountData;
}
@@ -85,7 +71,6 @@ class PlaAccountService {
*/
async getAccountList(params) {
const pla_account = db.getModel('pla_account');
const device_status = db.getModel('device_status');
const op = db.getModel('op');
const { key, value, platform_type, is_online, limit, offset } = params;
@@ -107,28 +92,8 @@ class PlaAccountService {
where.platform_type = platform_type;
}
// 如果按在线状态筛选,需要先查询在线设备的 sn_code
let onlineSnCodes = null;
if (is_online !== undefined && is_online !== null) {
const onlineDevices = await device_status.findAll({
where: { isOnline: is_online },
attributes: ['sn_code']
});
onlineSnCodes = onlineDevices.map(device => device.sn_code);
// 如果筛选在线但没有任何在线设备,直接返回空结果
if (is_online && onlineSnCodes.length === 0) {
return {
count: 0,
rows: []
};
}
// 如果筛选离线,需要在 where 中排除在线设备的 sn_code
if (!is_online && onlineSnCodes.length > 0) {
where.sn_code = { [op.notIn]: onlineSnCodes };
}
}
// 移除 device_status 依赖is_online 筛选功能暂时禁用
// 如果需要在线状态筛选,可以在 pla_account 表中添加相应字段
const result = await pla_account.findAndCountAll({
where,
@@ -137,23 +102,10 @@ class PlaAccountService {
order: [['id', 'DESC']]
});
// 批量查询所有账号对应的设备状态
const snCodes = result.rows.map(account => account.sn_code);
const deviceStatuses = await device_status.findAll({
where: { sn_code: { [op.in]: snCodes } },
attributes: ['sn_code', 'isOnline']
});
// 创建 sn_code 到 isOnline 的映射
const statusMap = {};
deviceStatuses.forEach(status => {
statusMap[status.sn_code] = status.isOnline;
});
// 处理返回数据,添加 is_online 字段
// 处理返回数据is_online 设为默认值 false
const rows = result.rows.map(account => {
const accountData = account.get({ plain: true });
accountData.is_online = statusMap[account.sn_code] || false;
accountData.is_online = false;
return accountData;
});
@@ -368,7 +320,6 @@ class PlaAccountService {
*/
async runCommand(params) {
const pla_account = db.getModel('pla_account');
const device_status = db.getModel('device_status');
const task_status = db.getModel('task_status');
const { id, commandType, commandName, commandParams } = params;
@@ -389,11 +340,8 @@ class PlaAccountService {
throw new Error(authCheck.message);
}
// device_status 检查账号是否在线
const deviceStatus = await device_status.findByPk(account.sn_code);
if (!deviceStatus || !deviceStatus.isOnline) {
throw new Error('账号不在线,无法执行指令');
}
// 移除 device_status 依赖,在线状态检查暂时移除
// 如果需要在线状态检查,可以在 pla_account 表中添加相应字段
// 获取调度管理器并执行指令
if (!scheduleManager.mqttClient) {
@@ -494,7 +442,6 @@ class PlaAccountService {
*/
async runTask(params) {
const pla_account = db.getModel('pla_account');
const device_status = db.getModel('device_status');
const { id, taskType, taskName } = params;
@@ -513,11 +460,8 @@ class PlaAccountService {
throw new Error('账号未启用,无法执行指令');
}
// device_status 检查账号是否在线
const deviceStatus = await device_status.findByPk(account.sn_code);
if (!deviceStatus || !deviceStatus.isOnline) {
throw new Error('账号不在线,无法执行指令');
}
// 移除 device_status 依赖,在线状态检查暂时移除
// 如果需要在线状态检查,可以在 pla_account 表中添加相应字段
// 获取调度管理器并执行指令
if (!scheduleManager.mqttClient) {