rentease-backend/controllers/statisticsController.js

221 lines
7.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { Room, Rental, Apartment } = require('../models');
const { Op } = require('sequelize');
// 租金统计
const getRentStatistics = async (req, res) => {
try {
// 计算过去12个月的开始日期
const now = new Date();
const startDate = new Date(now.getFullYear(), now.getMonth() - 11, 1); // 12个月前的第一天
// 初始化过去12个月的数据
const monthlyRent = {};
for (let i = 0; i < 12; i++) {
const date = new Date(now.getFullYear(), now.getMonth() - i, 1);
const monthKey = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}`;
monthlyRent[monthKey] = 0;
}
// 从数据库查询过去12个月的租赁记录排除已删除的
const rentals = await Rental.findAll({
where: {
createTime: {
[Op.gte]: startDate
},
isDeleted: 0
}
});
// 按月份统计已收租金
rentals.forEach(rental => {
// 检查租金是否有效
const rentAmount = parseFloat(rental.rent) || 0;
if (rentAmount > 0 && rental.createTime) {
// 解析创建时间
const createDate = new Date(rental.createTime);
const monthKey = `${createDate.getFullYear()}-${(createDate.getMonth() + 1).toString().padStart(2, '0')}`;
// 如果该月份在我们的统计范围内,添加租金
if (monthlyRent.hasOwnProperty(monthKey)) {
monthlyRent[monthKey] += rentAmount;
}
}
});
// 转换为数组格式并按月份倒序排序
const rentStatistics = Object.entries(monthlyRent)
.map(([month, amount]) => ({
month,
amount: Math.round(amount * 100) / 100 // 保留两位小数
}))
.sort((a, b) => b.month.localeCompare(a.month));
res.status(200).json(rentStatistics);
} catch (error) {
console.error('获取租金统计数据时出错:', error);
res.status(500).json({ error: error.message });
}
};
// 房间状态统计
const getRoomStatusStatistics = async (req, res) => {
try {
// 获取所有房间(排除已删除的)
const rooms = await Room.findAll({ where: { isDeleted: 0 } });
// 初始化统计数据
let empty = 0;
let reserved = 0;
let rented = 0;
let soon_expire = 0;
let expired = 0;
let cleaning = 0;
let maintenance = 0;
// 统计各状态房间数量
rooms.forEach(room => {
if (room.status === 'empty') {
empty++;
} else if (room.status === 'reserved') {
reserved++;
} else if (room.status === 'rented') {
rented++;
// 统计附属状态
if (room.subStatus === 'soon_expire') {
soon_expire++;
} else if (room.subStatus === 'expired') {
expired++;
}
// 统计其他状态
if (room.otherStatus === 'cleaning') {
cleaning++;
} else if (room.otherStatus === 'maintenance') {
maintenance++;
}
}
});
const roomStatusStatistics = [
{ status: '空房', count: empty },
{ status: '预订', count: reserved },
{ status: '在租', count: rented },
{ status: '即将到期', count: soon_expire },
{ status: '到期', count: expired },
{ status: '打扫中', count: cleaning },
{ status: '维修中', count: maintenance }
];
res.status(200).json(roomStatusStatistics);
} catch (error) {
res.status(500).json({ error: error.message });
}
};
// Dashboard统计数据
const getDashboardStatistics = async (req, res) => {
try {
// 导入所有需要的模型
const { Apartment, Room, WaterBill, Rental } = require('../models');
// 并行查询所有统计数据
const [apartmentCount, roomCount, emptyRoomCount, reservedRoomCount, rentedRoomCount, soonExpireRoomCount, expiredRoomCount, collectedRentAmount, collectedWaterAmount] = await Promise.all([
Apartment.count({ where: { isDeleted: 0 } }),
Room.count({ where: { isDeleted: 0 } }),
Room.count({ where: { status: 'empty', isDeleted: 0 } }),
Room.count({ where: { status: 'reserved', isDeleted: 0 } }),
Room.count({ where: { status: 'rented', isDeleted: 0 } }),
Room.count({ where: { status: 'rented', subStatus: 'soon_expire', isDeleted: 0 } }),
Room.count({ where: { status: 'rented', subStatus: 'expired', isDeleted: 0 } }),
// 统计已收租金(排除已删除的)
Rental.sum('rent', { where: { isDeleted: 0 } }),
// 统计已收水费(排除已删除的)
WaterBill.sum('amount', { where: { status: 'paid', isDeleted: 0 } })
]);
// 构造响应数据
const dashboardStatistics = {
apartmentCount,
roomCount,
emptyRoomCount,
reservedRoomCount,
rentedRoomCount,
soonExpireRoomCount,
expiredRoomCount,
collectedRentAmount: parseFloat(collectedRentAmount) || 0,
collectedWaterAmount: parseFloat(collectedWaterAmount) || 0
};
res.status(200).json(dashboardStatistics);
} catch (error) {
console.error('获取Dashboard统计数据时出错:', error);
res.status(500).json({ error: error.message });
}
};
// 公寓房间状态分布统计
const getApartmentRoomStatusStatistics = async (req, res) => {
try {
// 获取所有公寓(排除已删除的)
const apartments = await Apartment.findAll({ where: { isDeleted: 0 } });
// 获取所有房间(排除已删除的)
const rooms = await Room.findAll({ where: { isDeleted: 0 } });
// 构建公寓房间状态分布数据
const apartmentRoomStatusStatistics = apartments.map(apartment => {
const apartmentRooms = rooms.filter(room => room.apartmentId === apartment.id);
let empty = 0;
let reserved = 0;
let rented = 0;
let soon_expire = 0;
let expired = 0;
let cleaning = 0;
let maintenance = 0;
apartmentRooms.forEach(room => {
if (room.status === 'empty') {
empty++;
} else if (room.status === 'reserved') {
reserved++;
} else if (room.status === 'rented') {
rented++;
if (room.subStatus === 'soon_expire') {
soon_expire++;
} else if (room.subStatus === 'expired') {
expired++;
}
if (room.otherStatus === 'cleaning') {
cleaning++;
} else if (room.otherStatus === 'maintenance') {
maintenance++;
}
}
});
return {
apartment: apartment.name,
empty,
reserved,
rented,
soon_expire,
expired,
cleaning,
maintenance,
total: empty + reserved + rented
};
});
res.status(200).json(apartmentRoomStatusStatistics);
} catch (error) {
console.error('获取公寓房间状态分布数据时出错:', error);
res.status(500).json({ error: error.message });
}
};
module.exports = {
getRentStatistics,
getRoomStatusStatistics,
getDashboardStatistics,
getApartmentRoomStatusStatistics
};