diff --git a/config/db.js b/config/db.js index 15e2a45..ebf73fc 100644 --- a/config/db.js +++ b/config/db.js @@ -2,7 +2,7 @@ const { Sequelize } = require('sequelize'); const mysql = require('mysql2/promise'); // 环境配置 -const NODE_ENV = process.env.NODE_ENV || 'development'; +const NODE_ENV = process.env.NODE_ENV || 'local'; // 数据库配置 const dbConfig = { diff --git a/controllers/apartmentController.js b/controllers/apartmentController.js index 140e58f..bcc0d3e 100644 --- a/controllers/apartmentController.js +++ b/controllers/apartmentController.js @@ -1,6 +1,7 @@ const { Apartment, Tenant } = require('../models'); const { Op } = require('sequelize'); const { logOperation } = require('../utils/logger'); +const response = require('../utils/response'); // 格式化时间(考虑时区,转换为北京时间) const formatDate = (date) => { @@ -51,14 +52,14 @@ const getAllApartments = async (req, res) => { const formattedApartments = rows.map(formatApartmentData); // 返回结果 - res.status(200).json({ - data: formattedApartments, + response.success(res, '获取成功', { + list: formattedApartments, total: count, page: parseInt(page), pageSize: parseInt(pageSize) }); } catch (error) { - res.status(500).json({ error: error.message }); + response.serverError(res, '获取公寓列表失败', error); } }; @@ -70,16 +71,12 @@ const getApartmentById = async (req, res) => { where: { id, isDeleted: 0 } }); if (!apartment) { - return res.status(404).json({ error: '公寓不存在' }); + return response.notFound(res, '公寓不存在'); } const formattedApartment = formatApartmentData(apartment); - res.status(200).json({ - code: 200, - data: formattedApartment, - message: 'success' - }); + response.success(res, '获取成功', formattedApartment); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取公寓详情失败', error); } }; @@ -90,9 +87,10 @@ const createApartment = async (req, res) => { // 检查租户资源使用情况(仅记录日志,不阻止创建) const tenant = await Tenant.findByPk(req.user.tenantId); + let currentApartmentCount = 0; if (tenant) { // 获取当前公寓数量 - const currentApartmentCount = await Apartment.count({ + currentApartmentCount = await Apartment.count({ where: { tenantId: req.user.tenantId, isDeleted: 0 } }); @@ -122,14 +120,12 @@ const createApartment = async (req, res) => { createBy: req.user.id, updateBy: req.user.id }); - res.status(201).json({ - code: 201, - data: apartment, - message: '创建成功', + response.created(res, '创建成功', { + apartment, warning: tenant && currentApartmentCount >= tenant.maxApartments ? `当前已超出套餐限制(${tenant.maxApartments}栋),续费时将收取超额费用` : null }); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '创建公寓失败', error); } }; @@ -142,7 +138,7 @@ const updateApartment = async (req, res) => { where: { id, isDeleted: 0 } }); if (!apartment) { - return res.status(404).json({ error: '公寓不存在' }); + return response.notFound(res, '公寓不存在'); } await apartment.update({ name, @@ -150,13 +146,9 @@ const updateApartment = async (req, res) => { description, updateBy: req.user.id }); - res.status(200).json({ - code: 200, - data: apartment, - message: '更新成功' - }); + response.success(res, '更新成功', apartment); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '更新公寓失败', error); } }; @@ -168,18 +160,15 @@ const deleteApartment = async (req, res) => { where: { id, isDeleted: 0 } }); if (!apartment) { - return res.status(404).json({ error: '公寓不存在' }); + return response.notFound(res, '公寓不存在'); } await apartment.update({ isDeleted: 1, updateBy: req.user.id }); - res.status(200).json({ - code: 200, - message: '公寓删除成功' - }); + response.success(res, '公寓删除成功'); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '删除公寓失败', error); } }; @@ -208,13 +197,9 @@ const listApartments = async (req, res) => { const formattedApartments = apartments.map(formatApartmentData); // 返回结果 - res.status(200).json({ - code: 200, - data: formattedApartments, - message: 'success' - }); + response.success(res, '获取成功', formattedApartments); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取公寓列表失败', error); } }; @@ -225,4 +210,4 @@ module.exports = { createApartment, updateApartment, deleteApartment -}; \ No newline at end of file +}; diff --git a/controllers/authController.js b/controllers/authController.js index cc410f2..4e964ee 100644 --- a/controllers/authController.js +++ b/controllers/authController.js @@ -8,6 +8,7 @@ const Setting = require('../models/Setting'); const { SubscriptionPlan } = require('../models'); const { generateToken } = require('../middleware/auth'); const { logLogin, getClientIp } = require('../utils/logger'); +const response = require('../utils/response'); // 登录 exports.login = async (req, res) => { @@ -28,10 +29,7 @@ exports.login = async (req, res) => { status: 'fail', message: '用户名和密码不能为空' }); - return res.status(400).json({ - code: 400, - message: '用户名和密码不能为空' - }); + return response.badRequest(res, '用户名和密码不能为空'); } // 查找用户 @@ -58,10 +56,7 @@ exports.login = async (req, res) => { status: 'fail', message: '用户名或密码错误' }); - return res.status(401).json({ - code: 401, - message: '用户名或密码错误' - }); + return response.unauthorized(res, '用户名或密码错误'); } // 检查用户状态 @@ -75,10 +70,7 @@ exports.login = async (req, res) => { status: 'fail', message: '账号已被禁用' }); - return res.status(401).json({ - code: 401, - message: '账号已被禁用' - }); + return response.unauthorized(res, '账号已被禁用'); } // 验证密码 @@ -93,10 +85,7 @@ exports.login = async (req, res) => { status: 'fail', message: '用户名或密码错误' }); - return res.status(401).json({ - code: 401, - message: '用户名或密码错误' - }); + return response.unauthorized(res, '用户名或密码错误'); } // 检查租户计费状态(仅非系统管理员需要检查) @@ -112,15 +101,11 @@ exports.login = async (req, res) => { status: 'fail', message: '账户已过期,请续费' }); - return res.status(403).json({ - code: 403, - message: '您的账户已过期,请前往续费', - data: { - expired: true, - billingStatus: billingStatus, - trialEndDate: user.tenant.trialEndDate, - paidEndDate: user.tenant.paidEndDate - } + return response.forbidden(res, '您的账户已过期,请前往续费', { + expired: true, + billingStatus: billingStatus, + trialEndDate: user.tenant.trialEndDate, + paidEndDate: user.tenant.paidEndDate }); } } @@ -172,22 +157,18 @@ exports.login = async (req, res) => { }); // 返回用户信息和 Token - res.json({ - code: 200, - message: '登录成功', - data: { - token, - userInfo: { - id: user.id, - username: user.username, - nickname: user.nickname, - role: user.role, - tenantId: user.tenantId, - userType: user.userType - }, - tenant: user.tenant, - menus - } + response.success(res, '登录成功', { + token, + userInfo: { + id: user.id, + username: user.username, + nickname: user.nickname, + role: user.role, + tenantId: user.tenantId, + userType: user.userType + }, + tenant: user.tenant, + menus }); } catch (error) { console.error('登录错误:', error); @@ -199,11 +180,7 @@ exports.login = async (req, res) => { status: 'fail', message: error.message }); - res.status(500).json({ - code: 500, - message: '登录失败', - error: error.message - }); + response.serverError(res, '登录失败', error); } }; @@ -222,16 +199,10 @@ exports.logout = async (req, res) => { message: '登出成功' }); - res.json({ - code: 200, - message: '登出成功' - }); + response.success(res, '登出成功'); } catch (error) { console.error('登出错误:', error); - res.json({ - code: 200, - message: '登出成功' - }); + response.success(res, '登出成功'); } }; @@ -264,18 +235,10 @@ function buildMenuTree(menus, parentId = null) { exports.getCurrentUser = async (req, res) => { try { // req.user 由 authMiddleware 附加 - res.json({ - code: 200, - message: '获取成功', - data: req.user - }); + response.success(res, '获取成功', req.user); } catch (error) { console.error('获取用户信息错误:', error); - res.status(500).json({ - code: 500, - message: '获取用户信息失败', - error: error.message - }); + response.serverError(res, '获取用户信息失败', error); } }; @@ -287,35 +250,23 @@ exports.changePassword = async (req, res) => { // 参数验证 if (!oldPassword || !newPassword) { - return res.status(400).json({ - code: 400, - message: '原密码和新密码不能为空' - }); + return response.badRequest(res, '原密码和新密码不能为空'); } if (newPassword.length < 6) { - return res.status(400).json({ - code: 400, - message: '新密码长度不能少于6位' - }); + return response.badRequest(res, '新密码长度不能少于6位'); } // 查找用户 const user = await User.findByPk(userId); if (!user) { - return res.status(404).json({ - code: 404, - message: '用户不存在' - }); + return response.notFound(res, '用户不存在'); } // 验证原密码 const isPasswordValid = await bcrypt.compare(oldPassword, user.password); if (!isPasswordValid) { - return res.status(400).json({ - code: 400, - message: '原密码错误' - }); + return response.badRequest(res, '原密码错误'); } // 加密新密码 @@ -324,17 +275,10 @@ exports.changePassword = async (req, res) => { // 更新密码 await user.update({ password: hashedPassword }); - res.json({ - code: 200, - message: '密码修改成功' - }); + response.success(res, '密码修改成功'); } catch (error) { console.error('修改密码错误:', error); - res.status(500).json({ - code: 500, - message: '修改密码失败', - error: error.message - }); + response.serverError(res, '修改密码失败', error); } }; @@ -351,19 +295,13 @@ exports.registerTenant = async (req, res) => { try { // 参数验证 if (!contactName || !contactPhone || !contactEmail || !adminUsername || !adminPassword) { - return res.status(400).json({ - code: 400, - message: '请填写所有必填项' - }); + return response.badRequest(res, '请填写所有必填项'); } // 检查管理员账号是否已存在 const existingUser = await User.findOne({ where: { username: adminUsername } }); if (existingUser) { - return res.status(400).json({ - code: 400, - message: '管理员账号已存在' - }); + return response.badRequest(res, '管理员账号已存在'); } // 查询默认套餐 @@ -375,10 +313,7 @@ exports.registerTenant = async (req, res) => { }); if (!defaultPlan) { - return res.status(500).json({ - code: 500, - message: '系统未配置默认套餐,请联系管理员' - }); + return response.serverError(res, '系统未配置默认套餐,请联系管理员'); } // 生成租户编码:时间戳 + 随机数 @@ -489,21 +424,13 @@ exports.registerTenant = async (req, res) => { }); } - res.json({ - code: 200, - message: '注册成功,欢迎试用', - data: { - tenantId: tenant.id, - code: tenant.code, - status: tenant.status - } + response.success(res, '注册成功,欢迎试用', { + tenantId: tenant.id, + code: tenant.code, + status: tenant.status }); } catch (error) { console.error('租户注册失败:', error); - res.status(500).json({ - code: 500, - message: '注册失败', - error: error.message - }); + response.serverError(res, '注册失败', error); } }; diff --git a/controllers/billController.js b/controllers/billController.js index 1befe26..1e60dae 100644 --- a/controllers/billController.js +++ b/controllers/billController.js @@ -1,5 +1,6 @@ const { Bill, MeterReading, Room, Renter, Rental, BillPayment } = require('../models'); const { Op } = require('sequelize'); +const response = require('../utils/response'); // 生成账单编号 const generateBillNo = () => { @@ -141,16 +142,15 @@ const getAllBills = async (req, res) => { const formattedBills = rows.map(formatBillData); // 返回结果 - res.status(200).json({ - code: 200, - data: formattedBills, + response.success(res, '获取成功', { + list: formattedBills, total: count, page: parseInt(page), pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取账单列表失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取账单列表失败', error); } }; @@ -170,13 +170,10 @@ const getBillsList = async (req, res) => { const formattedBills = rows.map(formatBillData); // 返回结果 - res.status(200).json({ - code: 200, - data: formattedBills - }); + response.success(res, '获取成功', formattedBills); } catch (error) { console.error('获取账单列表失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取账单列表失败', error); } }; @@ -211,19 +208,15 @@ const getBillById = async (req, res) => { }); if (!bill) { - return res.status(404).json({ code: 404, error: '账单不存在' }); + return response.notFound(res, '账单不存在'); } const formattedBill = formatBillData(bill); - res.status(200).json({ - code: 200, - data: formattedBill, - message: 'success' - }); + response.success(res, '获取成功', formattedBill); } catch (error) { console.error('获取账单详情失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取账单详情失败', error); } }; @@ -261,14 +254,10 @@ const createBill = async (req, res) => { }); const formattedBill = formatBillData(bill); - res.status(201).json({ - code: 201, - data: formattedBill, - message: '创建成功' - }); + response.created(res, '创建成功', formattedBill); } catch (error) { console.error('创建账单失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '创建账单失败', error); } }; @@ -293,7 +282,7 @@ const updateBill = async (req, res) => { }); if (!bill) { - return res.status(404).json({ code: 404, error: '账单不存在' }); + return response.notFound(res, '账单不存在'); } await bill.update({ @@ -309,14 +298,10 @@ const updateBill = async (req, res) => { updateBy: req.user.id }); - res.status(200).json({ - code: 200, - data: formatBillData(bill), - message: '更新成功' - }); + response.success(res, '更新成功', formatBillData(bill)); } catch (error) { console.error('更新账单失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '更新账单失败', error); } }; @@ -329,7 +314,7 @@ const deleteBill = async (req, res) => { }); if (!bill) { - return res.status(404).json({ code: 404, error: '账单不存在' }); + return response.notFound(res, '账单不存在'); } await bill.update({ @@ -337,13 +322,10 @@ const deleteBill = async (req, res) => { updateBy: req.user.id }); - res.status(200).json({ - code: 200, - message: '账单删除成功' - }); + response.success(res, '账单删除成功'); } catch (error) { console.error('删除账单失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '删除账单失败', error); } }; @@ -358,7 +340,7 @@ const receivePayment = async (req, res) => { }); if (!bill) { - return res.status(404).json({ code: 404, error: '账单不存在' }); + return response.notFound(res, '账单不存在'); } const newReceivedAmount = parseFloat(bill.receivedAmount) + parseFloat(amount); @@ -378,14 +360,10 @@ const receivePayment = async (req, res) => { updateBy: req.user.id }); - res.status(200).json({ - code: 200, - data: formatBillData(bill), - message: '收款成功' - }); + response.success(res, '收款成功', formatBillData(bill)); } catch (error) { console.error('账单收款失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '账单收款失败', error); } }; @@ -443,22 +421,19 @@ const getBillStatistics = async (req, res) => { const totalReceivable = await Bill.sum('receivableAmount', { where }); const totalReceived = await Bill.sum('receivedAmount', { where }); - res.status(200).json({ - code: 200, - data: { - summary: { - totalReceivable: totalReceivable || 0, - totalReceived: totalReceived || 0, - totalUnreceived: (totalReceivable || 0) - (totalReceived || 0) - }, - income: incomeStats, - expense: expenseStats, - status: statusStats - } + response.success(res, '获取成功', { + summary: { + totalReceivable: totalReceivable || 0, + totalReceived: totalReceived || 0, + totalUnreceived: (totalReceivable || 0) - (totalReceived || 0) + }, + income: incomeStats, + expense: expenseStats, + status: statusStats }); } catch (error) { console.error('获取账单统计失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取账单统计失败', error); } }; diff --git a/controllers/billPaymentController.js b/controllers/billPaymentController.js index 159984e..c079d53 100644 --- a/controllers/billPaymentController.js +++ b/controllers/billPaymentController.js @@ -1,5 +1,6 @@ const { BillPayment, Bill } = require('../models'); const { Op } = require('sequelize'); +const response = require('../utils/response'); // 获取账单的所有支付流水 const getPaymentsByBillId = async (req, res) => { @@ -16,14 +17,10 @@ const getPaymentsByBillId = async (req, res) => { order: [['paymentTime', 'DESC']] }); - res.status(200).json({ - code: 200, - data: payments, - message: 'success' - }); + response.success(res, '获取成功', payments); } catch (error) { console.error('获取支付流水失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取支付流水失败', error); } }; @@ -41,15 +38,15 @@ const createPayment = async (req, res) => { }); if (!bill) { - return res.status(404).json({ code: 404, error: '账单不存在' }); + return response.notFound(res, '账单不存在'); } if (bill.status === 'paid') { - return res.status(400).json({ code: 400, error: '该账单已收清,无法继续收款' }); + return response.badRequest(res, '该账单已收清,无法继续收款'); } if (bill.status === 'cancelled') { - return res.status(400).json({ code: 400, error: '该账单已取消,无法收款' }); + return response.badRequest(res, '该账单已取消,无法收款'); } // 计算剩余应收金额 @@ -60,14 +57,11 @@ const createPayment = async (req, res) => { // 验证支付金额 const paymentAmount = parseFloat(amount); if (paymentAmount <= 0) { - return res.status(400).json({ code: 400, error: '支付金额必须大于0' }); + return response.badRequest(res, '支付金额必须大于0'); } if (paymentAmount > remainingAmount) { - return res.status(400).json({ - code: 400, - error: `支付金额不能超过剩余应收金额 ¥${remainingAmount.toFixed(2)}` - }); + return response.badRequest(res, `支付金额不能超过剩余应收金额 ¥${remainingAmount.toFixed(2)}`); } // 创建支付流水 @@ -99,21 +93,17 @@ const createPayment = async (req, res) => { updateBy: createBy }); - res.status(201).json({ - code: 201, - data: { - payment, - bill: { - id: bill.id, - receivedAmount: newReceivedAmount, - status: newStatus - } - }, - message: '收款成功' + response.created(res, '收款成功', { + payment, + bill: { + id: bill.id, + receivedAmount: newReceivedAmount, + status: newStatus + } }); } catch (error) { console.error('创建支付流水失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '创建支付流水失败', error); } }; @@ -129,7 +119,7 @@ const deletePayment = async (req, res) => { }); if (!payment) { - return res.status(404).json({ code: 404, error: '支付流水不存在' }); + return response.notFound(res, '支付流水不存在'); } // 查找关联账单 @@ -138,7 +128,7 @@ const deletePayment = async (req, res) => { }); if (!bill) { - return res.status(404).json({ code: 404, error: '关联账单不存在' }); + return response.notFound(res, '关联账单不存在'); } // 软删除支付流水 @@ -170,20 +160,16 @@ const deletePayment = async (req, res) => { updateBy }); - res.status(200).json({ - code: 200, - data: { - bill: { - id: bill.id, - receivedAmount: newReceivedAmount, - status: newStatus - } - }, - message: '支付流水已删除,账单状态已更新' + response.success(res, '支付流水已删除,账单状态已更新', { + bill: { + id: bill.id, + receivedAmount: newReceivedAmount, + status: newStatus + } }); } catch (error) { console.error('删除支付流水失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '删除支付流水失败', error); } }; @@ -210,14 +196,10 @@ const getPaymentStatistics = async (req, res) => { group: ['paymentMethod'] }); - res.status(200).json({ - code: 200, - data: payments, - message: 'success' - }); + response.success(res, '获取成功', payments); } catch (error) { console.error('获取支付统计失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取支付统计失败', error); } }; diff --git a/controllers/billingController.js b/controllers/billingController.js index 136e6e8..e8c4df5 100644 --- a/controllers/billingController.js +++ b/controllers/billingController.js @@ -1,6 +1,7 @@ const { SubscriptionPlan, PricingConfig, Order, Payment, Tenant, User, Apartment, Room, PaymentSetting } = require('../models'); const { Op } = require('sequelize'); const billingService = require('../services/billingService'); +const response = require('../utils/response'); // 获取所有套餐列表 const getAllPlans = async (req, res) => { @@ -10,17 +11,9 @@ const getAllPlans = async (req, res) => { order: [['sort', 'ASC']] }); - res.status(200).json({ - code: 200, - message: '获取套餐列表成功', - data: plans - }); + response.success(res, '获取套餐列表成功', plans); } catch (error) { - res.status(500).json({ - code: 500, - message: '获取套餐列表失败', - error: error.message - }); + response.serverError(res, '获取套餐列表失败', error); } }; @@ -31,10 +24,7 @@ const createPlan = async (req, res) => { // 验证必填字段 if (!name) { - return res.status(400).json({ - code: 400, - message: '套餐名称不能为空' - }); + return response.badRequest(res, '套餐名称不能为空'); } // 检查是否是第一个套餐 @@ -52,17 +42,9 @@ const createPlan = async (req, res) => { isDefault }); - res.status(201).json({ - code: 200, - message: '套餐创建成功', - data: plan - }); + response.created(res, '套餐创建成功', plan); } catch (error) { - res.status(500).json({ - code: 500, - message: '创建套餐失败', - error: error.message - }); + response.serverError(res, '创建套餐失败', error); } }; @@ -78,10 +60,7 @@ const updatePlan = async (req, res) => { }); if (!plan) { - return res.status(400).json({ - code: 400, - message: '套餐不存在' - }); + return response.badRequest(res, '套餐不存在'); } // 更新套餐信息 @@ -96,17 +75,9 @@ const updatePlan = async (req, res) => { sort: sort !== undefined ? sort : plan.sort }); - res.status(200).json({ - code: 200, - message: '套餐更新成功', - data: plan - }); + response.success(res, '套餐更新成功', plan); } catch (error) { - res.status(500).json({ - code: 500, - message: '更新套餐失败', - error: error.message - }); + response.serverError(res, '更新套餐失败', error); } }; @@ -121,33 +92,20 @@ const deletePlan = async (req, res) => { }); if (!plan) { - return res.status(400).json({ - code: 400, - message: '套餐不存在' - }); + return response.badRequest(res, '套餐不存在'); } // 不能删除默认套餐 if (plan.isDefault) { - return res.status(400).json({ - code: 400, - message: '不能删除默认套餐' - }); + return response.badRequest(res, '不能删除默认套餐'); } // 软删除 await plan.update({ isDeleted: 1 }); - res.status(200).json({ - code: 200, - message: '套餐删除成功' - }); + response.success(res, '套餐删除成功'); } catch (error) { - res.status(500).json({ - code: 500, - message: '删除套餐失败', - error: error.message - }); + response.serverError(res, '删除套餐失败', error); } }; @@ -162,10 +120,7 @@ const setDefaultPlan = async (req, res) => { }); if (!plan) { - return res.status(400).json({ - code: 400, - message: '套餐不存在' - }); + return response.badRequest(res, '套餐不存在'); } // 将其他套餐 isDefault 设为 false @@ -177,17 +132,9 @@ const setDefaultPlan = async (req, res) => { // 将指定套餐 isDefault 设为 true await plan.update({ isDefault: true }); - res.status(200).json({ - code: 200, - message: '设置默认套餐成功', - data: plan - }); + response.success(res, '设置默认套餐成功', plan); } catch (error) { - res.status(500).json({ - code: 500, - message: '设置默认套餐失败', - error: error.message - }); + response.serverError(res, '设置默认套餐失败', error); } }; @@ -202,29 +149,17 @@ const getPricingConfig = async (req, res) => { // 如果没有则返回默认配置 if (!config) { - return res.status(200).json({ - code: 200, - message: '获取价格配置成功', - data: { - overageApartmentPrice: 10.00, - overageRoomPrice: 2.00, - overageUserPrice: 5.00, - currency: 'CNY' - } + return response.success(res, '获取价格配置成功', { + overageApartmentPrice: 10.00, + overageRoomPrice: 2.00, + overageUserPrice: 5.00, + currency: 'CNY' }); } - res.status(200).json({ - code: 200, - message: '获取价格配置成功', - data: config - }); + response.success(res, '获取价格配置成功', config); } catch (error) { - res.status(500).json({ - code: 500, - message: '获取价格配置失败', - error: error.message - }); + response.serverError(res, '获取价格配置失败', error); } }; @@ -247,17 +182,9 @@ const updatePricingConfig = async (req, res) => { isActive: true }); - res.status(200).json({ - code: 200, - message: '价格配置更新成功', - data: config - }); + response.success(res, '价格配置更新成功', config); } catch (error) { - res.status(500).json({ - code: 500, - message: '更新价格配置失败', - error: error.message - }); + response.serverError(res, '更新价格配置失败', error); } }; @@ -267,10 +194,7 @@ const initDefaultPlans = async (req, res) => { // 检查是否已有套餐 const existingCount = await SubscriptionPlan.count({ where: { isDeleted: 0 } }); if (existingCount > 0) { - return res.status(400).json({ - code: 400, - message: '套餐数据已存在,无需初始化' - }); + return response.badRequest(res, '套餐数据已存在,无需初始化'); } // 默认套餐数据 @@ -320,17 +244,9 @@ const initDefaultPlans = async (req, res) => { // 批量创建套餐 const plans = await SubscriptionPlan.bulkCreate(defaultPlans); - res.status(200).json({ - code: 200, - message: '默认套餐初始化成功', - data: plans - }); + response.success(res, '默认套餐初始化成功', plans); } catch (error) { - res.status(500).json({ - code: 500, - message: '初始化默认套餐失败', - error: error.message - }); + response.serverError(res, '初始化默认套餐失败', error); } }; @@ -343,10 +259,7 @@ const initDefaultPricing = async (req, res) => { }); if (existingConfig) { - return res.status(400).json({ - code: 400, - message: '价格配置已存在,无需初始化' - }); + return response.badRequest(res, '价格配置已存在,无需初始化'); } // 创建默认价格配置 @@ -357,17 +270,9 @@ const initDefaultPricing = async (req, res) => { isActive: true }); - res.status(200).json({ - code: 200, - message: '默认价格配置初始化成功', - data: config - }); + response.success(res, '默认价格配置初始化成功', config); } catch (error) { - res.status(500).json({ - code: 500, - message: '初始化默认价格配置失败', - error: error.message - }); + response.serverError(res, '初始化默认价格配置失败', error); } }; @@ -412,23 +317,15 @@ const getOrders = async (req, res) => { ] }); - res.json({ - code: 200, - data: { - list: rows, - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - }, - message: '获取订单列表成功' + response.success(res, '获取订单列表成功', { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取订单列表失败:', error); - res.status(500).json({ - code: 500, - message: '获取订单列表失败', - error: error.message - }); + response.serverError(res, '获取订单列表失败', error); } }; @@ -440,17 +337,11 @@ const calculatePrice = async (req, res) => { // 验证必填字段 if (!planId || !months) { - return res.status(400).json({ - code: 400, - message: '套餐ID和购买月数不能为空' - }); + return response.badRequest(res, '套餐ID和购买月数不能为空'); } if (months < 1 || months > 36) { - return res.status(400).json({ - code: 400, - message: '购买月数必须在1-36之间' - }); + return response.badRequest(res, '购买月数必须在1-36之间'); } // 获取套餐信息 @@ -459,27 +350,16 @@ const calculatePrice = async (req, res) => { }); if (!plan) { - return res.status(400).json({ - code: 400, - message: '套餐不存在' - }); + return response.badRequest(res, '套餐不存在'); } // 计算订单金额(含超额费用) const amountInfo = await billingService.calculateRenewalAmount(tenantId, planId, months); - res.json({ - code: 200, - message: '计算成功', - data: amountInfo - }); + response.success(res, '计算成功', amountInfo); } catch (error) { console.error('计算价格失败:', error); - res.status(500).json({ - code: 500, - message: '计算价格失败', - error: error.message - }); + response.serverError(res, '计算价格失败', error); } }; @@ -491,17 +371,11 @@ const createOrder = async (req, res) => { // 验证必填字段 if (!planId || !months) { - return res.status(400).json({ - code: 400, - message: '套餐ID和购买月数不能为空' - }); + return response.badRequest(res, '套餐ID和购买月数不能为空'); } if (months < 1 || months > 36) { - return res.status(400).json({ - code: 400, - message: '购买月数必须在1-36之间' - }); + return response.badRequest(res, '购买月数必须在1-36之间'); } // 获取套餐信息 @@ -510,10 +384,7 @@ const createOrder = async (req, res) => { }); if (!plan) { - return res.status(400).json({ - code: 400, - message: '套餐不存在' - }); + return response.badRequest(res, '套餐不存在'); } // 计算订单金额 @@ -558,21 +429,13 @@ const createOrder = async (req, res) => { ] }); - res.status(201).json({ - code: 200, - message: '订单创建成功', - data: { - order: createdOrder.toJSON(), - details: amountInfo.details - } + response.created(res, '订单创建成功', { + order: createdOrder.toJSON(), + details: amountInfo.details }); } catch (error) { console.error('创建订单失败:', error); - res.status(500).json({ - code: 500, - message: '创建订单失败', - error: error.message - }); + response.serverError(res, '创建订单失败', error); } }; @@ -605,32 +468,18 @@ const getOrderDetail = async (req, res) => { }); if (!order) { - return res.status(404).json({ - code: 404, - message: '订单不存在' - }); + return response.notFound(res, '订单不存在'); } // 权限检查:普通租户只能查看自己的订单 if (!isSystemAdmin && order.tenantId !== currentTenantId) { - return res.status(403).json({ - code: 403, - message: '无权查看此订单' - }); + return response.forbidden(res, '无权查看此订单'); } - res.json({ - code: 200, - data: order, - message: '获取订单详情成功' - }); + response.success(res, '获取订单详情成功', order); } catch (error) { console.error('获取订单详情失败:', error); - res.status(500).json({ - code: 500, - message: '获取订单详情失败', - error: error.message - }); + response.serverError(res, '获取订单详情失败', error); } }; @@ -646,41 +495,25 @@ const cancelOrder = async (req, res) => { }); if (!order) { - return res.status(404).json({ - code: 404, - message: '订单不存在' - }); + return response.notFound(res, '订单不存在'); } // 权限检查:普通租户只能取消自己的订单 if (!isSystemAdmin && order.tenantId !== currentTenantId) { - return res.status(403).json({ - code: 403, - message: '无权取消此订单' - }); + return response.forbidden(res, '无权取消此订单'); } // 只能取消待支付的订单 if (order.status !== 'pending') { - return res.status(400).json({ - code: 400, - message: '只能取消待支付的订单' - }); + return response.badRequest(res, '只能取消待支付的订单'); } await order.update({ status: 'cancelled' }); - res.json({ - code: 200, - message: '订单取消成功' - }); + response.success(res, '订单取消成功'); } catch (error) { console.error('取消订单失败:', error); - res.status(500).json({ - code: 500, - message: '取消订单失败', - error: error.message - }); + response.serverError(res, '取消订单失败', error); } }; @@ -690,21 +523,14 @@ const payOrder = async (req, res) => { const { id: orderId } = req.params; const { paymentMethod = 'other', amount, transactionId: customTransactionId, remark } = req.body || {}; const isSystemAdmin = req.user.userType === 'super_admin'; - const currentTenantId = req.tenantId; if (!orderId) { - return res.status(400).json({ - code: 400, - message: '订单ID不能为空' - }); + return response.badRequest(res, '订单ID不能为空'); } // 只有管理员可以确认支付 if (!isSystemAdmin) { - return res.status(403).json({ - code: 403, - message: '无权操作,请联系管理员' - }); + return response.forbidden(res, '无权操作,请联系管理员'); } // 查询订单 @@ -713,27 +539,18 @@ const payOrder = async (req, res) => { }); if (!order) { - return res.status(404).json({ - code: 404, - message: '订单不存在' - }); + return response.notFound(res, '订单不存在'); } // 验证订单状态 if (order.status !== 'pending') { - return res.status(400).json({ - code: 400, - message: '订单状态异常,无法支付' - }); + return response.badRequest(res, '订单状态异常,无法支付'); } // 验证金额 const paymentAmount = parseFloat(amount) || order.actualAmount; if (paymentAmount <= 0) { - return res.status(400).json({ - code: 400, - message: '支付金额必须大于0' - }); + return response.badRequest(res, '支付金额必须大于0'); } // 生成或使用自定义交易流水号 @@ -762,26 +579,18 @@ const payOrder = async (req, res) => { // 使用订单的months字段和planId更新资源配置 const paymentResult = await billingService.processPaymentSuccess(order.tenantId, order.months, order.planId); - res.json({ - code: 200, - message: '支付成功', - data: { - payment, - order: { - ...order.toJSON(), - status: 'paid', - paidTime: paidTime - }, - tenant: paymentResult - } + response.success(res, '支付成功', { + payment, + order: { + ...order.toJSON(), + status: 'paid', + paidTime: paidTime + }, + tenant: paymentResult }); } catch (error) { console.error('支付订单失败:', error); - res.status(500).json({ - code: 500, - message: '支付订单失败', - error: error.message - }); + response.serverError(res, '支付订单失败', error); } }; @@ -822,23 +631,15 @@ const getPayments = async (req, res) => { ] }); - res.json({ - code: 200, - data: { - list: rows, - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - }, - message: '获取支付记录成功' + response.success(res, '获取支付记录成功', { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取支付记录失败:', error); - res.status(500).json({ - code: 500, - message: '获取支付记录失败', - error: error.message - }); + response.serverError(res, '获取支付记录失败', error); } }; @@ -859,10 +660,7 @@ const getBillingInfo = async (req, res) => { }); if (!tenant) { - return res.status(404).json({ - code: 404, - message: '租户不存在' - }); + return response.notFound(res, '租户不存在'); } // 获取当前使用量 @@ -872,37 +670,29 @@ const getBillingInfo = async (req, res) => { User.count({ where: { tenantId, isDeleted: 0 } }) ]); - res.json({ - code: 200, - data: { - tenant: { - id: tenant.id, - name: tenant.name, - code: tenant.code, - billingStatus: tenant.billingStatus, - trialStartDate: tenant.trialStartDate, - trialEndDate: tenant.trialEndDate, - paidStartDate: tenant.paidStartDate, - paidEndDate: tenant.paidEndDate, - currentPeriodStart: tenant.currentPeriodStart, - currentPeriodEnd: tenant.currentPeriodEnd - }, - plan: tenant.subscriptionPlan, - usage: { - apartments: apartmentCount, - rooms: roomCount, - users: userCount - } + response.success(res, '获取计费信息成功', { + tenant: { + id: tenant.id, + name: tenant.name, + code: tenant.code, + billingStatus: tenant.billingStatus, + trialStartDate: tenant.trialStartDate, + trialEndDate: tenant.trialEndDate, + paidStartDate: tenant.paidStartDate, + paidEndDate: tenant.paidEndDate, + currentPeriodStart: tenant.currentPeriodStart, + currentPeriodEnd: tenant.currentPeriodEnd }, - message: '获取计费信息成功' + plan: tenant.subscriptionPlan, + usage: { + apartments: apartmentCount, + rooms: roomCount, + users: userCount + } }); } catch (error) { console.error('获取计费信息失败:', error); - res.status(500).json({ - code: 500, - message: '获取计费信息失败', - error: error.message - }); + response.serverError(res, '获取计费信息失败', error); } }; @@ -913,18 +703,10 @@ const getUsageStats = async (req, res) => { const usageStats = await billingService.calculateOverage(tenantId); - res.json({ - code: 200, - data: usageStats, - message: '获取资源使用情况成功' - }); + response.success(res, '获取资源使用情况成功', usageStats); } catch (error) { console.error('获取资源使用情况失败:', error); - res.status(500).json({ - code: 500, - message: '获取资源使用情况失败', - error: error.message - }); + response.serverError(res, '获取资源使用情况失败', error); } }; @@ -934,10 +716,7 @@ const getBillingStats = async (req, res) => { const isSystemAdmin = req.user.userType === 'super_admin'; if (!isSystemAdmin) { - return res.status(403).json({ - code: 403, - message: '无权访问此接口' - }); + return response.forbidden(res, '无权访问此接口'); } // 各计费状态租户数量 @@ -1009,28 +788,20 @@ const getBillingStats = async (req, res) => { } }); - res.json({ - code: 200, - data: { - billingStatusStats: billingStatusStats.reduce((acc, item) => { - acc[item.billingStatus] = parseInt(item.get('count')); - return acc; - }, {}), - totalRevenue: totalRevenue || 0, - monthRevenue: monthRevenue || 0, - upcomingExpiredCount, - expiredCount, - pendingOrdersCount - }, - message: '获取计费统计成功' + response.success(res, '获取计费统计成功', { + billingStatusStats: billingStatusStats.reduce((acc, item) => { + acc[item.billingStatus] = parseInt(item.get('count')); + return acc; + }, {}), + totalRevenue: totalRevenue || 0, + monthRevenue: monthRevenue || 0, + upcomingExpiredCount, + expiredCount, + pendingOrdersCount }); } catch (error) { console.error('获取计费统计失败:', error); - res.status(500).json({ - code: 500, - message: '获取计费统计失败', - error: error.message - }); + response.serverError(res, '获取计费统计失败', error); } }; @@ -1044,25 +815,13 @@ const getPaymentSettings = async (req, res) => { // 如果没有记录,返回空对象 if (!settings) { - return res.json({ - code: 200, - message: '获取支付设置成功', - data: {} - }); + return response.success(res, '获取支付设置成功', {}); } - res.json({ - code: 200, - message: '获取支付设置成功', - data: settings - }); + response.success(res, '获取支付设置成功', settings); } catch (error) { console.error('获取支付设置失败:', error); - res.status(500).json({ - code: 500, - message: '获取支付设置失败', - error: error.message - }); + response.serverError(res, '获取支付设置失败', error); } }; @@ -1073,10 +832,7 @@ const updatePaymentSettings = async (req, res) => { // 只有超级管理员可以修改支付设置 if (!isSystemAdmin) { - return res.status(403).json({ - code: 403, - message: '无权操作,请联系管理员' - }); + return response.forbidden(res, '无权操作,请联系管理员'); } const { @@ -1124,18 +880,10 @@ const updatePaymentSettings = async (req, res) => { }); } - res.json({ - code: 200, - message: '支付设置更新成功', - data: settings - }); + response.success(res, '支付设置更新成功', settings); } catch (error) { console.error('更新支付设置失败:', error); - res.status(500).json({ - code: 500, - message: '更新支付设置失败', - error: error.message - }); + response.serverError(res, '更新支付设置失败', error); } }; diff --git a/controllers/electricityBillController.js b/controllers/electricityBillController.js deleted file mode 100644 index f888aa2..0000000 --- a/controllers/electricityBillController.js +++ /dev/null @@ -1,214 +0,0 @@ -const { ElectricityBill, Room } = require('../models'); -const { Op } = require('sequelize'); - -// 格式化时间(考虑时区,转换为北京时间) -const formatDate = (date) => { - if (!date) return null; - // 确保date是Date对象 - const dateObj = date instanceof Date ? date : new Date(date); - // 创建一个新的Date对象,加上8小时的时区偏移 - const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000); - return beijingDate.toISOString().split('T')[0]; -}; - -// 格式化电费数据 -const formatElectricityBillData = (bill) => { - const formattedBill = { - ...bill.toJSON(), - startDate: formatDate(bill.startDate), - endDate: formatDate(bill.endDate), - createTime: formatDate(bill.createTime), - updateTime: formatDate(bill.updateTime) - }; - - // 格式化关联数据 - if (formattedBill.Room) { - formattedBill.Room = { - ...formattedBill.Room, - createTime: formatDate(formattedBill.Room.createTime), - updateTime: formatDate(formattedBill.Room.updateTime) - }; - } - - return formattedBill; -}; - -// 获取所有电费记录(支持搜索和分页) -const getAllElectricityBills = async (req, res) => { - try { - const { roomId, status, startDate, endDate, page = 1, pageSize = 10 } = req.query; - - // 构建查询条件 - const where = { isDeleted: 0 }; - if (roomId) { - where.roomId = roomId; - } - if (status) { - where.status = status; - } - if (startDate) { - where.startDate = { [Op.gte]: new Date(startDate) }; - } - if (endDate) { - where.endDate = { [Op.lte]: new Date(endDate) }; - } - - // 计算偏移量 - const offset = (page - 1) * pageSize; - - // 查询电费数据 - const { count, rows } = await ElectricityBill.findAndCountAll({ - where, - include: [ - { - model: Room, - where: { isDeleted: 0 } - } - ], - limit: parseInt(pageSize), - offset: parseInt(offset) - }); - - // 格式化数据 - const formattedBills = rows.map(formatElectricityBillData); - - // 返回结果 - res.status(200).json({ - data: formattedBills, - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - }); - } catch (error) { - res.status(500).json({ error: error.message }); - } -}; - -// 获取单个电费记录 -const getElectricityBillById = async (req, res) => { - try { - const { id } = req.params; - const bill = await ElectricityBill.findOne({ - where: { id, isDeleted: 0 }, - include: [ - { - model: Room, - where: { isDeleted: 0 } - } - ] - }); - if (!bill) { - return res.status(404).json({ error: '电费记录不存在' }); - } - const formattedBill = formatElectricityBillData(bill); - res.status(200).json({ - code: 200, - data: formattedBill, - message: 'success' - }); - } catch (error) { - res.status(500).json({ code: 500, error: error.message }); - } -}; - -// 创建电费记录 -const createElectricityBill = async (req, res) => { - try { - const { roomId, startDate, endDate, startReading, endReading, unitPrice } = req.body; - - // 计算用电量和费用 - const usage = parseFloat(endReading) - parseFloat(startReading); - const amount = usage * parseFloat(unitPrice); - - const bill = await ElectricityBill.create({ - roomId, - startDate, - endDate, - startReading, - endReading, - usage, - unitPrice, - amount - }); - - const formattedBill = formatElectricityBillData(bill); - res.status(201).json({ - code: 201, - data: formattedBill, - message: '创建成功' - }); - } catch (error) { - res.status(500).json({ code: 500, error: error.message }); - } -}; - -// 更新电费记录 -const updateElectricityBill = async (req, res) => { - try { - const { id } = req.params; - const { startDate, endDate, startReading, endReading, unitPrice, status } = req.body; - - const bill = await ElectricityBill.findOne({ - where: { id, isDeleted: 0 } - }); - if (!bill) { - return res.status(404).json({ error: '电费记录不存在' }); - } - - // 计算用电量和费用 - let usage = bill.usage; - let amount = bill.amount; - if (startReading && endReading && unitPrice) { - usage = parseFloat(endReading) - parseFloat(startReading); - amount = usage * parseFloat(unitPrice); - } - - await bill.update({ - startDate, - endDate, - startReading, - endReading, - usage, - unitPrice, - amount, - status - }); - - const formattedBill = formatElectricityBillData(bill); - res.status(200).json({ - code: 200, - data: formattedBill, - message: '更新成功' - }); - } catch (error) { - res.status(500).json({ code: 500, error: error.message }); - } -}; - -// 删除电费记录(软删除) -const deleteElectricityBill = async (req, res) => { - try { - const { id } = req.params; - const bill = await ElectricityBill.findOne({ - where: { id, isDeleted: 0 } - }); - if (!bill) { - return res.status(404).json({ error: '电费记录不存在' }); - } - await bill.update({ isDeleted: 1 }); - res.status(200).json({ - code: 200, - message: '电费记录删除成功' - }); - } catch (error) { - res.status(500).json({ code: 500, error: error.message }); - } -}; - -module.exports = { - getAllElectricityBills, - getElectricityBillById, - createElectricityBill, - updateElectricityBill, - deleteElectricityBill -}; \ No newline at end of file diff --git a/controllers/logController.js b/controllers/logController.js index d84a992..2ed6d02 100644 --- a/controllers/logController.js +++ b/controllers/logController.js @@ -1,6 +1,7 @@ const { Op } = require('sequelize'); const OperationLog = require('../models/OperationLog'); const LoginLog = require('../models/LoginLog'); +const response = require('../utils/response'); // 获取操作日志列表 exports.getOperationLogs = async (req, res) => { @@ -35,23 +36,15 @@ exports.getOperationLogs = async (req, res) => { limit: parseInt(pageSize) }); - res.json({ - code: 200, - message: '获取成功', - data: { - list: rows, - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - } + response.success(res, '获取成功', { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取操作日志错误:', error); - res.status(500).json({ - code: 500, - message: '获取操作日志失败', - error: error.message - }); + response.serverError(res, '获取操作日志失败', error); } }; @@ -85,23 +78,15 @@ exports.getLoginLogs = async (req, res) => { limit: parseInt(pageSize) }); - res.json({ - code: 200, - message: '获取成功', - data: { - list: rows, - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - } + response.success(res, '获取成功', { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取登录日志错误:', error); - res.status(500).json({ - code: 500, - message: '获取登录日志失败', - error: error.message - }); + response.serverError(res, '获取登录日志失败', error); } }; @@ -119,17 +104,10 @@ exports.clearOperationLogs = async (req, res) => { await OperationLog.destroy({ where }); - res.json({ - code: 200, - message: '清空成功' - }); + response.success(res, '清空成功'); } catch (error) { console.error('清空操作日志错误:', error); - res.status(500).json({ - code: 500, - message: '清空操作日志失败', - error: error.message - }); + response.serverError(res, '清空操作日志失败', error); } }; @@ -147,16 +125,9 @@ exports.clearLoginLogs = async (req, res) => { await LoginLog.destroy({ where }); - res.json({ - code: 200, - message: '清空成功' - }); + response.success(res, '清空成功'); } catch (error) { console.error('清空登录日志错误:', error); - res.status(500).json({ - code: 500, - message: '清空登录日志失败', - error: error.message - }); + response.serverError(res, '清空登录日志失败', error); } }; diff --git a/controllers/menuController.js b/controllers/menuController.js index c5ecbce..b424f1f 100644 --- a/controllers/menuController.js +++ b/controllers/menuController.js @@ -2,6 +2,7 @@ const { Op } = require('sequelize'); const Menu = require('../models/Menu'); const RoleMenu = require('../models/RoleMenu'); const { logOperation } = require('../utils/logger'); +const response = require('../utils/response'); // 获取菜单树 exports.getMenuTree = async (req, res) => { @@ -29,18 +30,10 @@ exports.getMenuTree = async (req, res) => { const menuTree = buildTree(menus); - res.json({ - code: 200, - message: '获取成功', - data: menuTree - }); + response.success(res, '获取成功', menuTree); } catch (error) { console.error('获取菜单树失败:', error); - res.status(500).json({ - code: 500, - message: '获取菜单树失败', - error: error.message - }); + response.serverError(res, '获取菜单树失败', error); } }; @@ -67,23 +60,15 @@ exports.getMenuList = async (req, res) => { limit: parseInt(pageSize) }); - res.json({ - code: 200, - message: '获取成功', - data: { - list: rows, - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - } + response.success(res, '获取成功', { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取菜单列表失败:', error); - res.status(500).json({ - code: 500, - message: '获取菜单列表失败', - error: error.message - }); + response.serverError(res, '获取菜单列表失败', error); } }; @@ -97,24 +82,13 @@ exports.getMenuById = async (req, res) => { }); if (!menu) { - return res.status(404).json({ - code: 404, - message: '菜单不存在' - }); + return response.notFound(res, '菜单不存在'); } - res.json({ - code: 200, - message: '获取成功', - data: menu - }); + response.success(res, '获取成功', menu); } catch (error) { console.error('获取菜单详情失败:', error); - res.status(500).json({ - code: 500, - message: '获取菜单详情失败', - error: error.message - }); + response.serverError(res, '获取菜单详情失败', error); } }; @@ -124,17 +98,11 @@ exports.createMenu = async (req, res) => { const { parentId, name, code, type, path, component, icon, sort, visible, status } = req.body; if (!name || !code || !type) { - return res.status(400).json({ - code: 400, - message: '菜单名称、编码和类型不能为空' - }); + return response.badRequest(res, '菜单名称、编码和类型不能为空'); } if (type === 'menu' && !path) { - return res.status(400).json({ - code: 400, - message: '菜单类型必须填写路由路径' - }); + return response.badRequest(res, '菜单类型必须填写路由路径'); } const existingMenu = await Menu.findOne({ @@ -142,10 +110,7 @@ exports.createMenu = async (req, res) => { }); if (existingMenu) { - return res.status(400).json({ - code: 400, - message: '菜单编码已存在' - }); + return response.badRequest(res, '菜单编码已存在'); } if (parentId) { @@ -153,10 +118,7 @@ exports.createMenu = async (req, res) => { where: { isDeleted: false } }); if (!parentMenu) { - return res.status(400).json({ - code: 400, - message: '父菜单不存在' - }); + return response.badRequest(res, '父菜单不存在'); } } @@ -187,18 +149,10 @@ exports.createMenu = async (req, res) => { status: 'success' }); - res.json({ - code: 200, - message: '创建成功', - data: menu - }); + response.success(res, '创建成功', menu); } catch (error) { console.error('创建菜单失败:', error); - res.status(500).json({ - code: 500, - message: '创建菜单失败', - error: error.message - }); + response.serverError(res, '创建菜单失败', error); } }; @@ -213,10 +167,7 @@ exports.updateMenu = async (req, res) => { }); if (!menu) { - return res.status(404).json({ - code: 404, - message: '菜单不存在' - }); + return response.notFound(res, '菜单不存在'); } if (code && code !== menu.code) { @@ -225,29 +176,20 @@ exports.updateMenu = async (req, res) => { }); if (existingMenu) { - return res.status(400).json({ - code: 400, - message: '菜单编码已存在' - }); + return response.badRequest(res, '菜单编码已存在'); } } if (parentId) { if (parseInt(parentId) === parseInt(id)) { - return res.status(400).json({ - code: 400, - message: '不能将菜单设置为自己的子菜单' - }); + return response.badRequest(res, '不能将菜单设置为自己的子菜单'); } const parentMenu = await Menu.findByPk(parentId, { where: { isDeleted: false } }); if (!parentMenu) { - return res.status(400).json({ - code: 400, - message: '父菜单不存在' - }); + return response.badRequest(res, '父菜单不存在'); } } @@ -279,18 +221,10 @@ exports.updateMenu = async (req, res) => { status: 'success' }); - res.json({ - code: 200, - message: '更新成功', - data: menu - }); + response.success(res, '更新成功', menu); } catch (error) { console.error('更新菜单失败:', error); - res.status(500).json({ - code: 500, - message: '更新菜单失败', - error: error.message - }); + response.serverError(res, '更新菜单失败', error); } }; @@ -304,10 +238,7 @@ exports.deleteMenu = async (req, res) => { }); if (!menu) { - return res.status(404).json({ - code: 404, - message: '菜单不存在' - }); + return response.notFound(res, '菜单不存在'); } const children = await Menu.findAll({ @@ -315,10 +246,7 @@ exports.deleteMenu = async (req, res) => { }); if (children.length > 0) { - return res.status(400).json({ - code: 400, - message: '该菜单下有子菜单,无法删除' - }); + return response.badRequest(res, '该菜单下有子菜单,无法删除'); } await menu.update({ @@ -342,17 +270,10 @@ exports.deleteMenu = async (req, res) => { status: 'success' }); - res.json({ - code: 200, - message: '删除成功' - }); + response.success(res, '删除成功'); } catch (error) { console.error('删除菜单失败:', error); - res.status(500).json({ - code: 500, - message: '删除菜单失败', - error: error.message - }); + response.serverError(res, '删除菜单失败', error); } }; @@ -369,10 +290,7 @@ exports.getRoleMenus = async (req, res) => { }); if (!role) { - return res.status(404).json({ - code: 404, - message: '角色不存在' - }); + return response.notFound(res, '角色不存在'); } // 获取角色的菜单权限 @@ -388,18 +306,10 @@ exports.getRoleMenus = async (req, res) => { const menus = roleData ? roleData.menus : []; - res.json({ - code: 200, - message: '获取成功', - data: menus - }); + response.success(res, '获取成功', menus); } catch (error) { console.error('获取角色菜单失败:', error); - res.status(500).json({ - code: 500, - message: '获取角色菜单失败', - error: error.message - }); + response.serverError(res, '获取角色菜单失败', error); } }; @@ -410,20 +320,14 @@ exports.assignMenusToRole = async (req, res) => { const { menuIds } = req.body; if (!Array.isArray(menuIds)) { - return res.status(400).json({ - code: 400, - message: '菜单ID必须是数组' - }); + return response.badRequest(res, '菜单ID必须是数组'); } const Role = require('../models/Role'); const role = await Role.findByPk(roleId); if (!role) { - return res.status(404).json({ - code: 404, - message: '角色不存在' - }); + return response.notFound(res, '角色不存在'); } await RoleMenu.destroy({ @@ -450,17 +354,10 @@ exports.assignMenusToRole = async (req, res) => { status: 'success' }); - res.json({ - code: 200, - message: '分配成功' - }); + response.success(res, '分配成功'); } catch (error) { console.error('分配菜单权限失败:', error); - res.status(500).json({ - code: 500, - message: '分配菜单权限失败', - error: error.message - }); + response.serverError(res, '分配菜单权限失败', error); } }; @@ -505,18 +402,11 @@ exports.getUserMenus = async (req, res) => { const allMenus = [...menuList, ...buttonList]; const menuTree = buildTree(allMenus); - return res.json({ - code: 200, - message: '获取成功', - data: menuTree - }); + return response.success(res, '获取成功', menuTree); } if (!user.role) { - return res.status(403).json({ - code: 403, - message: '用户没有分配角色' - }); + return response.forbidden(res, '用户没有分配角色'); } // 普通用户返回角色分配的菜单 @@ -534,11 +424,7 @@ exports.getUserMenus = async (req, res) => { }); if (!roleData || !roleData.menus) { - return res.json({ - code: 200, - message: '获取成功', - data: [] - }); + return response.success(res, '获取成功', []); } // 按sort排序 @@ -547,18 +433,10 @@ exports.getUserMenus = async (req, res) => { // 构建菜单树 const menuTree = buildTree(menus); - res.json({ - code: 200, - message: '获取成功', - data: menuTree - }); + response.success(res, '获取成功', menuTree); } catch (error) { console.error('获取用户菜单失败:', error); - res.status(500).json({ - code: 500, - message: '获取用户菜单失败', - error: error.message - }); + response.serverError(res, '获取用户菜单失败', error); } }; diff --git a/controllers/meterReadingController.js b/controllers/meterReadingController.js index 303c1ec..083f873 100644 --- a/controllers/meterReadingController.js +++ b/controllers/meterReadingController.js @@ -1,5 +1,6 @@ const { MeterReading, Bill, Room, Renter, Rental } = require('../models'); const { Op } = require('sequelize'); +const response = require('../utils/response'); // 生成账单编号 const generateBillNo = () => { @@ -98,16 +99,15 @@ const getAllMeterReadings = async (req, res) => { const formattedReadings = rows.map(formatMeterReadingData); - res.status(200).json({ - code: 200, - data: formattedReadings, + response.success(res, '获取成功', { + list: formattedReadings, total: count, page: parseInt(page), pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取抄表记录列表失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取抄表记录列表失败', error); } }; @@ -135,17 +135,13 @@ const getMeterReadingById = async (req, res) => { }); if (!reading) { - return res.status(404).json({ code: 404, error: '抄表记录不存在' }); + return response.notFound(res, '抄表记录不存在'); } - res.status(200).json({ - code: 200, - data: formatMeterReadingData(reading), - message: 'success' - }); + response.success(res, '获取成功', formatMeterReadingData(reading)); } catch (error) { console.error('获取抄表记录详情失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取抄表记录详情失败', error); } }; @@ -221,17 +217,13 @@ const createMeterReading = async (req, res) => { // 更新抄表记录的账单ID await meterReading.update({ billId: bill.id }); - res.status(201).json({ - code: 201, - data: { - meterReading: formatMeterReadingData(meterReading), - bill: { - id: bill.id, - billNo: bill.billNo, - status: bill.status - } - }, - message: '抄表记录创建成功,已自动生成账单' + response.created(res, '抄表记录创建成功,已自动生成账单', { + meterReading: formatMeterReadingData(meterReading), + bill: { + id: bill.id, + billNo: bill.billNo, + status: bill.status + } }); } catch (error) { console.error('创建抄表记录失败:', error); @@ -239,23 +231,17 @@ const createMeterReading = async (req, res) => { if (error.name === 'SequelizeUniqueConstraintError') { const field = error.errors[0]?.path || '未知字段'; if (field === 'uk_room_type_month') { - return res.status(409).json({ - code: 409, - error: '该房间本月已存在此类型的抄表记录,请勿重复创建' - }); + return response.error(res, '该房间本月已存在此类型的抄表记录,请勿重复创建', 409); } - return res.status(409).json({ - code: 409, - error: `数据重复: ${field} 必须唯一` - }); + return response.error(res, `数据重复: ${field} 必须唯一`, 409); } // 输出详细的验证错误信息 if (error.name === 'SequelizeValidationError') { const messages = error.errors.map(e => `${e.path}: ${e.message}`).join(', '); console.error('验证错误详情:', messages); - return res.status(400).json({ code: 400, error: `Validation error: ${messages}` }); + return response.badRequest(res, `Validation error: ${messages}`); } - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '创建抄表记录失败', error); } }; @@ -276,7 +262,7 @@ const updateMeterReading = async (req, res) => { }); if (!meterReading) { - return res.status(404).json({ code: 404, error: '抄表记录不存在' }); + return response.notFound(res, '抄表记录不存在'); } // 重新计算用量和金额 @@ -305,14 +291,10 @@ const updateMeterReading = async (req, res) => { } } - res.status(200).json({ - code: 200, - data: formatMeterReadingData(meterReading), - message: '更新成功' - }); + response.success(res, '更新成功', formatMeterReadingData(meterReading)); } catch (error) { console.error('更新抄表记录失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '更新抄表记录失败', error); } }; @@ -325,7 +307,7 @@ const deleteMeterReading = async (req, res) => { }); if (!meterReading) { - return res.status(404).json({ code: 404, error: '抄表记录不存在' }); + return response.notFound(res, '抄表记录不存在'); } // 软删除抄表记录 @@ -345,13 +327,10 @@ const deleteMeterReading = async (req, res) => { } } - res.status(200).json({ - code: 200, - message: '抄表记录及关联账单删除成功' - }); + response.success(res, '抄表记录及关联账单删除成功'); } catch (error) { console.error('删除抄表记录失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '删除抄表记录失败', error); } }; @@ -390,16 +369,15 @@ const getRoomMeterReadings = async (req, res) => { const formattedReadings = rows.map(formatMeterReadingData); - res.status(200).json({ - code: 200, - data: formattedReadings, + response.success(res, '获取成功', { + list: formattedReadings, total: count, page: parseInt(page), pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取房间抄表记录失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取房间抄表记录失败', error); } }; @@ -418,16 +396,13 @@ const getLatestReading = async (req, res) => { order: [['billMonth', 'DESC']] }); - res.status(200).json({ - code: 200, - data: latestReading ? { - previousReading: latestReading.currentReading, - billMonth: latestReading.billMonth - } : null - }); + response.success(res, '获取成功', latestReading ? { + previousReading: latestReading.currentReading, + billMonth: latestReading.billMonth + } : null); } catch (error) { console.error('获取最新读数失败:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取最新读数失败', error); } }; diff --git a/controllers/rentalController.js b/controllers/rentalController.js index e15081f..ff05824 100644 --- a/controllers/rentalController.js +++ b/controllers/rentalController.js @@ -1,5 +1,6 @@ const { Rental, Room, Apartment, Bill, Transaction, Renter, MeterReading } = require('../models'); const { Op } = require('sequelize'); +const response = require('../utils/response'); // 格式化时间(考虑时区,转换为北京时间) const formatDate = (date) => { @@ -149,14 +150,14 @@ const getAllRentals = async (req, res) => { const formattedRentals = rows.map(formatRentalData); // 返回结果 - res.status(200).json({ - data: formattedRentals, + response.success(res, '获取成功', { + list: formattedRentals, total: count, page: parseInt(page), pageSize: parseInt(pageSize) }); } catch (error) { - res.status(500).json({ error: error.message }); + response.serverError(res, '获取租房列表失败', error); } }; @@ -183,16 +184,12 @@ const getRentalById = async (req, res) => { ] }); if (!rental) { - return res.status(404).json({ error: '租房记录不存在' }); + return response.notFound(res, '租房记录不存在'); } const formattedRental = formatRentalData(rental); - res.status(200).json({ - code: 200, - data: formattedRental, - message: 'success' - }); + response.success(res, '获取成功', formattedRental); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取租房详情失败', error); } }; @@ -206,34 +203,34 @@ const createRental = async (req, res) => { // 检查请求体是否存在 if (!body) { - return res.status(400).json({ error: '请求体不能为空' }); + return response.badRequest(res, '请求体不能为空'); } // 检查所有必要参数 if (!body.roomId) { - return res.status(400).json({ error: '缺少房间ID' }); + return response.badRequest(res, '缺少房间ID'); } if (!body.renterId) { - return res.status(400).json({ error: '缺少租客ID' }); + return response.badRequest(res, '缺少租客ID'); } if (!body.startDate) { - return res.status(400).json({ error: '缺少开始日期' }); + return response.badRequest(res, '缺少开始日期'); } if (!body.endDate) { - return res.status(400).json({ error: '缺少结束日期' }); + return response.badRequest(res, '缺少结束日期'); } if (!body.rent) { - return res.status(400).json({ error: '缺少租金' }); + return response.badRequest(res, '缺少租金'); } // 转换roomId和renterId为整数类型 const parsedRoomId = parseInt(body.roomId); const parsedRenterId = parseInt(body.renterId); if (isNaN(parsedRoomId)) { - return res.status(400).json({ error: '无效的房间ID' }); + return response.badRequest(res, '无效的房间ID'); } if (isNaN(parsedRenterId)) { - return res.status(400).json({ error: '无效的租客ID' }); + return response.badRequest(res, '无效的租客ID'); } // 处理押金,为空时设置为0 @@ -317,14 +314,10 @@ const createRental = async (req, res) => { }); } - res.status(201).json({ - code: 201, - data: rental, - message: '创建成功' - }); + response.created(res, '创建成功', rental); } catch (error) { console.error('创建租房记录时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '创建租房失败', error); } }; @@ -337,7 +330,7 @@ const updateRental = async (req, res) => { where: { id, isDeleted: 0 } }); if (!rental) { - return res.status(404).json({ error: '租房记录不存在' }); + return response.notFound(res, '租房记录不存在'); } // 处理押金,为空时设置为0 const updateDeposit = deposit || 0; @@ -358,13 +351,9 @@ const updateRental = async (req, res) => { remark, updateBy: req.user.id }); - res.status(200).json({ - code: 200, - data: rental, - message: '更新成功' - }); + response.success(res, '更新成功', rental); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '更新租房失败', error); } }; @@ -376,18 +365,15 @@ const deleteRental = async (req, res) => { where: { id, isDeleted: 0 } }); if (!rental) { - return res.status(404).json({ error: '租房记录不存在' }); + return response.notFound(res, '租房记录不存在'); } await rental.update({ isDeleted: 1, updateBy: req.user.id }); - res.status(200).json({ - code: 200, - message: '租房记录删除成功' - }); + response.success(res, '租房记录删除成功'); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '删除租房失败', error); } }; @@ -417,11 +403,11 @@ const terminateRental = async (req, res) => { }); if (!rental) { - return res.status(404).json({ error: '租房记录不存在' }); + return response.notFound(res, '租房记录不存在'); } if (rental.status !== 'active') { - return res.status(400).json({ error: '只有生效中的租约可以退租' }); + return response.badRequest(res, '只有生效中的租约可以退租'); } const room = rental.Room; @@ -484,14 +470,10 @@ const terminateRental = async (req, res) => { { where: { id: room.id } } ); - res.status(200).json({ - code: 200, - data: rental, - message: '退租处理成功' - }); + response.success(res, '退租处理成功', rental); } catch (error) { console.error('退租处理时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '退租处理失败', error); } }; @@ -560,13 +542,9 @@ const listRentals = async (req, res) => { const formattedRentals = rentals.map(formatRentalData); // 返回结果 - res.status(200).json({ - code: 200, - data: formattedRentals, - message: 'success' - }); + response.success(res, '获取成功', formattedRentals); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取租房列表失败', error); } }; @@ -602,25 +580,25 @@ const createRentalWithRenter = async (req, res) => { // 参数验证 if (!renterName) { await transaction.rollback(); - return res.status(400).json({ code: 400, error: '租客姓名不能为空' }); + return response.badRequest(res, '租客姓名不能为空'); } if (!roomId) { await transaction.rollback(); - return res.status(400).json({ code: 400, error: '房间ID不能为空' }); + return response.badRequest(res, '房间ID不能为空'); } if (!startDate || !endDate) { await transaction.rollback(); - return res.status(400).json({ code: 400, error: '开始日期和结束日期不能为空' }); + return response.badRequest(res, '开始日期和结束日期不能为空'); } if (!rent) { await transaction.rollback(); - return res.status(400).json({ code: 400, error: '租金不能为空' }); + return response.badRequest(res, '租金不能为空'); } const parsedRoomId = parseInt(roomId); if (isNaN(parsedRoomId)) { await transaction.rollback(); - return res.status(400).json({ code: 400, error: '无效的房间ID' }); + return response.badRequest(res, '无效的房间ID'); } // 1. 创建租客 @@ -775,21 +753,17 @@ const createRentalWithRenter = async (req, res) => { // 提交事务 await transaction.commit(); - res.status(201).json({ - code: 201, - data: { - rentalId: rental.id, - renterId: renter.id, - roomId: parsedRoomId - }, - message: '创建成功' + response.created(res, '创建成功', { + rentalId: rental.id, + renterId: renter.id, + roomId: parsedRoomId }); } catch (error) { // 回滚事务 await transaction.rollback(); console.error('创建租房(整合)时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '创建租房失败', error); } }; diff --git a/controllers/renterController.js b/controllers/renterController.js index 2c31f2e..43d10bb 100644 --- a/controllers/renterController.js +++ b/controllers/renterController.js @@ -1,5 +1,6 @@ const { Renter, Rental, Room, Apartment } = require('../models'); const { Op } = require('sequelize'); +const response = require('../utils/response'); // 获取租客列表(分页) const getRenters = async (req, res) => { @@ -28,23 +29,15 @@ const getRenters = async (req, res) => { limit: parseInt(pageSize) }); - res.json({ - code: 200, - data: { - list: rows, - pagination: { - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - } - } + response.success(res, '获取成功', { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取租客列表失败:', error); - res.status(500).json({ - code: 500, - message: '获取租客列表失败' - }); + response.serverError(res, '获取租客列表失败', error); } }; @@ -73,16 +66,10 @@ const getRenterList = async (req, res) => { order: [['createTime', 'DESC']] }); - res.json({ - code: 200, - data: rows - }); + response.success(res, '获取成功', rows); } catch (error) { console.error('获取租客列表失败:', error); - res.status(500).json({ - code: 500, - message: '获取租客列表失败' - }); + response.serverError(res, '获取租客列表失败', error); } }; @@ -97,10 +84,7 @@ const getRenterById = async (req, res) => { }); if (!renter) { - return res.status(404).json({ - code: 404, - message: '租客不存在' - }); + return response.notFound(res, '租客不存在'); } // 获取租客的租赁记录 @@ -121,20 +105,13 @@ const getRenterById = async (req, res) => { order: [['createTime', 'DESC']] }); - res.json({ - code: 200, - data: { - ...renter.toJSON(), - rentals - } + response.success(res, '获取成功', { + ...renter.toJSON(), + rentals }); } catch (error) { console.error('获取租客详情失败:', error); - res.status(500).json({ - code: 500, - message: '获取租客详情失败', - error: error.message - }); + response.serverError(res, '获取租客详情失败', error); } }; @@ -160,10 +137,7 @@ const createRenter = async (req, res) => { // 验证必填字段 if (!name) { - return res.status(400).json({ - code: 400, - message: '租客姓名不能为空' - }); + return response.badRequest(res, '租客姓名不能为空'); } // 检查手机号是否已存在 @@ -172,10 +146,7 @@ const createRenter = async (req, res) => { where: { phone, tenantId, isDeleted: 0 } }); if (existingRenter) { - return res.status(400).json({ - code: 400, - message: '该手机号已存在' - }); + return response.badRequest(res, '该手机号已存在'); } } @@ -196,17 +167,10 @@ const createRenter = async (req, res) => { status: 'active' }); - res.json({ - code: 200, - message: '创建成功', - data: renter - }); + response.created(res, '创建成功', renter); } catch (error) { console.error('创建租客失败:', error); - res.status(500).json({ - code: 500, - message: '创建租客失败' - }); + response.serverError(res, '创建租客失败', error); } }; @@ -222,10 +186,7 @@ const updateRenter = async (req, res) => { }); if (!renter) { - return res.status(404).json({ - code: 404, - message: '租客不存在' - }); + return response.notFound(res, '租客不存在'); } const { @@ -249,10 +210,7 @@ const updateRenter = async (req, res) => { where: { phone, tenantId, isDeleted: 0, id: { [Op.ne]: id } } }); if (existingRenter) { - return res.status(400).json({ - code: 400, - message: '该手机号已被其他租客使用' - }); + return response.badRequest(res, '该手机号已被其他租客使用'); } } @@ -272,17 +230,10 @@ const updateRenter = async (req, res) => { updateBy }); - res.json({ - code: 200, - message: '更新成功', - data: renter - }); + response.success(res, '更新成功', renter); } catch (error) { console.error('更新租客失败:', error); - res.status(500).json({ - code: 500, - message: '更新租客失败' - }); + response.serverError(res, '更新租客失败', error); } }; @@ -297,10 +248,7 @@ const deleteRenter = async (req, res) => { }); if (!renter) { - return res.status(404).json({ - code: 404, - message: '租客不存在' - }); + return response.notFound(res, '租客不存在'); } // 检查是否有进行中的租赁 @@ -313,24 +261,15 @@ const deleteRenter = async (req, res) => { }); if (activeRentals > 0) { - return res.status(400).json({ - code: 400, - message: '该租客有进行中的租赁,无法删除' - }); + return response.badRequest(res, '该租客有进行中的租赁,无法删除'); } await renter.update({ isDeleted: 1 }); - res.json({ - code: 200, - message: '删除成功' - }); + response.success(res, '删除成功'); } catch (error) { console.error('删除租客失败:', error); - res.status(500).json({ - code: 500, - message: '删除租客失败' - }); + response.serverError(res, '删除租客失败', error); } }; @@ -356,19 +295,13 @@ const getRenterOptions = async (req, res) => { limit: 50 }); - res.json({ - code: 200, - data: renters.map(r => ({ - value: r.id, - label: `${r.name} ${r.phone ? '(' + r.phone + ')' : ''}` - })) - }); + response.success(res, '获取成功', renters.map(r => ({ + value: r.id, + label: `${r.name} ${r.phone ? '(' + r.phone + ')' : ''}` + }))); } catch (error) { console.error('获取租客选项失败:', error); - res.status(500).json({ - code: 500, - message: '获取租客选项失败' - }); + response.serverError(res, '获取租客选项失败', error); } }; diff --git a/controllers/roleController.js b/controllers/roleController.js index 70ca87e..44d54e7 100644 --- a/controllers/roleController.js +++ b/controllers/roleController.js @@ -1,6 +1,7 @@ const { Op } = require('sequelize'); const Role = require('../models/Role'); const { logOperation } = require('../utils/logger'); +const response = require('../utils/response'); // 获取角色列表 exports.getRoles = async (req, res) => { @@ -25,15 +26,11 @@ exports.getRoles = async (req, res) => { order: [['id', 'DESC']] }); - res.json({ - code: 200, - message: '获取角色列表成功', - data: { - list: roles, - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - } + response.success(res, '获取角色列表成功', { + list: roles, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) }); // 记录操作日志 @@ -52,11 +49,7 @@ exports.getRoles = async (req, res) => { } catch (error) { console.error('获取角色列表错误:', error); - res.status(500).json({ - code: 500, - message: '获取角色列表失败', - error: error.message - }); + response.serverError(res, '获取角色列表失败', error); } }; @@ -78,17 +71,10 @@ exports.getRoleById = async (req, res) => { }); if (!role) { - return res.status(404).json({ - code: 404, - message: '角色不存在' - }); + return response.notFound(res, '角色不存在'); } - res.json({ - code: 200, - message: '获取角色详情成功', - data: role - }); + response.success(res, '获取角色详情成功', role); // 记录操作日志 await logOperation({ @@ -106,11 +92,7 @@ exports.getRoleById = async (req, res) => { } catch (error) { console.error('获取角色详情错误:', error); - res.status(500).json({ - code: 500, - message: '获取角色详情失败', - error: error.message - }); + response.serverError(res, '获取角色详情失败', error); } }; @@ -122,10 +104,7 @@ exports.createRole = async (req, res) => { // 参数验证 if (!name || !code) { - return res.status(400).json({ - code: 400, - message: '角色名称和编码不能为空' - }); + return response.badRequest(res, '角色名称和编码不能为空'); } // 检查角色编码是否已存在(限制在当前租户内) @@ -138,10 +117,7 @@ exports.createRole = async (req, res) => { }); if (existingRole) { - return res.status(400).json({ - code: 400, - message: '角色编码已存在' - }); + return response.badRequest(res, '角色编码已存在'); } const role = await Role.create({ @@ -155,11 +131,7 @@ exports.createRole = async (req, res) => { updateBy: req.user.id }); - res.json({ - code: 200, - message: '创建角色成功', - data: role - }); + response.success(res, '创建角色成功', role); // 记录操作日志 await logOperation({ @@ -177,11 +149,7 @@ exports.createRole = async (req, res) => { } catch (error) { console.error('创建角色错误:', error); - res.status(500).json({ - code: 500, - message: '创建角色失败', - error: error.message - }); + response.serverError(res, '创建角色失败', error); } }; @@ -202,10 +170,7 @@ exports.updateRole = async (req, res) => { }); if (!role) { - return res.status(404).json({ - code: 404, - message: '角色不存在' - }); + return response.notFound(res, '角色不存在'); } // 检查角色编码是否已存在(排除当前角色) @@ -220,10 +185,7 @@ exports.updateRole = async (req, res) => { }); if (existingRole) { - return res.status(400).json({ - code: 400, - message: '角色编码已存在' - }); + return response.badRequest(res, '角色编码已存在'); } } @@ -236,11 +198,7 @@ exports.updateRole = async (req, res) => { updateBy: req.user.id }); - res.json({ - code: 200, - message: '更新角色成功', - data: role - }); + response.success(res, '更新角色成功', role); // 记录操作日志 await logOperation({ @@ -258,11 +216,7 @@ exports.updateRole = async (req, res) => { } catch (error) { console.error('更新角色错误:', error); - res.status(500).json({ - code: 500, - message: '更新角色失败', - error: error.message - }); + response.serverError(res, '更新角色失败', error); } }; @@ -282,10 +236,7 @@ exports.deleteRole = async (req, res) => { }); if (!role) { - return res.status(404).json({ - code: 404, - message: '角色不存在' - }); + return response.notFound(res, '角色不存在'); } // 检查是否有用户使用此角色 @@ -294,10 +245,7 @@ exports.deleteRole = async (req, res) => { }); if (userCount > 0) { - return res.status(400).json({ - code: 400, - message: '该角色下还有用户,无法删除' - }); + return response.badRequest(res, '该角色下还有用户,无法删除'); } // 软删除 @@ -306,10 +254,7 @@ exports.deleteRole = async (req, res) => { updateBy: req.user.id }); - res.json({ - code: 200, - message: '删除角色成功' - }); + response.success(res, '删除角色成功'); // 记录操作日志 await logOperation({ @@ -327,11 +272,7 @@ exports.deleteRole = async (req, res) => { } catch (error) { console.error('删除角色错误:', error); - res.status(500).json({ - code: 500, - message: '删除角色失败', - error: error.message - }); + response.serverError(res, '删除角色失败', error); } }; @@ -352,18 +293,10 @@ exports.getAllRoles = async (req, res) => { attributes: ['id', 'name', 'code'] }); - res.json({ - code: 200, - message: '获取角色列表成功', - data: roles - }); + response.success(res, '获取角色列表成功', roles); } catch (error) { console.error('获取角色列表错误:', error); - res.status(500).json({ - code: 500, - message: '获取角色列表失败', - error: error.message - }); + response.serverError(res, '获取角色列表失败', error); } }; diff --git a/controllers/roomController.js b/controllers/roomController.js index 8c6e399..17bc672 100644 --- a/controllers/roomController.js +++ b/controllers/roomController.js @@ -1,6 +1,7 @@ const { Room, Apartment, Rental, Renter, Tenant } = require('../models'); const { Op } = require('sequelize'); const { logOperation } = require('../utils/logger'); +const response = require('../utils/response'); // 格式化时间(考虑时区,转换为北京时间) const formatDate = (date) => { @@ -179,14 +180,14 @@ const getAllRooms = async (req, res) => { // 返回结果 - res.status(200).json({ - data: formattedRooms, + response.success(res, '获取成功', { + list: formattedRooms, total: count, page: parseInt(page), pageSize: parseInt(pageSize) }); } catch (error) { - res.status(500).json({ error: error.message }); + response.serverError(res, '获取房间列表失败', error); } }; @@ -202,7 +203,7 @@ const getRoomById = async (req, res) => { include: [Apartment] }); if (!room) { - return res.status(404).json({ error: '房间不存在' }); + return response.notFound(res, '房间不存在'); } // 格式化房间数据 @@ -242,13 +243,9 @@ const getRoomById = async (req, res) => { } else { formattedRoom.Rentals = []; } - res.status(200).json({ - code: 200, - data: formattedRoom, - message: 'success' - }); + response.success(res, '获取成功', formattedRoom); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取房间详情失败', error); } }; @@ -302,14 +299,12 @@ const createRoom = async (req, res) => { updateBy: req.user.id }; const room = await Room.create(processedData); - res.status(201).json({ - code: 201, - data: room, - message: '创建成功', + response.created(res, '创建成功', { + room, warning: tenant && currentRoomCount >= tenant.maxRooms ? `当前已超出套餐限制(${tenant.maxRooms}间),续费时将收取超额费用` : null }); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '创建房间失败', error); } }; @@ -322,7 +317,7 @@ const updateRoom = async (req, res) => { where: { id, isDeleted: 0 } }); if (!room) { - return res.status(404).json({ error: '房间不存在' }); + return response.notFound(res, '房间不存在'); } // 处理空值 const processedData = { @@ -340,13 +335,9 @@ const updateRoom = async (req, res) => { updateBy: req.user.id }; await room.update(processedData); - res.status(200).json({ - code: 200, - data: room, - message: '更新成功' - }); + response.success(res, '更新成功', room); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '更新房间失败', error); } }; @@ -358,18 +349,15 @@ const deleteRoom = async (req, res) => { where: { id, isDeleted: 0 } }); if (!room) { - return res.status(404).json({ error: '房间不存在' }); + return response.notFound(res, '房间不存在'); } await room.update({ isDeleted: 1, updateBy: req.user.id }); - res.status(200).json({ - code: 200, - message: '房间删除成功' - }); + response.success(res, '房间删除成功'); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '删除房间失败', error); } }; @@ -446,13 +434,9 @@ const listRooms = async (req, res) => { })); // 返回结果 - res.status(200).json({ - code: 200, - data: formattedRooms, - message: 'success' - }); + response.success(res, '获取成功', formattedRooms); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取房间列表失败', error); } }; diff --git a/controllers/settingController.js b/controllers/settingController.js index f9d6387..2fb2983 100644 --- a/controllers/settingController.js +++ b/controllers/settingController.js @@ -1,4 +1,5 @@ const { Setting, Category } = require('../models'); +const response = require('../utils/response'); /** * 获取系统设置 @@ -24,18 +25,10 @@ const getSettings = async (req, res) => { ...settingsMap }; - res.json({ - code: 200, - message: '获取成功', - data: defaultSettings - }); + response.success(res, '获取成功', defaultSettings); } catch (error) { console.error('获取设置失败:', error); - res.status(500).json({ - code: 500, - message: '获取设置失败', - error: error.message - }); + response.serverError(res, '获取设置失败', error); } }; @@ -71,17 +64,10 @@ const updateSettings = async (req, res) => { } } - res.json({ - code: 200, - message: '设置保存成功' - }); + response.success(res, '设置保存成功'); } catch (error) { console.error('保存设置失败:', error); - res.status(500).json({ - code: 500, - message: '保存设置失败', - error: error.message - }); + response.serverError(res, '保存设置失败', error); } }; @@ -108,18 +94,10 @@ const getCategories = async (req, res) => { order: [['sort', 'ASC'], ['id', 'ASC']] }); - res.json({ - code: 200, - message: '获取成功', - data: categories - }); + response.success(res, '获取成功', categories); } catch (error) { console.error('获取类目失败:', error); - res.status(500).json({ - code: 500, - message: '获取类目失败', - error: error.message - }); + response.serverError(res, '获取类目失败', error); } }; @@ -138,10 +116,7 @@ const createCategory = async (req, res) => { }); if (existing) { - return res.status(400).json({ - code: 400, - message: '类目编码已存在' - }); + return response.badRequest(res, '类目编码已存在'); } const category = await Category.create({ @@ -154,18 +129,10 @@ const createCategory = async (req, res) => { updateBy: userId }); - res.json({ - code: 200, - message: '创建成功', - data: category - }); + response.success(res, '创建成功', category); } catch (error) { console.error('创建类目失败:', error); - res.status(500).json({ - code: 500, - message: '创建类目失败', - error: error.message - }); + response.serverError(res, '创建类目失败', error); } }; @@ -184,23 +151,17 @@ const updateCategory = async (req, res) => { }); if (!category) { - return res.status(404).json({ - code: 404, - message: '类目不存在' - }); + return response.notFound(res, '类目不存在'); } // 检查编码是否与其他类目冲突 if (code && code !== category.code) { const existing = await Category.findOne({ - where: { code, tenantId, isDeleted: 0, id: { $ne: id } } + where: { code, tenantId, isDeleted: 0, id: { [Op.ne]: id } } }); if (existing) { - return res.status(400).json({ - code: 400, - message: '类目编码已存在' - }); + return response.badRequest(res, '类目编码已存在'); } } @@ -213,18 +174,10 @@ const updateCategory = async (req, res) => { updateBy: userId }); - res.json({ - code: 200, - message: '更新成功', - data: category - }); + response.success(res, '更新成功', category); } catch (error) { console.error('更新类目失败:', error); - res.status(500).json({ - code: 500, - message: '更新类目失败', - error: error.message - }); + response.serverError(res, '更新类目失败', error); } }; @@ -242,18 +195,12 @@ const deleteCategory = async (req, res) => { }); if (!category) { - return res.status(404).json({ - code: 404, - message: '类目不存在' - }); + return response.notFound(res, '类目不存在'); } // 默认类目不允许删除 if (category.isDefault) { - return res.status(400).json({ - code: 400, - message: '默认类目不能删除' - }); + return response.badRequest(res, '默认类目不能删除'); } await category.update({ @@ -261,17 +208,10 @@ const deleteCategory = async (req, res) => { updateBy: userId }); - res.json({ - code: 200, - message: '删除成功' - }); + response.success(res, '删除成功'); } catch (error) { console.error('删除类目失败:', error); - res.status(500).json({ - code: 500, - message: '删除类目失败', - error: error.message - }); + response.serverError(res, '删除类目失败', error); } }; diff --git a/controllers/statisticsController.js b/controllers/statisticsController.js index 72fbd8e..03a9763 100644 --- a/controllers/statisticsController.js +++ b/controllers/statisticsController.js @@ -1,5 +1,6 @@ const { Room, Rental, Apartment, Bill } = require('../models'); const { Op } = require('sequelize'); +const response = require('../utils/response'); // 租金统计 const getRentStatistics = async (req, res) => { @@ -105,14 +106,10 @@ const getRentStatistics = async (req, res) => { })) .sort((a, b) => b.month.localeCompare(a.month)); - res.status(200).json({ - code: 200, - data: rentStatistics, - message: 'success' - }); + response.success(res, '获取成功', rentStatistics); } catch (error) { console.error('获取租金统计数据时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取租金统计数据失败', error); } }; @@ -156,13 +153,9 @@ const getRoomStatusStatistics = async (req, res) => { expired: expired }; - res.status(200).json({ - code: 200, - data: roomStatusStatistics, - message: 'success' - }); + response.success(res, '获取成功', roomStatusStatistics); } catch (error) { - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取房间状态统计失败', error); } }; @@ -223,14 +216,10 @@ const getDashboardStatistics = async (req, res) => { collectedWaterAmount: parseFloat(collectedWaterAmount) || 0 }; - res.status(200).json({ - code: 200, - data: dashboardStatistics, - message: 'success' - }); + response.success(res, '获取成功', dashboardStatistics); } catch (error) { console.error('获取Dashboard统计数据时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取Dashboard统计数据失败', error); } }; @@ -280,14 +269,10 @@ const getApartmentRoomStatusStatistics = async (req, res) => { }; }); - res.status(200).json({ - code: 200, - data: apartmentRoomStatusStatistics, - message: 'success' - }); + response.success(res, '获取成功', apartmentRoomStatusStatistics); } catch (error) { console.error('获取公寓房间状态分布数据时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取公寓房间状态分布数据失败', error); } }; @@ -323,14 +308,10 @@ const getEmptyRoomsByApartment = async (req, res) => { }; }); - res.status(200).json({ - code: 200, - data: emptyRoomsByApartment, - message: 'success' - }); + response.success(res, '获取成功', emptyRoomsByApartment); } catch (error) { console.error('获取空房分布数据时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取空房分布数据失败', error); } }; @@ -366,14 +347,10 @@ const getRentedRoomsByApartment = async (req, res) => { }; }); - res.status(200).json({ - code: 200, - data: rentedRoomsByApartment, - message: 'success' - }); + response.success(res, '获取成功', rentedRoomsByApartment); } catch (error) { console.error('获取在租分布数据时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取在租分布数据失败', error); } }; @@ -437,14 +414,10 @@ const getTenantRentalStats = async (req, res) => { // 转换为数组 const tenantRentalStats = Array.from(tenantMap.values()); - res.status(200).json({ - code: 200, - data: tenantRentalStats, - message: 'success' - }); + response.success(res, '获取成功', tenantRentalStats); } catch (error) { console.error('获取租客在租统计数据时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取租客在租统计数据失败', error); } }; @@ -481,14 +454,10 @@ const getSoonExpireRoomsByApartment = async (req, res) => { }; }); - res.status(200).json({ - code: 200, - data: soonExpireRoomsByApartment, - message: 'success' - }); + response.success(res, '获取成功', soonExpireRoomsByApartment); } catch (error) { console.error('获取即将到期分布数据时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取即将到期分布数据失败', error); } }; @@ -525,14 +494,10 @@ const getExpiredRoomsByApartment = async (req, res) => { }; }); - res.status(200).json({ - code: 200, - data: expiredRoomsByApartment, - message: 'success' - }); + response.success(res, '获取成功', expiredRoomsByApartment); } catch (error) { console.error('获取已到期分布数据时出错:', error); - res.status(500).json({ code: 500, error: error.message }); + response.serverError(res, '获取已到期分布数据失败', error); } }; @@ -546,4 +511,4 @@ module.exports = { getSoonExpireRoomsByApartment, getExpiredRoomsByApartment, getTenantRentalStats -}; \ No newline at end of file +}; diff --git a/controllers/userController.js b/controllers/userController.js index 1597766..8ac0366 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -4,6 +4,7 @@ const User = require('../models/User'); const Role = require('../models/Role'); const Tenant = require('../models/Tenant'); const { logOperation } = require('../utils/logger'); +const response = require('../utils/response'); // 获取用户列表 exports.getUserList = async (req, res) => { @@ -36,23 +37,15 @@ exports.getUserList = async (req, res) => { limit: parseInt(pageSize) }); - res.json({ - code: 200, - message: '获取成功', - data: { - list: rows, - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - } + response.success(res, '获取成功', { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) }); } catch (error) { console.error('获取用户列表错误:', error); - res.status(500).json({ - code: 500, - message: '获取用户列表失败', - error: error.message - }); + response.serverError(res, '获取用户列表失败', error); } }; @@ -72,17 +65,10 @@ exports.getUserById = async (req, res) => { }); if (!user) { - return res.status(404).json({ - code: 404, - message: '用户不存在' - }); + return response.notFound(res, '用户不存在'); } - res.json({ - code: 200, - message: '获取成功', - data: user - }); + response.success(res, '获取成功', user); // 记录操作日志 await logOperation({ @@ -98,11 +84,7 @@ exports.getUserById = async (req, res) => { }); } catch (error) { console.error('获取用户详情错误:', error); - res.status(500).json({ - code: 500, - message: '获取用户详情失败', - error: error.message - }); + response.serverError(res, '获取用户详情失败', error); } }; @@ -113,31 +95,19 @@ exports.createUser = async (req, res) => { // 参数验证 if (!username || !password) { - return res.status(400).json({ - code: 400, - message: '用户名和密码不能为空' - }); + return response.badRequest(res, '用户名和密码不能为空'); } if (username.length < 3 || username.length > 20) { - return res.status(400).json({ - code: 400, - message: '用户名长度应在3-20个字符之间' - }); + return response.badRequest(res, '用户名长度应在3-20个字符之间'); } if (password.length < 6 || password.length > 20) { - return res.status(400).json({ - code: 400, - message: '密码长度应在6-20个字符之间' - }); + return response.badRequest(res, '密码长度应在6-20个字符之间'); } if (!roleId) { - return res.status(400).json({ - code: 400, - message: '角色不能为空' - }); + return response.badRequest(res, '角色不能为空'); } // 检查租户资源使用情况(仅记录日志,不阻止创建) @@ -174,19 +144,13 @@ exports.createUser = async (req, res) => { where: { isDeleted: 0, status: 'active' } }); if (!role) { - return res.status(400).json({ - code: 400, - message: '角色不存在或已禁用' - }); + return response.badRequest(res, '角色不存在或已禁用'); } // 检查用户名是否已存在 const existingUser = await User.findOne({ where: { username, isDeleted: 0 } }); if (existingUser) { - return res.status(400).json({ - code: 400, - message: '用户名已存在' - }); + return response.badRequest(res, '用户名已存在'); } // 加密密码 @@ -203,16 +167,12 @@ exports.createUser = async (req, res) => { updateBy: req.user.id }); - res.json({ - code: 200, - message: '创建成功', - data: { - id: user.id, - username: user.username, - nickname: user.nickname, - roleId: user.roleId, - createTime: user.createTime - }, + response.success(res, '创建成功', { + id: user.id, + username: user.username, + nickname: user.nickname, + roleId: user.roleId, + createTime: user.createTime, warning: isOverage && tenant ? `当前已超出套餐限制(${tenant.maxUsers}人),续费时将收取超额费用` : null }); @@ -230,11 +190,7 @@ exports.createUser = async (req, res) => { }); } catch (error) { console.error('创建用户错误:', error); - res.status(500).json({ - code: 500, - message: '创建用户失败', - error: error.message - }); + response.serverError(res, '创建用户失败', error); } }; @@ -249,10 +205,7 @@ exports.updateUser = async (req, res) => { where: { isDeleted: 0 } }); if (!user) { - return res.status(404).json({ - code: 404, - message: '用户不存在' - }); + return response.notFound(res, '用户不存在'); } // 检查角色是否存在 @@ -261,10 +214,7 @@ exports.updateUser = async (req, res) => { where: { isDeleted: 0, status: 'active' } }); if (!role) { - return res.status(400).json({ - code: 400, - message: '角色不存在或已禁用' - }); + return response.badRequest(res, '角色不存在或已禁用'); } } @@ -279,17 +229,13 @@ exports.updateUser = async (req, res) => { // 更新用户 await user.update(updateData); - res.json({ - code: 200, - message: '更新成功', - data: { - id: user.id, - username: user.username, - nickname: user.nickname, - roleId: user.roleId, - status: user.status, - updateTime: user.updateTime - } + response.success(res, '更新成功', { + id: user.id, + username: user.username, + nickname: user.nickname, + roleId: user.roleId, + status: user.status, + updateTime: user.updateTime }); // 记录操作日志 @@ -306,11 +252,7 @@ exports.updateUser = async (req, res) => { }); } catch (error) { console.error('更新用户错误:', error); - res.status(500).json({ - code: 500, - message: '更新用户失败', - error: error.message - }); + response.serverError(res, '更新用户失败', error); } }; @@ -321,10 +263,7 @@ exports.deleteUser = async (req, res) => { // 不能删除自己 if (parseInt(id) === req.user.id) { - return res.status(400).json({ - code: 400, - message: '不能删除自己的账号' - }); + return response.badRequest(res, '不能删除自己的账号'); } // 查找用户 @@ -332,10 +271,7 @@ exports.deleteUser = async (req, res) => { where: { isDeleted: 0 } }); if (!user) { - return res.status(404).json({ - code: 404, - message: '用户不存在' - }); + return response.notFound(res, '用户不存在'); } // 软删除 @@ -344,10 +280,7 @@ exports.deleteUser = async (req, res) => { updateBy: req.user.id }); - res.json({ - code: 200, - message: '删除成功' - }); + response.success(res, '删除成功'); // 记录操作日志 await logOperation({ @@ -363,11 +296,7 @@ exports.deleteUser = async (req, res) => { }); } catch (error) { console.error('删除用户错误:', error); - res.status(500).json({ - code: 500, - message: '删除用户失败', - error: error.message - }); + response.serverError(res, '删除用户失败', error); } }; @@ -382,10 +311,7 @@ exports.resetUserPassword = async (req, res) => { where: { isDeleted: 0 } }); if (!user) { - return res.status(404).json({ - code: 404, - message: '用户不存在' - }); + return response.notFound(res, '用户不存在'); } // 加密默认密码 @@ -397,12 +323,8 @@ exports.resetUserPassword = async (req, res) => { updateBy: req.user.id }); - res.json({ - code: 200, - message: '密码重置成功', - data: { - defaultPassword - } + response.success(res, '密码重置成功', { + defaultPassword }); // 记录操作日志 @@ -419,11 +341,7 @@ exports.resetUserPassword = async (req, res) => { }); } catch (error) { console.error('重置密码错误:', error); - res.status(500).json({ - code: 500, - message: '重置密码失败', - error: error.message - }); + response.serverError(res, '重置密码失败', error); } }; @@ -435,19 +353,10 @@ exports.getAllUsers = async (req, res) => { attributes: ['id', 'username', 'nickname'] }); - res.json({ - code: 200, - message: '获取用户列表成功', - data: users - }); - + response.success(res, '获取用户列表成功', users); } catch (error) { console.error('获取用户列表错误:', error); - res.status(500).json({ - code: 500, - message: '获取用户列表失败', - error: error.message - }); + response.serverError(res, '获取用户列表失败', error); } }; @@ -464,24 +373,13 @@ exports.getCurrentUserInfo = async (req, res) => { }); if (!user) { - return res.status(404).json({ - code: 404, - message: '用户不存在' - }); + return response.notFound(res, '用户不存在'); } - res.json({ - code: 200, - message: '获取用户信息成功', - data: user - }); + response.success(res, '获取用户信息成功', user); } catch (error) { console.error('获取用户信息失败:', error); - res.status(500).json({ - code: 500, - message: '获取用户信息失败', - error: error.message - }); + response.serverError(res, '获取用户信息失败', error); } }; @@ -492,19 +390,13 @@ exports.updateUserProfile = async (req, res) => { // 验证昵称 if (!nickname || nickname.trim().length === 0) { - return res.status(400).json({ - code: 400, - message: '昵称不能为空' - }); + return response.badRequest(res, '昵称不能为空'); } // 更新用户信息 const user = await User.findByPk(req.user.id); if (!user) { - return res.status(404).json({ - code: 404, - message: '用户不存在' - }); + return response.notFound(res, '用户不存在'); } await user.update({ @@ -525,25 +417,17 @@ exports.updateUserProfile = async (req, res) => { status: 'success' }); - res.json({ - code: 200, - message: '个人资料更新成功', - data: { - id: user.id, - username: user.username, - nickname: user.nickname, - status: user.status, - createTime: user.createTime, - updateTime: user.updateTime - } + response.success(res, '个人资料更新成功', { + id: user.id, + username: user.username, + nickname: user.nickname, + status: user.status, + createTime: user.createTime, + updateTime: user.updateTime }); } catch (error) { console.error('更新个人资料失败:', error); - res.status(500).json({ - code: 500, - message: '更新个人资料失败', - error: error.message - }); + response.serverError(res, '更新个人资料失败', error); } }; @@ -554,34 +438,22 @@ exports.changePassword = async (req, res) => { // 验证参数 if (!oldPassword || !newPassword) { - return res.status(400).json({ - code: 400, - message: '旧密码和新密码不能为空' - }); + return response.badRequest(res, '旧密码和新密码不能为空'); } if (newPassword.length < 6) { - return res.status(400).json({ - code: 400, - message: '新密码长度至少6位' - }); + return response.badRequest(res, '新密码长度至少6位'); } // 验证旧密码 const user = await User.findByPk(req.user.id); if (!user) { - return res.status(404).json({ - code: 404, - message: '用户不存在' - }); + return response.notFound(res, '用户不存在'); } const isPasswordValid = await bcrypt.compare(oldPassword, user.password); if (!isPasswordValid) { - return res.status(400).json({ - code: 400, - message: '旧密码错误' - }); + return response.badRequest(res, '旧密码错误'); } // 更新密码 @@ -604,16 +476,9 @@ exports.changePassword = async (req, res) => { status: 'success' }); - res.json({ - code: 200, - message: '密码修改成功' - }); + response.success(res, '密码修改成功'); } catch (error) { console.error('修改密码失败:', error); - res.status(500).json({ - code: 500, - message: '修改密码失败', - error: error.message - }); + response.serverError(res, '修改密码失败', error); } }; diff --git a/controllers/waterBillController.js b/controllers/waterBillController.js deleted file mode 100644 index 100fb76..0000000 --- a/controllers/waterBillController.js +++ /dev/null @@ -1,283 +0,0 @@ -const { WaterBill, Room } = require('../models'); -const { Op } = require('sequelize'); - -// 格式化时间(考虑时区,转换为北京时间) -const formatDate = (date) => { - if (!date) return null; - // 确保date是Date对象 - const dateObj = date instanceof Date ? date : new Date(date); - // 创建一个新的Date对象,加上8小时的时区偏移 - const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000); - return beijingDate.toISOString().split('T')[0]; -}; - -// 格式化水费数据 -const formatWaterBillData = (bill) => { - const formattedBill = { - ...bill.toJSON(), - startDate: formatDate(bill.startDate), - endDate: formatDate(bill.endDate), - createTime: formatDate(bill.createTime), - updateTime: formatDate(bill.updateTime) - }; - - // 格式化关联数据 - if (formattedBill.Room) { - formattedBill.Room = { - ...formattedBill.Room, - createTime: formatDate(formattedBill.Room.createTime), - updateTime: formatDate(formattedBill.Room.updateTime) - }; - } - - return formattedBill; -}; - -// 获取所有水费记录(支持搜索和分页) -const getAllWaterBills = async (req, res) => { - try { - const { - apartmentId, - roomId, - status, - startDateFrom, - endDateTo, - page = 1, - pageSize = 10 - } = req.query; - - const where = { isDeleted: 0 }; - if (roomId) { - where.roomId = roomId; - } - if (status) { - where.status = status; - } - if (startDateFrom && endDateTo) { - where.startDate = { [Op.gte]: new Date(startDateFrom) }; - where.endDate = { [Op.lte]: new Date(endDateTo) }; - } - - const include = [ - { - model: Room, - where: { - isDeleted: 0, - ...(apartmentId ? { apartmentId } : {}) - } - } - ]; - - const offset = (page - 1) * pageSize; - - const { count, rows } = await WaterBill.findAndCountAll({ - where, - include, - limit: parseInt(pageSize), - offset: parseInt(offset), - order: [['createTime', 'DESC']] - }); - - const formattedBills = rows.map(formatWaterBillData); - - res.status(200).json({ - data: formattedBills, - total: count, - page: parseInt(page), - pageSize: parseInt(pageSize) - }); - } catch (error) { - res.status(500).json({ error: error.message }); - } -}; - -// 获取单个水费记录 -const getWaterBillById = async (req, res) => { - try { - const { id } = req.params; - const bill = await WaterBill.findOne({ - where: { id, isDeleted: 0 }, - include: [ - { - model: Room, - where: { isDeleted: 0 } - } - ] - }); - if (!bill) { - return res.status(404).json({ error: '水费记录不存在' }); - } - const formattedBill = formatWaterBillData(bill); - res.status(200).json({ - code: 200, - data: formattedBill, - message: 'success' - }); - } catch (error) { - res.status(500).json({ code: 500, error: error.message }); - } -}; - -// 创建水费记录 -const createWaterBill = async (req, res) => { - try { - const { roomId, startDate, endDate, startReading, endReading, unitPrice, status } = req.body; - - let usage = null; - let amount = null; - - if (startReading && endReading && unitPrice) { - usage = parseFloat(endReading) - parseFloat(startReading); - amount = usage * parseFloat(unitPrice); - } - - const bill = await WaterBill.create({ - roomId, - startDate, - endDate, - startReading, - endReading, - usage, - unitPrice, - amount, - status: status || 'unpaid', - createBy: req.user.id, - updateBy: req.user.id - }); - - const formattedBill = formatWaterBillData(bill); - res.status(201).json({ - code: 201, - data: formattedBill, - message: '创建成功' - }); - } catch (error) { - res.status(500).json({ code: 500, error: error.message }); - } -}; - -// 更新水费记录 -const updateWaterBill = async (req, res) => { - try { - const { id } = req.params; - const { startDate, endDate, startReading, endReading, unitPrice, status } = req.body; - - const bill = await WaterBill.findOne({ - where: { id, isDeleted: 0 } - }); - if (!bill) { - return res.status(404).json({ error: '水费记录不存在' }); - } - - let usage = bill.usage; - let amount = bill.amount; - if (startReading && endReading && unitPrice) { - usage = parseFloat(endReading) - parseFloat(startReading); - amount = usage * parseFloat(unitPrice); - } - - await bill.update({ - startDate, - endDate, - startReading, - endReading, - usage, - unitPrice, - amount, - status: status !== undefined ? status : bill.status, - updateBy: req.user.id - }); - - const formattedBill = formatWaterBillData(bill); - res.status(200).json({ - code: 200, - data: formattedBill, - message: '更新成功' - }); - } catch (error) { - res.status(500).json({ code: 500, error: error.message }); - } -}; - -// 删除水费记录(软删除) -const deleteWaterBill = async (req, res) => { - try { - const { id } = req.params; - const bill = await WaterBill.findOne({ - where: { id, isDeleted: 0 } - }); - if (!bill) { - return res.status(404).json({ error: '水费记录不存在' }); - } - await bill.update({ - isDeleted: 1, - updateBy: req.user.id - }); - res.status(200).json({ - code: 200, - message: '水费记录删除成功' - }); - } catch (error) { - res.status(500).json({ code: 500, error: error.message }); - } -}; - -// 获取所有水费记录(不分页) -const listWaterBills = async (req, res) => { - try { - const { - apartmentId, - roomId, - status, - startDateFrom, - endDateTo - } = req.query; - - const where = { isDeleted: 0 }; - if (roomId) { - where.roomId = roomId; - } - if (status) { - where.status = status; - } - if (startDateFrom && endDateTo) { - where.startDate = { [Op.gte]: new Date(startDateFrom) }; - where.endDate = { [Op.lte]: new Date(endDateTo) }; - } - - const include = [ - { - model: Room, - where: { - isDeleted: 0, - ...(apartmentId ? { apartmentId } : {}) - } - } - ]; - - const bills = await WaterBill.findAll({ - where, - include, - order: [['createTime', 'DESC']] - }); - - const formattedBills = bills.map(formatWaterBillData); - - res.status(200).json({ - code: 200, - data: formattedBills, - message: 'success' - }); - } catch (error) { - res.status(500).json({ code: 500, error: error.message }); - } -}; - -module.exports = { - getAllWaterBills, - listWaterBills, - getWaterBillById, - createWaterBill, - updateWaterBill, - deleteWaterBill -}; \ No newline at end of file diff --git a/init_base_data.sql b/init_base_data.sql index 46a61c3..6d4a275 100644 --- a/init_base_data.sql +++ b/init_base_data.sql @@ -134,14 +134,6 @@ INSERT IGNORE INTO `menus` (`id`, `parentId`, `name`, `code`, `type`, `path`, `c INSERT IGNORE INTO `menus` (`id`, `name`, `code`, `type`, `path`, `component`, `icon`, `sort`, `visible`, `status`, `isBasic`, `isDeleted`, `createTime`, `updateTime`) VALUES (13, '计费中心', 'billing_center', 'menu', '/billing/center', 'views/billing/BillingCenter', 'el-icon-wallet', 6, 'show', 'active', 1, 0, NOW(), NOW()); --- 7. 数据统计(父菜单) -INSERT IGNORE INTO `menus` (`id`, `name`, `code`, `type`, `path`, `component`, `icon`, `sort`, `visible`, `status`, `isBasic`, `isDeleted`, `createTime`, `updateTime`) VALUES -(14, '数据统计', 'statistics', 'menu', '/statistics', NULL, 'el-icon-s-data', 7, 'show', 'active', 1, 0, NOW(), NOW()); - --- 7.1 收支统计 -INSERT IGNORE INTO `menus` (`id`, `parentId`, `name`, `code`, `type`, `path`, `component`, `icon`, `sort`, `visible`, `status`, `isBasic`, `isDeleted`, `createTime`, `updateTime`) VALUES -(15, 14, '收支统计', 'finance_stats', 'menu', '/statistics/finance', 'views/statistics/Finance', 'el-icon-s-data', 1, 'show', 'active', 1, 0, NOW(), NOW()); - -- 8. 系统设置(父菜单) INSERT IGNORE INTO `menus` (`id`, `name`, `code`, `type`, `path`, `component`, `icon`, `sort`, `visible`, `status`, `isBasic`, `isDeleted`, `createTime`, `updateTime`) VALUES (17, '系统设置', 'settings', 'menu', '/settings', NULL, 'el-icon-setting', 8, 'show', 'active', 1, 0, NOW(), NOW()); diff --git a/routes/electricityBill.js b/routes/electricityBill.js deleted file mode 100644 index fc3f69c..0000000 --- a/routes/electricityBill.js +++ /dev/null @@ -1,20 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const electricityBillController = require('../controllers/electricityBillController'); - -// 获取所有电费记录 -router.get('/', electricityBillController.getAllElectricityBills); - -// 获取单个电费记录 -router.get('/:id', electricityBillController.getElectricityBillById); - -// 创建电费记录 -router.post('/', electricityBillController.createElectricityBill); - -// 更新电费记录 -router.put('/:id', electricityBillController.updateElectricityBill); - -// 删除电费记录 -router.delete('/:id', electricityBillController.deleteElectricityBill); - -module.exports = router; \ No newline at end of file diff --git a/routes/waterBill.js b/routes/waterBill.js deleted file mode 100644 index da87a53..0000000 --- a/routes/waterBill.js +++ /dev/null @@ -1,23 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const waterBillController = require('../controllers/waterBillController'); - -// 获取所有水费记录(分页) -router.get('/', waterBillController.getAllWaterBills); - -// 获取所有水费记录(不分页) -router.get('/list', waterBillController.listWaterBills); - -// 获取单个水费记录 -router.get('/:id', waterBillController.getWaterBillById); - -// 创建水费记录 -router.post('/', waterBillController.createWaterBill); - -// 更新水费记录 -router.put('/:id', waterBillController.updateWaterBill); - -// 删除水费记录 -router.delete('/:id', waterBillController.deleteWaterBill); - -module.exports = router; \ No newline at end of file diff --git a/utils/response.js b/utils/response.js new file mode 100644 index 0000000..ea0ff6f --- /dev/null +++ b/utils/response.js @@ -0,0 +1,114 @@ +/** + * 统一响应工具函数 + * 规范所有接口的返回数据格式 + */ + +/** + * 成功响应 + * @param {object} res - Express响应对象 + * @param {string} message - 成功消息 + * @param {any} data - 响应数据 + * @param {number} statusCode - HTTP状态码,默认200 + */ +const success = (res, message = '操作成功', data = null, statusCode = 200) => { + res.status(statusCode).json({ + code: 200, + message, + data + }); +}; + +/** + * 错误响应 + * @param {object} res - Express响应对象 + * @param {string} message - 错误消息 + * @param {number} code - 错误码,默认500 + * @param {number} statusCode - HTTP状态码,默认对应code + */ +const error = (res, message = '操作失败', code = 500, statusCode = null) => { + const httpStatus = statusCode || code; + res.status(httpStatus).json({ + code, + message, + data: null + }); +}; + +/** + * 参数错误响应 (400) + * @param {object} res - Express响应对象 + * @param {string} message - 错误消息 + */ +const badRequest = (res, message = '请求参数错误') => { + error(res, message, 400); +}; + +/** + * 未授权响应 (401) + * @param {object} res - Express响应对象 + * @param {string} message - 错误消息 + */ +const unauthorized = (res, message = '未授权,请先登录') => { + error(res, message, 401); +}; + +/** + * 禁止访问响应 (403) + * @param {object} res - Express响应对象 + * @param {string} message - 错误消息 + */ +const forbidden = (res, message = '没有权限执行此操作') => { + error(res, message, 403); +}; + +/** + * 资源不存在响应 (404) + * @param {object} res - Express响应对象 + * @param {string} message - 错误消息 + */ +const notFound = (res, message = '资源不存在') => { + error(res, message, 404); +}; + +/** + * 服务器错误响应 (500) + * @param {object} res - Express响应对象 + * @param {string} message - 错误消息 + * @param {Error} err - 错误对象(仅在开发环境返回) + */ +const serverError = (res, message = '服务器内部错误', err = null) => { + const response = { + code: 500, + message, + data: null + }; + + // 开发环境下返回错误详情 + if (process.env.NODE_ENV === 'development' && err) { + response.error = err.message; + response.stack = err.stack; + } + + res.status(500).json(response); +}; + +/** + * 创建成功响应 (201) + * @param {object} res - Express响应对象 + * @param {string} message - 成功消息 + * @param {any} data - 响应数据 + */ +const created = (res, message = '创建成功', data = null) => { + success(res, message, data, 201); +}; + +module.exports = { + success, + error, + badRequest, + unauthorized, + forbidden, + notFound, + serverError, + created +};