const { Room, Rental, Apartment, Region } = require('../models'); const { Op } = require('sequelize'); // 租金统计 const getRentStatistics = async (req, res) => { try { // 获取当前年份 const currentYear = new Date().getFullYear(); // 从数据库查询所有租房记录(包括活跃和已到期的) const rentals = await Rental.findAll({ include: [Room] }); // 按月份统计租金 const monthlyRent = {}; // 初始化12个月的数据 for (let i = 1; i <= 12; i++) { const monthKey = `${currentYear}-${i.toString().padStart(2, '0')}`; monthlyRent[monthKey] = 0; } // 计算每个月的租金收入 rentals.forEach(rental => { if (rental.Room) { // 检查租金是否有效 const rentAmount = parseFloat(rental.rent) || 0; if (rentAmount > 0 && rental.startDate && rental.endDate) { // 解析开始和结束日期 const startDate = new Date(rental.startDate); const endDate = new Date(rental.endDate); // 计算当前年份的开始和结束日期 const yearStart = new Date(currentYear, 0, 1); // 1月1日 const yearEnd = new Date(currentYear, 11, 31); // 12月31日 // 确定实际的开始和结束日期(考虑年份范围) const actualStart = startDate > yearStart ? startDate : yearStart; const actualEnd = endDate < yearEnd ? endDate : yearEnd; // 如果实际开始日期晚于实际结束日期,跳过 if (actualStart > actualEnd) { return; } // 遍历当前年份的每个月 for (let i = 1; i <= 12; i++) { const monthKey = `${currentYear}-${i.toString().padStart(2, '0')}`; const monthStart = new Date(currentYear, i - 1, 1); // 当月1日 const monthEnd = new Date(currentYear, i, 0); // 当月最后一天 // 检查租赁期是否与当前月份重叠 if (actualStart <= monthEnd && actualEnd >= monthStart) { // 如果重叠,添加当月租金 monthlyRent[monthKey] += rentAmount; } } } } }); // 转换为数组格式 const rentStatistics = Object.entries(monthlyRent).map(([month, amount]) => ({ month, amount: Math.round(amount * 100) / 100 // 保留两位小数 })); res.status(200).json(rentStatistics); } catch (error) { console.error('获取租金统计数据时出错:', error); res.status(500).json({ error: error.message }); } }; // 房间状态统计 const getRoomStatusStatistics = async (req, res) => { try { const statusCounts = await Room.count({ group: ['status'] }); const statusMap = { empty: '空房', rented: '在租', soon_expire: '即将到期', expired: '到期', cleaning: '打扫中', maintenance: '维修中' }; const roomStatusStatistics = Object.entries(statusMap).map(([status, label]) => { const count = statusCounts.find(item => item.status === status)?.count || 0; return { status: label, count }; }); res.status(200).json(roomStatusStatistics); } catch (error) { res.status(500).json({ error: error.message }); } }; // 区域房屋统计 const getRegionHouseStatistics = async (req, res) => { try { const regions = await Region.findAll({ include: [ { model: Apartment, include: [Room] } ] }); const regionHouseStatistics = regions.map(region => { let empty = 0; let rented = 0; let soon_expire = 0; let expired = 0; let cleaning = 0; let maintenance = 0; region.Apartments.forEach(apartment => { apartment.Rooms.forEach(room => { switch (room.status) { case 'empty': empty++; break; case 'rented': rented++; break; case 'soon_expire': soon_expire++; break; case 'expired': expired++; break; case 'cleaning': cleaning++; break; case 'maintenance': maintenance++; break; } }); }); return { region: region.name, empty, rented, soon_expire, expired, cleaning, maintenance, total: empty + rented + soon_expire + expired + cleaning + maintenance }; }); res.status(200).json(regionHouseStatistics); } catch (error) { res.status(500).json({ error: error.message }); } }; // 区域公寓房间状态分布 const getRegionApartmentHouseStatistics = async (req, res) => { try { const regions = await Region.findAll({ include: [ { model: Apartment, include: [Room] } ] }); const apartmentHouseStatistics = []; regions.forEach(region => { region.Apartments.forEach(apartment => { let empty = 0; let rented = 0; let soon_expire = 0; let expired = 0; let cleaning = 0; let maintenance = 0; apartment.Rooms.forEach(room => { switch (room.status) { case 'empty': empty++; break; case 'rented': rented++; break; case 'soon_expire': soon_expire++; break; case 'expired': expired++; break; case 'cleaning': cleaning++; break; case 'maintenance': maintenance++; break; } }); apartmentHouseStatistics.push({ region: region.name, apartment: apartment.name, empty, rented, soon_expire, expired, cleaning, maintenance, total: empty + rented + soon_expire + expired + cleaning + maintenance }); }); }); res.status(200).json(apartmentHouseStatistics); } catch (error) { res.status(500).json({ error: error.message }); } }; module.exports = { getRentStatistics, getRoomStatusStatistics, getRegionHouseStatistics, getRegionApartmentHouseStatistics };