feat(资产盘点): 新增资产盘点功能模块

This commit is contained in:
zhang1106
2026-02-26 11:24:00 +08:00
parent 9b7c653836
commit ff543eba30
11 changed files with 2625 additions and 8 deletions
+104
View File
@@ -0,0 +1,104 @@
const { DataTypes } = require('sequelize');
const { sequelize } = require('../db');
const User = require('./User');
const InventoryPlan = sequelize.define('InventoryPlan', {
planId: {
type: DataTypes.STRING,
primaryKey: true,
allowNull: false,
unique: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
type: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 'full',
comment: 'full:全面盘点, partial:局部盘点, sample:抽样盘点'
},
description: {
type: DataTypes.TEXT,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'draft',
comment: 'draft:草稿, pending:待执行, in_progress:进行中, completed:已完成, cancelled:已取消'
},
scheduledDate: {
type: DataTypes.DATE,
allowNull: true
},
completedDate: {
type: DataTypes.DATE,
allowNull: true
},
targetRooms: {
type: DataTypes.JSON,
defaultValue: [],
comment: '目标机房ID列表'
},
targetRacks: {
type: DataTypes.JSON,
defaultValue: [],
comment: '目标机柜ID列表'
},
totalDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '盘点设备总数'
},
checkedDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '已盘点设备数'
},
normalDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '正常设备数'
},
abnormalDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '异常设备数'
},
missedDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '漏盘设备数'
},
extraDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '多出设备数'
},
createdBy: {
type: DataTypes.STRING,
allowNull: true,
references: {
model: User,
key: 'userId'
}
},
remark: {
type: DataTypes.TEXT,
allowNull: true
}
}, {
tableName: 'inventory_plans',
timestamps: true,
indexes: [
{ fields: ['status'] },
{ fields: ['scheduledDate'] },
{ fields: ['createdAt'] }
]
});
InventoryPlan.belongsTo(User, { foreignKey: 'createdBy', as: 'Creator' });
User.hasMany(InventoryPlan, { foreignKey: 'createdBy' });
module.exports = InventoryPlan;
+100
View File
@@ -0,0 +1,100 @@
const { DataTypes } = require('sequelize');
const { sequelize } = require('../db');
const InventoryRecord = sequelize.define('InventoryRecord', {
recordId: {
type: DataTypes.STRING,
primaryKey: true,
allowNull: false,
unique: true
},
taskId: {
type: DataTypes.STRING,
allowNull: false
},
planId: {
type: DataTypes.STRING,
allowNull: false
},
deviceId: {
type: DataTypes.STRING,
allowNull: false
},
deviceName: {
type: DataTypes.STRING,
allowNull: true
},
deviceType: {
type: DataTypes.STRING,
allowNull: true
},
serialNumber: {
type: DataTypes.STRING,
allowNull: true,
comment: '系统记录的序列号'
},
actualSerialNumber: {
type: DataTypes.STRING,
allowNull: true,
comment: '实际盘点序列号'
},
rackId: {
type: DataTypes.STRING,
allowNull: true,
comment: '系统记录的机柜'
},
actualRackId: {
type: DataTypes.STRING,
allowNull: true,
comment: '实际盘点机柜'
},
position: {
type: DataTypes.INTEGER,
allowNull: true,
comment: '系统记录的位置'
},
actualPosition: {
type: DataTypes.INTEGER,
allowNull: true,
comment: '实际盘点位置'
},
status: {
type: DataTypes.STRING,
defaultValue: 'pending',
comment: 'pending:待盘点, normal:正常, abnormal:异常, missed:未盘点, not_found:未找到'
},
abnormalType: {
type: DataTypes.STRING,
allowNull: true,
comment: 'serial_mismatch:序列号不符, position_mismatch:位置不符, device_missing:设备缺失, extra_device:多出设备'
},
checkedBy: {
type: DataTypes.STRING,
allowNull: true
},
checkedAt: {
type: DataTypes.DATE,
allowNull: true
},
remark: {
type: DataTypes.TEXT,
allowNull: true
},
photoUrl: {
type: DataTypes.STRING,
allowNull: true,
comment: '盘点照片'
}
}, {
tableName: 'inventory_records',
timestamps: true,
indexes: [
{ fields: ['taskId'] },
{ fields: ['planId'] },
{ fields: ['deviceId'] },
{ fields: ['status'] },
{ fields: ['checkedBy'] }
]
});
module.exports = InventoryRecord;
+81
View File
@@ -0,0 +1,81 @@
const { DataTypes } = require('sequelize');
const { sequelize } = require('../db');
const InventoryTask = sequelize.define('InventoryTask', {
taskId: {
type: DataTypes.STRING,
primaryKey: true,
allowNull: false,
unique: true
},
planId: {
type: DataTypes.STRING,
allowNull: false
},
targetType: {
type: DataTypes.STRING,
allowNull: false,
comment: 'room:机房, rack:机柜, device:设备'
},
targetId: {
type: DataTypes.STRING,
allowNull: false,
comment: '目标ID(机房ID/机柜ID/设备ID'
},
targetName: {
type: DataTypes.STRING,
allowNull: true,
comment: '目标名称'
},
status: {
type: DataTypes.STRING,
defaultValue: 'pending',
comment: 'pending:待执行, in_progress:进行中, completed:已完成, skipped:已跳过'
},
totalDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '设备总数'
},
checkedDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '已盘点设备数'
},
normalDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '正常设备数'
},
abnormalDevices: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '异常设备数'
},
assignedTo: {
type: DataTypes.STRING,
allowNull: true
},
assignedAt: {
type: DataTypes.DATE,
allowNull: true
},
completedAt: {
type: DataTypes.DATE,
allowNull: true
},
remark: {
type: DataTypes.TEXT,
allowNull: true
}
}, {
tableName: 'inventory_tasks',
timestamps: true,
indexes: [
{ fields: ['planId'] },
{ fields: ['status'] },
{ fields: ['assignedTo'] }
]
});
module.exports = InventoryTask;