diff --git a/add_fields.js b/add_fields.js new file mode 100644 index 0000000..079ba71 --- /dev/null +++ b/add_fields.js @@ -0,0 +1,53 @@ +const mysql = require('mysql2/promise'); + +async function addFields() { + try { + // 连接到数据库 + const connection = await mysql.createConnection({ + host: '8.152.207.41', + user: 'rentease', + password: 'Wxx@123!', + database: 'rentease' + }); + + console.log('成功连接到数据库'); + + // 检查 subStatus 字段是否存在 + const [subStatusResult] = await connection.query(` + SHOW COLUMNS FROM rooms LIKE 'subStatus' + `); + + // 如果 subStatus 字段不存在,则添加 + if (subStatusResult.length === 0) { + await connection.query(` + ALTER TABLE rooms ADD COLUMN subStatus ENUM('normal', 'soon_expire', 'expired') NOT NULL DEFAULT 'normal' + `); + console.log('添加 subStatus 字段成功'); + } else { + console.log('subStatus 字段已存在'); + } + + // 检查 otherStatus 字段是否存在 + const [otherStatusResult] = await connection.query(` + SHOW COLUMNS FROM rooms LIKE 'otherStatus' + `); + + // 如果 otherStatus 字段不存在,则添加 + if (otherStatusResult.length === 0) { + await connection.query(` + ALTER TABLE rooms ADD COLUMN otherStatus ENUM('', 'cleaning', 'maintenance') NOT NULL DEFAULT '' + `); + console.log('添加 otherStatus 字段成功'); + } else { + console.log('otherStatus 字段已存在'); + } + + // 关闭连接 + await connection.end(); + console.log('数据库连接已关闭'); + } catch (error) { + console.error('添加字段时出错:', error); + } +} + +addFields(); \ No newline at end of file diff --git a/add_fields.sql b/add_fields.sql new file mode 100644 index 0000000..062ee75 --- /dev/null +++ b/add_fields.sql @@ -0,0 +1,31 @@ +-- 为 rooms 表添加字段 +ALTER TABLE rooms ADD COLUMN updateTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE rooms ADD COLUMN isDeleted INT NOT NULL DEFAULT 0; + +-- 为 tenants 表添加字段 +ALTER TABLE tenants ADD COLUMN updateTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE tenants ADD COLUMN isDeleted INT NOT NULL DEFAULT 0; + +-- 为 regions 表添加字段 +ALTER TABLE regions ADD COLUMN updateTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE regions ADD COLUMN isDeleted INT NOT NULL DEFAULT 0; + +-- 为 apartments 表添加字段 +ALTER TABLE apartments ADD COLUMN updateTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE apartments ADD COLUMN isDeleted INT NOT NULL DEFAULT 0; + +-- 为 contracts 表添加字段 +ALTER TABLE contracts ADD COLUMN updateTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE contracts ADD COLUMN isDeleted INT NOT NULL DEFAULT 0; + +-- 为 rentals 表添加字段 +ALTER TABLE rentals ADD COLUMN updateTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE rentals ADD COLUMN isDeleted INT NOT NULL DEFAULT 0; + +-- 为 water_bills 表添加字段 +ALTER TABLE water_bills ADD COLUMN updateTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE water_bills ADD COLUMN isDeleted INT NOT NULL DEFAULT 0; + +-- 为 electricity_bills 表添加字段 +ALTER TABLE electricity_bills ADD COLUMN updateTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE electricity_bills ADD COLUMN isDeleted INT NOT NULL DEFAULT 0; \ No newline at end of file diff --git a/config/db.js b/config/db.js index cc20c7a..7b07715 100644 --- a/config/db.js +++ b/config/db.js @@ -6,7 +6,7 @@ const createDatabase = async () => { try { // 连接到MySQL服务器 const connection = await mysql.createConnection({ - host: 'localhost', + host: '8.152.207.41', user: 'rentease', password: 'Wxx@123!' }); @@ -28,7 +28,7 @@ const sequelize = new Sequelize( 'rentease', // 用户名 'Wxx@123!', // 密码 { - host: 'localhost', + host: '8.152.207.41', dialect: 'mysql', logging: false, timezone: '+08:00' @@ -45,7 +45,7 @@ const testConnection = async () => { 'rentease', // 用户名 'Wxx@123!', // 密码 { - host: 'localhost', + host: '8.152.207.41', dialect: 'mysql', logging: false, timezone: '+08:00' diff --git a/controllers/apartmentController.js b/controllers/apartmentController.js index d35e46a..19fa133 100644 --- a/controllers/apartmentController.js +++ b/controllers/apartmentController.js @@ -13,14 +13,16 @@ const formatDate = (date) => { const formatApartmentData = (apartment) => { const formattedApartment = { ...apartment.toJSON(), - createTime: formatDate(apartment.createTime) + createTime: formatDate(apartment.createTime), + updateTime: formatDate(apartment.updateTime) }; // 格式化关联数据 if (formattedApartment.Region) { formattedApartment.Region = { ...formattedApartment.Region, - createTime: formatDate(formattedApartment.Region.createTime) + createTime: formatDate(formattedApartment.Region.createTime), + updateTime: formatDate(formattedApartment.Region.updateTime) }; } @@ -33,7 +35,7 @@ const getAllApartments = async (req, res) => { const { regionId, name, page = 1, pageSize = 10 } = req.query; // 构建查询条件 - const where = {}; + const where = { isDeleted: 0 }; if (regionId) { where.regionId = regionId; } @@ -73,7 +75,8 @@ const getAllApartments = async (req, res) => { const getApartmentById = async (req, res) => { try { const { id } = req.params; - const apartment = await Apartment.findByPk(id, { + const apartment = await Apartment.findOne({ + where: { id, isDeleted: 0 }, include: [Region] }); if (!apartment) { @@ -102,7 +105,9 @@ const updateApartment = async (req, res) => { try { const { id } = req.params; const { regionId, name, address } = req.body; - const apartment = await Apartment.findByPk(id); + const apartment = await Apartment.findOne({ + where: { id, isDeleted: 0 } + }); if (!apartment) { return res.status(404).json({ error: '公寓不存在' }); } @@ -113,15 +118,17 @@ const updateApartment = async (req, res) => { } }; -// 删除公寓 +// 删除公寓(软删除) const deleteApartment = async (req, res) => { try { const { id } = req.params; - const apartment = await Apartment.findByPk(id); + const apartment = await Apartment.findOne({ + where: { id, isDeleted: 0 } + }); if (!apartment) { return res.status(404).json({ error: '公寓不存在' }); } - await apartment.destroy(); + await apartment.update({ isDeleted: 1 }); res.status(200).json({ message: '公寓删除成功' }); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/controllers/contractController.js b/controllers/contractController.js index 21e3eb0..249048e 100644 --- a/controllers/contractController.js +++ b/controllers/contractController.js @@ -14,26 +14,30 @@ const formatContractData = (contract) => { ...contract.toJSON(), startDate: formatDate(contract.startDate), endDate: formatDate(contract.endDate), - createTime: formatDate(contract.createTime) + createTime: formatDate(contract.createTime), + updateTime: formatDate(contract.updateTime) }; // 格式化关联数据 if (formattedContract.Room) { formattedContract.Room = { ...formattedContract.Room, - createTime: formatDate(formattedContract.Room.createTime) + createTime: formatDate(formattedContract.Room.createTime), + updateTime: formatDate(formattedContract.Room.updateTime) }; if (formattedContract.Room.Apartment) { formattedContract.Room.Apartment = { ...formattedContract.Room.Apartment, - createTime: formatDate(formattedContract.Room.Apartment.createTime) + createTime: formatDate(formattedContract.Room.Apartment.createTime), + updateTime: formatDate(formattedContract.Room.Apartment.updateTime) }; if (formattedContract.Room.Apartment.Region) { formattedContract.Room.Apartment.Region = { ...formattedContract.Room.Apartment.Region, - createTime: formatDate(formattedContract.Room.Apartment.Region.createTime) + createTime: formatDate(formattedContract.Room.Apartment.Region.createTime), + updateTime: formatDate(formattedContract.Room.Apartment.Region.updateTime) }; } } @@ -42,7 +46,8 @@ const formatContractData = (contract) => { if (formattedContract.Tenant) { formattedContract.Tenant = { ...formattedContract.Tenant, - createTime: formatDate(formattedContract.Tenant.createTime) + createTime: formatDate(formattedContract.Tenant.createTime), + updateTime: formatDate(formattedContract.Tenant.updateTime) }; } @@ -53,17 +58,28 @@ const formatContractData = (contract) => { const getAllContracts = async (req, res) => { try { const contracts = await Contract.findAll({ + where: { isDeleted: 0 }, include: [ { model: Room, + where: { isDeleted: 0 }, include: [ { model: Apartment, - include: [Region] + where: { isDeleted: 0 }, + include: [ + { + model: Region, + where: { isDeleted: 0 } + } + ] } ] }, - Tenant + { + model: Tenant, + where: { isDeleted: 0 } + } ] }); const formattedContracts = contracts.map(formatContractData); @@ -77,18 +93,29 @@ const getAllContracts = async (req, res) => { const getContractById = async (req, res) => { try { const { id } = req.params; - const contract = await Contract.findByPk(id, { + const contract = await Contract.findOne({ + where: { id, isDeleted: 0 }, include: [ { model: Room, + where: { isDeleted: 0 }, include: [ { model: Apartment, - include: [Region] + where: { isDeleted: 0 }, + include: [ + { + model: Region, + where: { isDeleted: 0 } + } + ] } ] }, - Tenant + { + model: Tenant, + where: { isDeleted: 0 } + } ] }); if (!contract) { @@ -117,7 +144,9 @@ const updateContract = async (req, res) => { try { const { id } = req.params; const { roomId, tenantId, startDate, endDate, rent, deposit, status } = req.body; - const contract = await Contract.findByPk(id); + const contract = await Contract.findOne({ + where: { id, isDeleted: 0 } + }); if (!contract) { return res.status(404).json({ error: '合同不存在' }); } @@ -128,15 +157,17 @@ const updateContract = async (req, res) => { } }; -// 删除合同 +// 删除合同(软删除) const deleteContract = async (req, res) => { try { const { id } = req.params; - const contract = await Contract.findByPk(id); + const contract = await Contract.findOne({ + where: { id, isDeleted: 0 } + }); if (!contract) { return res.status(404).json({ error: '合同不存在' }); } - await contract.destroy(); + await contract.update({ isDeleted: 1 }); res.status(200).json({ message: '合同删除成功' }); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/controllers/electricityBillController.js b/controllers/electricityBillController.js index 675c392..1b4fc09 100644 --- a/controllers/electricityBillController.js +++ b/controllers/electricityBillController.js @@ -15,14 +15,16 @@ const formatElectricityBillData = (bill) => { ...bill.toJSON(), startDate: formatDate(bill.startDate), endDate: formatDate(bill.endDate), - createTime: formatDate(bill.createTime) + createTime: formatDate(bill.createTime), + updateTime: formatDate(bill.updateTime) }; // 格式化关联数据 if (formattedBill.Room) { formattedBill.Room = { ...formattedBill.Room, - createTime: formatDate(formattedBill.Room.createTime) + createTime: formatDate(formattedBill.Room.createTime), + updateTime: formatDate(formattedBill.Room.updateTime) }; } @@ -35,7 +37,7 @@ const getAllElectricityBills = async (req, res) => { const { roomId, status, startDate, endDate, page = 1, pageSize = 10 } = req.query; // 构建查询条件 - const where = {}; + const where = { isDeleted: 0 }; if (roomId) { where.roomId = roomId; } @@ -55,7 +57,12 @@ const getAllElectricityBills = async (req, res) => { // 查询电费数据 const { count, rows } = await ElectricityBill.findAndCountAll({ where, - include: [Room], + include: [ + { + model: Room, + where: { isDeleted: 0 } + } + ], limit: parseInt(pageSize), offset: parseInt(offset) }); @@ -79,8 +86,14 @@ const getAllElectricityBills = async (req, res) => { const getElectricityBillById = async (req, res) => { try { const { id } = req.params; - const bill = await ElectricityBill.findByPk(id, { - include: [Room] + const bill = await ElectricityBill.findOne({ + where: { id, isDeleted: 0 }, + include: [ + { + model: Room, + where: { isDeleted: 0 } + } + ] }); if (!bill) { return res.status(404).json({ error: '电费记录不存在' }); @@ -125,7 +138,9 @@ const updateElectricityBill = async (req, res) => { const { id } = req.params; const { startDate, endDate, startReading, endReading, unitPrice, status } = req.body; - const bill = await ElectricityBill.findByPk(id); + const bill = await ElectricityBill.findOne({ + where: { id, isDeleted: 0 } + }); if (!bill) { return res.status(404).json({ error: '电费记录不存在' }); } @@ -156,15 +171,17 @@ const updateElectricityBill = async (req, res) => { } }; -// 删除电费记录 +// 删除电费记录(软删除) const deleteElectricityBill = async (req, res) => { try { const { id } = req.params; - const bill = await ElectricityBill.findByPk(id); + const bill = await ElectricityBill.findOne({ + where: { id, isDeleted: 0 } + }); if (!bill) { return res.status(404).json({ error: '电费记录不存在' }); } - await bill.destroy(); + await bill.update({ isDeleted: 1 }); res.status(200).json({ message: '电费记录删除成功' }); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/controllers/regionController.js b/controllers/regionController.js index 8518eb3..0b0e1f4 100644 --- a/controllers/regionController.js +++ b/controllers/regionController.js @@ -12,14 +12,17 @@ const formatDate = (date) => { const formatRegionData = (region) => { return { ...region.toJSON(), - createTime: formatDate(region.createTime) + createTime: formatDate(region.createTime), + updateTime: formatDate(region.updateTime) }; }; // 获取所有区域 const getAllRegions = async (req, res) => { try { - const regions = await Region.findAll(); + const regions = await Region.findAll({ + where: { isDeleted: 0 } + }); const formattedRegions = regions.map(formatRegionData); res.status(200).json(formattedRegions); } catch (error) { @@ -31,7 +34,9 @@ const getAllRegions = async (req, res) => { const getRegionById = async (req, res) => { try { const { id } = req.params; - const region = await Region.findByPk(id); + const region = await Region.findOne({ + where: { id, isDeleted: 0 } + }); if (!region) { return res.status(404).json({ error: '区域不存在' }); } @@ -58,7 +63,9 @@ const updateRegion = async (req, res) => { try { const { id } = req.params; const { name, description } = req.body; - const region = await Region.findByPk(id); + const region = await Region.findOne({ + where: { id, isDeleted: 0 } + }); if (!region) { return res.status(404).json({ error: '区域不存在' }); } @@ -69,15 +76,17 @@ const updateRegion = async (req, res) => { } }; -// 删除区域 +// 删除区域(软删除) const deleteRegion = async (req, res) => { try { const { id } = req.params; - const region = await Region.findByPk(id); + const region = await Region.findOne({ + where: { id, isDeleted: 0 } + }); if (!region) { return res.status(404).json({ error: '区域不存在' }); } - await region.destroy(); + await region.update({ isDeleted: 1 }); res.status(200).json({ message: '区域删除成功' }); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/controllers/rentalController.js b/controllers/rentalController.js index a852e83..d49a4e1 100644 --- a/controllers/rentalController.js +++ b/controllers/rentalController.js @@ -15,7 +15,8 @@ const formatRentalData = (rental) => { ...rental.toJSON(), startDate: formatDate(rental.startDate), endDate: formatDate(rental.endDate), - createTime: formatDate(rental.createTime) + createTime: formatDate(rental.createTime), + updateTime: formatDate(rental.updateTime) }; // 格式化关联数据 @@ -24,7 +25,8 @@ const formatRentalData = (rental) => { ...formattedRental.Contract, startDate: formatDate(formattedRental.Contract.startDate), endDate: formatDate(formattedRental.Contract.endDate), - createTime: formatDate(formattedRental.Contract.createTime) + createTime: formatDate(formattedRental.Contract.createTime), + updateTime: formatDate(formattedRental.Contract.updateTime) }; } @@ -42,8 +44,13 @@ const checkAndUpdateRentalStatus = async () => { // 查找所有活跃的租房记录 const rentals = await Rental.findAll({ - where: { status: 'active' }, - include: [Room] + where: { status: 'active', isDeleted: 0 }, + include: [ + { + model: Room, + where: { isDeleted: 0 } + } + ] }); // 检查每个租房记录的状态 @@ -81,7 +88,7 @@ const getAllRentals = async (req, res) => { const { roomNumber, tenantName, status, page = 1, pageSize = 10 } = req.query; // 构建查询条件 - const where = {}; + const where = { isDeleted: 0 }; if (status) { where.status = status; } @@ -90,19 +97,28 @@ const getAllRentals = async (req, res) => { const include = [ { model: Room, + where: roomNumber ? { roomNumber: { [Op.like]: `%${roomNumber}%` }, isDeleted: 0 } : { isDeleted: 0 }, include: [ { model: Apartment, - include: [Region] + where: { isDeleted: 0 }, + include: [ + { + model: Region, + where: { isDeleted: 0 } + } + ] } - ], - where: roomNumber ? { roomNumber: { [Op.like]: `%${roomNumber}%` } } : {} + ] }, { model: Tenant, - where: tenantName ? { name: { [Op.like]: `%${tenantName}%` } } : {} + where: tenantName ? { name: { [Op.like]: `%${tenantName}%` }, isDeleted: 0 } : { isDeleted: 0 } }, - Contract + { + model: Contract, + where: { isDeleted: 0 } + } ]; // 计算偏移量 @@ -135,19 +151,33 @@ const getAllRentals = async (req, res) => { const getRentalById = async (req, res) => { try { const { id } = req.params; - const rental = await Rental.findByPk(id, { + const rental = await Rental.findOne({ + where: { id, isDeleted: 0 }, include: [ { model: Room, + where: { isDeleted: 0 }, include: [ { model: Apartment, - include: [Region] + where: { isDeleted: 0 }, + include: [ + { + model: Region, + where: { isDeleted: 0 } + } + ] } ] }, - Tenant, - Contract + { + model: Tenant, + where: { isDeleted: 0 } + }, + { + model: Contract, + where: { isDeleted: 0 } + } ] }); if (!rental) { @@ -286,7 +316,9 @@ 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.findByPk(id); + const rental = await Rental.findOne({ + where: { id, isDeleted: 0 } + }); if (!rental) { return res.status(404).json({ error: '租房记录不存在' }); } @@ -297,15 +329,17 @@ const updateRental = async (req, res) => { } }; -// 删除租房 +// 删除租房(软删除) const deleteRental = async (req, res) => { try { const { id } = req.params; - const rental = await Rental.findByPk(id); + const rental = await Rental.findOne({ + where: { id, isDeleted: 0 } + }); if (!rental) { return res.status(404).json({ error: '租房记录不存在' }); } - await rental.destroy(); + await rental.update({ isDeleted: 1 }); res.status(200).json({ message: '租房记录删除成功' }); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/controllers/roomController.js b/controllers/roomController.js index 49c93bc..4b50459 100644 --- a/controllers/roomController.js +++ b/controllers/roomController.js @@ -13,14 +13,16 @@ const formatDate = (date) => { const formatRoomData = (room) => { const formattedRoom = { ...room.toJSON(), - createTime: formatDate(room.createTime) + createTime: formatDate(room.createTime), + updateTime: formatDate(room.updateTime) }; // 格式化关联数据 if (formattedRoom.Apartment) { formattedRoom.Apartment = { ...formattedRoom.Apartment, - createTime: formatDate(formattedRoom.Apartment.createTime) + createTime: formatDate(formattedRoom.Apartment.createTime), + updateTime: formatDate(formattedRoom.Apartment.updateTime) }; } @@ -31,14 +33,16 @@ const formatRoomData = (room) => { ...rental, startDate: formatDate(rental.startDate), endDate: formatDate(rental.endDate), - createTime: formatDate(rental.createTime) + createTime: formatDate(rental.createTime), + updateTime: formatDate(rental.updateTime) }; // 格式化租客信息 if (formattedRental.Tenant) { formattedRental.Tenant = { ...formattedRental.Tenant, - createTime: formatDate(formattedRental.Tenant.createTime) + createTime: formatDate(formattedRental.Tenant.createTime), + updateTime: formatDate(formattedRental.Tenant.updateTime) }; } @@ -60,7 +64,7 @@ const checkAndUpdateRentalStatus = async () => { // 查找所有活跃的租房记录 const rentals = await Rental.findAll({ - where: { status: 'active' } + where: { status: 'active', isDeleted: 0 } }); // 检查每个租房记录的状态 @@ -73,14 +77,20 @@ const checkAndUpdateRentalStatus = async () => { await rental.update({ status: 'expired' }); // 更新房间状态为空房 const room = await Room.findByPk(rental.roomId); - if (room) { - await room.update({ status: 'empty' }); + if (room && room.status === 'rented') { + await room.update({ status: 'empty', subStatus: 'normal' }); } } else if (endDate <= tenDaysLater) { - // 更新房间状态为即将到期 + // 更新房间附属状态为即将到期 const room = await Room.findByPk(rental.roomId); if (room && room.status === 'rented') { - await room.update({ status: 'soon_expire' }); + await room.update({ subStatus: 'soon_expire' }); + } + } else { + // 更新房间附属状态为正常 + const room = await Room.findByPk(rental.roomId); + if (room && room.status === 'rented') { + await room.update({ subStatus: 'normal' }); } } } @@ -97,10 +107,10 @@ const getAllRooms = async (req, res) => { // 先检查并更新租房状态 await checkAndUpdateRentalStatus(); - const { apartmentId, roomNumber, status, page = 1, pageSize = 10 } = req.query; + const { apartmentId, roomNumber, status, otherStatus, subStatus, page = 1, pageSize = 10 } = req.query; // 构建查询条件 - const where = {}; + const where = { isDeleted: 0 }; if (apartmentId) { where.apartmentId = apartmentId; } @@ -112,6 +122,12 @@ const getAllRooms = async (req, res) => { if (status) { where.status = status; } + if (otherStatus) { + where.otherStatus = otherStatus; + } + if (subStatus) { + where.subStatus = subStatus; + } // 计算偏移量 const offset = (page - 1) * pageSize; @@ -187,7 +203,8 @@ const getRoomById = async (req, res) => { await checkAndUpdateRentalStatus(); const { id } = req.params; - const room = await Room.findByPk(id, { + const room = await Room.findOne({ + where: { id, isDeleted: 0 }, include: [Apartment] }); if (!room) { @@ -238,8 +255,8 @@ const getRoomById = async (req, res) => { // 创建房间 const createRoom = async (req, res) => { try { - const { apartmentId, roomNumber, area, price, status } = req.body; - const room = await Room.create({ apartmentId, roomNumber, area, price, status }); + const { apartmentId, roomNumber, area, monthlyPrice, yearlyPrice, status, subStatus, otherStatus } = req.body; + const room = await Room.create({ apartmentId, roomNumber, area, monthlyPrice, yearlyPrice, status, subStatus, otherStatus }); res.status(201).json(room); } catch (error) { res.status(500).json({ error: error.message }); @@ -250,27 +267,31 @@ const createRoom = async (req, res) => { const updateRoom = async (req, res) => { try { const { id } = req.params; - const { apartmentId, roomNumber, area, price, status } = req.body; - const room = await Room.findByPk(id); + const { apartmentId, roomNumber, area, monthlyPrice, yearlyPrice, status, subStatus, otherStatus } = req.body; + const room = await Room.findOne({ + where: { id, isDeleted: 0 } + }); if (!room) { return res.status(404).json({ error: '房间不存在' }); } - await room.update({ apartmentId, roomNumber, area, price, status }); + await room.update({ apartmentId, roomNumber, area, monthlyPrice, yearlyPrice, status, subStatus, otherStatus }); res.status(200).json(room); } catch (error) { res.status(500).json({ error: error.message }); } }; -// 删除房间 +// 删除房间(软删除) const deleteRoom = async (req, res) => { try { const { id } = req.params; - const room = await Room.findByPk(id); + const room = await Room.findOne({ + where: { id, isDeleted: 0 } + }); if (!room) { return res.status(404).json({ error: '房间不存在' }); } - await room.destroy(); + await room.update({ isDeleted: 1 }); res.status(200).json({ message: '房间删除成功' }); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/controllers/tenantController.js b/controllers/tenantController.js index 1d069a5..9f0ccda 100644 --- a/controllers/tenantController.js +++ b/controllers/tenantController.js @@ -12,14 +12,17 @@ const formatDate = (date) => { const formatTenantData = (tenant) => { return { ...tenant.toJSON(), - createTime: formatDate(tenant.createTime) + createTime: formatDate(tenant.createTime), + updateTime: formatDate(tenant.updateTime) }; }; // 获取所有租客 const getAllTenants = async (req, res) => { try { - const tenants = await Tenant.findAll(); + const tenants = await Tenant.findAll({ + where: { isDeleted: 0 } + }); const formattedTenants = tenants.map(formatTenantData); res.status(200).json(formattedTenants); } catch (error) { @@ -31,7 +34,9 @@ const getAllTenants = async (req, res) => { const getTenantById = async (req, res) => { try { const { id } = req.params; - const tenant = await Tenant.findByPk(id); + const tenant = await Tenant.findOne({ + where: { id, isDeleted: 0 } + }); if (!tenant) { return res.status(404).json({ error: '租客不存在' }); } @@ -58,7 +63,9 @@ const updateTenant = async (req, res) => { try { const { id } = req.params; const { name, phone, idCard } = req.body; - const tenant = await Tenant.findByPk(id); + const tenant = await Tenant.findOne({ + where: { id, isDeleted: 0 } + }); if (!tenant) { return res.status(404).json({ error: '租客不存在' }); } @@ -69,15 +76,17 @@ const updateTenant = async (req, res) => { } }; -// 删除租客 +// 删除租客(软删除) const deleteTenant = async (req, res) => { try { const { id } = req.params; - const tenant = await Tenant.findByPk(id); + const tenant = await Tenant.findOne({ + where: { id, isDeleted: 0 } + }); if (!tenant) { return res.status(404).json({ error: '租客不存在' }); } - await tenant.destroy(); + await tenant.update({ isDeleted: 1 }); res.status(200).json({ message: '租客删除成功' }); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/controllers/waterBillController.js b/controllers/waterBillController.js index cdaab14..7e9b638 100644 --- a/controllers/waterBillController.js +++ b/controllers/waterBillController.js @@ -15,14 +15,16 @@ const formatWaterBillData = (bill) => { ...bill.toJSON(), startDate: formatDate(bill.startDate), endDate: formatDate(bill.endDate), - createTime: formatDate(bill.createTime) + createTime: formatDate(bill.createTime), + updateTime: formatDate(bill.updateTime) }; // 格式化关联数据 if (formattedBill.Room) { formattedBill.Room = { ...formattedBill.Room, - createTime: formatDate(formattedBill.Room.createTime) + createTime: formatDate(formattedBill.Room.createTime), + updateTime: formatDate(formattedBill.Room.updateTime) }; } @@ -35,7 +37,7 @@ const getAllWaterBills = async (req, res) => { const { roomId, status, startDate, endDate, page = 1, pageSize = 10 } = req.query; // 构建查询条件 - const where = {}; + const where = { isDeleted: 0 }; if (roomId) { where.roomId = roomId; } @@ -55,7 +57,12 @@ const getAllWaterBills = async (req, res) => { // 查询水费数据 const { count, rows } = await WaterBill.findAndCountAll({ where, - include: [Room], + include: [ + { + model: Room, + where: { isDeleted: 0 } + } + ], limit: parseInt(pageSize), offset: parseInt(offset) }); @@ -79,8 +86,14 @@ const getAllWaterBills = async (req, res) => { const getWaterBillById = async (req, res) => { try { const { id } = req.params; - const bill = await WaterBill.findByPk(id, { - include: [Room] + const bill = await WaterBill.findOne({ + where: { id, isDeleted: 0 }, + include: [ + { + model: Room, + where: { isDeleted: 0 } + } + ] }); if (!bill) { return res.status(404).json({ error: '水费记录不存在' }); @@ -125,7 +138,9 @@ const updateWaterBill = async (req, res) => { const { id } = req.params; const { startDate, endDate, startReading, endReading, unitPrice, status } = req.body; - const bill = await WaterBill.findByPk(id); + const bill = await WaterBill.findOne({ + where: { id, isDeleted: 0 } + }); if (!bill) { return res.status(404).json({ error: '水费记录不存在' }); } @@ -156,15 +171,17 @@ const updateWaterBill = async (req, res) => { } }; -// 删除水费记录 +// 删除水费记录(软删除) const deleteWaterBill = async (req, res) => { try { const { id } = req.params; - const bill = await WaterBill.findByPk(id); + const bill = await WaterBill.findOne({ + where: { id, isDeleted: 0 } + }); if (!bill) { return res.status(404).json({ error: '水费记录不存在' }); } - await bill.destroy(); + await bill.update({ isDeleted: 1 }); res.status(200).json({ message: '水费记录删除成功' }); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/models/Apartment.js b/models/Apartment.js index bf4d1f0..5607854 100644 --- a/models/Apartment.js +++ b/models/Apartment.js @@ -27,6 +27,16 @@ const Apartment = sequelize.define('Apartment', { createTime: { type: DataTypes.DATE, defaultValue: DataTypes.NOW + }, + updateTime: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + onUpdate: DataTypes.NOW + }, + isDeleted: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 } }, { tableName: 'apartments', diff --git a/models/Contract.js b/models/Contract.js index 121c3c6..a058aea 100644 --- a/models/Contract.js +++ b/models/Contract.js @@ -49,6 +49,16 @@ const Contract = sequelize.define('Contract', { createTime: { type: DataTypes.DATE, defaultValue: DataTypes.NOW + }, + updateTime: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + onUpdate: DataTypes.NOW + }, + isDeleted: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 } }, { tableName: 'contracts', diff --git a/models/ElectricityBill.js b/models/ElectricityBill.js index 5bd09f2..4960f72 100644 --- a/models/ElectricityBill.js +++ b/models/ElectricityBill.js @@ -52,6 +52,16 @@ const ElectricityBill = sequelize.define('ElectricityBill', { createTime: { type: DataTypes.DATE, defaultValue: DataTypes.NOW + }, + updateTime: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + onUpdate: DataTypes.NOW + }, + isDeleted: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 } }, { tableName: 'electricity_bills', diff --git a/models/Region.js b/models/Region.js index 3856f5f..ac30803 100644 --- a/models/Region.js +++ b/models/Region.js @@ -19,6 +19,16 @@ const Region = sequelize.define('Region', { createTime: { type: DataTypes.DATE, defaultValue: DataTypes.NOW + }, + updateTime: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + onUpdate: DataTypes.NOW + }, + isDeleted: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 } }, { tableName: 'regions', diff --git a/models/Rental.js b/models/Rental.js index e9c3aa4..fcffcd4 100644 --- a/models/Rental.js +++ b/models/Rental.js @@ -62,6 +62,16 @@ const Rental = sequelize.define('Rental', { createTime: { type: DataTypes.DATE, defaultValue: DataTypes.NOW + }, + updateTime: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + onUpdate: DataTypes.NOW + }, + isDeleted: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 } }, { tableName: 'rentals', diff --git a/models/Room.js b/models/Room.js index 2eee9ea..de16835 100644 --- a/models/Room.js +++ b/models/Room.js @@ -24,18 +24,42 @@ const Room = sequelize.define('Room', { type: DataTypes.DECIMAL(10, 2), allowNull: false }, - price: { + monthlyPrice: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false + }, + yearlyPrice: { type: DataTypes.DECIMAL(10, 2), allowNull: false }, status: { - type: DataTypes.ENUM('empty', 'rented', 'soon_expire', 'expired', 'cleaning', 'maintenance'), + type: DataTypes.ENUM('empty', 'rented'), allowNull: false, defaultValue: 'empty' }, + subStatus: { + type: DataTypes.ENUM('normal', 'soon_expire', 'expired'), + allowNull: false, + defaultValue: 'normal' + }, + otherStatus: { + type: DataTypes.ENUM('', 'cleaning', 'maintenance'), + allowNull: false, + defaultValue: '' + }, createTime: { type: DataTypes.DATE, defaultValue: DataTypes.NOW + }, + updateTime: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + onUpdate: DataTypes.NOW + }, + isDeleted: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 } }, { tableName: 'rooms', diff --git a/models/Tenant.js b/models/Tenant.js index a968f5d..3a0c425 100644 --- a/models/Tenant.js +++ b/models/Tenant.js @@ -23,6 +23,16 @@ const Tenant = sequelize.define('Tenant', { createTime: { type: DataTypes.DATE, defaultValue: DataTypes.NOW + }, + updateTime: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + onUpdate: DataTypes.NOW + }, + isDeleted: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 } }, { tableName: 'tenants', diff --git a/models/WaterBill.js b/models/WaterBill.js index 7e451da..43ee603 100644 --- a/models/WaterBill.js +++ b/models/WaterBill.js @@ -52,6 +52,16 @@ const WaterBill = sequelize.define('WaterBill', { createTime: { type: DataTypes.DATE, defaultValue: DataTypes.NOW + }, + updateTime: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + onUpdate: DataTypes.NOW + }, + isDeleted: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 } }, { tableName: 'water_bills', diff --git a/update_db.js b/update_db.js new file mode 100644 index 0000000..d66c192 --- /dev/null +++ b/update_db.js @@ -0,0 +1,37 @@ +const mysql = require('mysql2/promise'); +const fs = require('fs'); + +async function updateDatabase() { + try { + // 连接到数据库 + const connection = await mysql.createConnection({ + host: '8.152.207.41', + user: 'rentease', + password: 'Wxx@123!', + database: 'rentease' + }); + + console.log('成功连接到数据库'); + + // 读取 SQL 文件 + const sqlContent = fs.readFileSync('add_fields.sql', 'utf8'); + + // 执行 SQL 语句 + const statements = sqlContent.split(';').filter(statement => statement.trim()); + + for (const statement of statements) { + await connection.query(statement); + console.log(`执行 SQL: ${statement.substring(0, 50)}...`); + } + + console.log('数据库表结构更新完成'); + + // 关闭连接 + await connection.end(); + console.log('数据库连接已关闭'); + } catch (error) { + console.error('更新数据库表结构时出错:', error); + } +} + +updateDatabase(); \ No newline at end of file diff --git a/update_room_price.js b/update_room_price.js new file mode 100644 index 0000000..283e22e --- /dev/null +++ b/update_room_price.js @@ -0,0 +1,41 @@ +const mysql = require('mysql2/promise'); +const fs = require('fs'); + +// 数据库连接配置 +const dbConfig = { + host: '8.152.207.41', + user: 'root', + password: '123456', + database: 'rentease', + port: 3306 +}; + +// 读取 SQL 文件 +const sqlFilePath = './update_room_price_fields.sql'; +const sqlContent = fs.readFileSync(sqlFilePath, 'utf8'); + +// 执行 SQL 语句 +const executeSql = async () => { + let connection; + try { + // 连接数据库 + connection = await mysql.createConnection(dbConfig); + console.log('成功连接到数据库'); + + // 执行 SQL 语句 + const [results] = await connection.execute(sqlContent); + console.log('数据库表结构更新成功'); + + } catch (error) { + console.error('更新数据库表结构时出错:', error); + } finally { + // 关闭数据库连接 + if (connection) { + await connection.end(); + console.log('数据库连接已关闭'); + } + } +}; + +// 执行脚本 +executeSql(); \ No newline at end of file diff --git a/update_room_price_fields.sql b/update_room_price_fields.sql new file mode 100644 index 0000000..dc4c8f4 --- /dev/null +++ b/update_room_price_fields.sql @@ -0,0 +1,16 @@ +-- 更新房间表结构,将原来的 price 字段改为 monthlyPrice 和 yearlyPrice 两个字段 + +-- 添加 monthlyPrice 字段 +ALTER TABLE rooms ADD COLUMN monthlyPrice DECIMAL(10, 2) NOT NULL DEFAULT 0 AFTER area; + +-- 添加 yearlyPrice 字段 +ALTER TABLE rooms ADD COLUMN yearlyPrice DECIMAL(10, 2) NOT NULL DEFAULT 0 AFTER monthlyPrice; + +-- 将原来的 price 字段值复制到 monthlyPrice 字段 +UPDATE rooms SET monthlyPrice = price; + +-- 计算年租金并更新 yearlyPrice 字段(月租金 * 12) +UPDATE rooms SET yearlyPrice = monthlyPrice * 12; + +-- 删除原来的 price 字段 +ALTER TABLE rooms DROP COLUMN price; \ No newline at end of file