rentease-backend/controllers/statisticsController.js

221 lines
7.0 KiB
JavaScript
Raw Normal View History

2026-03-08 16:28:33 +00:00
const { Room, Rental, Apartment } = require('../models');
2026-03-02 12:36:41 +00:00
const { Op } = require('sequelize');
// 租金统计
const getRentStatistics = async (req, res) => {
try {
2026-03-03 16:33:04 +00:00
// 计算过去12个月的开始日期
const now = new Date();
const startDate = new Date(now.getFullYear(), now.getMonth() - 11, 1); // 12个月前的第一天
2026-03-02 12:36:41 +00:00
2026-03-03 16:33:04 +00:00
// 初始化过去12个月的数据
2026-03-02 12:36:41 +00:00
const monthlyRent = {};
2026-03-03 16:33:04 +00:00
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')}`;
2026-03-02 12:36:41 +00:00
monthlyRent[monthKey] = 0;
}
2026-03-05 15:26:13 +00:00
// 从数据库查询过去12个月的租赁记录排除已删除的
const rentals = await Rental.findAll({
2026-03-03 16:33:04 +00:00
where: {
createTime: {
[Op.gte]: startDate
2026-03-05 15:26:13 +00:00
},
isDeleted: 0
2026-03-02 12:36:41 +00:00
}
});
2026-03-03 16:33:04 +00:00
// 按月份统计已收租金
2026-03-05 15:26:13 +00:00
rentals.forEach(rental => {
2026-03-03 16:33:04 +00:00
// 检查租金是否有效
2026-03-05 15:26:13 +00:00
const rentAmount = parseFloat(rental.rent) || 0;
if (rentAmount > 0 && rental.createTime) {
2026-03-03 16:33:04 +00:00
// 解析创建时间
2026-03-05 15:26:13 +00:00
const createDate = new Date(rental.createTime);
2026-03-03 16:33:04 +00:00
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));
2026-03-02 12:36:41 +00:00
res.status(200).json(rentStatistics);
} catch (error) {
console.error('获取租金统计数据时出错:', error);
res.status(500).json({ error: error.message });
}
};
// 房间状态统计
const getRoomStatusStatistics = async (req, res) => {
try {
2026-03-05 15:26:13 +00:00
// 获取所有房间(排除已删除的)
const rooms = await Room.findAll({ where: { isDeleted: 0 } });
2026-03-02 12:36:41 +00:00
2026-03-03 16:33:04 +00:00
// 初始化统计数据
let empty = 0;
2026-03-07 11:40:53 +00:00
let reserved = 0;
2026-03-03 16:33:04 +00:00
let rented = 0;
let soon_expire = 0;
let expired = 0;
let cleaning = 0;
let maintenance = 0;
2026-03-02 12:36:41 +00:00
2026-03-03 16:33:04 +00:00
// 统计各状态房间数量
rooms.forEach(room => {
if (room.status === 'empty') {
empty++;
2026-03-07 11:40:53 +00:00
} else if (room.status === 'reserved') {
reserved++;
2026-03-03 16:33:04 +00:00
} 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++;
}
}
2026-03-02 12:36:41 +00:00
});
2026-03-03 16:33:04 +00:00
const roomStatusStatistics = [
{ status: '空房', count: empty },
2026-03-07 11:40:53 +00:00
{ status: '预订', count: reserved },
2026-03-03 16:33:04 +00:00
{ status: '在租', count: rented },
{ status: '即将到期', count: soon_expire },
{ status: '到期', count: expired },
{ status: '打扫中', count: cleaning },
{ status: '维修中', count: maintenance }
];
2026-03-02 12:36:41 +00:00
res.status(200).json(roomStatusStatistics);
} catch (error) {
res.status(500).json({ error: error.message });
}
};
2026-03-03 16:33:04 +00:00
// Dashboard统计数据
const getDashboardStatistics = async (req, res) => {
try {
// 导入所有需要的模型
2026-03-08 16:28:33 +00:00
const { Apartment, Room, WaterBill, Rental } = require('../models');
2026-03-03 16:33:04 +00:00
// 并行查询所有统计数据
2026-03-08 16:28:33 +00:00
const [apartmentCount, roomCount, emptyRoomCount, reservedRoomCount, rentedRoomCount, soonExpireRoomCount, expiredRoomCount, collectedRentAmount, collectedWaterAmount] = await Promise.all([
2026-03-05 15:26:13 +00:00
Apartment.count({ where: { isDeleted: 0 } }),
Room.count({ where: { isDeleted: 0 } }),
Room.count({ where: { status: 'empty', isDeleted: 0 } }),
2026-03-07 11:40:53 +00:00
Room.count({ where: { status: 'reserved', isDeleted: 0 } }),
2026-03-05 15:26:13 +00:00
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 } })
2026-03-03 16:33:04 +00:00
]);
// 构造响应数据
const dashboardStatistics = {
apartmentCount,
roomCount,
emptyRoomCount,
2026-03-07 11:40:53 +00:00
reservedRoomCount,
2026-03-03 16:33:04 +00:00
rentedRoomCount,
2026-03-05 15:26:13 +00:00
soonExpireRoomCount,
expiredRoomCount,
2026-03-03 16:33:04 +00:00
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 });
}
};
2026-03-08 16:28:33 +00:00
// 公寓房间状态分布统计
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 });
}
};
2026-03-02 12:36:41 +00:00
module.exports = {
getRentStatistics,
getRoomStatusStatistics,
2026-03-08 16:28:33 +00:00
getDashboardStatistics,
getApartmentRoomStatusStatistics
2026-03-02 12:36:41 +00:00
};