// 创建账号池相关表的迁移脚本 const { DataTypes, QueryInterface } = require('sequelize'); module.exports = { up: async (queryInterface, Sequelize) => { // 创建账号池主表 await queryInterface.createTable('accounts_pool', { id: { type: DataTypes.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true, comment: "主键ID" }, accountId: { type: DataTypes.INTEGER, allowNull: false, unique: true, comment: "关联的TG账号ID (accounts表)" }, phone: { type: DataTypes.STRING(50), allowNull: false, unique: true, comment: "手机号码" }, status: { type: DataTypes.ENUM('active', 'warning', 'limited', 'banned', 'cooling', 'inactive'), defaultValue: 'active', comment: "账号状态" }, tier: { type: DataTypes.ENUM('new', 'warming', 'normal', 'trusted', 'vip'), defaultValue: 'new', comment: "账号分级" }, dailyLimit: { type: DataTypes.INTEGER, defaultValue: 30, comment: "每日发送限制" }, hourlyLimit: { type: DataTypes.INTEGER, defaultValue: 5, comment: "每小时发送限制" }, intervalSeconds: { type: DataTypes.INTEGER, defaultValue: 120, comment: "发送间隔(秒)" }, lastActiveTime: { type: DataTypes.DATE, comment: "最后活跃时间" }, joinedGroupCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "已加入群组数" }, totalSentCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "累计发送数" }, todaySentCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "今日发送数" }, consecutiveFailures: { type: DataTypes.INTEGER, defaultValue: 0, comment: "连续失败次数" }, riskScore: { type: DataTypes.FLOAT, defaultValue: 0, comment: "风险评分(0-100)" }, priority: { type: DataTypes.INTEGER, defaultValue: 50, comment: "调度优先级(0-100)" }, tags: { type: DataTypes.JSON, defaultValue: [], comment: "标签数组" }, metadata: { type: DataTypes.JSON, defaultValue: {}, comment: "扩展元数据" }, isActive: { type: DataTypes.BOOLEAN, defaultValue: true, comment: "是否启用" }, createdAt: { type: DataTypes.DATE, allowNull: false }, updatedAt: { type: DataTypes.DATE, allowNull: false } }); // 创建索引 await queryInterface.addIndex('accounts_pool', ['status', 'isActive']); await queryInterface.addIndex('accounts_pool', ['tier']); await queryInterface.addIndex('accounts_pool', ['riskScore']); await queryInterface.addIndex('accounts_pool', ['lastActiveTime']); // 创建账号健康度表 await queryInterface.createTable('accounts_health', { id: { type: DataTypes.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true, comment: "主键ID" }, accountPoolId: { type: DataTypes.INTEGER, allowNull: false, comment: "关联的账号池ID" }, healthScore: { type: DataTypes.FLOAT, defaultValue: 100, comment: "健康度评分(0-100)" }, responseTime: { type: DataTypes.FLOAT, comment: "平均响应时间(ms)" }, successRate: { type: DataTypes.FLOAT, defaultValue: 100, comment: "成功率百分比" }, errorCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "错误次数" }, warningCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "警告次数" }, dailyUsageRate: { type: DataTypes.FLOAT, defaultValue: 0, comment: "日使用率百分比" }, weeklyUsageRate: { type: DataTypes.FLOAT, defaultValue: 0, comment: "周使用率百分比" }, restDuration: { type: DataTypes.INTEGER, defaultValue: 0, comment: "休息时长(分钟)" }, spamReportCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "垃圾信息举报次数" }, blockCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "被拉黑次数" }, restrictionCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "被限制次数" }, anomalyScore: { type: DataTypes.FLOAT, defaultValue: 0, comment: "异常行为评分" }, activeHours: { type: DataTypes.JSON, defaultValue: [], comment: "活跃时段分布" }, engagementRate: { type: DataTypes.FLOAT, defaultValue: 0, comment: "互动率" }, evaluationDetails: { type: DataTypes.JSON, defaultValue: {}, comment: "评估详细信息" }, lastEvaluationTime: { type: DataTypes.DATE, defaultValue: Sequelize.NOW, comment: "最后评估时间" }, trend: { type: DataTypes.ENUM('improving', 'stable', 'declining'), defaultValue: 'stable', comment: "健康度趋势" }, recommendations: { type: DataTypes.JSON, defaultValue: [], comment: "改善建议" }, createdAt: { type: DataTypes.DATE, allowNull: false }, updatedAt: { type: DataTypes.DATE, allowNull: false } }); // 创建索引 await queryInterface.addIndex('accounts_health', ['accountPoolId']); await queryInterface.addIndex('accounts_health', ['healthScore']); await queryInterface.addIndex('accounts_health', ['lastEvaluationTime']); // 创建账号使用记录表 await queryInterface.createTable('accounts_usage_log', { id: { type: DataTypes.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true, comment: "主键ID" }, accountPoolId: { type: DataTypes.INTEGER, allowNull: false, comment: "关联的账号池ID" }, taskId: { type: DataTypes.INTEGER, allowNull: false, comment: "关联的任务ID" }, taskType: { type: DataTypes.ENUM('group_send', 'private_send', 'join_group', 'leave_group', 'other'), defaultValue: 'group_send', comment: "任务类型" }, groupId: { type: DataTypes.INTEGER, comment: "群组ID(如果是群发任务)" }, messageContent: { type: DataTypes.TEXT, comment: "发送的消息内容" }, status: { type: DataTypes.ENUM('pending', 'success', 'failed', 'timeout', 'cancelled'), defaultValue: 'pending', comment: "执行状态" }, errorCode: { type: DataTypes.STRING(50), comment: "错误代码" }, errorMessage: { type: DataTypes.STRING(500), comment: "错误信息" }, retryCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "重试次数" }, startTime: { type: DataTypes.DATE, allowNull: false, comment: "开始时间" }, endTime: { type: DataTypes.DATE, comment: "结束时间" }, duration: { type: DataTypes.INTEGER, comment: "执行时长(毫秒)" }, riskLevel: { type: DataTypes.ENUM('low', 'medium', 'high', 'critical'), defaultValue: 'low', comment: "风险级别" }, behaviorSimulation: { type: DataTypes.JSON, defaultValue: {}, comment: "行为模拟参数" }, ipAddress: { type: DataTypes.STRING(50), comment: "使用的IP地址" }, deviceFingerprint: { type: DataTypes.STRING(100), comment: "设备指纹" }, recipientCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "接收者数量" }, readCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "已读数量" }, replyCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "回复数量" }, reportCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "举报数量" }, metadata: { type: DataTypes.JSON, defaultValue: {}, comment: "其他元数据" }, createdAt: { type: DataTypes.DATE, allowNull: false }, updatedAt: { type: DataTypes.DATE, allowNull: false } }); // 创建索引 await queryInterface.addIndex('accounts_usage_log', ['accountPoolId']); await queryInterface.addIndex('accounts_usage_log', ['taskId']); await queryInterface.addIndex('accounts_usage_log', ['startTime', 'endTime']); await queryInterface.addIndex('accounts_usage_log', ['status']); await queryInterface.addIndex('accounts_usage_log', ['riskLevel']); }, down: async (queryInterface, Sequelize) => { // 删除表(按相反顺序) await queryInterface.dropTable('accounts_usage_log'); await queryInterface.dropTable('accounts_health'); await queryInterface.dropTable('accounts_pool'); } };