通知、统计

This commit is contained in:
wangxiaoxian 2026-03-09 21:27:09 +08:00
parent 795d7ea5c1
commit c0aee7e17f
4 changed files with 54 additions and 25 deletions

View File

@ -27,9 +27,9 @@ const checkAndUpdateRentalStatus = async () => {
try { try {
// 获取当前日期 // 获取当前日期
const currentDate = new Date(); const currentDate = new Date();
// 计算10天后的日期 // 计算5天后的日期
const tenDaysLater = new Date(); const fiveDaysLater = new Date();
tenDaysLater.setDate(currentDate.getDate() + 7); fiveDaysLater.setDate(currentDate.getDate() + 5);
// 查找所有活跃的租房记录 // 查找所有活跃的租房记录
const rentals = await Rental.findAll({ const rentals = await Rental.findAll({
@ -53,7 +53,7 @@ const checkAndUpdateRentalStatus = async () => {
if (room && room.status === 'rented') { if (room && room.status === 'rented') {
await room.update({ subStatus: 'expired' }); await room.update({ subStatus: 'expired' });
} }
} else if (endDate <= tenDaysLater) { } else if (endDate <= fiveDaysLater) {
// 更新房间附属状态为即将到期 // 更新房间附属状态为即将到期
const room = await Room.findByPk(rental.roomId); const room = await Room.findByPk(rental.roomId);
if (room && room.status === 'rented') { if (room && room.status === 'rented') {
@ -168,13 +168,7 @@ const getRentalById = async (req, res) => {
include: [ include: [
{ {
model: Apartment, model: Apartment,
where: { isDeleted: 0 }, where: { isDeleted: 0 }
include: [
{
model: Region,
where: { isDeleted: 0 }
}
]
} }
] ]
} }
@ -228,6 +222,8 @@ const createRental = async (req, res) => {
// 处理押金为空时设置为0 // 处理押金为空时设置为0
const deposit = body.deposit || 0; const deposit = body.deposit || 0;
// 处理已退押金为空时设置为0
const refundedDeposit = body.refundedDeposit || 0;
// 创建租房记录 // 创建租房记录
console.log('创建租房记录:', { console.log('创建租房记录:', {
@ -237,6 +233,7 @@ const createRental = async (req, res) => {
endDate: body.endDate, endDate: body.endDate,
rent: body.rent, rent: body.rent,
deposit: deposit, deposit: deposit,
refundedDeposit: refundedDeposit,
status: body.status || 'active' status: body.status || 'active'
}); });
@ -247,6 +244,7 @@ const createRental = async (req, res) => {
endDate: body.endDate, endDate: body.endDate,
rent: body.rent, rent: body.rent,
deposit: deposit, deposit: deposit,
refundedDeposit: refundedDeposit,
status: body.status || 'active', status: body.status || 'active',
createBy: req.user.id, createBy: req.user.id,
updateBy: req.user.id updateBy: req.user.id
@ -268,7 +266,7 @@ const createRental = async (req, res) => {
const updateRental = async (req, res) => { const updateRental = async (req, res) => {
try { try {
const { id } = req.params; const { id } = req.params;
const { roomId, tenantName, startDate, endDate, rent, deposit, status } = req.body; const { roomId, tenantName, startDate, endDate, rent, deposit, refundedDeposit, status, remark } = req.body;
const rental = await Rental.findOne({ const rental = await Rental.findOne({
where: { id, isDeleted: 0 } where: { id, isDeleted: 0 }
}); });
@ -277,6 +275,8 @@ const updateRental = async (req, res) => {
} }
// 处理押金为空时设置为0 // 处理押金为空时设置为0
const updateDeposit = deposit || 0; const updateDeposit = deposit || 0;
// 处理已退押金为空时设置为0
const updateRefundedDeposit = refundedDeposit || 0;
await rental.update({ await rental.update({
roomId, roomId,
tenantName, tenantName,
@ -284,7 +284,9 @@ const updateRental = async (req, res) => {
endDate, endDate,
rent, rent,
deposit: updateDeposit, deposit: updateDeposit,
refundedDeposit: updateRefundedDeposit,
status, status,
remark,
updateBy: req.user.id updateBy: req.user.id
}); });
res.status(200).json(rental); res.status(200).json(rental);

View File

@ -49,9 +49,9 @@ const checkAndUpdateRentalStatus = async () => {
try { try {
// 获取当前日期 // 获取当前日期
const currentDate = new Date(); const currentDate = new Date();
// 计算10天后的日期 // 计算5天后的日期
const tenDaysLater = new Date(); const fiveDaysLater = new Date();
tenDaysLater.setDate(currentDate.getDate() + 7); fiveDaysLater.setDate(currentDate.getDate() + 5);
// 查找所有在租的租房记录 // 查找所有在租的租房记录
const rentals = await Rental.findAll({ const rentals = await Rental.findAll({
@ -69,7 +69,7 @@ const checkAndUpdateRentalStatus = async () => {
if (room && room.status === 'rented') { if (room && room.status === 'rented') {
await room.update({ subStatus: 'expired' }); await room.update({ subStatus: 'expired' });
} }
} else if (endDate <= tenDaysLater) { } else if (endDate <= fiveDaysLater) {
// 更新房间附属状态为即将到期 // 更新房间附属状态为即将到期
const room = await Room.findByPk(rental.roomId); const room = await Room.findByPk(rental.roomId);
if (room && room.status === 'rented') { if (room && room.status === 'rented') {

View File

@ -13,7 +13,11 @@ const getRentStatistics = async (req, res) => {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
const date = new Date(now.getFullYear(), now.getMonth() - i, 1); const date = new Date(now.getFullYear(), now.getMonth() - i, 1);
const monthKey = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}`; const monthKey = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}`;
monthlyRent[monthKey] = 0; monthlyRent[monthKey] = {
amount: 0,
depositReceived: 0,
depositRefunded: 0
};
} }
// 从数据库查询过去12个月的租赁记录排除已删除的 // 从数据库查询过去12个月的租赁记录排除已删除的
@ -26,27 +30,43 @@ const getRentStatistics = async (req, res) => {
} }
}); });
// 按月份统计已收租金 // 按月份统计已收租金和押金
rentals.forEach(rental => { rentals.forEach(rental => {
// 检查租金是否有效 if (rental.createTime) {
const rentAmount = parseFloat(rental.rent) || 0;
if (rentAmount > 0 && rental.createTime) {
// 解析创建时间 // 解析创建时间
const createDate = new Date(rental.createTime); const createDate = new Date(rental.createTime);
const monthKey = `${createDate.getFullYear()}-${(createDate.getMonth() + 1).toString().padStart(2, '0')}`; const monthKey = `${createDate.getFullYear()}-${(createDate.getMonth() + 1).toString().padStart(2, '0')}`;
// 如果该月份在我们的统计范围内,添加租金 // 如果该月份在我们的统计范围内
if (monthlyRent.hasOwnProperty(monthKey)) { if (monthlyRent.hasOwnProperty(monthKey)) {
monthlyRent[monthKey] += rentAmount; // 统计租金
const rentAmount = parseFloat(rental.rent) || 0;
if (rentAmount > 0) {
monthlyRent[monthKey].amount += rentAmount;
}
// 统计已收押金(创建租赁记录时的押金)
const depositReceived = parseFloat(rental.deposit) || 0;
if (depositReceived > 0) {
monthlyRent[monthKey].depositReceived += depositReceived;
}
// 统计已退押金
const depositRefunded = parseFloat(rental.refundedDeposit) || 0;
if (depositRefunded > 0) {
monthlyRent[monthKey].depositRefunded += depositRefunded;
}
} }
} }
}); });
// 转换为数组格式并按月份倒序排序 // 转换为数组格式并按月份倒序排序
const rentStatistics = Object.entries(monthlyRent) const rentStatistics = Object.entries(monthlyRent)
.map(([month, amount]) => ({ .map(([month, data]) => ({
month, month,
amount: Math.round(amount * 100) / 100 // 保留两位小数 amount: Math.round(data.amount * 100) / 100, // 保留两位小数
depositReceived: Math.round(data.depositReceived * 100) / 100, // 保留两位小数
depositRefunded: Math.round(data.depositRefunded * 100) / 100 // 保留两位小数
})) }))
.sort((a, b) => b.month.localeCompare(a.month)); .sort((a, b) => b.month.localeCompare(a.month));
@ -194,6 +214,7 @@ const getApartmentRoomStatusStatistics = async (req, res) => {
}); });
return { return {
apartmentId: apartment.id,
apartment: apartment.name, apartment: apartment.name,
empty, empty,
reserved, reserved,

View File

@ -43,6 +43,12 @@ const Rental = sequelize.define('Rental', {
allowNull: true, allowNull: true,
comment: '押金' comment: '押金'
}, },
refundedDeposit: {
type: DataTypes.DECIMAL(10, 2),
allowNull: true,
defaultValue: 0,
comment: '已退押金'
},
status: { status: {
type: DataTypes.ENUM('active', 'expired'), type: DataTypes.ENUM('active', 'expired'),
allowNull: false, allowNull: false,