This commit is contained in:
parent
6195a34212
commit
05cfcc1809
|
|
@ -1,53 +0,0 @@
|
||||||
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();
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
-- 为 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;
|
|
||||||
4
app.js
4
app.js
|
|
@ -6,8 +6,6 @@ const sequelize = require('./config/db');
|
||||||
const regionRoutes = require('./routes/region');
|
const regionRoutes = require('./routes/region');
|
||||||
const apartmentRoutes = require('./routes/apartment');
|
const apartmentRoutes = require('./routes/apartment');
|
||||||
const roomRoutes = require('./routes/room');
|
const roomRoutes = require('./routes/room');
|
||||||
const tenantRoutes = require('./routes/tenant');
|
|
||||||
const contractRoutes = require('./routes/contract');
|
|
||||||
const rentalRoutes = require('./routes/rental');
|
const rentalRoutes = require('./routes/rental');
|
||||||
const statisticsRoutes = require('./routes/statistics');
|
const statisticsRoutes = require('./routes/statistics');
|
||||||
const waterBillRoutes = require('./routes/waterBill');
|
const waterBillRoutes = require('./routes/waterBill');
|
||||||
|
|
@ -25,8 +23,6 @@ app.use(express.urlencoded({ extended: true }));
|
||||||
app.use('/api/regions', regionRoutes);
|
app.use('/api/regions', regionRoutes);
|
||||||
app.use('/api/apartments', apartmentRoutes);
|
app.use('/api/apartments', apartmentRoutes);
|
||||||
app.use('/api/rooms', roomRoutes);
|
app.use('/api/rooms', roomRoutes);
|
||||||
app.use('/api/tenants', tenantRoutes);
|
|
||||||
app.use('/api/contracts', contractRoutes);
|
|
||||||
app.use('/api/rentals', rentalRoutes);
|
app.use('/api/rentals', rentalRoutes);
|
||||||
app.use('/api/statistics', statisticsRoutes);
|
app.use('/api/statistics', statisticsRoutes);
|
||||||
app.use('/api/water-bills', waterBillRoutes);
|
app.use('/api/water-bills', waterBillRoutes);
|
||||||
|
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
const sequelize = require('./config/db');
|
|
||||||
const { Region, Apartment, Room, Tenant, Contract, Rental } = require('./models');
|
|
||||||
|
|
||||||
// 检查数据库数据的函数
|
|
||||||
async function checkData() {
|
|
||||||
try {
|
|
||||||
console.log('开始检查数据库数据...');
|
|
||||||
|
|
||||||
// 检查区域数据
|
|
||||||
const regions = await Region.findAll();
|
|
||||||
console.log(`区域数据数量: ${regions.length}`);
|
|
||||||
regions.forEach(region => {
|
|
||||||
console.log(`区域: ${region.name}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检查公寓数据
|
|
||||||
const apartments = await Apartment.findAll();
|
|
||||||
console.log(`\n公寓数据数量: ${apartments.length}`);
|
|
||||||
apartments.forEach(apartment => {
|
|
||||||
console.log(`公寓: ${apartment.name}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检查房间数据
|
|
||||||
const rooms = await Room.findAll();
|
|
||||||
console.log(`\n房间数据数量: ${rooms.length}`);
|
|
||||||
rooms.forEach(room => {
|
|
||||||
console.log(`房间: ${room.roomNumber}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检查租客数据
|
|
||||||
const tenants = await Tenant.findAll();
|
|
||||||
console.log(`\n租客数据数量: ${tenants.length}`);
|
|
||||||
tenants.forEach(tenant => {
|
|
||||||
console.log(`租客: ${tenant.name}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检查合同数据
|
|
||||||
const contracts = await Contract.findAll();
|
|
||||||
console.log(`\n合同数据数量: ${contracts.length}`);
|
|
||||||
contracts.forEach(contract => {
|
|
||||||
console.log(`合同 ID: ${contract.id}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检查租房数据
|
|
||||||
const rentals = await Rental.findAll();
|
|
||||||
console.log(`\n租房数据数量: ${rentals.length}`);
|
|
||||||
rentals.forEach(rental => {
|
|
||||||
console.log(`租房 ID: ${rental.id}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('\n数据检查完成!');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('检查数据时出错:', error);
|
|
||||||
} finally {
|
|
||||||
// 关闭数据库连接
|
|
||||||
await sequelize.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行检查操作
|
|
||||||
checkData();
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
const sequelize = require('./config/db');
|
|
||||||
const { Room, Rental, Tenant, Contract } = require('./models');
|
|
||||||
|
|
||||||
// 清空数据的函数
|
|
||||||
async function clearData() {
|
|
||||||
try {
|
|
||||||
console.log('开始清空数据...');
|
|
||||||
|
|
||||||
// 按照依赖关系的顺序删除数据
|
|
||||||
// 先删除租房记录(依赖于房间、租客和合同)
|
|
||||||
await Rental.destroy({ where: {} });
|
|
||||||
console.log('租房数据已删除');
|
|
||||||
|
|
||||||
// 删除合同记录(依赖于房间和租客)
|
|
||||||
await Contract.destroy({ where: {} });
|
|
||||||
console.log('合同数据已删除');
|
|
||||||
|
|
||||||
// 删除房间记录(依赖于公寓)
|
|
||||||
await Room.destroy({ where: {} });
|
|
||||||
console.log('房间数据已删除');
|
|
||||||
|
|
||||||
// 删除租客记录(无依赖)
|
|
||||||
await Tenant.destroy({ where: {} });
|
|
||||||
console.log('租客数据已删除');
|
|
||||||
|
|
||||||
console.log('数据清空完成!');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('清空数据时出错:', error);
|
|
||||||
} finally {
|
|
||||||
// 关闭数据库连接
|
|
||||||
await sequelize.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行清空操作
|
|
||||||
clearData();
|
|
||||||
46
config/db.js
46
config/db.js
|
|
@ -1,18 +1,40 @@
|
||||||
const { Sequelize } = require('sequelize');
|
const { Sequelize } = require('sequelize');
|
||||||
const mysql = require('mysql2/promise');
|
const mysql = require('mysql2/promise');
|
||||||
|
|
||||||
|
// 环境配置
|
||||||
|
const NODE_ENV = 'development';
|
||||||
|
|
||||||
|
// 数据库配置
|
||||||
|
const dbConfig = {
|
||||||
|
development: {
|
||||||
|
host: 'localhost',
|
||||||
|
user: 'root',
|
||||||
|
password: '123456',
|
||||||
|
database: 'rentease'
|
||||||
|
},
|
||||||
|
production: {
|
||||||
|
host: '8.152.207.41',
|
||||||
|
user: 'rentease',
|
||||||
|
password: 'Wxx@123!',
|
||||||
|
database: 'rentease'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取当前环境的配置
|
||||||
|
const currentConfig = dbConfig[NODE_ENV];
|
||||||
|
|
||||||
// 先创建数据库
|
// 先创建数据库
|
||||||
const createDatabase = async () => {
|
const createDatabase = async () => {
|
||||||
try {
|
try {
|
||||||
// 连接到MySQL服务器
|
// 连接到MySQL服务器
|
||||||
const connection = await mysql.createConnection({
|
const connection = await mysql.createConnection({
|
||||||
host: '8.152.207.41',
|
host: currentConfig.host,
|
||||||
user: 'rentease',
|
user: currentConfig.user,
|
||||||
password: 'Wxx@123!'
|
password: currentConfig.password
|
||||||
});
|
});
|
||||||
|
|
||||||
// 创建数据库
|
// 创建数据库
|
||||||
await connection.query('CREATE DATABASE IF NOT EXISTS rentease');
|
await connection.query(`CREATE DATABASE IF NOT EXISTS ${currentConfig.database}`);
|
||||||
console.log('数据库创建成功');
|
console.log('数据库创建成功');
|
||||||
await connection.end();
|
await connection.end();
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -24,11 +46,11 @@ const createDatabase = async () => {
|
||||||
|
|
||||||
// 创建数据库连接 - 使用MySQL
|
// 创建数据库连接 - 使用MySQL
|
||||||
const sequelize = new Sequelize(
|
const sequelize = new Sequelize(
|
||||||
'rentease', // 数据库名称
|
currentConfig.database, // 数据库名称
|
||||||
'rentease', // 用户名
|
currentConfig.user, // 用户名
|
||||||
'Wxx@123!', // 密码
|
currentConfig.password, // 密码
|
||||||
{
|
{
|
||||||
host: '8.152.207.41',
|
host: currentConfig.host,
|
||||||
dialect: 'mysql',
|
dialect: 'mysql',
|
||||||
logging: false,
|
logging: false,
|
||||||
timezone: '+08:00'
|
timezone: '+08:00'
|
||||||
|
|
@ -41,11 +63,11 @@ const testConnection = async () => {
|
||||||
await createDatabase();
|
await createDatabase();
|
||||||
// 重新创建sequelize实例,确保连接管理器是活跃的
|
// 重新创建sequelize实例,确保连接管理器是活跃的
|
||||||
const newSequelize = new Sequelize(
|
const newSequelize = new Sequelize(
|
||||||
'rentease', // 数据库名称
|
currentConfig.database, // 数据库名称
|
||||||
'rentease', // 用户名
|
currentConfig.user, // 用户名
|
||||||
'Wxx@123!', // 密码
|
currentConfig.password, // 密码
|
||||||
{
|
{
|
||||||
host: '8.152.207.41',
|
host: currentConfig.host,
|
||||||
dialect: 'mysql',
|
dialect: 'mysql',
|
||||||
logging: false,
|
logging: false,
|
||||||
timezone: '+08:00'
|
timezone: '+08:00'
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const sequelize = require('./db');
|
const sequelize = require('./db');
|
||||||
const { Region, Apartment, Room, Tenant, Contract, Rental } = require('../models');
|
const { Region, Apartment, Room, Rental } = require('../models');
|
||||||
|
|
||||||
// 同步数据库表结构
|
// 同步数据库表结构
|
||||||
const syncDatabase = async () => {
|
const syncDatabase = async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,183 +0,0 @@
|
||||||
const { Contract, Room, Tenant, Apartment, Region } = require('../models');
|
|
||||||
|
|
||||||
// 格式化时间(考虑时区,转换为北京时间)
|
|
||||||
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 formatContractData = (contract) => {
|
|
||||||
const formattedContract = {
|
|
||||||
...contract.toJSON(),
|
|
||||||
startDate: formatDate(contract.startDate),
|
|
||||||
endDate: formatDate(contract.endDate),
|
|
||||||
createTime: formatDate(contract.createTime),
|
|
||||||
updateTime: formatDate(contract.updateTime)
|
|
||||||
};
|
|
||||||
|
|
||||||
// 格式化关联数据
|
|
||||||
if (formattedContract.Room) {
|
|
||||||
formattedContract.Room = {
|
|
||||||
...formattedContract.Room,
|
|
||||||
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),
|
|
||||||
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),
|
|
||||||
updateTime: formatDate(formattedContract.Room.Apartment.Region.updateTime)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formattedContract.Tenant) {
|
|
||||||
formattedContract.Tenant = {
|
|
||||||
...formattedContract.Tenant,
|
|
||||||
createTime: formatDate(formattedContract.Tenant.createTime),
|
|
||||||
updateTime: formatDate(formattedContract.Tenant.updateTime)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return formattedContract;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取所有合同
|
|
||||||
const getAllContracts = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const contracts = await Contract.findAll({
|
|
||||||
where: { 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 }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
const formattedContracts = contracts.map(formatContractData);
|
|
||||||
res.status(200).json(formattedContracts);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取单个合同
|
|
||||||
const getContractById = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
const contract = await Contract.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 }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
if (!contract) {
|
|
||||||
return res.status(404).json({ error: '合同不存在' });
|
|
||||||
}
|
|
||||||
const formattedContract = formatContractData(contract);
|
|
||||||
res.status(200).json(formattedContract);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 创建合同
|
|
||||||
const createContract = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { roomId, tenantId, startDate, endDate, rent, deposit, status } = req.body;
|
|
||||||
const contract = await Contract.create({ roomId, tenantId, startDate, endDate, rent, deposit, status });
|
|
||||||
res.status(201).json(contract);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 更新合同
|
|
||||||
const updateContract = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
const { roomId, tenantId, startDate, endDate, rent, deposit, status } = req.body;
|
|
||||||
const contract = await Contract.findOne({
|
|
||||||
where: { id, isDeleted: 0 }
|
|
||||||
});
|
|
||||||
if (!contract) {
|
|
||||||
return res.status(404).json({ error: '合同不存在' });
|
|
||||||
}
|
|
||||||
await contract.update({ roomId, tenantId, startDate, endDate, rent, deposit, status });
|
|
||||||
res.status(200).json(contract);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除合同(软删除)
|
|
||||||
const deleteContract = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
const contract = await Contract.findOne({
|
|
||||||
where: { id, isDeleted: 0 }
|
|
||||||
});
|
|
||||||
if (!contract) {
|
|
||||||
return res.status(404).json({ error: '合同不存在' });
|
|
||||||
}
|
|
||||||
await contract.update({ isDeleted: 1 });
|
|
||||||
res.status(200).json({ message: '合同删除成功' });
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getAllContracts,
|
|
||||||
getContractById,
|
|
||||||
createContract,
|
|
||||||
updateContract,
|
|
||||||
deleteContract
|
|
||||||
};
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const { Rental, Room, Tenant, Contract, Apartment, Region } = require('../models');
|
const { Rental, Room, Apartment, Region } = require('../models');
|
||||||
const { Op } = require('sequelize');
|
const { Op } = require('sequelize');
|
||||||
|
|
||||||
// 格式化时间(考虑时区,转换为北京时间)
|
// 格式化时间(考虑时区,转换为北京时间)
|
||||||
|
|
@ -19,17 +19,6 @@ const formatRentalData = (rental) => {
|
||||||
updateTime: formatDate(rental.updateTime)
|
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;
|
return formattedRental;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -101,17 +90,28 @@ const getAllRentals = async (req, res) => {
|
||||||
if (roomId) {
|
if (roomId) {
|
||||||
where.roomId = roomId;
|
where.roomId = roomId;
|
||||||
}
|
}
|
||||||
|
if (tenantName) {
|
||||||
|
where.tenantName = { [Op.like]: `%${tenantName}%` };
|
||||||
|
}
|
||||||
|
|
||||||
// 构建包含关系 - 关联租客信息和合同信息
|
// 构建包含关系
|
||||||
const include = [
|
const include = [
|
||||||
{
|
{
|
||||||
model: Tenant,
|
model: Room,
|
||||||
where: tenantName ? { name: { [Op.like]: `%${tenantName}%` }, isDeleted: 0 } : { isDeleted: 0 }
|
where: { isDeleted: 0 },
|
||||||
},
|
include: [
|
||||||
{
|
{
|
||||||
model: Contract,
|
model: Apartment,
|
||||||
|
where: { isDeleted: 0 },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Region,
|
||||||
where: { isDeleted: 0 }
|
where: { isDeleted: 0 }
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// 计算偏移量
|
// 计算偏移量
|
||||||
|
|
@ -163,14 +163,6 @@ const getRentalById = async (req, res) => {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
model: Tenant,
|
|
||||||
where: { isDeleted: 0 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
model: Contract,
|
|
||||||
where: { isDeleted: 0 }
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
@ -220,60 +212,13 @@ const createRental = async (req, res) => {
|
||||||
return res.status(400).json({ error: '无效的房间ID' });
|
return res.status(400).json({ error: '无效的房间ID' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 先查找或创建租客
|
|
||||||
let tenant;
|
|
||||||
if (body.tenantIdCard) {
|
|
||||||
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: '创建租客失败' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理押金,为空时设置为0
|
// 处理押金,为空时设置为0
|
||||||
const deposit = body.deposit || 0;
|
const deposit = body.deposit || 0;
|
||||||
|
|
||||||
// 创建合同
|
|
||||||
console.log('创建合同:', {
|
|
||||||
roomId: parsedRoomId,
|
|
||||||
tenantId: tenant.id,
|
|
||||||
startDate: body.startDate,
|
|
||||||
endDate: body.endDate,
|
|
||||||
rent: body.rent,
|
|
||||||
deposit: 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: deposit,
|
|
||||||
status: body.status || 'active'
|
|
||||||
});
|
|
||||||
console.log('合同信息:', contract);
|
|
||||||
|
|
||||||
// 确保合同创建成功
|
|
||||||
if (!contract || !contract.id) {
|
|
||||||
return res.status(500).json({ error: '创建合同失败' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建租房记录
|
// 创建租房记录
|
||||||
console.log('创建租房记录:', {
|
console.log('创建租房记录:', {
|
||||||
roomId: parsedRoomId,
|
roomId: parsedRoomId,
|
||||||
tenantId: tenant.id,
|
tenantName: body.tenantName,
|
||||||
contractId: contract.id,
|
|
||||||
startDate: body.startDate,
|
startDate: body.startDate,
|
||||||
endDate: body.endDate,
|
endDate: body.endDate,
|
||||||
rent: body.rent,
|
rent: body.rent,
|
||||||
|
|
@ -281,11 +226,9 @@ const createRental = async (req, res) => {
|
||||||
status: body.status || 'active'
|
status: body.status || 'active'
|
||||||
});
|
});
|
||||||
|
|
||||||
// 直接使用具体的数值创建租房记录
|
|
||||||
const rental = await Rental.create({
|
const rental = await Rental.create({
|
||||||
roomId: parsedRoomId,
|
roomId: parsedRoomId,
|
||||||
tenantId: tenant.id,
|
tenantName: body.tenantName,
|
||||||
contractId: contract.id,
|
|
||||||
startDate: body.startDate,
|
startDate: body.startDate,
|
||||||
endDate: body.endDate,
|
endDate: body.endDate,
|
||||||
rent: body.rent,
|
rent: body.rent,
|
||||||
|
|
@ -309,7 +252,7 @@ const createRental = async (req, res) => {
|
||||||
const updateRental = async (req, res) => {
|
const updateRental = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const { roomId, tenantId, contractId, startDate, endDate, rent, deposit, status } = req.body;
|
const { roomId, tenantName, startDate, endDate, rent, deposit, status } = req.body;
|
||||||
const rental = await Rental.findOne({
|
const rental = await Rental.findOne({
|
||||||
where: { id, isDeleted: 0 }
|
where: { id, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
|
|
@ -318,7 +261,7 @@ const updateRental = async (req, res) => {
|
||||||
}
|
}
|
||||||
// 处理押金,为空时设置为0
|
// 处理押金,为空时设置为0
|
||||||
const updateDeposit = deposit || 0;
|
const updateDeposit = deposit || 0;
|
||||||
await rental.update({ roomId, tenantId, contractId, startDate, endDate, rent, deposit: updateDeposit, status });
|
await rental.update({ roomId, tenantName, startDate, endDate, rent, deposit: updateDeposit, status });
|
||||||
res.status(200).json(rental);
|
res.status(200).json(rental);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
|
|
@ -358,17 +301,28 @@ const listRentals = async (req, res) => {
|
||||||
if (roomId) {
|
if (roomId) {
|
||||||
where.roomId = roomId;
|
where.roomId = roomId;
|
||||||
}
|
}
|
||||||
|
if (tenantName) {
|
||||||
|
where.tenantName = { [Op.like]: `%${tenantName}%` };
|
||||||
|
}
|
||||||
|
|
||||||
// 构建包含关系 - 关联租客信息和合同信息
|
// 构建包含关系
|
||||||
const include = [
|
const include = [
|
||||||
{
|
{
|
||||||
model: Tenant,
|
model: Room,
|
||||||
where: tenantName ? { name: { [Op.like]: `%${tenantName}%` }, isDeleted: 0 } : { isDeleted: 0 }
|
where: { isDeleted: 0 },
|
||||||
},
|
include: [
|
||||||
{
|
{
|
||||||
model: Contract,
|
model: Apartment,
|
||||||
|
where: { isDeleted: 0 },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Region,
|
||||||
where: { isDeleted: 0 }
|
where: { isDeleted: 0 }
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// 查询租房数据
|
// 查询租房数据
|
||||||
|
|
|
||||||
|
|
@ -37,15 +37,6 @@ const formatRoomData = (room) => {
|
||||||
updateTime: formatDate(rental.updateTime)
|
updateTime: formatDate(rental.updateTime)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 格式化租客信息
|
|
||||||
if (formattedRental.Tenant) {
|
|
||||||
formattedRental.Tenant = {
|
|
||||||
...formattedRental.Tenant,
|
|
||||||
createTime: formatDate(formattedRental.Tenant.createTime),
|
|
||||||
updateTime: formatDate(formattedRental.Tenant.updateTime)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return formattedRental;
|
return formattedRental;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -62,7 +53,7 @@ const checkAndUpdateRentalStatus = async () => {
|
||||||
const tenDaysLater = new Date();
|
const tenDaysLater = new Date();
|
||||||
tenDaysLater.setDate(currentDate.getDate() + 30);
|
tenDaysLater.setDate(currentDate.getDate() + 30);
|
||||||
|
|
||||||
// 查找所有活跃的租房记录
|
// 查找所有在租的租房记录
|
||||||
const rentals = await Rental.findAll({
|
const rentals = await Rental.findAll({
|
||||||
where: { status: 'active', isDeleted: 0 }
|
where: { status: 'active', isDeleted: 0 }
|
||||||
});
|
});
|
||||||
|
|
@ -149,8 +140,7 @@ const getAllRooms = async (req, res) => {
|
||||||
where: {
|
where: {
|
||||||
roomId: room.id,
|
roomId: room.id,
|
||||||
status: { [Op.ne]: 'expired' }
|
status: { [Op.ne]: 'expired' }
|
||||||
},
|
}
|
||||||
include: ['Tenant']
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 格式化租房信息
|
// 格式化租房信息
|
||||||
|
|
@ -163,14 +153,6 @@ const getAllRooms = async (req, res) => {
|
||||||
createTime: formatDate(rental.createTime)
|
createTime: formatDate(rental.createTime)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 格式化租客信息
|
|
||||||
if (formattedRental.Tenant) {
|
|
||||||
formattedRental.Tenant = {
|
|
||||||
...formattedRental.Tenant,
|
|
||||||
createTime: formatDate(formattedRental.Tenant.createTime)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return formattedRental;
|
return formattedRental;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -217,8 +199,7 @@ const getRoomById = async (req, res) => {
|
||||||
where: {
|
where: {
|
||||||
roomId: room.id,
|
roomId: room.id,
|
||||||
status: { [Op.ne]: 'expired' }
|
status: { [Op.ne]: 'expired' }
|
||||||
},
|
}
|
||||||
include: ['Tenant']
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 格式化租房信息
|
// 格式化租房信息
|
||||||
|
|
@ -231,14 +212,6 @@ const getRoomById = async (req, res) => {
|
||||||
createTime: formatDate(rental.createTime)
|
createTime: formatDate(rental.createTime)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 格式化租客信息
|
|
||||||
if (formattedRental.Tenant) {
|
|
||||||
formattedRental.Tenant = {
|
|
||||||
...formattedRental.Tenant,
|
|
||||||
createTime: formatDate(formattedRental.Tenant.createTime)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return formattedRental;
|
return formattedRental;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -254,7 +227,18 @@ const getRoomById = async (req, res) => {
|
||||||
const createRoom = async (req, res) => {
|
const createRoom = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { apartmentId, roomNumber, area, monthlyPrice, yearlyPrice, status, subStatus, otherStatus } = req.body;
|
const { apartmentId, roomNumber, area, monthlyPrice, yearlyPrice, status, subStatus, otherStatus } = req.body;
|
||||||
const room = await Room.create({ apartmentId, roomNumber, area, monthlyPrice, yearlyPrice, status, subStatus, otherStatus });
|
// 处理空值
|
||||||
|
const processedData = {
|
||||||
|
apartmentId,
|
||||||
|
roomNumber,
|
||||||
|
area: area === '' ? null : area,
|
||||||
|
monthlyPrice: monthlyPrice === '' ? null : monthlyPrice,
|
||||||
|
yearlyPrice: yearlyPrice === '' ? null : yearlyPrice,
|
||||||
|
status,
|
||||||
|
subStatus,
|
||||||
|
otherStatus
|
||||||
|
};
|
||||||
|
const room = await Room.create(processedData);
|
||||||
res.status(201).json(room);
|
res.status(201).json(room);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
|
|
@ -272,7 +256,18 @@ const updateRoom = async (req, res) => {
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return res.status(404).json({ error: '房间不存在' });
|
return res.status(404).json({ error: '房间不存在' });
|
||||||
}
|
}
|
||||||
await room.update({ apartmentId, roomNumber, area, monthlyPrice, yearlyPrice, status, subStatus, otherStatus });
|
// 处理空值
|
||||||
|
const processedData = {
|
||||||
|
apartmentId,
|
||||||
|
roomNumber,
|
||||||
|
area: area === '' ? null : area,
|
||||||
|
monthlyPrice: monthlyPrice === '' ? null : monthlyPrice,
|
||||||
|
yearlyPrice: yearlyPrice === '' ? null : yearlyPrice,
|
||||||
|
status,
|
||||||
|
subStatus,
|
||||||
|
otherStatus
|
||||||
|
};
|
||||||
|
await room.update(processedData);
|
||||||
res.status(200).json(room);
|
res.status(200).json(room);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,6 @@ const { Op } = require('sequelize');
|
||||||
// 租金统计
|
// 租金统计
|
||||||
const getRentStatistics = async (req, res) => {
|
const getRentStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 导入Contract模型
|
|
||||||
const { Contract } = require('../models');
|
|
||||||
|
|
||||||
// 计算过去12个月的开始日期
|
// 计算过去12个月的开始日期
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const startDate = new Date(now.getFullYear(), now.getMonth() - 11, 1); // 12个月前的第一天
|
const startDate = new Date(now.getFullYear(), now.getMonth() - 11, 1); // 12个月前的第一天
|
||||||
|
|
@ -19,22 +16,23 @@ const getRentStatistics = async (req, res) => {
|
||||||
monthlyRent[monthKey] = 0;
|
monthlyRent[monthKey] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从数据库查询过去12个月的合同记录
|
// 从数据库查询过去12个月的租赁记录(排除已删除的)
|
||||||
const contracts = await Contract.findAll({
|
const rentals = await Rental.findAll({
|
||||||
where: {
|
where: {
|
||||||
createTime: {
|
createTime: {
|
||||||
[Op.gte]: startDate
|
[Op.gte]: startDate
|
||||||
}
|
},
|
||||||
|
isDeleted: 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 按月份统计已收租金
|
// 按月份统计已收租金
|
||||||
contracts.forEach(contract => {
|
rentals.forEach(rental => {
|
||||||
// 检查租金是否有效
|
// 检查租金是否有效
|
||||||
const rentAmount = parseFloat(contract.rent) || 0;
|
const rentAmount = parseFloat(rental.rent) || 0;
|
||||||
if (rentAmount > 0 && contract.createTime) {
|
if (rentAmount > 0 && rental.createTime) {
|
||||||
// 解析创建时间
|
// 解析创建时间
|
||||||
const createDate = new Date(contract.createTime);
|
const createDate = new Date(rental.createTime);
|
||||||
const monthKey = `${createDate.getFullYear()}-${(createDate.getMonth() + 1).toString().padStart(2, '0')}`;
|
const monthKey = `${createDate.getFullYear()}-${(createDate.getMonth() + 1).toString().padStart(2, '0')}`;
|
||||||
|
|
||||||
// 如果该月份在我们的统计范围内,添加租金
|
// 如果该月份在我们的统计范围内,添加租金
|
||||||
|
|
@ -62,8 +60,8 @@ const getRentStatistics = async (req, res) => {
|
||||||
// 房间状态统计
|
// 房间状态统计
|
||||||
const getRoomStatusStatistics = async (req, res) => {
|
const getRoomStatusStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 获取所有房间
|
// 获取所有房间(排除已删除的)
|
||||||
const rooms = await Room.findAll();
|
const rooms = await Room.findAll({ where: { isDeleted: 0 } });
|
||||||
|
|
||||||
// 初始化统计数据
|
// 初始化统计数据
|
||||||
let empty = 0;
|
let empty = 0;
|
||||||
|
|
@ -113,10 +111,15 @@ const getRoomStatusStatistics = async (req, res) => {
|
||||||
const getRegionHouseStatistics = async (req, res) => {
|
const getRegionHouseStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const regions = await Region.findAll({
|
const regions = await Region.findAll({
|
||||||
|
where: { isDeleted: 0 },
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: Apartment,
|
model: Apartment,
|
||||||
include: [Room]
|
where: { isDeleted: 0 },
|
||||||
|
include: [{
|
||||||
|
model: Room,
|
||||||
|
where: { isDeleted: 0 }
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
@ -173,10 +176,15 @@ const getRegionHouseStatistics = async (req, res) => {
|
||||||
const getRegionApartmentHouseStatistics = async (req, res) => {
|
const getRegionApartmentHouseStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const regions = await Region.findAll({
|
const regions = await Region.findAll({
|
||||||
|
where: { isDeleted: 0 },
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: Apartment,
|
model: Apartment,
|
||||||
include: [Room]
|
where: { isDeleted: 0 },
|
||||||
|
include: [{
|
||||||
|
model: Room,
|
||||||
|
where: { isDeleted: 0 }
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
@ -236,21 +244,21 @@ const getRegionApartmentHouseStatistics = async (req, res) => {
|
||||||
const getDashboardStatistics = async (req, res) => {
|
const getDashboardStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 导入所有需要的模型
|
// 导入所有需要的模型
|
||||||
const { Region, Apartment, Room, Tenant, Contract, WaterBill, Rental } = require('../models');
|
const { Region, Apartment, Room, WaterBill, Rental } = require('../models');
|
||||||
|
|
||||||
// 并行查询所有统计数据
|
// 并行查询所有统计数据
|
||||||
const [regionCount, apartmentCount, roomCount, tenantCount, contractCount, emptyRoomCount, rentedRoomCount, collectedRentAmount, collectedWaterAmount] = await Promise.all([
|
const [regionCount, apartmentCount, roomCount, emptyRoomCount, rentedRoomCount, soonExpireRoomCount, expiredRoomCount, collectedRentAmount, collectedWaterAmount] = await Promise.all([
|
||||||
Region.count(),
|
Region.count({ where: { isDeleted: 0 } }),
|
||||||
Apartment.count(),
|
Apartment.count({ where: { isDeleted: 0 } }),
|
||||||
Room.count(),
|
Room.count({ where: { isDeleted: 0 } }),
|
||||||
Tenant.count(),
|
Room.count({ where: { status: 'empty', isDeleted: 0 } }),
|
||||||
Contract.count(),
|
Room.count({ where: { status: 'rented', isDeleted: 0 } }),
|
||||||
Room.count({ where: { status: 'empty' } }),
|
Room.count({ where: { status: 'rented', subStatus: 'soon_expire', isDeleted: 0 } }),
|
||||||
Room.count({ where: { status: 'rented' } }),
|
Room.count({ where: { status: 'rented', subStatus: 'expired', isDeleted: 0 } }),
|
||||||
// 统计已收租金
|
// 统计已收租金(排除已删除的)
|
||||||
Rental.sum('rent', { where: { status: 'active' } }),
|
Rental.sum('rent', { where: { isDeleted: 0 } }),
|
||||||
// 统计已收水费
|
// 统计已收水费(排除已删除的)
|
||||||
WaterBill.sum('amount', { where: { status: 'paid' } })
|
WaterBill.sum('amount', { where: { status: 'paid', isDeleted: 0 } })
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 构造响应数据
|
// 构造响应数据
|
||||||
|
|
@ -258,10 +266,10 @@ const getDashboardStatistics = async (req, res) => {
|
||||||
regionCount,
|
regionCount,
|
||||||
apartmentCount,
|
apartmentCount,
|
||||||
roomCount,
|
roomCount,
|
||||||
tenantCount,
|
|
||||||
contractCount,
|
|
||||||
emptyRoomCount,
|
emptyRoomCount,
|
||||||
rentedRoomCount,
|
rentedRoomCount,
|
||||||
|
soonExpireRoomCount,
|
||||||
|
expiredRoomCount,
|
||||||
collectedRentAmount: parseFloat(collectedRentAmount) || 0,
|
collectedRentAmount: parseFloat(collectedRentAmount) || 0,
|
||||||
collectedWaterAmount: parseFloat(collectedWaterAmount) || 0
|
collectedWaterAmount: parseFloat(collectedWaterAmount) || 0
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
const { Tenant } = 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 formatTenantData = (tenant) => {
|
|
||||||
return {
|
|
||||||
...tenant.toJSON(),
|
|
||||||
createTime: formatDate(tenant.createTime),
|
|
||||||
updateTime: formatDate(tenant.updateTime)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取所有租客
|
|
||||||
const getAllTenants = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const tenants = await Tenant.findAll({
|
|
||||||
where: { isDeleted: 0 }
|
|
||||||
});
|
|
||||||
const formattedTenants = tenants.map(formatTenantData);
|
|
||||||
res.status(200).json(formattedTenants);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取单个租客
|
|
||||||
const getTenantById = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
const tenant = await Tenant.findOne({
|
|
||||||
where: { id, isDeleted: 0 }
|
|
||||||
});
|
|
||||||
if (!tenant) {
|
|
||||||
return res.status(404).json({ error: '租客不存在' });
|
|
||||||
}
|
|
||||||
const formattedTenant = formatTenantData(tenant);
|
|
||||||
res.status(200).json(formattedTenant);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 创建租客
|
|
||||||
const createTenant = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { name, phone, idCard } = req.body;
|
|
||||||
const tenant = await Tenant.create({ name, phone, idCard });
|
|
||||||
res.status(201).json(tenant);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 更新租客
|
|
||||||
const updateTenant = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
const { name, phone, idCard } = req.body;
|
|
||||||
const tenant = await Tenant.findOne({
|
|
||||||
where: { id, isDeleted: 0 }
|
|
||||||
});
|
|
||||||
if (!tenant) {
|
|
||||||
return res.status(404).json({ error: '租客不存在' });
|
|
||||||
}
|
|
||||||
await tenant.update({ name, phone, idCard });
|
|
||||||
res.status(200).json(tenant);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除租客(软删除)
|
|
||||||
const deleteTenant = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
const tenant = await Tenant.findOne({
|
|
||||||
where: { id, isDeleted: 0 }
|
|
||||||
});
|
|
||||||
if (!tenant) {
|
|
||||||
return res.status(404).json({ error: '租客不存在' });
|
|
||||||
}
|
|
||||||
await tenant.update({ isDeleted: 1 });
|
|
||||||
res.status(200).json({ message: '租客删除成功' });
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取所有租客(不分页)
|
|
||||||
const listTenants = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { name, phone, idCard } = req.query;
|
|
||||||
|
|
||||||
// 构建查询条件
|
|
||||||
const where = { isDeleted: 0 };
|
|
||||||
if (name) {
|
|
||||||
where.name = {
|
|
||||||
[Op.like]: `%${name}%`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (phone) {
|
|
||||||
where.phone = {
|
|
||||||
[Op.like]: `%${phone}%`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (idCard) {
|
|
||||||
where.idCard = {
|
|
||||||
[Op.like]: `%${idCard}%`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const tenants = await Tenant.findAll({ where });
|
|
||||||
const formattedTenants = tenants.map(formatTenantData);
|
|
||||||
res.status(200).json(formattedTenants);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getAllTenants,
|
|
||||||
listTenants,
|
|
||||||
getTenantById,
|
|
||||||
createTenant,
|
|
||||||
updateTenant,
|
|
||||||
deleteTenant
|
|
||||||
};
|
|
||||||
|
|
@ -6,7 +6,8 @@ const Apartment = sequelize.define('Apartment', {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
autoIncrement: true
|
autoIncrement: true,
|
||||||
|
comment: '公寓ID'
|
||||||
},
|
},
|
||||||
regionId: {
|
regionId: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
|
|
@ -14,29 +15,35 @@ const Apartment = sequelize.define('Apartment', {
|
||||||
references: {
|
references: {
|
||||||
model: Region,
|
model: Region,
|
||||||
key: 'id'
|
key: 'id'
|
||||||
}
|
},
|
||||||
|
comment: '所属区域ID'
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: DataTypes.STRING(50),
|
type: DataTypes.STRING(50),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '公寓名称'
|
||||||
},
|
},
|
||||||
address: {
|
address: {
|
||||||
type: DataTypes.STRING(255),
|
type: DataTypes.STRING(255),
|
||||||
allowNull: true
|
allowNull: true,
|
||||||
|
comment: '公寓地址'
|
||||||
},
|
},
|
||||||
createTime: {
|
createTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW
|
defaultValue: DataTypes.NOW,
|
||||||
|
comment: '创建时间'
|
||||||
},
|
},
|
||||||
updateTime: {
|
updateTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW,
|
defaultValue: DataTypes.NOW,
|
||||||
onUpdate: DataTypes.NOW
|
onUpdate: DataTypes.NOW,
|
||||||
|
comment: '更新时间'
|
||||||
},
|
},
|
||||||
isDeleted: {
|
isDeleted: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 0
|
defaultValue: 0,
|
||||||
|
comment: '删除状态(0:未删除,1:已删除)'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
tableName: 'apartments',
|
tableName: 'apartments',
|
||||||
|
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
const { DataTypes } = require('sequelize');
|
|
||||||
const sequelize = require('../config/db');
|
|
||||||
const Room = require('./Room');
|
|
||||||
const Tenant = require('./Tenant');
|
|
||||||
|
|
||||||
const Contract = sequelize.define('Contract', {
|
|
||||||
id: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true
|
|
||||||
},
|
|
||||||
roomId: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: false,
|
|
||||||
references: {
|
|
||||||
model: Room,
|
|
||||||
key: 'id'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tenantId: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: false,
|
|
||||||
references: {
|
|
||||||
model: Tenant,
|
|
||||||
key: 'id'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
startDate: {
|
|
||||||
type: DataTypes.DATE,
|
|
||||||
allowNull: false
|
|
||||||
},
|
|
||||||
endDate: {
|
|
||||||
type: DataTypes.DATE,
|
|
||||||
allowNull: false
|
|
||||||
},
|
|
||||||
rent: {
|
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
|
||||||
allowNull: false
|
|
||||||
},
|
|
||||||
deposit: {
|
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
|
||||||
allowNull: true
|
|
||||||
},
|
|
||||||
status: {
|
|
||||||
type: DataTypes.ENUM('active', 'expired'),
|
|
||||||
allowNull: false,
|
|
||||||
defaultValue: 'active'
|
|
||||||
},
|
|
||||||
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',
|
|
||||||
timestamps: false
|
|
||||||
});
|
|
||||||
|
|
||||||
// 建立关联
|
|
||||||
Contract.belongsTo(Room, { foreignKey: 'roomId' });
|
|
||||||
Contract.belongsTo(Tenant, { foreignKey: 'tenantId' });
|
|
||||||
|
|
||||||
module.exports = Contract;
|
|
||||||
|
|
@ -6,7 +6,8 @@ const ElectricityBill = sequelize.define('ElectricityBill', {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
autoIncrement: true
|
autoIncrement: true,
|
||||||
|
comment: '电费账单ID'
|
||||||
},
|
},
|
||||||
roomId: {
|
roomId: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
|
|
@ -14,54 +15,66 @@ const ElectricityBill = sequelize.define('ElectricityBill', {
|
||||||
references: {
|
references: {
|
||||||
model: Room,
|
model: Room,
|
||||||
key: 'id'
|
key: 'id'
|
||||||
}
|
},
|
||||||
|
comment: '房间ID'
|
||||||
},
|
},
|
||||||
startDate: {
|
startDate: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '开始日期'
|
||||||
},
|
},
|
||||||
endDate: {
|
endDate: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '结束日期'
|
||||||
},
|
},
|
||||||
startReading: {
|
startReading: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '起始读数'
|
||||||
},
|
},
|
||||||
endReading: {
|
endReading: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '结束读数'
|
||||||
},
|
},
|
||||||
usage: {
|
usage: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '用电量'
|
||||||
},
|
},
|
||||||
unitPrice: {
|
unitPrice: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '单价'
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '金额'
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
type: DataTypes.ENUM('unpaid', 'paid'),
|
type: DataTypes.ENUM('unpaid', 'paid'),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 'unpaid'
|
defaultValue: 'unpaid',
|
||||||
|
comment: '状态(unpaid:未支付,paid:已支付)'
|
||||||
},
|
},
|
||||||
createTime: {
|
createTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW
|
defaultValue: DataTypes.NOW,
|
||||||
|
comment: '创建时间'
|
||||||
},
|
},
|
||||||
updateTime: {
|
updateTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW,
|
defaultValue: DataTypes.NOW,
|
||||||
onUpdate: DataTypes.NOW
|
onUpdate: DataTypes.NOW,
|
||||||
|
comment: '更新时间'
|
||||||
},
|
},
|
||||||
isDeleted: {
|
isDeleted: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 0
|
defaultValue: 0,
|
||||||
|
comment: '删除状态(0:未删除,1:已删除)'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
tableName: 'electricity_bills',
|
tableName: 'electricity_bills',
|
||||||
|
|
|
||||||
|
|
@ -5,30 +5,36 @@ const Region = sequelize.define('Region', {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
autoIncrement: true
|
autoIncrement: true,
|
||||||
|
comment: '区域ID'
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: DataTypes.STRING(50),
|
type: DataTypes.STRING(50),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
unique: true
|
unique: true,
|
||||||
|
comment: '区域名称'
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
type: DataTypes.TEXT,
|
type: DataTypes.TEXT,
|
||||||
allowNull: true
|
allowNull: true,
|
||||||
|
comment: '区域描述'
|
||||||
},
|
},
|
||||||
createTime: {
|
createTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW
|
defaultValue: DataTypes.NOW,
|
||||||
|
comment: '创建时间'
|
||||||
},
|
},
|
||||||
updateTime: {
|
updateTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW,
|
defaultValue: DataTypes.NOW,
|
||||||
onUpdate: DataTypes.NOW
|
onUpdate: DataTypes.NOW,
|
||||||
|
comment: '更新时间'
|
||||||
},
|
},
|
||||||
isDeleted: {
|
isDeleted: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 0
|
defaultValue: 0,
|
||||||
|
comment: '删除状态(0:未删除,1:已删除)'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
tableName: 'regions',
|
tableName: 'regions',
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
const { DataTypes } = require('sequelize');
|
const { DataTypes } = require('sequelize');
|
||||||
const sequelize = require('../config/db');
|
const sequelize = require('../config/db');
|
||||||
const Room = require('./Room');
|
const Room = require('./Room');
|
||||||
const Tenant = require('./Tenant');
|
|
||||||
const Contract = require('./Contract');
|
|
||||||
|
|
||||||
const Rental = sequelize.define('Rental', {
|
const Rental = sequelize.define('Rental', {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
autoIncrement: true
|
autoIncrement: true,
|
||||||
|
comment: '租赁记录ID'
|
||||||
},
|
},
|
||||||
roomId: {
|
roomId: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
|
|
@ -16,62 +15,61 @@ const Rental = sequelize.define('Rental', {
|
||||||
references: {
|
references: {
|
||||||
model: Room,
|
model: Room,
|
||||||
key: 'id'
|
key: 'id'
|
||||||
}
|
|
||||||
},
|
},
|
||||||
tenantId: {
|
comment: '房间ID'
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: false,
|
|
||||||
references: {
|
|
||||||
model: Tenant,
|
|
||||||
key: 'id'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
contractId: {
|
tenantName: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.STRING(50),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
references: {
|
comment: '租客姓名'
|
||||||
model: Contract,
|
|
||||||
key: 'id'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
startDate: {
|
startDate: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '开始日期'
|
||||||
},
|
},
|
||||||
endDate: {
|
endDate: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '结束日期'
|
||||||
},
|
},
|
||||||
rent: {
|
rent: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '租金'
|
||||||
},
|
},
|
||||||
deposit: {
|
deposit: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: true
|
allowNull: true,
|
||||||
|
comment: '押金'
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
type: DataTypes.ENUM('active', 'expired'),
|
type: DataTypes.ENUM('active', 'expired'),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 'active'
|
defaultValue: 'active',
|
||||||
|
comment: '租赁状态(active:在租,expired:已过期)'
|
||||||
},
|
},
|
||||||
remark: {
|
remark: {
|
||||||
type: DataTypes.TEXT,
|
type: DataTypes.TEXT,
|
||||||
allowNull: true
|
allowNull: true,
|
||||||
|
comment: '备注'
|
||||||
},
|
},
|
||||||
createTime: {
|
createTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW
|
defaultValue: DataTypes.NOW,
|
||||||
|
comment: '创建时间'
|
||||||
},
|
},
|
||||||
updateTime: {
|
updateTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW,
|
defaultValue: DataTypes.NOW,
|
||||||
onUpdate: DataTypes.NOW
|
onUpdate: DataTypes.NOW,
|
||||||
|
comment: '更新时间'
|
||||||
},
|
},
|
||||||
isDeleted: {
|
isDeleted: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 0
|
defaultValue: 0,
|
||||||
|
comment: '删除状态(0:未删除,1:已删除)'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
tableName: 'rentals',
|
tableName: 'rentals',
|
||||||
|
|
@ -80,7 +78,5 @@ const Rental = sequelize.define('Rental', {
|
||||||
|
|
||||||
// 建立关联
|
// 建立关联
|
||||||
Rental.belongsTo(Room, { foreignKey: 'roomId' });
|
Rental.belongsTo(Room, { foreignKey: 'roomId' });
|
||||||
Rental.belongsTo(Tenant, { foreignKey: 'tenantId' });
|
|
||||||
Rental.belongsTo(Contract, { foreignKey: 'contractId' });
|
|
||||||
|
|
||||||
module.exports = Rental;
|
module.exports = Rental;
|
||||||
|
|
@ -6,7 +6,8 @@ const Room = sequelize.define('Room', {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
autoIncrement: true
|
autoIncrement: true,
|
||||||
|
comment: '房间ID'
|
||||||
},
|
},
|
||||||
apartmentId: {
|
apartmentId: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
|
|
@ -14,52 +15,63 @@ const Room = sequelize.define('Room', {
|
||||||
references: {
|
references: {
|
||||||
model: Apartment,
|
model: Apartment,
|
||||||
key: 'id'
|
key: 'id'
|
||||||
}
|
},
|
||||||
|
comment: '所属公寓ID'
|
||||||
},
|
},
|
||||||
roomNumber: {
|
roomNumber: {
|
||||||
type: DataTypes.STRING(20),
|
type: DataTypes.STRING(20),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '房间编号'
|
||||||
},
|
},
|
||||||
area: {
|
area: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: true,
|
||||||
|
comment: '房间面积'
|
||||||
},
|
},
|
||||||
monthlyPrice: {
|
monthlyPrice: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: true,
|
||||||
|
comment: '月租金'
|
||||||
},
|
},
|
||||||
yearlyPrice: {
|
yearlyPrice: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: true,
|
||||||
|
comment: '年租金'
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
type: DataTypes.ENUM('empty', 'rented'),
|
type: DataTypes.ENUM('empty', 'rented'),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 'empty'
|
defaultValue: 'empty',
|
||||||
|
comment: '房间状态(empty:空房,rented:在租)'
|
||||||
},
|
},
|
||||||
subStatus: {
|
subStatus: {
|
||||||
type: DataTypes.ENUM('normal', 'soon_expire', 'expired'),
|
type: DataTypes.ENUM('normal', 'soon_expire', 'expired'),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 'normal'
|
defaultValue: 'normal',
|
||||||
|
comment: '附属状态(normal:正常,soon_expire:即将到期,expired:已到期)'
|
||||||
},
|
},
|
||||||
otherStatus: {
|
otherStatus: {
|
||||||
type: DataTypes.ENUM('', 'cleaning', 'maintenance'),
|
type: DataTypes.ENUM('', 'cleaning', 'maintenance'),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: ''
|
defaultValue: '',
|
||||||
|
comment: '其他状态(cleaning:打扫中,maintenance:维修中)'
|
||||||
},
|
},
|
||||||
createTime: {
|
createTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW
|
defaultValue: DataTypes.NOW,
|
||||||
|
comment: '创建时间'
|
||||||
},
|
},
|
||||||
updateTime: {
|
updateTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW,
|
defaultValue: DataTypes.NOW,
|
||||||
onUpdate: DataTypes.NOW
|
onUpdate: DataTypes.NOW,
|
||||||
|
comment: '更新时间'
|
||||||
},
|
},
|
||||||
isDeleted: {
|
isDeleted: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 0
|
defaultValue: 0,
|
||||||
|
comment: '删除状态(0:未删除,1:已删除)'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
tableName: 'rooms',
|
tableName: 'rooms',
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
const { DataTypes } = require('sequelize');
|
|
||||||
const sequelize = require('../config/db');
|
|
||||||
|
|
||||||
const Tenant = sequelize.define('Tenant', {
|
|
||||||
id: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: DataTypes.STRING(50),
|
|
||||||
allowNull: false
|
|
||||||
},
|
|
||||||
phone: {
|
|
||||||
type: DataTypes.STRING(20),
|
|
||||||
allowNull: true
|
|
||||||
},
|
|
||||||
idCard: {
|
|
||||||
type: DataTypes.STRING(20),
|
|
||||||
allowNull: true,
|
|
||||||
unique: true
|
|
||||||
},
|
|
||||||
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',
|
|
||||||
timestamps: false
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = Tenant;
|
|
||||||
|
|
@ -6,7 +6,8 @@ const WaterBill = sequelize.define('WaterBill', {
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
autoIncrement: true
|
autoIncrement: true,
|
||||||
|
comment: '水费账单ID'
|
||||||
},
|
},
|
||||||
roomId: {
|
roomId: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
|
|
@ -14,54 +15,66 @@ const WaterBill = sequelize.define('WaterBill', {
|
||||||
references: {
|
references: {
|
||||||
model: Room,
|
model: Room,
|
||||||
key: 'id'
|
key: 'id'
|
||||||
}
|
},
|
||||||
|
comment: '房间ID'
|
||||||
},
|
},
|
||||||
startDate: {
|
startDate: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '开始日期'
|
||||||
},
|
},
|
||||||
endDate: {
|
endDate: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '结束日期'
|
||||||
},
|
},
|
||||||
startReading: {
|
startReading: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '起始读数'
|
||||||
},
|
},
|
||||||
endReading: {
|
endReading: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '结束读数'
|
||||||
},
|
},
|
||||||
usage: {
|
usage: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '用水量'
|
||||||
},
|
},
|
||||||
unitPrice: {
|
unitPrice: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '单价'
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
type: DataTypes.DECIMAL(10, 2),
|
type: DataTypes.DECIMAL(10, 2),
|
||||||
allowNull: false
|
allowNull: false,
|
||||||
|
comment: '金额'
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
type: DataTypes.ENUM('unpaid', 'paid'),
|
type: DataTypes.ENUM('unpaid', 'paid'),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 'unpaid'
|
defaultValue: 'unpaid',
|
||||||
|
comment: '状态(unpaid:未支付,paid:已支付)'
|
||||||
},
|
},
|
||||||
createTime: {
|
createTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW
|
defaultValue: DataTypes.NOW,
|
||||||
|
comment: '创建时间'
|
||||||
},
|
},
|
||||||
updateTime: {
|
updateTime: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
defaultValue: DataTypes.NOW,
|
defaultValue: DataTypes.NOW,
|
||||||
onUpdate: DataTypes.NOW
|
onUpdate: DataTypes.NOW,
|
||||||
|
comment: '更新时间'
|
||||||
},
|
},
|
||||||
isDeleted: {
|
isDeleted: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: 0
|
defaultValue: 0,
|
||||||
|
comment: '删除状态(0:未删除,1:已删除)'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
tableName: 'water_bills',
|
tableName: 'water_bills',
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
const Region = require('./Region');
|
const Region = require('./Region');
|
||||||
const Apartment = require('./Apartment');
|
const Apartment = require('./Apartment');
|
||||||
const Room = require('./Room');
|
const Room = require('./Room');
|
||||||
const Tenant = require('./Tenant');
|
|
||||||
const Contract = require('./Contract');
|
|
||||||
const Rental = require('./Rental');
|
const Rental = require('./Rental');
|
||||||
const WaterBill = require('./WaterBill');
|
const WaterBill = require('./WaterBill');
|
||||||
const ElectricityBill = require('./ElectricityBill');
|
const ElectricityBill = require('./ElectricityBill');
|
||||||
|
|
@ -11,8 +9,6 @@ module.exports = {
|
||||||
Region,
|
Region,
|
||||||
Apartment,
|
Apartment,
|
||||||
Room,
|
Room,
|
||||||
Tenant,
|
|
||||||
Contract,
|
|
||||||
Rental,
|
Rental,
|
||||||
WaterBill,
|
WaterBill,
|
||||||
ElectricityBill
|
ElectricityBill
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const contractController = require('../controllers/contractController');
|
|
||||||
|
|
||||||
// 路由
|
|
||||||
router.get('/', contractController.getAllContracts);
|
|
||||||
router.get('/:id', contractController.getContractById);
|
|
||||||
router.post('/', contractController.createContract);
|
|
||||||
router.put('/:id', contractController.updateContract);
|
|
||||||
router.delete('/:id', contractController.deleteContract);
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const tenantController = require('../controllers/tenantController');
|
|
||||||
|
|
||||||
// 路由
|
|
||||||
router.get('/', tenantController.getAllTenants);
|
|
||||||
router.get('/list', tenantController.listTenants);
|
|
||||||
router.get('/:id', tenantController.getTenantById);
|
|
||||||
router.post('/', tenantController.createTenant);
|
|
||||||
router.put('/:id', tenantController.updateTenant);
|
|
||||||
router.delete('/:id', tenantController.deleteTenant);
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
const { Region, Apartment, Room } = require('../models');
|
|
||||||
|
|
||||||
// 房间列表
|
|
||||||
const roomNumbers = [
|
|
||||||
'201', '202', '203', '205', '206', '208', '209',
|
|
||||||
'301', '302', '303', '305', '306', '308', '309',
|
|
||||||
'401', '402', '403', '405', '406', '408', '409',
|
|
||||||
'501', '502', '503', '505', '506', '508', '509'
|
|
||||||
];
|
|
||||||
|
|
||||||
async function addRooms() {
|
|
||||||
try {
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
|
|
||||||
// 查找或创建碧云公寓
|
|
||||||
let apartment = await Apartment.findOne({ where: { name: '碧云公寓' } });
|
|
||||||
|
|
||||||
if (!apartment) {
|
|
||||||
console.log('碧云公寓不存在,创建中...');
|
|
||||||
// 查找或创建大商汇区域
|
|
||||||
let region = await Region.findOne({ where: { name: '大商汇' } });
|
|
||||||
if (!region) {
|
|
||||||
region = await Region.create({ name: '大商汇', description: '大商汇区域' });
|
|
||||||
console.log('创建了大商汇区域');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建碧云公寓
|
|
||||||
apartment = await Apartment.create({
|
|
||||||
regionId: region.id,
|
|
||||||
name: '碧云公寓',
|
|
||||||
address: '大商汇区域'
|
|
||||||
});
|
|
||||||
console.log('创建了碧云公寓');
|
|
||||||
} else {
|
|
||||||
console.log('找到碧云公寓,ID:', apartment.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加房间
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
for (const roomNumber of roomNumbers) {
|
|
||||||
// 检查房间是否已存在
|
|
||||||
const existingRoom = await Room.findOne({
|
|
||||||
where: {
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingRoom) {
|
|
||||||
await Room.create({
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber,
|
|
||||||
area: 25, // 默认面积
|
|
||||||
price: 2000, // 默认价格
|
|
||||||
status: 'empty' // 空房状态
|
|
||||||
});
|
|
||||||
console.log(`添加了房间: ${roomNumber}`);
|
|
||||||
} else {
|
|
||||||
console.log(`房间 ${roomNumber} 已存在,跳过`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('房间添加完成!');
|
|
||||||
process.exit(0);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('添加房间时出错:', error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行脚本
|
|
||||||
addRooms();
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
const { Region, Apartment, Room } = require('../models');
|
|
||||||
|
|
||||||
// 房间列表
|
|
||||||
const roomNumbers = [
|
|
||||||
'301', '302', '303', '304', '305', '306', '307',
|
|
||||||
'401', '402', '403', '404', '405', '406', '407',
|
|
||||||
'501', '502', '503', '504', '505', '506', '507',
|
|
||||||
'601', '602', '603', '604', '605', '606', '607'
|
|
||||||
];
|
|
||||||
|
|
||||||
async function addRooms() {
|
|
||||||
try {
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
|
|
||||||
// 查找或创建谷景公寓
|
|
||||||
let apartment = await Apartment.findOne({ where: { name: '谷景公寓' } });
|
|
||||||
|
|
||||||
if (!apartment) {
|
|
||||||
console.log('谷景公寓不存在,创建中...');
|
|
||||||
// 查找或创建大商汇区域
|
|
||||||
let region = await Region.findOne({ where: { name: '大商汇' } });
|
|
||||||
if (!region) {
|
|
||||||
region = await Region.create({ name: '大商汇', description: '大商汇区域' });
|
|
||||||
console.log('创建了大商汇区域');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建谷景公寓
|
|
||||||
apartment = await Apartment.create({
|
|
||||||
regionId: region.id,
|
|
||||||
name: '谷景公寓',
|
|
||||||
address: '大商汇区域'
|
|
||||||
});
|
|
||||||
console.log('创建了谷景公寓');
|
|
||||||
} else {
|
|
||||||
console.log('找到谷景公寓,ID:', apartment.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加房间
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
for (const roomNumber of roomNumbers) {
|
|
||||||
// 检查房间是否已存在
|
|
||||||
const existingRoom = await Room.findOne({
|
|
||||||
where: {
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingRoom) {
|
|
||||||
await Room.create({
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber,
|
|
||||||
area: 25, // 默认面积
|
|
||||||
price: 2000, // 默认价格
|
|
||||||
status: 'empty' // 空房状态
|
|
||||||
});
|
|
||||||
console.log(`添加了房间: ${roomNumber}`);
|
|
||||||
} else {
|
|
||||||
console.log(`房间 ${roomNumber} 已存在,跳过`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('房间添加完成!');
|
|
||||||
process.exit(0);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('添加房间时出错:', error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行脚本
|
|
||||||
addRooms();
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
const { Region, Apartment, Room } = require('../models');
|
|
||||||
|
|
||||||
// 房间列表
|
|
||||||
const roomNumbers = [
|
|
||||||
'201', '202', '203', '205', '206',
|
|
||||||
'301', '302', '303', '305', '306',
|
|
||||||
'401', '402', '403', '405', '406'
|
|
||||||
];
|
|
||||||
|
|
||||||
async function addRooms() {
|
|
||||||
try {
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
|
|
||||||
// 查找或创建沐航公寓
|
|
||||||
let apartment = await Apartment.findOne({ where: { name: '沐航公寓' } });
|
|
||||||
|
|
||||||
if (!apartment) {
|
|
||||||
console.log('沐航公寓不存在,创建中...');
|
|
||||||
// 查找或创建丰源市场区域
|
|
||||||
let region = await Region.findOne({ where: { name: '丰源市场' } });
|
|
||||||
if (!region) {
|
|
||||||
region = await Region.create({ name: '丰源市场', description: '丰源市场区域' });
|
|
||||||
console.log('创建了丰源市场区域');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建沐航公寓
|
|
||||||
apartment = await Apartment.create({
|
|
||||||
regionId: region.id,
|
|
||||||
name: '沐航公寓',
|
|
||||||
address: '丰源市场区域'
|
|
||||||
});
|
|
||||||
console.log('创建了沐航公寓');
|
|
||||||
} else {
|
|
||||||
console.log('找到沐航公寓,ID:', apartment.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加房间
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
for (const roomNumber of roomNumbers) {
|
|
||||||
// 检查房间是否已存在
|
|
||||||
const existingRoom = await Room.findOne({
|
|
||||||
where: {
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingRoom) {
|
|
||||||
await Room.create({
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber,
|
|
||||||
area: 25, // 默认面积
|
|
||||||
price: 2000, // 默认价格
|
|
||||||
status: 'empty' // 空房状态
|
|
||||||
});
|
|
||||||
console.log(`添加了房间: ${roomNumber}`);
|
|
||||||
} else {
|
|
||||||
console.log(`房间 ${roomNumber} 已存在,跳过`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('房间添加完成!');
|
|
||||||
process.exit(0);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('添加房间时出错:', error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行脚本
|
|
||||||
addRooms();
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
const { Region, Apartment, Room } = require('../models');
|
|
||||||
|
|
||||||
// 房间列表
|
|
||||||
const roomNumbers = [
|
|
||||||
'201', '202', '203', '204',
|
|
||||||
'301', '302', '303', '304', '305', '306', '307',
|
|
||||||
'401', '402', '403', '404',
|
|
||||||
'501', '502'
|
|
||||||
];
|
|
||||||
|
|
||||||
async function addRooms() {
|
|
||||||
try {
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
|
|
||||||
// 查找或创建千妗公寓
|
|
||||||
let apartment = await Apartment.findOne({ where: { name: '千妗公寓' } });
|
|
||||||
|
|
||||||
if (!apartment) {
|
|
||||||
console.log('千妗公寓不存在,创建中...');
|
|
||||||
// 查找或创建丰源市场区域
|
|
||||||
let region = await Region.findOne({ where: { name: '丰源市场' } });
|
|
||||||
if (!region) {
|
|
||||||
region = await Region.create({ name: '丰源市场', description: '丰源市场区域' });
|
|
||||||
console.log('创建了丰源市场区域');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建千妗公寓
|
|
||||||
apartment = await Apartment.create({
|
|
||||||
regionId: region.id,
|
|
||||||
name: '千妗公寓',
|
|
||||||
address: '丰源市场区域'
|
|
||||||
});
|
|
||||||
console.log('创建了千妗公寓');
|
|
||||||
} else {
|
|
||||||
console.log('找到千妗公寓,ID:', apartment.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加房间
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
for (const roomNumber of roomNumbers) {
|
|
||||||
// 检查房间是否已存在
|
|
||||||
const existingRoom = await Room.findOne({
|
|
||||||
where: {
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingRoom) {
|
|
||||||
await Room.create({
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber,
|
|
||||||
area: 25, // 默认面积
|
|
||||||
price: 2000, // 默认价格
|
|
||||||
status: 'empty' // 空房状态
|
|
||||||
});
|
|
||||||
console.log(`添加了房间: ${roomNumber}`);
|
|
||||||
} else {
|
|
||||||
console.log(`房间 ${roomNumber} 已存在,跳过`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('房间添加完成!');
|
|
||||||
process.exit(0);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('添加房间时出错:', error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行脚本
|
|
||||||
addRooms();
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
const { Region, Apartment, Room } = require('../models');
|
|
||||||
|
|
||||||
// 房间列表
|
|
||||||
const roomNumbers = [
|
|
||||||
'301', '302', '303', '304', '305', '306', '307',
|
|
||||||
'401', '402', '403', '404', '405', '406', '407',
|
|
||||||
'501', '502', '503', '504', '505', '506', '507'
|
|
||||||
];
|
|
||||||
|
|
||||||
async function addRooms() {
|
|
||||||
try {
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
|
|
||||||
// 查找或创建归宿公寓
|
|
||||||
let apartment = await Apartment.findOne({ where: { name: '归宿公寓' } });
|
|
||||||
|
|
||||||
if (!apartment) {
|
|
||||||
console.log('归宿公寓不存在,创建中...');
|
|
||||||
// 查找或创建丰源市场区域
|
|
||||||
let region = await Region.findOne({ where: { name: '丰源市场' } });
|
|
||||||
if (!region) {
|
|
||||||
region = await Region.create({ name: '丰源市场', description: '丰源市场区域' });
|
|
||||||
console.log('创建了丰源市场区域');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建归宿公寓
|
|
||||||
apartment = await Apartment.create({
|
|
||||||
regionId: region.id,
|
|
||||||
name: '归宿公寓',
|
|
||||||
address: '丰源市场区域'
|
|
||||||
});
|
|
||||||
console.log('创建了归宿公寓');
|
|
||||||
} else {
|
|
||||||
console.log('找到归宿公寓,ID:', apartment.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加房间
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
for (const roomNumber of roomNumbers) {
|
|
||||||
// 检查房间是否已存在
|
|
||||||
const existingRoom = await Room.findOne({
|
|
||||||
where: {
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingRoom) {
|
|
||||||
await Room.create({
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber,
|
|
||||||
area: 25, // 默认面积
|
|
||||||
price: 2000, // 默认价格
|
|
||||||
status: 'empty' // 空房状态
|
|
||||||
});
|
|
||||||
console.log(`添加了房间: ${roomNumber}`);
|
|
||||||
} else {
|
|
||||||
console.log(`房间 ${roomNumber} 已存在,跳过`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('房间添加完成!');
|
|
||||||
process.exit(0);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('添加房间时出错:', error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行脚本
|
|
||||||
addRooms();
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
const { Region, Apartment, Room } = require('../models');
|
|
||||||
|
|
||||||
// 房间列表
|
|
||||||
const roomNumbers = [
|
|
||||||
'201', '202', '203', '205', '206',
|
|
||||||
'301', '302', '303', '305', '306',
|
|
||||||
'401', '402', '403', '405', '406',
|
|
||||||
'501', '502', '503', '505'
|
|
||||||
];
|
|
||||||
|
|
||||||
async function addRooms() {
|
|
||||||
try {
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
|
|
||||||
// 查找或创建义和公寓
|
|
||||||
let apartment = await Apartment.findOne({ where: { name: '义和公寓' } });
|
|
||||||
|
|
||||||
if (!apartment) {
|
|
||||||
console.log('义和公寓不存在,创建中...');
|
|
||||||
// 查找或创建丰源市场区域
|
|
||||||
let region = await Region.findOne({ where: { name: '丰源市场' } });
|
|
||||||
if (!region) {
|
|
||||||
region = await Region.create({ name: '丰源市场', description: '丰源市场区域' });
|
|
||||||
console.log('创建了丰源市场区域');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建义和公寓
|
|
||||||
apartment = await Apartment.create({
|
|
||||||
regionId: region.id,
|
|
||||||
name: '义和公寓',
|
|
||||||
address: '丰源市场区域'
|
|
||||||
});
|
|
||||||
console.log('创建了义和公寓');
|
|
||||||
} else {
|
|
||||||
console.log('找到义和公寓,ID:', apartment.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加房间
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
for (const roomNumber of roomNumbers) {
|
|
||||||
// 检查房间是否已存在
|
|
||||||
const existingRoom = await Room.findOne({
|
|
||||||
where: {
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingRoom) {
|
|
||||||
await Room.create({
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber,
|
|
||||||
area: 25, // 默认面积
|
|
||||||
price: 2000, // 默认价格
|
|
||||||
status: 'empty' // 空房状态
|
|
||||||
});
|
|
||||||
console.log(`添加了房间: ${roomNumber}`);
|
|
||||||
} else {
|
|
||||||
console.log(`房间 ${roomNumber} 已存在,跳过`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('房间添加完成!');
|
|
||||||
process.exit(0);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('添加房间时出错:', error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行脚本
|
|
||||||
addRooms();
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
const { Region, Apartment, Room } = require('../models');
|
|
||||||
|
|
||||||
// 房间列表
|
|
||||||
const roomNumbers = [
|
|
||||||
'402', '403', '404', '405', '406', '407', '408', '409', '410', '411', '412', '413',
|
|
||||||
'501', '502', '503', '504', '505', '506', '507', '508', '509', '510', '511', '512', '513'
|
|
||||||
];
|
|
||||||
|
|
||||||
async function addRooms() {
|
|
||||||
try {
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
|
|
||||||
// 查找或创建爱奇艺公寓
|
|
||||||
let apartment = await Apartment.findOne({ where: { name: '爱奇艺公寓' } });
|
|
||||||
|
|
||||||
if (!apartment) {
|
|
||||||
console.log('爱奇艺公寓不存在,创建中...');
|
|
||||||
// 查找或创建大商汇区域
|
|
||||||
let region = await Region.findOne({ where: { name: '大商汇' } });
|
|
||||||
if (!region) {
|
|
||||||
region = await Region.create({ name: '大商汇', description: '大商汇区域' });
|
|
||||||
console.log('创建了大商汇区域');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建爱奇艺公寓
|
|
||||||
apartment = await Apartment.create({
|
|
||||||
regionId: region.id,
|
|
||||||
name: '爱奇艺公寓',
|
|
||||||
address: '大商汇区域'
|
|
||||||
});
|
|
||||||
console.log('创建了爱奇艺公寓');
|
|
||||||
} else {
|
|
||||||
console.log('找到爱奇艺公寓,ID:', apartment.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加房间
|
|
||||||
console.log('开始添加房间...');
|
|
||||||
for (const roomNumber of roomNumbers) {
|
|
||||||
// 检查房间是否已存在
|
|
||||||
const existingRoom = await Room.findOne({
|
|
||||||
where: {
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingRoom) {
|
|
||||||
await Room.create({
|
|
||||||
apartmentId: apartment.id,
|
|
||||||
roomNumber: roomNumber,
|
|
||||||
area: 25, // 默认面积
|
|
||||||
price: 2000, // 默认价格
|
|
||||||
status: 'empty' // 空房状态
|
|
||||||
});
|
|
||||||
console.log(`添加了房间: ${roomNumber}`);
|
|
||||||
} else {
|
|
||||||
console.log(`房间 ${roomNumber} 已存在,跳过`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('房间添加完成!');
|
|
||||||
process.exit(0);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('添加房间时出错:', error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行脚本
|
|
||||||
addRooms();
|
|
||||||
37
update_db.js
37
update_db.js
|
|
@ -1,37 +0,0 @@
|
||||||
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();
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
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();
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
-- 更新房间表结构,将原来的 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;
|
|
||||||
Loading…
Reference in New Issue