fix: 修复后端12个+前端5个高优先级问题
后端: - devices.js: 修复 newRackId 重复声明、批量移动加事务、ID生成改MAX聚合 - tickets.js: 添加工单状态机校验、req.body白名单过滤 - roles.js: init-roles 添加 authMiddleware - backup.js: 备份列表只读4KB头部,压缩文件超1MB跳过 - consumables.js: SN查询改用数据库LIKE替代全表扫描 - consumableRecords.js: 出入库加 SELECT FOR UPDATE 行级锁 - inventory.js: not_found 状态判断从 abnormal if 内移到 else if - idleDevices.js: 删除重复的 batch-restore 路由定义(182行) - cables.js: 接线冲突检测增加反向端口检查 前端: - AuthContext.jsx: 初始化时调用 fetchProfile 验证token、Error提取message - api/index.js: backupAPI.download 返回Promise、checkAdmin改POST - Login.jsx: checkIsFirstUser 静默处理错误 - DeviceManagement.jsx: 导出 currentPage scope 使用 currentPageDevices
This commit is contained in:
@@ -605,7 +605,24 @@ router.put('/:ticketId', async (req, res) => {
|
||||
const beforeState = ticket.toJSON();
|
||||
const { operatorId, operatorName, operatorRole } = req.body;
|
||||
|
||||
await ticket.update(req.body);
|
||||
// 白名单过滤:只允许更新安全字段,防止覆盖 ticketId/createdAt 等关键字段
|
||||
const ALLOWED_UPDATE_FIELDS = [
|
||||
'title', 'description', 'category', 'priority', 'location',
|
||||
'contactPerson', 'contactPhone', 'contactEmail',
|
||||
'expectedDate', 'attachments', 'customFields',
|
||||
];
|
||||
const updateData = {};
|
||||
ALLOWED_UPDATE_FIELDS.forEach(field => {
|
||||
if (req.body[field] !== undefined) {
|
||||
updateData[field] = req.body[field];
|
||||
}
|
||||
});
|
||||
|
||||
if (Object.keys(updateData).length === 0) {
|
||||
return res.status(400).json({ error: '没有可更新的字段' });
|
||||
}
|
||||
|
||||
await ticket.update(updateData);
|
||||
|
||||
await TicketOperationRecord.create({
|
||||
recordId: uuidv4(),
|
||||
@@ -630,11 +647,30 @@ router.put('/:ticketId/status', async (req, res) => {
|
||||
try {
|
||||
const { status, operatorId, operatorName, operatorRole, resolution } = req.body;
|
||||
|
||||
if (!status) {
|
||||
return res.status(400).json({ error: '请提供目标状态' });
|
||||
}
|
||||
|
||||
const ticket = await Ticket.findByPk(req.params.ticketId);
|
||||
if (!ticket) {
|
||||
return res.status(404).json({ error: '工单不存在' });
|
||||
}
|
||||
|
||||
// 状态机校验:定义合法的状态流转
|
||||
const STATUS_TRANSITIONS = {
|
||||
pending: ['processing', 'closed'],
|
||||
processing: ['completed', 'closed'],
|
||||
completed: ['closed'],
|
||||
closed: [],
|
||||
};
|
||||
|
||||
const allowedTransitions = STATUS_TRANSITIONS[ticket.status] || [];
|
||||
if (!allowedTransitions.includes(status)) {
|
||||
return res.status(400).json({
|
||||
error: `不允许从 "${ticket.status}" 变更为 "${status}",合法目标状态: ${allowedTransitions.join(', ') || '无'}`,
|
||||
});
|
||||
}
|
||||
|
||||
const beforeState = ticket.toJSON();
|
||||
const updateData = { status };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user