rentease-backend/controllers/rentalController.js

355 lines
9.7 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 { Rental, Room, Tenant, Contract, Apartment, Region } = 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)
};
// 格式化关联数据
if (formattedRental.Contract) {
formattedRental.Contract = {
...formattedRental.Contract,
startDate: formatDate(formattedRental.Contract.startDate),
endDate: formatDate(formattedRental.Contract.endDate),
createTime: formatDate(formattedRental.Contract.createTime),
updateTime: formatDate(formattedRental.Contract.updateTime)
};
}
return formattedRental;
};
// 检查并更新租房状态
const checkAndUpdateRentalStatus = async () => {
try {
// 获取当前日期
const currentDate = new Date();
// 计算10天后的日期
const tenDaysLater = new Date();
tenDaysLater.setDate(currentDate.getDate() + 10);
// 查找所有活跃的租房记录
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) {
// 更新租房状态为已到期
await rental.update({ status: 'expired' });
// 更新房间状态为空房
if (rental.Room) {
await rental.Room.update({ status: 'empty' });
}
} else if (endDate <= tenDaysLater) {
// 更新房间状态为即将到期
if (rental.Room && rental.Room.status === 'rented') {
await rental.Room.update({ status: 'soon_expire' });
}
}
}
console.log('租房状态检查和更新完成');
} catch (error) {
console.error('检查和更新租房状态时出错:', error);
}
};
// 获取所有租房(支持搜索和分页)
const getAllRentals = async (req, res) => {
try {
// 先检查并更新租房状态
await checkAndUpdateRentalStatus();
const { roomNumber, tenantName, status, page = 1, pageSize = 10 } = req.query;
// 构建查询条件
const where = { isDeleted: 0 };
if (status) {
where.status = status;
}
// 构建包含关系
const include = [
{
model: Room,
where: roomNumber ? { roomNumber: { [Op.like]: `%${roomNumber}%` }, isDeleted: 0 } : { isDeleted: 0 },
include: [
{
model: Apartment,
where: { isDeleted: 0 },
include: [
{
model: Region,
where: { isDeleted: 0 }
}
]
}
]
},
{
model: Tenant,
where: tenantName ? { name: { [Op.like]: `%${tenantName}%` }, isDeleted: 0 } : { isDeleted: 0 }
},
{
model: Contract,
where: { isDeleted: 0 }
}
];
// 计算偏移量
const offset = (page - 1) * pageSize;
// 查询租房数据
const { count, rows } = await Rental.findAndCountAll({
where,
include,
limit: parseInt(pageSize),
offset: parseInt(offset)
});
// 格式化数据
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 },
include: [
{
model: Region,
where: { isDeleted: 0 }
}
]
}
]
},
{
model: Tenant,
where: { isDeleted: 0 }
},
{
model: Contract,
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.tenantPhone) {
return res.status(400).json({ error: '缺少租客电话' });
}
if (!body.tenantIdCard) {
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' });
}
// 先查找或创建租客
let tenant = await Tenant.findOne({ where: { idCard: body.tenantIdCard } });
if (!tenant) {
console.log('创建新租客:', { name: body.tenantName, phone: body.tenantPhone, idCard: body.tenantIdCard });
tenant = await Tenant.create({
name: body.tenantName,
phone: body.tenantPhone,
idCard: body.tenantIdCard
});
}
console.log('租客信息:', tenant);
// 确保租客创建成功
if (!tenant || !tenant.id) {
return res.status(500).json({ error: '创建租客失败' });
}
// 创建合同
console.log('创建合同:', {
roomId: parsedRoomId,
tenantId: tenant.id,
startDate: body.startDate,
endDate: body.endDate,
rent: body.rent,
deposit: body.deposit,
status: body.status || 'active'
});
const contract = await Contract.create({
roomId: parsedRoomId,
tenantId: tenant.id,
startDate: body.startDate,
endDate: body.endDate,
rent: body.rent,
deposit: body.deposit,
status: body.status || 'active'
});
console.log('合同信息:', contract);
// 确保合同创建成功
if (!contract || !contract.id) {
return res.status(500).json({ error: '创建合同失败' });
}
// 创建租房记录
console.log('创建租房记录:', {
roomId: parsedRoomId,
tenantId: tenant.id,
contractId: contract.id,
startDate: body.startDate,
endDate: body.endDate,
rent: body.rent,
deposit: body.deposit,
status: body.status || 'active'
});
// 直接使用具体的数值创建租房记录
const rental = await Rental.create({
roomId: parsedRoomId,
tenantId: tenant.id,
contractId: contract.id,
startDate: body.startDate,
endDate: body.endDate,
rent: body.rent,
deposit: body.deposit,
status: body.status || 'active'
});
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, tenantId, contractId, startDate, endDate, rent, deposit, status } = req.body;
const rental = await Rental.findOne({
where: { id, isDeleted: 0 }
});
if (!rental) {
return res.status(404).json({ error: '租房记录不存在' });
}
await rental.update({ roomId, tenantId, contractId, startDate, endDate, rent, deposit, status });
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 });
res.status(200).json({ message: '租房记录删除成功' });
} catch (error) {
res.status(500).json({ error: error.message });
}
};
module.exports = {
getAllRentals,
getRentalById,
createRental,
updateRental,
deleteRental
};