水费修改

This commit is contained in:
wangxiaoxian 2026-03-07 15:23:18 +08:00
parent 2e8bddab4e
commit b7a7549aa0
6 changed files with 85 additions and 86 deletions

View File

@ -2,10 +2,16 @@ const { Sequelize } = require('sequelize');
const mysql = require('mysql2/promise'); const mysql = require('mysql2/promise');
// 环境配置 // 环境配置
const NODE_ENV = 'production'; const NODE_ENV = process.env.NODE_ENV || 'local';
// 数据库配置 // 数据库配置
const dbConfig = { const dbConfig = {
local: {
host: 'localhost',
user: 'root',
password: 'root',
database: 'rentease'
},
development: { development: {
host: 'localhost', host: 'localhost',
user: 'root', user: 'root',

View File

@ -29,7 +29,7 @@ const checkAndUpdateRentalStatus = async () => {
const currentDate = new Date(); const currentDate = new Date();
// 计算10天后的日期 // 计算10天后的日期
const tenDaysLater = new Date(); const tenDaysLater = new Date();
tenDaysLater.setDate(currentDate.getDate() + 30); tenDaysLater.setDate(currentDate.getDate() + 7);
// 查找所有活跃的租房记录 // 查找所有活跃的租房记录
const rentals = await Rental.findAll({ const rentals = await Rental.findAll({
@ -80,17 +80,17 @@ const getAllRentals = async (req, res) => {
// 先检查并更新租房状态 // 先检查并更新租房状态
await checkAndUpdateRentalStatus(); await checkAndUpdateRentalStatus();
const { const {
apartmentId, apartmentId,
roomId, roomId,
tenantName, tenantName,
status, status,
startDateFrom, startDateFrom,
startDateTo, startDateTo,
endDateFrom, endDateFrom,
endDateTo, endDateTo,
page = 1, page = 1,
pageSize = 10 pageSize = 10
} = req.query; } = req.query;
// 构建查询条件 // 构建查询条件
@ -115,7 +115,7 @@ const getAllRentals = async (req, res) => {
const include = [ const include = [
{ {
model: Room, model: Room,
where: { where: {
isDeleted: 0, isDeleted: 0,
...(apartmentId ? { apartmentId } : {}) ...(apartmentId ? { apartmentId } : {})
}, },
@ -311,15 +311,15 @@ const listRentals = async (req, res) => {
// 先检查并更新租房状态 // 先检查并更新租房状态
await checkAndUpdateRentalStatus(); await checkAndUpdateRentalStatus();
const { const {
apartmentId, apartmentId,
roomId, roomId,
tenantName, tenantName,
status, status,
startDateFrom, startDateFrom,
startDateTo, startDateTo,
endDateFrom, endDateFrom,
endDateTo endDateTo
} = req.query; } = req.query;
// 构建查询条件 // 构建查询条件
@ -344,7 +344,7 @@ const listRentals = async (req, res) => {
const include = [ const include = [
{ {
model: Room, model: Room,
where: { where: {
isDeleted: 0, isDeleted: 0,
...(apartmentId ? { apartmentId } : {}) ...(apartmentId ? { apartmentId } : {})
}, },

View File

@ -16,7 +16,7 @@ const formatRoomData = (room) => {
createTime: formatDate(room.createTime), createTime: formatDate(room.createTime),
updateTime: formatDate(room.updateTime) updateTime: formatDate(room.updateTime)
}; };
// 格式化关联数据 // 格式化关联数据
if (formattedRoom.Apartment) { if (formattedRoom.Apartment) {
formattedRoom.Apartment = { formattedRoom.Apartment = {
@ -25,7 +25,7 @@ const formatRoomData = (room) => {
updateTime: formatDate(formattedRoom.Apartment.updateTime) updateTime: formatDate(formattedRoom.Apartment.updateTime)
}; };
} }
// 格式化租房信息 // 格式化租房信息
if (formattedRoom.Rentals && formattedRoom.Rentals.length > 0) { if (formattedRoom.Rentals && formattedRoom.Rentals.length > 0) {
formattedRoom.Rentals = formattedRoom.Rentals.map(rental => { formattedRoom.Rentals = formattedRoom.Rentals.map(rental => {
@ -36,11 +36,11 @@ const formatRoomData = (room) => {
createTime: formatDate(rental.createTime), createTime: formatDate(rental.createTime),
updateTime: formatDate(rental.updateTime) updateTime: formatDate(rental.updateTime)
}; };
return formattedRental; return formattedRental;
}); });
} }
return formattedRoom; return formattedRoom;
}; };
@ -51,17 +51,17 @@ const checkAndUpdateRentalStatus = async () => {
const currentDate = new Date(); const currentDate = new Date();
// 计算10天后的日期 // 计算10天后的日期
const tenDaysLater = new Date(); const tenDaysLater = new Date();
tenDaysLater.setDate(currentDate.getDate() + 30); tenDaysLater.setDate(currentDate.getDate() + 7);
// 查找所有在租的租房记录 // 查找所有在租的租房记录
const rentals = await Rental.findAll({ const rentals = await Rental.findAll({
where: { status: 'active', isDeleted: 0 } where: { status: 'active', isDeleted: 0 }
}); });
// 检查每个租房记录的状态 // 检查每个租房记录的状态
for (const rental of rentals) { for (const rental of rentals) {
const endDate = new Date(rental.endDate); const endDate = new Date(rental.endDate);
// 检查是否已到期 // 检查是否已到期
if (endDate < currentDate) { if (endDate < currentDate) {
// 更新房间附属状态为已到期 // 更新房间附属状态为已到期
@ -83,7 +83,7 @@ const checkAndUpdateRentalStatus = async () => {
} }
} }
} }
console.log('租房状态检查和更新完成'); console.log('租房状态检查和更新完成');
} catch (error) { } catch (error) {
console.error('检查和更新租房状态时出错:', error); console.error('检查和更新租房状态时出错:', error);
@ -95,9 +95,9 @@ const getAllRooms = async (req, res) => {
try { try {
// 先检查并更新租房状态 // 先检查并更新租房状态
await checkAndUpdateRentalStatus(); await checkAndUpdateRentalStatus();
const { apartmentId, roomNumber, status, otherStatus, subStatus, page = 1, pageSize = 10 } = req.query; const { apartmentId, roomNumber, status, otherStatus, subStatus, page = 1, pageSize = 10 } = req.query;
// 构建查询条件 // 构建查询条件
const where = { isDeleted: 0 }; const where = { isDeleted: 0 };
if (apartmentId) { if (apartmentId) {
@ -117,10 +117,10 @@ const getAllRooms = async (req, res) => {
if (subStatus) { if (subStatus) {
where.subStatus = subStatus; where.subStatus = subStatus;
} }
// 计算偏移量 // 计算偏移量
const offset = (page - 1) * pageSize; const offset = (page - 1) * pageSize;
// 查询房间数据 // 查询房间数据
const { count, rows } = await Room.findAndCountAll({ const { count, rows } = await Room.findAndCountAll({
where, where,
@ -130,11 +130,11 @@ const getAllRooms = async (req, res) => {
limit: parseInt(pageSize), limit: parseInt(pageSize),
offset: parseInt(offset) offset: parseInt(offset)
}); });
// 为每个房间获取非过期的租房信息 // 为每个房间获取非过期的租房信息
const formattedRooms = await Promise.all(rows.map(async (room) => { const formattedRooms = await Promise.all(rows.map(async (room) => {
const formattedRoom = formatRoomData(room); const formattedRoom = formatRoomData(room);
// 查询非过期的租房信息 // 查询非过期的租房信息
const rentals = await Rental.findAll({ const rentals = await Rental.findAll({
where: { where: {
@ -142,7 +142,7 @@ const getAllRooms = async (req, res) => {
status: { [Op.ne]: 'expired' } status: { [Op.ne]: 'expired' }
} }
}); });
// 格式化租房信息 // 格式化租房信息
if (rentals.length > 0) { if (rentals.length > 0) {
formattedRoom.Rentals = rentals.map(rental => { formattedRoom.Rentals = rentals.map(rental => {
@ -152,18 +152,18 @@ const getAllRooms = async (req, res) => {
endDate: formatDate(rental.endDate), endDate: formatDate(rental.endDate),
createTime: formatDate(rental.createTime) createTime: formatDate(rental.createTime)
}; };
return formattedRental; return formattedRental;
}); });
} else { } else {
formattedRoom.Rentals = []; formattedRoom.Rentals = [];
} }
return formattedRoom; return formattedRoom;
})); }));
// 返回结果 // 返回结果
res.status(200).json({ res.status(200).json({
data: formattedRooms, data: formattedRooms,
@ -181,7 +181,7 @@ const getRoomById = async (req, res) => {
try { try {
// 先检查并更新租房状态 // 先检查并更新租房状态
await checkAndUpdateRentalStatus(); await checkAndUpdateRentalStatus();
const { id } = req.params; const { id } = req.params;
const room = await Room.findOne({ const room = await Room.findOne({
where: { id, isDeleted: 0 }, where: { id, isDeleted: 0 },
@ -190,10 +190,10 @@ const getRoomById = async (req, res) => {
if (!room) { if (!room) {
return res.status(404).json({ error: '房间不存在' }); return res.status(404).json({ error: '房间不存在' });
} }
// 格式化房间数据 // 格式化房间数据
const formattedRoom = formatRoomData(room); const formattedRoom = formatRoomData(room);
// 查询非过期的租房信息 // 查询非过期的租房信息
const rentals = await Rental.findAll({ const rentals = await Rental.findAll({
where: { where: {
@ -201,7 +201,7 @@ const getRoomById = async (req, res) => {
status: { [Op.ne]: 'expired' } status: { [Op.ne]: 'expired' }
} }
}); });
// 格式化租房信息 // 格式化租房信息
if (rentals.length > 0) { if (rentals.length > 0) {
formattedRoom.Rentals = rentals.map(rental => { formattedRoom.Rentals = rentals.map(rental => {
@ -211,7 +211,7 @@ const getRoomById = async (req, res) => {
endDate: formatDate(rental.endDate), endDate: formatDate(rental.endDate),
createTime: formatDate(rental.createTime) createTime: formatDate(rental.createTime)
}; };
return formattedRental; return formattedRental;
}); });
} else { } else {
@ -296,9 +296,9 @@ const listRooms = async (req, res) => {
try { try {
// 先检查并更新租房状态 // 先检查并更新租房状态
await checkAndUpdateRentalStatus(); await checkAndUpdateRentalStatus();
const { apartmentId, roomNumber, status, otherStatus, subStatus } = req.query; const { apartmentId, roomNumber, status, otherStatus, subStatus } = req.query;
// 构建查询条件 // 构建查询条件
const where = { isDeleted: 0 }; const where = { isDeleted: 0 };
if (apartmentId) { if (apartmentId) {
@ -318,7 +318,7 @@ const listRooms = async (req, res) => {
if (subStatus) { if (subStatus) {
where.subStatus = subStatus; where.subStatus = subStatus;
} }
// 查询房间数据 // 查询房间数据
const rooms = await Room.findAll({ const rooms = await Room.findAll({
where, where,
@ -326,10 +326,10 @@ const listRooms = async (req, res) => {
Apartment Apartment
] ]
}); });
// 格式化房间数据 // 格式化房间数据
const formattedRooms = rooms.map(formatRoomData); const formattedRooms = rooms.map(formatRoomData);
// 返回结果 // 返回结果
res.status(200).json(formattedRooms); res.status(200).json(formattedRooms);
} catch (error) { } catch (error) {
@ -344,4 +344,4 @@ module.exports = {
createRoom, createRoom,
updateRoom, updateRoom,
deleteRoom deleteRoom
}; };

View File

@ -44,7 +44,6 @@ const getAllWaterBills = async (req, res) => {
pageSize = 10 pageSize = 10
} = req.query; } = req.query;
// 构建查询条件
const where = { isDeleted: 0 }; const where = { isDeleted: 0 };
if (roomId) { if (roomId) {
where.roomId = roomId; where.roomId = roomId;
@ -57,7 +56,6 @@ const getAllWaterBills = async (req, res) => {
where.endDate = { [Op.lte]: new Date(endDateTo) }; where.endDate = { [Op.lte]: new Date(endDateTo) };
} }
// 构建包含关系
const include = [ const include = [
{ {
model: Room, model: Room,
@ -68,22 +66,18 @@ const getAllWaterBills = async (req, res) => {
} }
]; ];
// 计算偏移量
const offset = (page - 1) * pageSize; const offset = (page - 1) * pageSize;
// 查询水费数据
const { count, rows } = await WaterBill.findAndCountAll({ const { count, rows } = await WaterBill.findAndCountAll({
where, where,
include, include,
limit: parseInt(pageSize), limit: parseInt(pageSize),
offset: parseInt(offset), offset: parseInt(offset),
order: [['createTime', 'DESC']] // 按创建时间倒序排序 order: [['createTime', 'DESC']]
}); });
// 格式化数据
const formattedBills = rows.map(formatWaterBillData); const formattedBills = rows.map(formatWaterBillData);
// 返回结果
res.status(200).json({ res.status(200).json({
data: formattedBills, data: formattedBills,
total: count, total: count,
@ -121,11 +115,15 @@ const getWaterBillById = async (req, res) => {
// 创建水费记录 // 创建水费记录
const createWaterBill = async (req, res) => { const createWaterBill = async (req, res) => {
try { try {
const { roomId, startDate, endDate, startReading, endReading, unitPrice } = req.body; const { roomId, startDate, endDate, startReading, endReading, unitPrice, status } = req.body;
// 计算用水量和费用 let usage = null;
const usage = parseFloat(endReading) - parseFloat(startReading); let amount = null;
const amount = usage * parseFloat(unitPrice);
if (startReading && endReading && unitPrice) {
usage = parseFloat(endReading) - parseFloat(startReading);
amount = usage * parseFloat(unitPrice);
}
const bill = await WaterBill.create({ const bill = await WaterBill.create({
roomId, roomId,
@ -135,7 +133,8 @@ const createWaterBill = async (req, res) => {
endReading, endReading,
usage, usage,
unitPrice, unitPrice,
amount amount,
status: status || 'unpaid'
}); });
const formattedBill = formatWaterBillData(bill); const formattedBill = formatWaterBillData(bill);
@ -158,7 +157,6 @@ const updateWaterBill = async (req, res) => {
return res.status(404).json({ error: '水费记录不存在' }); return res.status(404).json({ error: '水费记录不存在' });
} }
// 计算用水量和费用
let usage = bill.usage; let usage = bill.usage;
let amount = bill.amount; let amount = bill.amount;
if (startReading && endReading && unitPrice) { if (startReading && endReading && unitPrice) {
@ -174,7 +172,7 @@ const updateWaterBill = async (req, res) => {
usage, usage,
unitPrice, unitPrice,
amount, amount,
status status: status !== undefined ? status : bill.status
}); });
const formattedBill = formatWaterBillData(bill); const formattedBill = formatWaterBillData(bill);
@ -212,7 +210,6 @@ const listWaterBills = async (req, res) => {
endDateTo endDateTo
} = req.query; } = req.query;
// 构建查询条件
const where = { isDeleted: 0 }; const where = { isDeleted: 0 };
if (roomId) { if (roomId) {
where.roomId = roomId; where.roomId = roomId;
@ -225,7 +222,6 @@ const listWaterBills = async (req, res) => {
where.endDate = { [Op.lte]: new Date(endDateTo) }; where.endDate = { [Op.lte]: new Date(endDateTo) };
} }
// 构建包含关系
const include = [ const include = [
{ {
model: Room, model: Room,
@ -236,17 +232,14 @@ const listWaterBills = async (req, res) => {
} }
]; ];
// 查询水费数据
const bills = await WaterBill.findAll({ const bills = await WaterBill.findAll({
where, where,
include, include,
order: [['createTime', 'DESC']] // 按创建时间倒序排序 order: [['createTime', 'DESC']]
}); });
// 格式化数据
const formattedBills = bills.map(formatWaterBillData); const formattedBills = bills.map(formatWaterBillData);
// 返回结果
res.status(200).json(formattedBills); res.status(200).json(formattedBills);
} catch (error) { } catch (error) {
res.status(500).json({ error: error.message }); res.status(500).json({ error: error.message });

View File

@ -25,7 +25,7 @@ const WaterBill = sequelize.define('WaterBill', {
}, },
endDate: { endDate: {
type: DataTypes.DATE, type: DataTypes.DATE,
allowNull: false, allowNull: true,
comment: '结束日期' comment: '结束日期'
}, },
startReading: { startReading: {
@ -35,12 +35,12 @@ const WaterBill = sequelize.define('WaterBill', {
}, },
endReading: { endReading: {
type: DataTypes.DECIMAL(10, 2), type: DataTypes.DECIMAL(10, 2),
allowNull: false, allowNull: true,
comment: '结束读数' comment: '结束读数'
}, },
usage: { usage: {
type: DataTypes.DECIMAL(10, 2), type: DataTypes.DECIMAL(10, 2),
allowNull: false, allowNull: true,
comment: '用水量' comment: '用水量'
}, },
unitPrice: { unitPrice: {
@ -50,14 +50,14 @@ const WaterBill = sequelize.define('WaterBill', {
}, },
amount: { amount: {
type: DataTypes.DECIMAL(10, 2), type: DataTypes.DECIMAL(10, 2),
allowNull: false, allowNull: true,
comment: '金额' comment: '金额'
}, },
status: { status: {
type: DataTypes.ENUM('unpaid', 'paid'), type: DataTypes.ENUM('unbilled', 'unpaid', 'paid'),
allowNull: false, allowNull: false,
defaultValue: 'unpaid', defaultValue: 'unpaid',
comment: '状态unpaid未支付paid已支付' comment: '状态unbilled未出账unpaid未支付paid已支付'
}, },
createTime: { createTime: {
type: DataTypes.DATE, type: DataTypes.DATE,

View File

@ -22,7 +22,7 @@ const WaterBill = sequelize.define('WaterBill', {
}, },
endDate: { endDate: {
type: DataTypes.DATE, type: DataTypes.DATE,
allowNull: false allowNull: true
}, },
startReading: { startReading: {
type: DataTypes.DECIMAL(10, 2), type: DataTypes.DECIMAL(10, 2),
@ -30,11 +30,11 @@ const WaterBill = sequelize.define('WaterBill', {
}, },
endReading: { endReading: {
type: DataTypes.DECIMAL(10, 2), type: DataTypes.DECIMAL(10, 2),
allowNull: false allowNull: true
}, },
usage: { usage: {
type: DataTypes.DECIMAL(10, 2), type: DataTypes.DECIMAL(10, 2),
allowNull: false allowNull: true
}, },
unitPrice: { unitPrice: {
type: DataTypes.DECIMAL(10, 2), type: DataTypes.DECIMAL(10, 2),
@ -42,10 +42,10 @@ const WaterBill = sequelize.define('WaterBill', {
}, },
amount: { amount: {
type: DataTypes.DECIMAL(10, 2), type: DataTypes.DECIMAL(10, 2),
allowNull: false allowNull: true
}, },
status: { status: {
type: DataTypes.ENUM('unpaid', 'paid'), type: DataTypes.ENUM('unbilled', 'unpaid', 'paid'),
allowNull: false, allowNull: false,
defaultValue: 'unpaid' defaultValue: 'unpaid'
}, },