rentease-backend/controllers/rentalController.js

397 lines
10 KiB
JavaScript
Raw Permalink 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, 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
};