const { Room, Rental, Apartment, Region } = require('../models'); const { Op } = require('sequelize'); // 租金统计 const getRentStatistics = async (req, res) => { try { // 导入Contract模型 const { Contract } = require('../models'); // 计算过去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 contracts = await Contract.findAll({ where: { createTime: { [Op.gte]: startDate } } }); // 按月份统计已收租金 contracts.forEach(contract => { // 检查租金是否有效 const rentAmount = parseFloat(contract.rent) || 0; if (rentAmount > 0 && contract.createTime) { // 解析创建时间 const createDate = new Date(contract.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(); // 初始化统计数据 let empty = 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 === '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: 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 }); } }; // 区域房屋统计 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 => { if (room.status === 'empty') { empty++; } 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 { region: region.name, empty, rented, soon_expire, expired, cleaning, maintenance, total: empty + rented }; }); 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 => { if (room.status === 'empty') { empty++; } 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++; } } }); apartmentHouseStatistics.push({ region: region.name, apartment: apartment.name, empty, rented, soon_expire, expired, cleaning, maintenance, total: empty + rented }); }); }); res.status(200).json(apartmentHouseStatistics); } catch (error) { res.status(500).json({ error: error.message }); } }; // Dashboard统计数据 const getDashboardStatistics = async (req, res) => { try { // 导入所有需要的模型 const { Region, Apartment, Room, Tenant, Contract, WaterBill, Rental } = require('../models'); // 并行查询所有统计数据 const [regionCount, apartmentCount, roomCount, tenantCount, contractCount, emptyRoomCount, rentedRoomCount, collectedRentAmount, collectedWaterAmount] = await Promise.all([ Region.count(), Apartment.count(), Room.count(), Tenant.count(), Contract.count(), Room.count({ where: { status: 'empty' } }), Room.count({ where: { status: 'rented' } }), // 统计已收租金 Rental.sum('rent', { where: { status: 'active' } }), // 统计已收水费 WaterBill.sum('amount', { where: { status: 'paid' } }) ]); // 构造响应数据 const dashboardStatistics = { regionCount, apartmentCount, roomCount, tenantCount, contractCount, emptyRoomCount, rentedRoomCount, 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 }); } }; module.exports = { getRentStatistics, getRoomStatusStatistics, getRegionHouseStatistics, getRegionApartmentHouseStatistics, getDashboardStatistics };