rentease-backend-new/controllers/renterController.js

342 lines
8.0 KiB
JavaScript

const { Renter, Rental, Room, Apartment } = require('../models');
const { Op } = require('sequelize');
const response = require('../utils/response');
// 格式化日期时间(年月日时分秒)
const formatDateTime = (date) => {
if (!date) return null;
const dateObj = date instanceof Date ? date : new Date(date);
if (isNaN(dateObj.getTime())) return null;
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
return beijingDate.toISOString().replace('T', ' ').slice(0, 19);
};
// 格式化租客数据
const formatRenterData = (renter) => {
const data = renter.toJSON ? renter.toJSON() : renter;
return {
...data,
createTime: formatDateTime(data.createTime),
updateTime: formatDateTime(data.updateTime)
};
};
// 获取租客列表(分页)
const getRenters = async (req, res) => {
try {
const { page = 1, pageSize = 10, keyword, status } = req.query;
const tenantId = req.tenantId;
const where = { tenantId, isDeleted: 0 };
if (keyword) {
where[Op.or] = [
{ name: { [Op.like]: `%${keyword}%` } },
{ phone: { [Op.like]: `%${keyword}%` } },
{ idCard: { [Op.like]: `%${keyword}%` } }
];
}
if (status) {
where.status = status;
}
const { count, rows } = await Renter.findAndCountAll({
where,
order: [['createTime', 'DESC']],
offset: (page - 1) * pageSize,
limit: parseInt(pageSize)
});
response.success(res, '获取成功', {
list: rows.map(formatRenterData),
total: count,
page: parseInt(page),
pageSize: parseInt(pageSize)
});
} catch (error) {
console.error('获取租客列表失败:', error);
response.serverError(res, '获取租客列表失败', error);
}
};
// 获取租客列表(不分页)
const getRenterList = async (req, res) => {
try {
const { keyword, status } = req.query;
const tenantId = req.tenantId;
const where = { tenantId, isDeleted: 0 };
if (keyword) {
where[Op.or] = [
{ name: { [Op.like]: `%${keyword}%` } },
{ phone: { [Op.like]: `%${keyword}%` } },
{ idCard: { [Op.like]: `%${keyword}%` } }
];
}
if (status) {
where.status = status;
}
const rows = await Renter.findAll({
where,
order: [['createTime', 'DESC']]
});
response.success(res, '获取成功', rows.map(formatRenterData));
} catch (error) {
console.error('获取租客列表失败:', error);
response.serverError(res, '获取租客列表失败', error);
}
};
// 获取租客详情
const getRenterById = async (req, res) => {
try {
const { id } = req.params;
const tenantId = req.tenantId;
const renter = await Renter.findOne({
where: { id, tenantId, isDeleted: 0 }
});
if (!renter) {
return response.notFound(res, '租客不存在');
}
// 获取租客的租赁记录
const rentals = await Rental.findAll({
where: { renterId: id, tenantId },
include: [
{
model: Room,
attributes: ['id', 'roomNumber'],
include: [
{
model: Apartment,
attributes: ['id', 'name']
}
]
}
],
order: [['createTime', 'DESC']]
});
response.success(res, '获取成功', {
...renter.toJSON(),
createTime: formatDateTime(renter.createTime),
updateTime: formatDateTime(renter.updateTime),
rentals: rentals.map(r => ({
...r.toJSON(),
createTime: formatDateTime(r.createTime),
updateTime: formatDateTime(r.updateTime)
}))
});
} catch (error) {
console.error('获取租客详情失败:', error);
response.serverError(res, '获取租客详情失败', error);
}
};
// 创建租客
const createRenter = async (req, res) => {
try {
const tenantId = req.tenantId;
const createBy = req.user.id;
const {
name,
phone,
email,
idCard,
gender,
birthday,
emergencyContact,
emergencyPhone,
address,
workUnit,
remark
} = req.body;
// 验证必填字段
if (!name) {
return response.badRequest(res, '租客姓名不能为空');
}
// 检查手机号是否已存在
if (phone) {
const existingRenter = await Renter.findOne({
where: { phone, tenantId, isDeleted: 0 }
});
if (existingRenter) {
return response.badRequest(res, '该手机号已存在');
}
}
const renter = await Renter.create({
name,
phone,
email,
idCard,
gender,
birthday,
emergencyContact,
emergencyPhone,
address,
workUnit,
remark,
tenantId,
createBy,
status: 'active'
});
response.created(res, '创建成功', formatRenterData(renter));
} catch (error) {
console.error('创建租客失败:', error);
response.serverError(res, '创建租客失败', error);
}
};
// 更新租客
const updateRenter = async (req, res) => {
try {
const { id } = req.params;
const tenantId = req.tenantId;
const updateBy = req.user.id;
const renter = await Renter.findOne({
where: { id, tenantId, isDeleted: 0 }
});
if (!renter) {
return response.notFound(res, '租客不存在');
}
const {
name,
phone,
email,
idCard,
gender,
birthday,
emergencyContact,
emergencyPhone,
address,
workUnit,
remark,
status
} = req.body;
// 检查手机号是否被其他租客使用
if (phone && phone !== renter.phone) {
const existingRenter = await Renter.findOne({
where: { phone, tenantId, isDeleted: 0, id: { [Op.ne]: id } }
});
if (existingRenter) {
return response.badRequest(res, '该手机号已被其他租客使用');
}
}
await renter.update({
name,
phone,
email,
idCard,
gender,
birthday,
emergencyContact,
emergencyPhone,
address,
workUnit,
remark,
status,
updateBy
});
response.success(res, '更新成功', formatRenterData(renter));
} catch (error) {
console.error('更新租客失败:', error);
response.serverError(res, '更新租客失败', error);
}
};
// 删除租客
const deleteRenter = async (req, res) => {
try {
const { id } = req.params;
const tenantId = req.tenantId;
const renter = await Renter.findOne({
where: { id, tenantId, isDeleted: 0 }
});
if (!renter) {
return response.notFound(res, '租客不存在');
}
// 检查是否有进行中的租赁
const activeRentals = await Rental.count({
where: {
renterId: id,
tenantId,
status: 'active'
}
});
if (activeRentals > 0) {
return response.badRequest(res, '该租客有进行中的租赁,无法删除');
}
await renter.update({ isDeleted: 1 });
response.success(res, '删除成功');
} catch (error) {
console.error('删除租客失败:', error);
response.serverError(res, '删除租客失败', error);
}
};
// 获取租客下拉列表(用于租赁表单)
const getRenterOptions = async (req, res) => {
try {
const tenantId = req.tenantId;
const { keyword } = req.query;
const where = { tenantId, isDeleted: 0, status: 'active' };
if (keyword) {
where[Op.or] = [
{ name: { [Op.like]: `%${keyword}%` } },
{ phone: { [Op.like]: `%${keyword}%` } }
];
}
const renters = await Renter.findAll({
where,
attributes: ['id', 'name', 'phone'],
order: [['name', 'ASC']],
limit: 50
});
response.success(res, '获取成功', renters.map(r => ({
value: r.id,
label: `${r.name} ${r.phone ? '(' + r.phone + ')' : ''}`
})));
} catch (error) {
console.error('获取租客选项失败:', error);
response.serverError(res, '获取租客选项失败', error);
}
};
module.exports = {
getRenters,
getRenterList,
getRenterById,
createRenter,
updateRenter,
deleteRenter,
getRenterOptions
};