refactor: 集中管理配置常量并优化样式一致性

This commit is contained in:
zhang1106
2026-03-06 14:39:52 +08:00
parent 0cd0107008
commit 885ac47fd2
19 changed files with 348 additions and 64 deletions
+8 -9
View File
@@ -4,11 +4,10 @@ const User = require('../models/User');
const Role = require('../models/Role');
const UserRole = require('../models/UserRole');
const { generateToken, authMiddleware } = require('../middleware/auth');
const { SALT_ROUNDS, MAX_LOGIN_ATTEMPTS, PASSWORD_MIN_LENGTH, USERNAME_MIN_LENGTH, USERNAME_MAX_LENGTH } = require('../config');
const router = express.Router();
const SALT_ROUNDS = 10;
const generateId = () => {
return 'user_' + Date.now().toString(36) + Math.random().toString(36).substr(2, 9);
};
@@ -24,17 +23,17 @@ router.post('/register', async (req, res) => {
});
}
if (username.length < 3 || username.length > 20) {
if (username.length < USERNAME_MIN_LENGTH || username.length > USERNAME_MAX_LENGTH) {
return res.status(400).json({
success: false,
message: '用户名长度必须在3-20个字符之间'
message: `用户名长度必须在${USERNAME_MIN_LENGTH}-${USERNAME_MAX_LENGTH}个字符之间`
});
}
if (password.length < 6) {
if (password.length < PASSWORD_MIN_LENGTH) {
return res.status(400).json({
success: false,
message: '密码长度不能少于6个字符'
message: `密码长度不能少于${PASSWORD_MIN_LENGTH}个字符`
});
}
@@ -175,7 +174,7 @@ router.post('/login', async (req, res) => {
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) {
user.loginCount = (user.loginCount || 0) + 1;
if (user.loginCount >= 5) {
if (user.loginCount >= MAX_LOGIN_ATTEMPTS) {
user.status = 'locked';
}
await user.save();
@@ -309,10 +308,10 @@ router.put('/password', authMiddleware, async (req, res) => {
});
}
if (newPassword.length < 6) {
if (newPassword.length < PASSWORD_MIN_LENGTH) {
return res.status(400).json({
success: false,
message: '新密码长度不能少于6个字符'
message: `新密码长度不能少于${PASSWORD_MIN_LENGTH}个字符`
});
}
+11 -13
View File
@@ -7,10 +7,11 @@ const Consumable = require('../models/Consumable');
const ConsumableRecord = require('../models/ConsumableRecord');
const ConsumableLog = require('../models/ConsumableLog');
const ConsumableLogArchive = require('../models/ConsumableLogArchive');
const { PAGINATION, RETRY } = require('../config');
router.get('/', async (req, res) => {
try {
const { keyword, category, status, page = 1, pageSize = 10 } = req.query;
const { keyword, category, status, page = 1, pageSize = PAGINATION.DEFAULT_PAGE_SIZE } = req.query;
const offset = (page - 1) * pageSize;
const where = {};
@@ -281,10 +282,9 @@ router.get('/inout/records', async (req, res) => {
});
router.post('/quick-inout', async (req, res) => {
const MAX_RETRIES = 3;
let attempt = 0;
while (attempt < MAX_RETRIES) {
while (attempt < RETRY.MAX_RETRIES) {
const transaction = await sequelize.transaction();
try {
const { consumableId, type, quantity, operator, reason, notes, snList } = req.body;
@@ -348,7 +348,7 @@ router.post('/quick-inout', async (req, res) => {
if (affectedRows === 0) {
await transaction.rollback();
attempt++;
if (attempt >= MAX_RETRIES) {
if (attempt >= RETRY.MAX_RETRIES) {
return res.status(409).json({ error: '并发冲突,请稍后重试' });
}
continue;
@@ -397,7 +397,7 @@ router.post('/quick-inout', async (req, res) => {
return;
} catch (error) {
await transaction.rollback();
if (attempt >= MAX_RETRIES - 1) {
if (attempt >= RETRY.MAX_RETRIES - 1) {
return res.status(500).json({ error: error.message });
}
attempt++;
@@ -406,10 +406,9 @@ router.post('/quick-inout', async (req, res) => {
});
router.post('/inout', async (req, res) => {
const MAX_RETRIES = 3;
let attempt = 0;
while (attempt < MAX_RETRIES) {
while (attempt < RETRY.MAX_RETRIES) {
const transaction = await sequelize.transaction();
try {
const { consumableId, type, quantity, operator, reason, recipient, notes, snList } = req.body;
@@ -470,7 +469,7 @@ router.post('/inout', async (req, res) => {
if (affectedRows === 0) {
await transaction.rollback();
attempt++;
if (attempt >= MAX_RETRIES) {
if (attempt >= RETRY.MAX_RETRIES) {
return res.status(409).json({ error: '并发冲突,请稍后重试' });
}
continue;
@@ -520,7 +519,7 @@ router.post('/inout', async (req, res) => {
return;
} catch (error) {
await transaction.rollback();
if (attempt >= MAX_RETRIES - 1) {
if (attempt >= RETRY.MAX_RETRIES - 1) {
return res.status(500).json({ error: error.message });
}
attempt++;
@@ -529,10 +528,9 @@ router.post('/inout', async (req, res) => {
});
router.post('/adjust', async (req, res) => {
const MAX_RETRIES = 3;
let attempt = 0;
while (attempt < MAX_RETRIES) {
while (attempt < RETRY.MAX_RETRIES) {
const transaction = await sequelize.transaction();
try {
const { consumableId, adjustType, quantity, operator, reason, notes } = req.body;
@@ -582,7 +580,7 @@ router.post('/adjust', async (req, res) => {
if (affectedRows === 0) {
await transaction.rollback();
attempt++;
if (attempt >= MAX_RETRIES) {
if (attempt >= RETRY.MAX_RETRIES) {
return res.status(409).json({ error: '并发冲突,请稍后重试' });
}
continue;
@@ -619,7 +617,7 @@ router.post('/adjust', async (req, res) => {
return;
} catch (error) {
await transaction.rollback();
if (attempt >= MAX_RETRIES - 1) {
if (attempt >= RETRY.MAX_RETRIES - 1) {
return res.status(500).json({ error: error.message });
}
attempt++;
+2 -1
View File
@@ -10,6 +10,7 @@ const Rack = require('../models/Rack');
const Room = require('../models/Room');
const User = require('../models/User');
const { authMiddleware, authorize } = require('../middleware/auth');
const { PAGINATION } = require('../config');
InventoryTask.belongsTo(InventoryPlan, { foreignKey: 'planId', as: 'Plan' });
InventoryPlan.hasMany(InventoryTask, { foreignKey: 'planId', as: 'Tasks' });
@@ -41,7 +42,7 @@ router.use(authMiddleware);
router.get('/plans', async (req, res) => {
try {
const { status, page = 1, pageSize = 10, keyword } = req.query;
const { status, page = 1, pageSize = PAGINATION.DEFAULT_PAGE_SIZE, keyword } = req.query;
const offset = (page - 1) * pageSize;
const where = {};
+4 -3
View File
@@ -4,6 +4,7 @@ const fs = require('fs');
const path = require('path');
const { Op } = require('sequelize');
const SystemSetting = require('../models/SystemSetting');
const { FRONTEND } = require('../config');
// 初始化默认系统设置
const initDefaultSettings = async () => {
@@ -267,7 +268,7 @@ router.post('/reset/:key', async (req, res) => {
idle_warning_time: 60,
max_login_attempts: 5,
maintenance_mode: false,
frontend_port: 3000,
frontend_port: FRONTEND.DEFAULT_PORT,
primary_color: '#667eea',
secondary_color: '#764ba2',
compact_mode: false,
@@ -563,7 +564,7 @@ router.get('/system/info', async (req, res) => {
router.get('/frontend/port', async (req, res) => {
try {
const portSetting = await SystemSetting.findByPk('frontend_port');
const port = portSetting ? JSON.parse(portSetting.settingValue) : 3000;
const port = portSetting ? JSON.parse(portSetting.settingValue) : FRONTEND.DEFAULT_PORT;
res.json({ port });
} catch (error) {
res.status(500).json({ error: error.message });
@@ -577,7 +578,7 @@ router.post('/frontend/port/sync', async (req, res) => {
const path = require('path');
const portSetting = await SystemSetting.findByPk('frontend_port');
const port = portSetting ? JSON.parse(portSetting.settingValue) : 3000;
const port = portSetting ? JSON.parse(portSetting.settingValue) : FRONTEND.DEFAULT_PORT;
// 写入前端配置文件
const frontendDir = path.join(__dirname, '../../frontend');
+8 -9
View File
@@ -6,11 +6,10 @@ const User = require('../models/User');
const Role = require('../models/Role');
const UserRole = require('../models/UserRole');
const { authMiddleware } = require('../middleware/auth');
const { SALT_ROUNDS, PASSWORD_MIN_LENGTH, FILE_UPLOAD, PAGINATION } = require('../config');
const router = express.Router();
const SALT_ROUNDS = 10;
const generateId = () => {
return 'user_' + Date.now().toString(36) + Math.random().toString(36).substr(2, 9);
};
@@ -37,9 +36,9 @@ const { Op } = require('sequelize');
router.get('/', authMiddleware, async (req, res) => {
try {
const { page = 1, pageSize = 10, username, status, realName } = req.query;
const { page = 1, pageSize = PAGINATION.DEFAULT_PAGE_SIZE, username, status, realName } = req.query;
const offset = (parseInt(page) - 1) * parseInt(pageSize);
const limit = parseInt(pageSize);
const limit = Math.min(parseInt(pageSize), PAGINATION.MAX_PAGE_SIZE);
const where = getWhereClause({ username, status, realName });
@@ -256,7 +255,7 @@ router.put('/:userId', authMiddleware, async (req, res) => {
if (status !== undefined) user.status = status;
if (remark !== undefined) user.remark = remark;
if (newPassword && newPassword.length >= 6) {
if (newPassword && newPassword.length >= PASSWORD_MIN_LENGTH) {
user.password = await bcrypt.hash(newPassword, SALT_ROUNDS);
}
@@ -303,10 +302,10 @@ router.put('/:userId/password', authMiddleware, async (req, res) => {
});
}
if (!newPassword || newPassword.length < 6) {
if (!newPassword || newPassword.length < PASSWORD_MIN_LENGTH) {
return res.status(400).json({
success: false,
message: '密码长度不能少于6个字符'
message: `密码长度不能少于${PASSWORD_MIN_LENGTH}个字符`
});
}
@@ -388,10 +387,10 @@ router.post('/:userId/avatar', authMiddleware, async (req, res) => {
});
}
if (avatarFile.size > 5 * 1024 * 1024) {
if (avatarFile.size > FILE_UPLOAD.MAX_AVATAR_SIZE) {
return res.status(400).json({
success: false,
message: '图片大小不能超过 5MB'
message: `图片大小不能超过 ${FILE_UPLOAD.MAX_AVATAR_SIZE / 1024 / 1024}MB`
});
}