refactor: 移除调试日志并优化代码结构
feat(components): 新增设备管理相关组件和仪表盘组件 feat(hooks): 添加自定义hooks用于API调用和数据管理 style: 优化滚动条样式和模态框布局 chore: 清理无用脚本和调试文件 docs: 更新组件导出文件
This commit is contained in:
@@ -1,33 +0,0 @@
|
||||
const { sequelize } = require('./db');
|
||||
const User = require('./models/User');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
console.log('数据库连接成功!\n');
|
||||
|
||||
const users = await User.findAll({
|
||||
attributes: ['userId', 'username', 'password', 'email', 'status', 'createdAt']
|
||||
});
|
||||
|
||||
console.log('用户列表:');
|
||||
console.log('============');
|
||||
|
||||
for (const user of users) {
|
||||
console.log('用户名:', user.username);
|
||||
console.log('密码(加密后):', user.password);
|
||||
console.log('状态:', user.status);
|
||||
console.log('创建时间:', user.createdAt);
|
||||
console.log('------------');
|
||||
}
|
||||
|
||||
console.log('\n' + users.length + ' 个用户');
|
||||
|
||||
await sequelize.close();
|
||||
} catch (error) {
|
||||
console.error('错误:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,99 +0,0 @@
|
||||
const { sequelize } = require('./db');
|
||||
|
||||
async function fixMaxStock() {
|
||||
try {
|
||||
console.log('开始修复 maxStock 字段...');
|
||||
|
||||
// 检查当前表结构
|
||||
const [results] = await sequelize.query(
|
||||
"PRAGMA table_info(consumables);"
|
||||
);
|
||||
|
||||
console.log('当前表结构:');
|
||||
results.forEach(col => {
|
||||
console.log(` ${col.name}: ${col.type} ${col.notnull ? 'NOT NULL' : 'NULL'} default=${col.dflt_value}`);
|
||||
});
|
||||
|
||||
const maxStockCol = results.find(c => c.name === 'maxStock');
|
||||
if (maxStockCol) {
|
||||
console.log('\n当前 maxStock 字段:', maxStockCol);
|
||||
|
||||
// SQLite 不支持直接修改列,需要创建新表
|
||||
console.log('\n需要重建表结构...');
|
||||
|
||||
// 1. 创建新表
|
||||
await sequelize.query(`
|
||||
CREATE TABLE consumables_new (
|
||||
consumableId VARCHAR(255) PRIMARY KEY NOT NULL UNIQUE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
category VARCHAR(255) NOT NULL,
|
||||
unit VARCHAR(255) NOT NULL DEFAULT '个',
|
||||
currentStock INTEGER NOT NULL DEFAULT 0,
|
||||
minStock INTEGER NOT NULL DEFAULT 10,
|
||||
maxStock INTEGER NOT NULL DEFAULT 0,
|
||||
unitPrice DECIMAL(10,2) NOT NULL DEFAULT 0,
|
||||
supplier VARCHAR(255),
|
||||
location VARCHAR(255),
|
||||
description TEXT,
|
||||
status VARCHAR(255) DEFAULT 'active',
|
||||
version INTEGER NOT NULL DEFAULT 0,
|
||||
createdAt DATETIME,
|
||||
updatedAt DATETIME
|
||||
)
|
||||
`);
|
||||
|
||||
// 2. 复制数据(将 null 转换为 0)
|
||||
await sequelize.query(`
|
||||
INSERT INTO consumables_new
|
||||
SELECT
|
||||
consumableId,
|
||||
name,
|
||||
category,
|
||||
unit,
|
||||
currentStock,
|
||||
minStock,
|
||||
COALESCE(maxStock, 0) as maxStock,
|
||||
unitPrice,
|
||||
supplier,
|
||||
location,
|
||||
description,
|
||||
status,
|
||||
version,
|
||||
createdAt,
|
||||
updatedAt
|
||||
FROM consumables
|
||||
`);
|
||||
|
||||
// 3. 删除旧表
|
||||
await sequelize.query('DROP TABLE consumables');
|
||||
|
||||
// 4. 重命名新表
|
||||
await sequelize.query('ALTER TABLE consumables_new RENAME TO consumables');
|
||||
|
||||
// 5. 创建索引
|
||||
await sequelize.query('CREATE INDEX consumables_category ON consumables(category)');
|
||||
await sequelize.query('CREATE INDEX consumables_status ON consumables(status)');
|
||||
await sequelize.query('CREATE INDEX consumables_category_status ON consumables(category, status)');
|
||||
await sequelize.query('CREATE INDEX consumables_updatedAt ON consumables(updatedAt)');
|
||||
|
||||
console.log('\n表结构修复完成!');
|
||||
|
||||
// 验证新表结构
|
||||
const [newResults] = await sequelize.query(
|
||||
"PRAGMA table_info(consumables);"
|
||||
);
|
||||
console.log('\n新表结构:');
|
||||
newResults.forEach(col => {
|
||||
console.log(` ${col.name}: ${col.type} ${col.notnull ? 'NOT NULL' : 'NULL'} default=${col.dflt_value}`);
|
||||
});
|
||||
}
|
||||
|
||||
console.log('\n修复完成!');
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
console.error('修复失败:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
fixMaxStock();
|
||||
@@ -1,125 +0,0 @@
|
||||
const bcrypt = require('bcryptjs');
|
||||
const { sequelize } = require('./db');
|
||||
const User = require('./models/User');
|
||||
const Role = require('./models/Role');
|
||||
const UserRole = require('./models/UserRole');
|
||||
|
||||
async function fixAdminUser() {
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
console.log('数据库连接成功!\n');
|
||||
|
||||
const adminUser = await User.findOne({
|
||||
where: { username: 'admin' }
|
||||
});
|
||||
|
||||
if (!adminUser) {
|
||||
console.log('未找到 admin 用户');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('当前 admin 用户信息:');
|
||||
console.log('用户名:', adminUser.username);
|
||||
console.log('邮箱:', adminUser.email);
|
||||
console.log('状态:', adminUser.status);
|
||||
console.log('');
|
||||
|
||||
const userRoles = await UserRole.findAll({
|
||||
where: { UserId: adminUser.userId },
|
||||
include: [{ model: Role }]
|
||||
});
|
||||
|
||||
console.log('当前用户角色:');
|
||||
if (userRoles.length === 0) {
|
||||
console.log(' - 无角色分配');
|
||||
} else {
|
||||
userRoles.forEach(ur => {
|
||||
console.log(` - ${ur.Role.roleName} (${ur.Role.roleCode})`);
|
||||
});
|
||||
}
|
||||
console.log('');
|
||||
|
||||
let adminRole = await Role.findOne({
|
||||
where: { roleCode: 'admin' }
|
||||
});
|
||||
|
||||
if (!adminRole) {
|
||||
console.log('正在创建管理员角色...');
|
||||
adminRole = await Role.create({
|
||||
roleId: 'role_admin',
|
||||
roleName: '管理员',
|
||||
roleCode: 'admin',
|
||||
description: '系统管理员,拥有所有权限',
|
||||
status: 'active',
|
||||
permissions: []
|
||||
});
|
||||
console.log('管理员角色创建成功!');
|
||||
} else {
|
||||
console.log('管理员角色已存在');
|
||||
}
|
||||
|
||||
const existingUserRole = await UserRole.findOne({
|
||||
where: {
|
||||
UserId: adminUser.userId,
|
||||
RoleId: adminRole.roleId
|
||||
}
|
||||
});
|
||||
|
||||
if (!existingUserRole) {
|
||||
console.log('正在为 admin 用户分配管理员角色...');
|
||||
await UserRole.create({
|
||||
UserId: adminUser.userId,
|
||||
RoleId: adminRole.roleId
|
||||
});
|
||||
console.log('角色分配成功!');
|
||||
} else {
|
||||
console.log('管理员角色已分配给该用户');
|
||||
}
|
||||
console.log('');
|
||||
|
||||
const newPassword = 'admin123';
|
||||
const salt = await bcrypt.genSalt(10);
|
||||
const hashedPassword = await bcrypt.hash(newPassword, salt);
|
||||
|
||||
await adminUser.update({
|
||||
password: hashedPassword
|
||||
});
|
||||
|
||||
console.log('密码已重置为: admin123');
|
||||
console.log('');
|
||||
|
||||
const updatedUser = await User.findOne({
|
||||
where: { username: 'admin' },
|
||||
include: [{ model: Role }]
|
||||
});
|
||||
|
||||
console.log('修复后的 admin 用户信息:');
|
||||
console.log('用户名:', updatedUser.username);
|
||||
console.log('邮箱:', updatedUser.email);
|
||||
console.log('状态:', updatedUser.status);
|
||||
console.log('角色:',
|
||||
updatedUser.Roles && updatedUser.Roles.length > 0
|
||||
? updatedUser.Roles.map(r => r.roleName).join(', ')
|
||||
: '无角色'
|
||||
);
|
||||
console.log('');
|
||||
|
||||
const testResult = bcrypt.compareSync(newPassword, updatedUser.password);
|
||||
console.log('密码验证测试:');
|
||||
console.log(` 输入密码: "${newPassword}"`);
|
||||
console.log(` 验证结果: ${testResult ? '✓ 成功' : '✗ 失败'}`);
|
||||
|
||||
console.log('\n========================================');
|
||||
console.log('修复完成!现在可以使用以下信息登录:');
|
||||
console.log(' 用户名: admin');
|
||||
console.log(' 密码: admin123');
|
||||
console.log('========================================');
|
||||
|
||||
} catch (error) {
|
||||
console.error('修复过程中发生错误:', error.message);
|
||||
} finally {
|
||||
await sequelize.close();
|
||||
}
|
||||
}
|
||||
|
||||
fixAdminUser();
|
||||
@@ -1,133 +0,0 @@
|
||||
const { sequelize } = require('./db');
|
||||
const Role = require('./models/Role');
|
||||
const User = require('./models/User');
|
||||
const UserRole = require('./models/UserRole');
|
||||
|
||||
async function fixForeignKeys() {
|
||||
try {
|
||||
console.log('开始修复外键约束...');
|
||||
|
||||
await sequelize.query('PRAGMA foreign_keys = OFF');
|
||||
|
||||
await sequelize.query('DROP TABLE IF EXISTS user_roles');
|
||||
await sequelize.query('DROP TABLE IF EXISTS users');
|
||||
await sequelize.query('DROP TABLE IF EXISTS roles');
|
||||
|
||||
console.log('已删除现有表,正在重新创建...');
|
||||
|
||||
await sequelize.query(`
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
roleId TEXT PRIMARY KEY,
|
||||
roleName TEXT NOT NULL,
|
||||
roleCode TEXT NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
permissions TEXT DEFAULT '[]',
|
||||
sort INTEGER DEFAULT 0,
|
||||
status TEXT DEFAULT 'active',
|
||||
createdAt DATETIME,
|
||||
updatedAt DATETIME
|
||||
)
|
||||
`);
|
||||
|
||||
await sequelize.query(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
userId TEXT PRIMARY KEY,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
password TEXT NOT NULL,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
realName TEXT,
|
||||
avatar TEXT,
|
||||
status TEXT DEFAULT 'active',
|
||||
lastLoginTime DATETIME,
|
||||
lastLoginIp TEXT,
|
||||
loginCount INTEGER DEFAULT 0,
|
||||
remark TEXT,
|
||||
createdAt DATETIME,
|
||||
updatedAt DATETIME
|
||||
)
|
||||
`);
|
||||
|
||||
await sequelize.query(`
|
||||
CREATE TABLE IF NOT EXISTS user_roles (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
UserId TEXT NOT NULL,
|
||||
RoleId TEXT NOT NULL,
|
||||
createdAt DATETIME,
|
||||
updatedAt DATETIME,
|
||||
FOREIGN KEY (UserId) REFERENCES users(userId) ON DELETE CASCADE,
|
||||
FOREIGN KEY (RoleId) REFERENCES roles(roleId) ON DELETE CASCADE,
|
||||
UNIQUE(UserId, RoleId)
|
||||
)
|
||||
`);
|
||||
|
||||
await sequelize.query('PRAGMA foreign_keys = ON');
|
||||
|
||||
console.log('外键约束修复完成!');
|
||||
console.log('正在重新初始化角色数据...');
|
||||
|
||||
const bcrypt = require('bcryptjs');
|
||||
const SALT_ROUNDS = 10;
|
||||
|
||||
await Role.bulkCreate([
|
||||
{
|
||||
roleId: 'role_admin',
|
||||
roleName: '管理员',
|
||||
roleCode: 'admin',
|
||||
description: '系统管理员,拥有所有权限',
|
||||
permissions: '[]',
|
||||
sort: 1,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
roleId: 'role_operator',
|
||||
roleName: '操作员',
|
||||
roleCode: 'operator',
|
||||
description: '设备操作员,可进行设备操作',
|
||||
permissions: '[]',
|
||||
sort: 2,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
roleId: 'role_viewer',
|
||||
roleName: '访客',
|
||||
roleCode: 'viewer',
|
||||
description: '只读权限,只能查看数据',
|
||||
permissions: '[]',
|
||||
sort: 3,
|
||||
status: 'active'
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('角色数据初始化完成!');
|
||||
|
||||
const hashedPassword = await bcrypt.hash('admin123', SALT_ROUNDS);
|
||||
|
||||
const adminUser = await User.create({
|
||||
userId: 'user_admin',
|
||||
username: 'admin',
|
||||
password: hashedPassword,
|
||||
email: 'admin@example.com',
|
||||
realName: '系统管理员',
|
||||
status: 'active'
|
||||
});
|
||||
|
||||
await UserRole.create({
|
||||
UserId: adminUser.userId,
|
||||
RoleId: 'role_admin'
|
||||
});
|
||||
|
||||
console.log('管理员账户创建完成!');
|
||||
console.log('用户名: admin');
|
||||
console.log('密码: admin123');
|
||||
|
||||
console.log('\n修复完成!请重启后端服务。');
|
||||
|
||||
} catch (error) {
|
||||
console.error('修复外键约束失败:', error);
|
||||
} finally {
|
||||
await sequelize.close();
|
||||
}
|
||||
}
|
||||
|
||||
fixForeignKeys();
|
||||
@@ -1,35 +0,0 @@
|
||||
const sqlite3 = require('sqlite3').verbose();
|
||||
const path = require('path');
|
||||
|
||||
const dbPath = path.join(__dirname, 'idc_management.db');
|
||||
|
||||
const db = new sqlite3.Database(dbPath, (err) => {
|
||||
if (err) {
|
||||
console.error('无法打开数据库:', err);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('开始修复数据库表结构...');
|
||||
|
||||
db.serialize(() => {
|
||||
db.run(`ALTER TABLE consumables ADD COLUMN location TEXT;`, function(err) {
|
||||
if (err) {
|
||||
if (err.message.includes('duplicate column name: location')) {
|
||||
console.log('location 列已存在,无需添加');
|
||||
} else {
|
||||
console.error('添加 location 列失败:', err.message);
|
||||
}
|
||||
} else {
|
||||
console.log('成功添加 location 列到 consumables 表');
|
||||
}
|
||||
|
||||
db.close((closeErr) => {
|
||||
if (closeErr) {
|
||||
console.error('关闭数据库失败:', closeErr);
|
||||
} else {
|
||||
console.log('数据库修复完成');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,58 +0,0 @@
|
||||
const sqlite3 = require('sqlite3').verbose();
|
||||
const path = require('path');
|
||||
|
||||
const dbPath = process.env.DB_PATH || path.join(__dirname, 'idc_management.db');
|
||||
|
||||
const db = new sqlite3.Database(dbPath, (err) => {
|
||||
if (err) {
|
||||
console.error('无法连接到数据库:', err);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('已连接到数据库:', dbPath);
|
||||
});
|
||||
|
||||
const columnsToAdd = [
|
||||
{ table: 'pending_devices', column: 'height', type: 'INTEGER', defaultValue: 1 },
|
||||
{ table: 'pending_devices', column: 'powerConsumption', type: 'FLOAT', defaultValue: 0 },
|
||||
{ table: 'pending_devices', column: 'brand', type: 'VARCHAR(255)', defaultValue: null },
|
||||
{ table: 'pending_devices', column: 'purchaseDate', type: 'DATE', defaultValue: null },
|
||||
{ table: 'pending_devices', column: 'warrantyExpiry', type: 'DATE', defaultValue: null },
|
||||
];
|
||||
|
||||
db.serialize(() => {
|
||||
columnsToAdd.forEach(({ table, column, type, defaultValue }) => {
|
||||
db.all(`PRAGMA table_info(${table})`, (err, rows) => {
|
||||
if (err) {
|
||||
console.error(`获取表 ${table} 信息失败:`, err);
|
||||
return;
|
||||
}
|
||||
|
||||
const columnExists = rows && rows.some(row => row.name === column);
|
||||
|
||||
if (!columnExists) {
|
||||
const defaultClause = defaultValue !== null ? ` DEFAULT ${typeof defaultValue === 'string' ? `'${defaultValue}'` : defaultValue}` : '';
|
||||
const sql = `ALTER TABLE ${table} ADD COLUMN ${column} ${type}${defaultClause}`;
|
||||
|
||||
db.run(sql, (err) => {
|
||||
if (err) {
|
||||
console.error(`添加列 ${table}.${column} 失败:`, err.message);
|
||||
} else {
|
||||
console.log(`成功添加列 ${table}.${column}`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log(`列 ${table}.${column} 已存在,跳过`);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
db.close((err) => {
|
||||
if (err) {
|
||||
console.error('关闭数据库失败:', err);
|
||||
} else {
|
||||
console.log('数据库迁移完成,连接已关闭');
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
@@ -1,51 +0,0 @@
|
||||
const { sequelize } = require('./db');
|
||||
const FaultCategory = require('./models/FaultCategory');
|
||||
|
||||
async function recreateFaultCategoryTable() {
|
||||
try {
|
||||
console.log('开始重建故障分类表...');
|
||||
|
||||
await sequelize.authenticate();
|
||||
console.log('数据库连接成功');
|
||||
|
||||
// 删除旧表并创建新表
|
||||
await sequelize.query('DROP TABLE IF EXISTS fault_categories');
|
||||
console.log('旧表已删除');
|
||||
|
||||
await FaultCategory.sync();
|
||||
console.log('新表已创建');
|
||||
|
||||
// 初始化默认分类
|
||||
const defaultCategories = [
|
||||
{ name: '系统故障', description: '操作系统、应用程序等系统软件的故障问题', priority: 1, defaultPriority: 'high', expectedDuration: 120, isSystem: true, isActive: true },
|
||||
{ name: '硬件故障', description: '物理设备、服务器、存储等硬件设备的故障问题', priority: 2, defaultPriority: 'high', expectedDuration: 180, isSystem: true, isActive: true },
|
||||
{ name: '网络故障', description: '网络连接、交换机、路由器等网络相关故障', priority: 3, defaultPriority: 'high', expectedDuration: 120, isSystem: true, isActive: true },
|
||||
{ name: '软件故障', description: '应用程序错误、软件兼容性等问题', priority: 4, defaultPriority: 'medium', expectedDuration: 90, isSystem: true, isActive: true },
|
||||
{ name: '安全事件', description: '安全漏洞、入侵检测、权限异常等安全问题', priority: 5, defaultPriority: 'urgent', expectedDuration: 60, isSystem: true, isActive: true },
|
||||
{ name: '性能问题', description: '系统响应慢、资源利用率高等性能问题', priority: 6, defaultPriority: 'medium', expectedDuration: 120, isSystem: true, isActive: true },
|
||||
{ name: '配置变更', description: '系统配置、软件配置等变更需求', priority: 7, defaultPriority: 'low', expectedDuration: 60, isSystem: true, isActive: true },
|
||||
{ name: '例行维护', description: '定期维护、巡检、更新等计划性工作', priority: 8, defaultPriority: 'low', expectedDuration: 120, isSystem: true, isActive: true },
|
||||
{ name: '数据问题', description: '数据错误、数据丢失、数据同步等数据相关问题', priority: 9, defaultPriority: 'high', expectedDuration: 150, isSystem: true, isActive: true },
|
||||
{ name: '其他问题', description: '无法归类的其他问题', priority: 99, defaultPriority: 'medium', expectedDuration: 90, isSystem: true, isActive: true }
|
||||
];
|
||||
|
||||
for (const cat of defaultCategories) {
|
||||
const categoryId = `CAT${Date.now().toString(36).toUpperCase()}${Math.random().toString(36).substr(2, 4).toUpperCase()}`;
|
||||
await FaultCategory.create({
|
||||
categoryId,
|
||||
...cat,
|
||||
solutions: [],
|
||||
metadata: {}
|
||||
});
|
||||
}
|
||||
console.log('默认分类已初始化');
|
||||
|
||||
console.log('故障分类表重建完成!');
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
console.error('操作失败:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
recreateFaultCategoryTable();
|
||||
@@ -55,12 +55,10 @@ router.get('/', async (req, res) => {
|
||||
router.post('/', async (req, res) => {
|
||||
const transaction = await sequelize.transaction();
|
||||
try {
|
||||
console.log('接收到的数据:', JSON.stringify(req.body, null, 2));
|
||||
const consumableData = {
|
||||
...req.body,
|
||||
consumableId: req.body.consumableId || `CON${Date.now()}`
|
||||
};
|
||||
console.log('处理后的数据:', JSON.stringify(consumableData, null, 2));
|
||||
const consumable = await Consumable.create(consumableData, { transaction });
|
||||
|
||||
await ConsumableLog.create({
|
||||
|
||||
@@ -81,8 +81,6 @@ router.get('/plans', async (req, res) => {
|
||||
|
||||
router.get('/plans/:planId', async (req, res) => {
|
||||
try {
|
||||
console.log('=== GET /plans/:planId ===', req.params.planId);
|
||||
|
||||
const plan = await InventoryPlan.findByPk(req.params.planId, {
|
||||
include: [
|
||||
{ model: require('../models/User'), as: 'Creator', attributes: ['userId', 'username', 'realName'] }
|
||||
@@ -90,7 +88,6 @@ router.get('/plans/:planId', async (req, res) => {
|
||||
});
|
||||
|
||||
if (!plan) {
|
||||
console.log('Plan not found');
|
||||
return res.status(404).json({ error: '盘点计划不存在' });
|
||||
}
|
||||
|
||||
@@ -102,10 +99,8 @@ router.get('/plans/:planId', async (req, res) => {
|
||||
order: [['createdAt', 'ASC']]
|
||||
});
|
||||
|
||||
console.log('Found tasks:', tasks.length);
|
||||
res.json({ plan, tasks });
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
+123
-132
@@ -13,136 +13,131 @@ app.use(express.json());
|
||||
app.use(fileUpload({ limits: { fileSize: FILE_UPLOAD.MAX_FILE_SIZE } }));
|
||||
app.use('/temp', express.static('temp'));
|
||||
|
||||
// 数据库连接已从db.js导入
|
||||
async function syncDatabase() {
|
||||
await sequelize.authenticate();
|
||||
console.log('数据库连接成功');
|
||||
|
||||
// 测试数据库连接并同步表结构
|
||||
sequelize.authenticate()
|
||||
.then(() => {
|
||||
console.log('数据库连接成功');
|
||||
// 自动同步表结构,不再强制删除表
|
||||
return sequelize.sync({
|
||||
force: false, // 改为false,避免每次启动都删除表结构
|
||||
alter: false // SQLite不支持复杂的表结构修改
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
console.log('数据库表结构同步完成');
|
||||
// 同步完成后初始化设备字段
|
||||
return require('./initDeviceFields')();
|
||||
})
|
||||
.then(() => {
|
||||
// 初始化工单字段
|
||||
return require('./initTicketFields')();
|
||||
})
|
||||
.then(() => {
|
||||
// 初始化工单模型关联
|
||||
return require('./models/ticketIndex').initializeModels();
|
||||
})
|
||||
.then(() => {
|
||||
// 同步系统设置模型
|
||||
const SystemSetting = require('./models/SystemSetting');
|
||||
return SystemSetting.sync();
|
||||
})
|
||||
.then(() => {
|
||||
// 同步耗材模型
|
||||
const Consumable = require('./models/Consumable');
|
||||
const ConsumableLog = require('./models/ConsumableLog');
|
||||
const ConsumableCategory = require('./models/ConsumableCategory');
|
||||
const ConsumableRecord = require('./models/ConsumableRecord');
|
||||
const ConsumableLogArchive = require('./models/ConsumableLogArchive');
|
||||
return Promise.all([
|
||||
Consumable.sync({ alter: true }),
|
||||
ConsumableLog.sync(),
|
||||
ConsumableCategory.sync(),
|
||||
ConsumableRecord.sync(),
|
||||
ConsumableLogArchive.sync()
|
||||
]);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('耗材模型同步完成');
|
||||
})
|
||||
.then(() => {
|
||||
// 同步盘点模型
|
||||
const InventoryPlan = require('./models/InventoryPlan');
|
||||
const InventoryTask = require('./models/InventoryTask');
|
||||
const InventoryRecord = require('./models/InventoryRecord');
|
||||
return Promise.all([
|
||||
InventoryPlan.sync(),
|
||||
InventoryTask.sync(),
|
||||
InventoryRecord.sync()
|
||||
]);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('盘点模型同步完成');
|
||||
})
|
||||
.then(() => {
|
||||
// 同步耗材相关模型
|
||||
const Consumable = require('./models/Consumable');
|
||||
const ConsumableLog = require('./models/ConsumableLog');
|
||||
const ConsumableCategory = require('./models/ConsumableCategory');
|
||||
const ConsumableRecord = require('./models/ConsumableRecord');
|
||||
const ConsumableLogArchive = require('./models/ConsumableLogArchive');
|
||||
return Promise.all([
|
||||
Consumable.sync({ alter: true }),
|
||||
ConsumableLog.sync(),
|
||||
ConsumableCategory.sync(),
|
||||
ConsumableRecord.sync(),
|
||||
ConsumableLogArchive.sync()
|
||||
]);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('耗材模型同步完成');
|
||||
})
|
||||
.then(() => {
|
||||
// 初始化系统设置默认值(关键:确保部署时数据正确初始化)
|
||||
console.log('开始初始化系统设置默认值...');
|
||||
const { initDefaultSettings } = require('./routes/systemSettings');
|
||||
return initDefaultSettings();
|
||||
})
|
||||
.then(() => {
|
||||
console.log('系统设置初始化完成');
|
||||
})
|
||||
.then(() => {
|
||||
// 初始化故障分类数据
|
||||
console.log('开始初始化故障分类...');
|
||||
const FaultCategory = require('./models/FaultCategory');
|
||||
const defaultCategories = [
|
||||
{ name: '系统故障', description: '操作系统、应用程序等系统软件的故障问题', priority: 1, defaultPriority: 'high' },
|
||||
{ name: '硬件故障', description: '物理设备、服务器、存储等硬件设备的故障问题', priority: 2, defaultPriority: 'high' },
|
||||
{ name: '网络故障', description: '网络连接、交换机、路由器等网络相关故障', priority: 3, defaultPriority: 'high' },
|
||||
{ name: '软件故障', description: '应用程序错误、软件兼容性等问题', priority: 4, defaultPriority: 'medium' },
|
||||
{ name: '安全事件', description: '安全漏洞、入侵检测、权限异常等安全问题', priority: 5, defaultPriority: 'urgent' },
|
||||
{ name: '性能问题', description: '系统响应慢、资源利用率高等性能问题', priority: 6, defaultPriority: 'medium' },
|
||||
{ name: '配置变更', description: '系统配置、软件配置等变更需求', priority: 7, defaultPriority: 'low' },
|
||||
{ name: '例行维护', description: '定期维护、巡检、更新等计划性工作', priority: 8, defaultPriority: 'low' },
|
||||
{ name: '数据问题', description: '数据错误、数据丢失、数据同步等数据相关问题', priority: 9, defaultPriority: 'high' },
|
||||
{ name: '其他问题', description: '无法归类的其他问题', priority: 99, defaultPriority: 'medium' }
|
||||
];
|
||||
await sequelize.sync({
|
||||
force: false,
|
||||
alter: false
|
||||
});
|
||||
console.log('数据库表结构同步完成');
|
||||
}
|
||||
|
||||
return Promise.all(
|
||||
defaultCategories.map(async (cat) => {
|
||||
const existing = await FaultCategory.findOne({ where: { name: cat.name } });
|
||||
if (!existing) {
|
||||
const categoryId = `CAT${Date.now().toString(36).toUpperCase()}${Math.random().toString(36).substr(2, 4).toUpperCase()}`;
|
||||
await FaultCategory.create({
|
||||
categoryId,
|
||||
...cat,
|
||||
expectedDuration: 120,
|
||||
solutions: [],
|
||||
isSystem: true,
|
||||
isActive: true
|
||||
});
|
||||
console.log(`创建故障分类: ${cat.name}`);
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('故障分类初始化完成');
|
||||
})
|
||||
.catch(err => console.error('数据库操作失败:', err));
|
||||
async function initDeviceFields() {
|
||||
await require('./initDeviceFields')();
|
||||
console.log('设备字段初始化完成');
|
||||
}
|
||||
|
||||
async function initTicketFields() {
|
||||
await require('./initTicketFields')();
|
||||
console.log('工单字段初始化完成');
|
||||
}
|
||||
|
||||
async function initTicketModels() {
|
||||
await require('./models/ticketIndex').initializeModels();
|
||||
console.log('工单模型关联初始化完成');
|
||||
}
|
||||
|
||||
async function syncSystemSettings() {
|
||||
const SystemSetting = require('./models/SystemSetting');
|
||||
await SystemSetting.sync();
|
||||
console.log('系统设置模型同步完成');
|
||||
}
|
||||
|
||||
async function syncConsumableModels() {
|
||||
const Consumable = require('./models/Consumable');
|
||||
const ConsumableLog = require('./models/ConsumableLog');
|
||||
const ConsumableCategory = require('./models/ConsumableCategory');
|
||||
const ConsumableRecord = require('./models/ConsumableRecord');
|
||||
const ConsumableLogArchive = require('./models/ConsumableLogArchive');
|
||||
|
||||
await Promise.all([
|
||||
Consumable.sync({ alter: true }),
|
||||
ConsumableLog.sync(),
|
||||
ConsumableCategory.sync(),
|
||||
ConsumableRecord.sync(),
|
||||
ConsumableLogArchive.sync()
|
||||
]);
|
||||
console.log('耗材模型同步完成');
|
||||
}
|
||||
|
||||
async function syncInventoryModels() {
|
||||
const InventoryPlan = require('./models/InventoryPlan');
|
||||
const InventoryTask = require('./models/InventoryTask');
|
||||
const InventoryRecord = require('./models/InventoryRecord');
|
||||
|
||||
await Promise.all([
|
||||
InventoryPlan.sync(),
|
||||
InventoryTask.sync(),
|
||||
InventoryRecord.sync()
|
||||
]);
|
||||
console.log('盘点模型同步完成');
|
||||
}
|
||||
|
||||
async function initDefaultSystemSettings() {
|
||||
console.log('开始初始化系统设置默认值...');
|
||||
const { initDefaultSettings } = require('./routes/systemSettings');
|
||||
await initDefaultSettings();
|
||||
console.log('系统设置初始化完成');
|
||||
}
|
||||
|
||||
async function initFaultCategories() {
|
||||
console.log('开始初始化故障分类...');
|
||||
const FaultCategory = require('./models/FaultCategory');
|
||||
|
||||
const defaultCategories = [
|
||||
{ name: '系统故障', description: '操作系统、应用程序等系统软件的故障问题', priority: 1, defaultPriority: 'high' },
|
||||
{ name: '硬件故障', description: '物理设备、服务器、存储等硬件设备的故障问题', priority: 2, defaultPriority: 'high' },
|
||||
{ name: '网络故障', description: '网络连接、交换机、路由器等网络相关故障', priority: 3, defaultPriority: 'high' },
|
||||
{ name: '软件故障', description: '应用程序错误、软件兼容性等问题', priority: 4, defaultPriority: 'medium' },
|
||||
{ name: '安全事件', description: '安全漏洞、入侵检测、权限异常等安全问题', priority: 5, defaultPriority: 'urgent' },
|
||||
{ name: '性能问题', description: '系统响应慢、资源利用率高等性能问题', priority: 6, defaultPriority: 'medium' },
|
||||
{ name: '配置变更', description: '系统配置、软件配置等变更需求', priority: 7, defaultPriority: 'low' },
|
||||
{ name: '例行维护', description: '定期维护、巡检、更新等计划性工作', priority: 8, defaultPriority: 'low' },
|
||||
{ name: '数据问题', description: '数据错误、数据丢失、数据同步等数据相关问题', priority: 9, defaultPriority: 'high' },
|
||||
{ name: '其他问题', description: '无法归类的其他问题', priority: 99, defaultPriority: 'medium' }
|
||||
];
|
||||
|
||||
for (const cat of defaultCategories) {
|
||||
const existing = await FaultCategory.findOne({ where: { name: cat.name } });
|
||||
if (!existing) {
|
||||
const categoryId = `CAT${Date.now().toString(36).toUpperCase()}${Math.random().toString(36).substr(2, 4).toUpperCase()}`;
|
||||
await FaultCategory.create({
|
||||
categoryId,
|
||||
...cat,
|
||||
expectedDuration: 120,
|
||||
solutions: [],
|
||||
isSystem: true,
|
||||
isActive: true
|
||||
});
|
||||
console.log(`创建故障分类: ${cat.name}`);
|
||||
}
|
||||
}
|
||||
console.log('故障分类初始化完成');
|
||||
}
|
||||
|
||||
async function initializeApp() {
|
||||
try {
|
||||
await syncDatabase();
|
||||
await initDeviceFields();
|
||||
await initTicketFields();
|
||||
await initTicketModels();
|
||||
await syncSystemSettings();
|
||||
await syncConsumableModels();
|
||||
await syncInventoryModels();
|
||||
await initDefaultSystemSettings();
|
||||
await initFaultCategories();
|
||||
|
||||
console.log('所有初始化完成,服务器准备就绪');
|
||||
} catch (error) {
|
||||
console.error('初始化失败:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
initializeApp();
|
||||
|
||||
// 导入路由
|
||||
const deviceRoutes = require('./routes/devices');
|
||||
const rackRoutes = require('./routes/racks');
|
||||
const roomRoutes = require('./routes/rooms');
|
||||
@@ -163,7 +158,6 @@ const devicePortRoutes = require('./routes/devicePorts');
|
||||
const networkCardRoutes = require('./routes/networkCards');
|
||||
const inventoryRoutes = require('./routes/inventory');
|
||||
|
||||
// 使用路由
|
||||
app.use('/api/devices', deviceRoutes);
|
||||
app.use('/api/racks', rackRoutes);
|
||||
app.use('/api/rooms', roomRoutes);
|
||||
@@ -184,15 +178,12 @@ app.use('/api/device-ports', devicePortRoutes);
|
||||
app.use('/api/network-cards', networkCardRoutes);
|
||||
app.use('/api/inventory', inventoryRoutes);
|
||||
|
||||
// 静态文件服务
|
||||
app.use('/uploads', express.static('uploads'));
|
||||
|
||||
// 健康检查
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', message: 'IDC设备管理系统后端服务正常运行' });
|
||||
});
|
||||
|
||||
// 启动服务器
|
||||
app.listen(PORT, () => {
|
||||
console.log(`服务器运行在 http://localhost:${PORT}`);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user