const { Rental, Room, Apartment } = require('../models'); const { Op } = require('sequelize'); // 格式化时间(考虑时区,转换为北京时间) const formatDate = (date) => { if (!date) return null; // 创建一个新的Date对象,加上8小时的时区偏移 const beijingDate = new Date(date.getTime() + 8 * 60 * 60 * 1000); return beijingDate.toISOString().split('T')[0]; }; // 格式化租房数据 const formatRentalData = (rental) => { const formattedRental = { ...rental.toJSON(), startDate: formatDate(rental.startDate), endDate: formatDate(rental.endDate), createTime: formatDate(rental.createTime), updateTime: formatDate(rental.updateTime) }; return formattedRental; }; // 检查并更新租房状态 const checkAndUpdateRentalStatus = async () => { try { // 获取当前日期 const currentDate = new Date(); // 计算5天后的日期 const fiveDaysLater = new Date(); fiveDaysLater.setDate(currentDate.getDate() + 5); // 查找所有活跃的租房记录 const rentals = await Rental.findAll({ where: { status: 'active', isDeleted: 0 }, include: [ { model: Room, where: { isDeleted: 0 } } ] }); // 检查每个租房记录的状态 for (const rental of rentals) { const endDate = new Date(rental.endDate); // 检查是否已到期 if (endDate < currentDate) { // 更新房间附属状态为已到期 const room = await Room.findByPk(rental.roomId); if (room && room.status === 'rented') { await room.update({ subStatus: 'expired' }); } } else if (endDate <= fiveDaysLater) { // 更新房间附属状态为即将到期 const room = await Room.findByPk(rental.roomId); if (room && room.status === 'rented') { await room.update({ subStatus: 'soon_expire' }); } } else { // 更新房间附属状态为正常 const room = await Room.findByPk(rental.roomId); if (room && room.status === 'rented') { await room.update({ subStatus: 'normal' }); } } } console.log('租房状态检查和更新完成'); } catch (error) { console.error('检查和更新租房状态时出错:', error); } }; // 获取所有租房(支持搜索和分页) const getAllRentals = async (req, res) => { try { // 先检查并更新租房状态 await checkAndUpdateRentalStatus(); const { apartmentId, roomId, tenantName, status, startDateFrom, startDateTo, endDateFrom, endDateTo, page = 1, pageSize = 10 } = req.query; // 构建查询条件 const where = { isDeleted: 0 }; if (status) { where.status = status; } if (roomId) { where.roomId = roomId; } if (tenantName) { where.tenantName = { [Op.like]: `%${tenantName}%` }; } if (startDateFrom && startDateTo) { where.startDate = { [Op.between]: [new Date(startDateFrom), new Date(startDateTo)] }; } if (endDateFrom && endDateTo) { where.endDate = { [Op.between]: [new Date(endDateFrom), new Date(endDateTo)] }; } // 构建包含关系 const include = [ { model: Room, where: { isDeleted: 0, ...(apartmentId ? { apartmentId } : {}) }, include: [ { model: Apartment, where: { isDeleted: 0 } } ] } ]; // 计算偏移量 const offset = (page - 1) * pageSize; // 查询租房数据 const { count, rows } = await Rental.findAndCountAll({ where, include, limit: parseInt(pageSize), offset: parseInt(offset), order: [['createTime', 'DESC']] // 按创建时间倒序排序 }); // 格式化数据 const formattedRentals = rows.map(formatRentalData); // 返回结果 res.status(200).json({ data: formattedRentals, total: count, page: parseInt(page), pageSize: parseInt(pageSize) }); } catch (error) { res.status(500).json({ error: error.message }); } }; // 获取单个租房 const getRentalById = async (req, res) => { try { const { id } = req.params; const rental = await Rental.findOne({ where: { id, isDeleted: 0 }, include: [ { model: Room, where: { isDeleted: 0 }, include: [ { model: Apartment, where: { isDeleted: 0 } } ] } ] }); if (!rental) { return res.status(404).json({ error: '租房记录不存在' }); } const formattedRental = formatRentalData(rental); res.status(200).json(formattedRental); } catch (error) { res.status(500).json({ error: error.message }); } }; // 创建租房 const createRental = async (req, res) => { try { console.log('接收到的请求数据:', req.body); // 直接使用req.body中的数据 const body = req.body; // 检查请求体是否存在 if (!body) { return res.status(400).json({ error: '请求体不能为空' }); } // 检查所有必要参数 if (!body.roomId) { return res.status(400).json({ error: '缺少房间ID' }); } if (!body.tenantName) { return res.status(400).json({ error: '缺少租客姓名' }); } if (!body.startDate) { return res.status(400).json({ error: '缺少开始日期' }); } if (!body.endDate) { return res.status(400).json({ error: '缺少结束日期' }); } if (!body.rent) { return res.status(400).json({ error: '缺少租金' }); } // 转换roomId为整数类型 const parsedRoomId = parseInt(body.roomId); if (isNaN(parsedRoomId)) { return res.status(400).json({ error: '无效的房间ID' }); } // 处理押金,为空时设置为0 const deposit = body.deposit || 0; // 处理已退押金,为空时设置为0 const refundedDeposit = body.refundedDeposit || 0; // 创建租房记录 console.log('创建租房记录:', { roomId: parsedRoomId, tenantName: body.tenantName, startDate: body.startDate, endDate: body.endDate, rent: body.rent, deposit: deposit, refundedDeposit: refundedDeposit, status: body.status || 'active', remark: body.remark }); const rental = await Rental.create({ roomId: parsedRoomId, tenantName: body.tenantName, startDate: body.startDate, endDate: body.endDate, rent: body.rent, deposit: deposit, refundedDeposit: refundedDeposit, status: body.status || 'active', remark: body.remark, createBy: req.user.id, updateBy: req.user.id }); console.log('租房记录:', rental); // 更新房间状态为已租 await Room.update({ status: 'rented' }, { where: { id: parsedRoomId } }); res.status(201).json(rental); } catch (error) { console.error('创建租房记录时出错:', error); res.status(500).json({ error: error.message }); } }; // 更新租房 const updateRental = async (req, res) => { try { const { id } = req.params; const { roomId, tenantName, startDate, endDate, rent, deposit, refundedDeposit, status, remark } = req.body; const rental = await Rental.findOne({ where: { id, isDeleted: 0 } }); if (!rental) { return res.status(404).json({ error: '租房记录不存在' }); } // 处理押金,为空时设置为0 const updateDeposit = deposit || 0; // 处理已退押金,为空时设置为0 const updateRefundedDeposit = refundedDeposit || 0; await rental.update({ roomId, tenantName, startDate, endDate, rent, deposit: updateDeposit, refundedDeposit: updateRefundedDeposit, status, remark, updateBy: req.user.id }); res.status(200).json(rental); } catch (error) { res.status(500).json({ error: error.message }); } }; // 删除租房(软删除) const deleteRental = async (req, res) => { try { const { id } = req.params; const rental = await Rental.findOne({ where: { id, isDeleted: 0 } }); if (!rental) { return res.status(404).json({ error: '租房记录不存在' }); } await rental.update({ isDeleted: 1, updateBy: req.user.id }); res.status(200).json({ message: '租房记录删除成功' }); } catch (error) { res.status(500).json({ error: error.message }); } }; // 获取所有租房(不分页) const listRentals = async (req, res) => { try { // 先检查并更新租房状态 await checkAndUpdateRentalStatus(); const { apartmentId, roomId, tenantName, status, startDateFrom, startDateTo, endDateFrom, endDateTo } = req.query; // 构建查询条件 const where = { isDeleted: 0 }; if (status) { where.status = status; } if (roomId) { where.roomId = roomId; } if (tenantName) { where.tenantName = { [Op.like]: `%${tenantName}%` }; } if (startDateFrom && startDateTo) { where.startDate = { [Op.between]: [new Date(startDateFrom), new Date(startDateTo)] }; } if (endDateFrom && endDateTo) { where.endDate = { [Op.between]: [new Date(endDateFrom), new Date(endDateTo)] }; } // 构建包含关系 const include = [ { model: Room, where: { isDeleted: 0, ...(apartmentId ? { apartmentId } : {}) }, include: [ { model: Apartment, where: { isDeleted: 0 } } ] } ]; // 查询租房数据 const rentals = await Rental.findAll({ where, include, order: [['createTime', 'DESC']] // 按创建时间倒序排序 }); // 格式化数据 const formattedRentals = rentals.map(formatRentalData); // 返回结果 res.status(200).json(formattedRentals); } catch (error) { res.status(500).json({ error: error.message }); } }; module.exports = { getAllRentals, listRentals, getRentalById, createRental, updateRental, deleteRental };