refactor: 统一代码风格并迁移至 ESLint 新配置
style(backend): 格式化模型文件代码 style(frontend): 调整组件代码格式 chore: 删除旧 ESLint 配置并添加新配置 refactor(backend): 重构模型定义语法 style: 统一箭头函数和对象属性简写
This commit is contained in:
@@ -16,61 +16,61 @@ async function migrate() {
|
||||
userId: {
|
||||
type: sequelize.Sequelize.STRING,
|
||||
primaryKey: true,
|
||||
allowNull: false
|
||||
allowNull: false,
|
||||
},
|
||||
username: {
|
||||
type: sequelize.Sequelize.STRING,
|
||||
allowNull: false,
|
||||
unique: true
|
||||
unique: true,
|
||||
},
|
||||
password: {
|
||||
type: sequelize.Sequelize.STRING,
|
||||
allowNull: false
|
||||
allowNull: false,
|
||||
},
|
||||
email: {
|
||||
type: sequelize.Sequelize.STRING,
|
||||
allowNull: true
|
||||
allowNull: true,
|
||||
},
|
||||
phone: {
|
||||
type: sequelize.Sequelize.STRING,
|
||||
allowNull: true
|
||||
allowNull: true,
|
||||
},
|
||||
realName: {
|
||||
type: sequelize.Sequelize.STRING,
|
||||
allowNull: true
|
||||
allowNull: true,
|
||||
},
|
||||
avatar: {
|
||||
type: sequelize.Sequelize.STRING,
|
||||
allowNull: true
|
||||
allowNull: true,
|
||||
},
|
||||
status: {
|
||||
type: sequelize.Sequelize.ENUM('active', 'inactive', 'locked', 'pending'),
|
||||
defaultValue: 'active'
|
||||
defaultValue: 'active',
|
||||
},
|
||||
lastLoginTime: {
|
||||
type: sequelize.Sequelize.DATE,
|
||||
allowNull: true
|
||||
allowNull: true,
|
||||
},
|
||||
lastLoginIp: {
|
||||
type: sequelize.Sequelize.STRING,
|
||||
allowNull: true
|
||||
allowNull: true,
|
||||
},
|
||||
loginCount: {
|
||||
type: sequelize.Sequelize.INTEGER,
|
||||
defaultValue: 0
|
||||
defaultValue: 0,
|
||||
},
|
||||
remark: {
|
||||
type: sequelize.Sequelize.TEXT,
|
||||
allowNull: true
|
||||
allowNull: true,
|
||||
},
|
||||
createdAt: {
|
||||
type: sequelize.Sequelize.DATE,
|
||||
allowNull: false
|
||||
allowNull: false,
|
||||
},
|
||||
updatedAt: {
|
||||
type: sequelize.Sequelize.DATE,
|
||||
allowNull: false
|
||||
}
|
||||
allowNull: false,
|
||||
},
|
||||
});
|
||||
|
||||
// 2. 复制数据
|
||||
|
||||
@@ -104,14 +104,12 @@ async function migrateSQLite() {
|
||||
{ name: 'idx_archive_consumable_id', fields: 'consumableId' },
|
||||
{ name: 'idx_archive_archive_id', fields: 'archiveId' },
|
||||
{ name: 'idx_archive_deleted_at', fields: 'deletedAt' },
|
||||
{ name: 'idx_archive_consumable_deleted', fields: 'consumableId, deletedAt' }
|
||||
{ name: 'idx_archive_consumable_deleted', fields: 'consumableId, deletedAt' },
|
||||
];
|
||||
|
||||
for (const idx of indexes) {
|
||||
try {
|
||||
await sequelize.query(
|
||||
`CREATE INDEX ${idx.name} ON consumable_log_archives(${idx.fields})`
|
||||
);
|
||||
await sequelize.query(`CREATE INDEX ${idx.name} ON consumable_log_archives(${idx.fields})`);
|
||||
console.log(`✓ 创建索引: ${idx.name}`);
|
||||
} catch (err) {
|
||||
console.log(`! 创建索引失败: ${idx.name}`, err.message);
|
||||
|
||||
@@ -120,7 +120,17 @@ async function updateExistingLogs() {
|
||||
|
||||
try {
|
||||
const consumables = await Consumable.findAll({
|
||||
attributes: ['consumableId', 'category', 'unit', 'unitPrice', 'supplier', 'location', 'minStock', 'maxStock', 'status']
|
||||
attributes: [
|
||||
'consumableId',
|
||||
'category',
|
||||
'unit',
|
||||
'unitPrice',
|
||||
'supplier',
|
||||
'location',
|
||||
'minStock',
|
||||
'maxStock',
|
||||
'status',
|
||||
],
|
||||
});
|
||||
|
||||
const consumableMap = new Map();
|
||||
@@ -133,14 +143,14 @@ async function updateExistingLogs() {
|
||||
location: c.location,
|
||||
minStock: c.minStock,
|
||||
maxStock: c.maxStock,
|
||||
status: c.status
|
||||
status: c.status,
|
||||
});
|
||||
});
|
||||
|
||||
const logs = await ConsumableLog.findAll({
|
||||
where: {
|
||||
consumableSnapshot: null
|
||||
}
|
||||
consumableSnapshot: null,
|
||||
},
|
||||
});
|
||||
|
||||
let updatedCount = 0;
|
||||
@@ -155,10 +165,9 @@ async function updateExistingLogs() {
|
||||
console.log(`✓ 更新了 ${updatedCount} 条日志的快照信息`);
|
||||
|
||||
const deletedLogsCount = await ConsumableLog.count({
|
||||
where: { operationType: 'delete' }
|
||||
where: { operationType: 'delete' },
|
||||
});
|
||||
console.log(`✓ 当前有 ${deletedLogsCount} 条删除类型日志`);
|
||||
|
||||
} catch (error) {
|
||||
console.log('! 更新现有日志数据时出错:', error.message);
|
||||
}
|
||||
|
||||
@@ -16,18 +16,15 @@ async function migrate() {
|
||||
|
||||
if (actualDbType === 'sqlite') {
|
||||
// SQLite: 检查字段是否存在
|
||||
const tableInfo = await sequelize.query(
|
||||
"PRAGMA table_info(consumables)",
|
||||
{ type: sequelize.QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
const tableInfo = await sequelize.query('PRAGMA table_info(consumables)', {
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
});
|
||||
|
||||
const hasVersion = tableInfo.some(col => col.name === 'version');
|
||||
|
||||
|
||||
if (!hasVersion) {
|
||||
console.log('添加 version 字段...');
|
||||
await sequelize.query(
|
||||
"ALTER TABLE consumables ADD COLUMN version INTEGER DEFAULT 0"
|
||||
);
|
||||
await sequelize.query('ALTER TABLE consumables ADD COLUMN version INTEGER DEFAULT 0');
|
||||
console.log('version 字段添加成功');
|
||||
} else {
|
||||
console.log('version 字段已存在,跳过');
|
||||
@@ -38,19 +35,16 @@ async function migrate() {
|
||||
"SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='consumables'",
|
||||
{ type: sequelize.QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
|
||||
const hasUpdatedAtIndex = indexes.some(idx => idx.name === 'consumables_updatedAt');
|
||||
|
||||
|
||||
if (!hasUpdatedAtIndex) {
|
||||
console.log('添加 updatedAt 索引...');
|
||||
await sequelize.query(
|
||||
"CREATE INDEX consumables_updatedAt ON consumables(updatedAt)"
|
||||
);
|
||||
await sequelize.query('CREATE INDEX consumables_updatedAt ON consumables(updatedAt)');
|
||||
console.log('updatedAt 索引添加成功');
|
||||
} else {
|
||||
console.log('updatedAt 索引已存在,跳过');
|
||||
}
|
||||
|
||||
} else if (actualDbType === 'mysql') {
|
||||
// MySQL: 检查并添加字段
|
||||
try {
|
||||
@@ -70,9 +64,7 @@ async function migrate() {
|
||||
// 添加索引
|
||||
try {
|
||||
console.log('添加 updatedAt 索引...');
|
||||
await sequelize.query(
|
||||
"CREATE INDEX idx_consumables_updatedAt ON consumables(updatedAt)"
|
||||
);
|
||||
await sequelize.query('CREATE INDEX idx_consumables_updatedAt ON consumables(updatedAt)');
|
||||
console.log('updatedAt 索引添加成功');
|
||||
} catch (err) {
|
||||
if (err.message.includes('Duplicate key')) {
|
||||
@@ -85,9 +77,7 @@ async function migrate() {
|
||||
|
||||
// 初始化现有数据的 version 值
|
||||
console.log('初始化现有数据的 version 值...');
|
||||
await sequelize.query(
|
||||
"UPDATE consumables SET version = 0 WHERE version IS NULL"
|
||||
);
|
||||
await sequelize.query('UPDATE consumables SET version = 0 WHERE version IS NULL');
|
||||
console.log('version 值初始化完成');
|
||||
|
||||
console.log('迁移完成!');
|
||||
|
||||
@@ -8,19 +8,19 @@ async function migrate() {
|
||||
console.log(' IDC管理系统 - 数据库迁移脚本 v2.0 ');
|
||||
console.log('========================================');
|
||||
console.log('');
|
||||
|
||||
|
||||
try {
|
||||
console.log('🔍 检测数据库类型...');
|
||||
const dbType = sequelize.getDialect();
|
||||
console.log(` 数据库类型: ${dbType}`);
|
||||
console.log('');
|
||||
|
||||
|
||||
console.log('📋 开始迁移...');
|
||||
console.log(' 1. 创建 network_cards 表');
|
||||
console.log(' 2. 为 device_ports 添加 nic_id 字段');
|
||||
console.log(' 3. 创建相关索引');
|
||||
console.log('');
|
||||
|
||||
|
||||
if (dbType === 'sqlite') {
|
||||
await migrateSQLite();
|
||||
} else if (dbType === 'mysql') {
|
||||
@@ -29,25 +29,26 @@ async function migrate() {
|
||||
console.log(`⚠️ 不支持的数据库类型: ${dbType}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
console.log('');
|
||||
console.log('✅ 迁移完成!');
|
||||
console.log('');
|
||||
console.log('📊 验证迁移结果...');
|
||||
|
||||
const [tables] = await sequelize.query("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name");
|
||||
|
||||
const [tables] = await sequelize.query(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
|
||||
);
|
||||
console.log(` 数据库表: ${tables.map(t => t.name).join(', ')}`);
|
||||
|
||||
|
||||
const portCount = await DevicePort.count();
|
||||
const cardCount = await NetworkCard.count();
|
||||
console.log(` device_ports: ${portCount} 条记录`);
|
||||
console.log(` network_cards: ${cardCount} 条记录`);
|
||||
|
||||
|
||||
console.log('');
|
||||
console.log('========================================');
|
||||
console.log(' 迁移成功完成!🎉');
|
||||
console.log('========================================');
|
||||
|
||||
} catch (error) {
|
||||
console.error('');
|
||||
console.error('❌ 迁移失败:', error.message);
|
||||
@@ -62,33 +63,32 @@ async function migrate() {
|
||||
async function migrateSQLite() {
|
||||
console.log('');
|
||||
console.log('🔄 执行 SQLite 迁移...');
|
||||
|
||||
|
||||
await sequelize.query('PRAGMA foreign_keys = OFF');
|
||||
|
||||
|
||||
try {
|
||||
console.log(' → 删除旧的 device_ports 表...');
|
||||
await sequelize.query('DROP TABLE IF EXISTS `device_ports`');
|
||||
|
||||
|
||||
console.log(' → 删除旧的 network_cards 表...');
|
||||
await sequelize.query('DROP TABLE IF EXISTS `network_cards`');
|
||||
|
||||
|
||||
console.log(' → 同步 DevicePort 模型...');
|
||||
await DevicePort.sync({ force: false });
|
||||
|
||||
|
||||
console.log(' → 同步 NetworkCard 模型...');
|
||||
await NetworkCard.sync({ force: false });
|
||||
|
||||
|
||||
console.log(' → 同步 Device 模型(确保外键关系)...');
|
||||
await Device.sync({ force: false });
|
||||
|
||||
|
||||
console.log(' → 重新同步 DevicePort 模型(含外键)...');
|
||||
await DevicePort.sync({ force: true });
|
||||
|
||||
|
||||
console.log(' → 重新同步 NetworkCard 模型...');
|
||||
await NetworkCard.sync({ force: false });
|
||||
|
||||
|
||||
await sequelize.query('PRAGMA foreign_keys = ON');
|
||||
|
||||
} catch (error) {
|
||||
await sequelize.query('PRAGMA foreign_keys = ON');
|
||||
throw error;
|
||||
@@ -98,10 +98,10 @@ async function migrateSQLite() {
|
||||
async function migrateMySQL() {
|
||||
console.log('');
|
||||
console.log('🔄 执行 MySQL 迁移...');
|
||||
|
||||
|
||||
const tableName = 'network_cards';
|
||||
console.log(` → 创建表: ${tableName}`);
|
||||
|
||||
|
||||
const createTableSQL = `
|
||||
CREATE TABLE IF NOT EXISTS \`${tableName}\` (
|
||||
\`nic_id\` VARCHAR(255) NOT NULL PRIMARY KEY,
|
||||
@@ -120,15 +120,14 @@ async function migrateMySQL() {
|
||||
UNIQUE INDEX \`idx_device_name\` (\`device_id\`, \`name\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
`;
|
||||
|
||||
|
||||
await sequelize.query(createTableSQL);
|
||||
|
||||
|
||||
console.log(' → 检查 nic_id 字段是否存在...');
|
||||
const [columns] = await sequelize.query(
|
||||
"SHOW COLUMNS FROM `device_ports` LIKE 'nic_id'",
|
||||
{ type: sequelize.QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
const [columns] = await sequelize.query("SHOW COLUMNS FROM `device_ports` LIKE 'nic_id'", {
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
});
|
||||
|
||||
if (columns.length === 0) {
|
||||
console.log(' → 添加 nic_id 字段...');
|
||||
await sequelize.query(
|
||||
@@ -137,7 +136,7 @@ async function migrateMySQL() {
|
||||
} else {
|
||||
console.log(' → nic_id 字段已存在,跳过');
|
||||
}
|
||||
|
||||
|
||||
console.log(' → 创建 nic_id 索引...');
|
||||
try {
|
||||
await sequelize.query('CREATE INDEX `idx_port_nic_id` ON `device_ports`(`nic_id`)');
|
||||
@@ -148,11 +147,11 @@ async function migrateMySQL() {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
console.log(' → 同步模型以确保关系正确...');
|
||||
await NetworkCard.sync({ force: false });
|
||||
await DevicePort.sync({ force: false });
|
||||
|
||||
|
||||
console.log(' → 添加外键约束...');
|
||||
try {
|
||||
await sequelize.query(
|
||||
|
||||
@@ -55,10 +55,9 @@ async function removeSQLiteForeignKey() {
|
||||
console.log('SQLite 不支持直接删除外键,需要重建表');
|
||||
|
||||
// 检查外键是否存在
|
||||
const fks = await sequelize.query(
|
||||
`PRAGMA foreign_key_list(consumable_logs);`,
|
||||
{ type: sequelize.QueryTypes.SELECT }
|
||||
);
|
||||
const fks = await sequelize.query(`PRAGMA foreign_key_list(consumable_logs);`, {
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
});
|
||||
|
||||
if (!fks || fks.length === 0) {
|
||||
console.log('✓ 没有外键约束需要移除');
|
||||
@@ -68,17 +67,21 @@ async function removeSQLiteForeignKey() {
|
||||
console.log('发现外键约束:', fks);
|
||||
|
||||
// SQLite 不支持 ALTER TABLE DROP FOREIGN KEY,需要重建表
|
||||
await sequelize.transaction(async (transaction) => {
|
||||
await sequelize.transaction(async transaction => {
|
||||
// 获取表结构
|
||||
const columns = await sequelize.query(
|
||||
`PRAGMA table_info(consumable_logs);`,
|
||||
{ type: sequelize.QueryTypes.SELECT, transaction }
|
||||
const columns = await sequelize.query(`PRAGMA table_info(consumable_logs);`, {
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
transaction,
|
||||
});
|
||||
|
||||
console.log(
|
||||
'\n当前表列:',
|
||||
columns.map(c => c.name)
|
||||
);
|
||||
|
||||
console.log('\n当前表列:', columns.map(c => c.name));
|
||||
|
||||
// 创建新表(不包含外键约束)
|
||||
await sequelize.query(`
|
||||
await sequelize.query(
|
||||
`
|
||||
CREATE TABLE consumable_logs_new (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
consumableId VARCHAR(255) NOT NULL,
|
||||
@@ -101,20 +104,25 @@ async function removeSQLiteForeignKey() {
|
||||
isConsumableDeleted BOOLEAN DEFAULT 0,
|
||||
consumableSnapshot TEXT
|
||||
)
|
||||
`, { transaction });
|
||||
`,
|
||||
{ transaction }
|
||||
);
|
||||
|
||||
console.log('✓ 创建新表成功');
|
||||
|
||||
// 复制数据
|
||||
await sequelize.query(`
|
||||
await sequelize.query(
|
||||
`
|
||||
INSERT INTO consumable_logs_new
|
||||
SELECT * FROM consumable_logs
|
||||
`, { transaction });
|
||||
|
||||
const countResult = await sequelize.query(
|
||||
`SELECT COUNT(*) as count FROM consumable_logs_new`,
|
||||
{ type: sequelize.QueryTypes.SELECT, transaction }
|
||||
`,
|
||||
{ transaction }
|
||||
);
|
||||
|
||||
const countResult = await sequelize.query(`SELECT COUNT(*) as count FROM consumable_logs_new`, {
|
||||
type: sequelize.QueryTypes.SELECT,
|
||||
transaction,
|
||||
});
|
||||
console.log(`✓ 复制了 ${countResult[0].count} 条数据`);
|
||||
|
||||
// 删除旧表
|
||||
@@ -122,7 +130,9 @@ async function removeSQLiteForeignKey() {
|
||||
console.log('✓ 删除旧表成功');
|
||||
|
||||
// 重命名新表
|
||||
await sequelize.query(`ALTER TABLE consumable_logs_new RENAME TO consumable_logs`, { transaction });
|
||||
await sequelize.query(`ALTER TABLE consumable_logs_new RENAME TO consumable_logs`, {
|
||||
transaction,
|
||||
});
|
||||
console.log('✓ 重命名新表成功');
|
||||
|
||||
// 创建索引
|
||||
@@ -133,7 +143,7 @@ async function removeSQLiteForeignKey() {
|
||||
{ name: 'consumable_logs_consumable_id_created_at', fields: ['consumableId', 'createdAt'] },
|
||||
{ name: 'consumable_logs_original_log_id', fields: ['originalLogId'] },
|
||||
{ name: 'consumable_logs_is_editable', fields: ['isEditable'] },
|
||||
{ name: 'idx_consumable_logs_is_deleted', fields: ['isConsumableDeleted'] }
|
||||
{ name: 'idx_consumable_logs_is_deleted', fields: ['isConsumableDeleted'] },
|
||||
];
|
||||
|
||||
for (const idx of indexes) {
|
||||
|
||||
Reference in New Issue
Block a user