384 lines
7.8 KiB
JavaScript
384 lines
7.8 KiB
JavaScript
|
|
const { Renter, Rental, Room, Apartment } = require('../models');
|
||
|
|
const { Op } = require('sequelize');
|
||
|
|
|
||
|
|
// 获取租客列表(分页)
|
||
|
|
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)
|
||
|
|
});
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
code: 200,
|
||
|
|
data: {
|
||
|
|
list: rows,
|
||
|
|
pagination: {
|
||
|
|
total: count,
|
||
|
|
page: parseInt(page),
|
||
|
|
pageSize: parseInt(pageSize)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('获取租客列表失败:', error);
|
||
|
|
res.status(500).json({
|
||
|
|
code: 500,
|
||
|
|
message: '获取租客列表失败'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 获取租客列表(不分页)
|
||
|
|
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']]
|
||
|
|
});
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
code: 200,
|
||
|
|
data: rows
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('获取租客列表失败:', error);
|
||
|
|
res.status(500).json({
|
||
|
|
code: 500,
|
||
|
|
message: '获取租客列表失败'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 获取租客详情
|
||
|
|
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 res.status(404).json({
|
||
|
|
code: 404,
|
||
|
|
message: '租客不存在'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// 获取租客的租赁记录
|
||
|
|
const rentals = await Rental.findAll({
|
||
|
|
where: { renterId: id, tenantId },
|
||
|
|
include: [
|
||
|
|
{
|
||
|
|
model: Room,
|
||
|
|
attributes: ['id', 'roomNumber'],
|
||
|
|
include: [
|
||
|
|
{
|
||
|
|
model: Apartment,
|
||
|
|
attributes: ['id', 'name']
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
],
|
||
|
|
order: [['createTime', 'DESC']]
|
||
|
|
});
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
code: 200,
|
||
|
|
data: {
|
||
|
|
...renter.toJSON(),
|
||
|
|
rentals
|
||
|
|
}
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('获取租客详情失败:', error);
|
||
|
|
res.status(500).json({
|
||
|
|
code: 500,
|
||
|
|
message: '获取租客详情失败',
|
||
|
|
error: error.message
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 创建租客
|
||
|
|
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 res.status(400).json({
|
||
|
|
code: 400,
|
||
|
|
message: '租客姓名不能为空'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// 检查手机号是否已存在
|
||
|
|
if (phone) {
|
||
|
|
const existingRenter = await Renter.findOne({
|
||
|
|
where: { phone, tenantId, isDeleted: 0 }
|
||
|
|
});
|
||
|
|
if (existingRenter) {
|
||
|
|
return res.status(400).json({
|
||
|
|
code: 400,
|
||
|
|
message: '该手机号已存在'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const renter = await Renter.create({
|
||
|
|
name,
|
||
|
|
phone,
|
||
|
|
email,
|
||
|
|
idCard,
|
||
|
|
gender,
|
||
|
|
birthday,
|
||
|
|
emergencyContact,
|
||
|
|
emergencyPhone,
|
||
|
|
address,
|
||
|
|
workUnit,
|
||
|
|
remark,
|
||
|
|
tenantId,
|
||
|
|
createBy,
|
||
|
|
status: 'active'
|
||
|
|
});
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
code: 200,
|
||
|
|
message: '创建成功',
|
||
|
|
data: renter
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('创建租客失败:', error);
|
||
|
|
res.status(500).json({
|
||
|
|
code: 500,
|
||
|
|
message: '创建租客失败'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 更新租客
|
||
|
|
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 res.status(404).json({
|
||
|
|
code: 404,
|
||
|
|
message: '租客不存在'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
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 res.status(400).json({
|
||
|
|
code: 400,
|
||
|
|
message: '该手机号已被其他租客使用'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
await renter.update({
|
||
|
|
name,
|
||
|
|
phone,
|
||
|
|
email,
|
||
|
|
idCard,
|
||
|
|
gender,
|
||
|
|
birthday,
|
||
|
|
emergencyContact,
|
||
|
|
emergencyPhone,
|
||
|
|
address,
|
||
|
|
workUnit,
|
||
|
|
remark,
|
||
|
|
status,
|
||
|
|
updateBy
|
||
|
|
});
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
code: 200,
|
||
|
|
message: '更新成功',
|
||
|
|
data: renter
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('更新租客失败:', error);
|
||
|
|
res.status(500).json({
|
||
|
|
code: 500,
|
||
|
|
message: '更新租客失败'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 删除租客
|
||
|
|
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 res.status(404).json({
|
||
|
|
code: 404,
|
||
|
|
message: '租客不存在'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// 检查是否有进行中的租赁
|
||
|
|
const activeRentals = await Rental.count({
|
||
|
|
where: {
|
||
|
|
tenantName: renter.name,
|
||
|
|
tenantId,
|
||
|
|
status: 'active'
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
if (activeRentals > 0) {
|
||
|
|
return res.status(400).json({
|
||
|
|
code: 400,
|
||
|
|
message: '该租客有进行中的租赁,无法删除'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
await renter.update({ isDeleted: 1 });
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
code: 200,
|
||
|
|
message: '删除成功'
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('删除租客失败:', error);
|
||
|
|
res.status(500).json({
|
||
|
|
code: 500,
|
||
|
|
message: '删除租客失败'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 获取租客下拉列表(用于租赁表单)
|
||
|
|
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
|
||
|
|
});
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
code: 200,
|
||
|
|
data: renters.map(r => ({
|
||
|
|
value: r.id,
|
||
|
|
label: `${r.name} ${r.phone ? '(' + r.phone + ')' : ''}`
|
||
|
|
}))
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('获取租客选项失败:', error);
|
||
|
|
res.status(500).json({
|
||
|
|
code: 500,
|
||
|
|
message: '获取租客选项失败'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
module.exports = {
|
||
|
|
getRenters,
|
||
|
|
getRenterList,
|
||
|
|
getRenterById,
|
||
|
|
createRenter,
|
||
|
|
updateRenter,
|
||
|
|
deleteRenter,
|
||
|
|
getRenterOptions
|
||
|
|
};
|