This commit is contained in:
parent
ed4ff56082
commit
a4ed46d10a
|
|
@ -9,7 +9,7 @@ const dbConfig = {
|
||||||
local: {
|
local: {
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
user: 'root',
|
user: 'root',
|
||||||
password: 'root',
|
password: '123456',
|
||||||
database: 'rentease'
|
database: 'rentease'
|
||||||
},
|
},
|
||||||
development: {
|
development: {
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,25 @@ const response = require('../utils/response');
|
||||||
// 格式化时间(考虑时区,转换为北京时间)
|
// 格式化时间(考虑时区,转换为北京时间)
|
||||||
const formatDate = (date) => {
|
const formatDate = (date) => {
|
||||||
if (!date) return null;
|
if (!date) return null;
|
||||||
// 确保date是Date对象
|
|
||||||
const dateObj = date instanceof Date ? date : new Date(date);
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
// 创建一个新的Date对象,加上8小时的时区偏移
|
|
||||||
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
return beijingDate.toISOString().split('T')[0];
|
return beijingDate.toISOString().split('T')[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 格式化日期时间(年月日时分秒)
|
||||||
|
const formatDateTime = (date) => {
|
||||||
|
if (!date) return null;
|
||||||
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
|
return beijingDate.toISOString().replace('T', ' ').slice(0, 19);
|
||||||
|
};
|
||||||
|
|
||||||
// 格式化公寓数据
|
// 格式化公寓数据
|
||||||
const formatApartmentData = (apartment) => {
|
const formatApartmentData = (apartment) => {
|
||||||
return {
|
return {
|
||||||
...apartment.toJSON(),
|
...apartment.toJSON(),
|
||||||
createTime: formatDate(apartment.createTime),
|
createTime: formatDateTime(apartment.createTime),
|
||||||
updateTime: formatDate(apartment.updateTime)
|
updateTime: formatDateTime(apartment.updateTime)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -28,7 +34,7 @@ const getAllApartments = async (req, res) => {
|
||||||
const { regionId, name, page = 1, pageSize = 10 } = req.query;
|
const { regionId, name, page = 1, pageSize = 10 } = req.query;
|
||||||
|
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
const where = { isDeleted: 0 };
|
const where = { tenantId: req.user.tenantId, isDeleted: 0 };
|
||||||
if (regionId) {
|
if (regionId) {
|
||||||
where.regionId = regionId;
|
where.regionId = regionId;
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +74,7 @@ const getApartmentById = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const apartment = await Apartment.findOne({
|
const apartment = await Apartment.findOne({
|
||||||
where: { id, isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!apartment) {
|
if (!apartment) {
|
||||||
return response.notFound(res, '公寓不存在');
|
return response.notFound(res, '公寓不存在');
|
||||||
|
|
@ -135,7 +141,7 @@ const updateApartment = async (req, res) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const { name, address, description } = req.body;
|
const { name, address, description } = req.body;
|
||||||
const apartment = await Apartment.findOne({
|
const apartment = await Apartment.findOne({
|
||||||
where: { id, isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!apartment) {
|
if (!apartment) {
|
||||||
return response.notFound(res, '公寓不存在');
|
return response.notFound(res, '公寓不存在');
|
||||||
|
|
@ -157,7 +163,7 @@ const deleteApartment = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const apartment = await Apartment.findOne({
|
const apartment = await Apartment.findOne({
|
||||||
where: { id, isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!apartment) {
|
if (!apartment) {
|
||||||
return response.notFound(res, '公寓不存在');
|
return response.notFound(res, '公寓不存在');
|
||||||
|
|
@ -178,7 +184,7 @@ const listApartments = async (req, res) => {
|
||||||
const { regionId, name } = req.query;
|
const { regionId, name } = req.query;
|
||||||
|
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
const where = { isDeleted: 0 };
|
const where = { tenantId: req.user.tenantId, isDeleted: 0 };
|
||||||
if (regionId) {
|
if (regionId) {
|
||||||
where.regionId = regionId;
|
where.regionId = regionId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,26 @@ const { Op } = require('sequelize');
|
||||||
const billingService = require('../services/billingService');
|
const billingService = require('../services/billingService');
|
||||||
const response = require('../utils/response');
|
const response = require('../utils/response');
|
||||||
|
|
||||||
|
// 格式化日期时间(年月日时分秒)
|
||||||
|
const formatDateTime = (date) => {
|
||||||
|
if (!date) return null;
|
||||||
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
|
if (isNaN(dateObj.getTime())) return null;
|
||||||
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
|
return beijingDate.toISOString().replace('T', ' ').slice(0, 19);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 格式化订单数据
|
||||||
|
const formatOrderData = (order) => {
|
||||||
|
const data = order.toJSON ? order.toJSON() : order;
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
createTime: formatDateTime(data.createTime),
|
||||||
|
updateTime: formatDateTime(data.updateTime),
|
||||||
|
paidTime: formatDateTime(data.paidTime)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// 获取所有套餐列表
|
// 获取所有套餐列表
|
||||||
const getAllPlans = async (req, res) => {
|
const getAllPlans = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -318,7 +338,7 @@ const getOrders = async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '获取订单列表成功', {
|
response.success(res, '获取订单列表成功', {
|
||||||
list: rows,
|
list: rows.map(formatOrderData),
|
||||||
total: count,
|
total: count,
|
||||||
page: parseInt(page),
|
page: parseInt(page),
|
||||||
pageSize: parseInt(pageSize)
|
pageSize: parseInt(pageSize)
|
||||||
|
|
@ -430,7 +450,7 @@ const createOrder = async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
response.created(res, '订单创建成功', {
|
response.created(res, '订单创建成功', {
|
||||||
order: createdOrder.toJSON(),
|
order: formatOrderData(createdOrder),
|
||||||
details: amountInfo.details
|
details: amountInfo.details
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -476,7 +496,7 @@ const getOrderDetail = async (req, res) => {
|
||||||
return response.forbidden(res, '无权查看此订单');
|
return response.forbidden(res, '无权查看此订单');
|
||||||
}
|
}
|
||||||
|
|
||||||
response.success(res, '获取订单详情成功', order);
|
response.success(res, '获取订单详情成功', formatOrderData(order));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取订单详情失败:', error);
|
console.error('获取订单详情失败:', error);
|
||||||
response.serverError(res, '获取订单详情失败', error);
|
response.serverError(res, '获取订单详情失败', error);
|
||||||
|
|
@ -582,9 +602,9 @@ const payOrder = async (req, res) => {
|
||||||
response.success(res, '支付成功', {
|
response.success(res, '支付成功', {
|
||||||
payment,
|
payment,
|
||||||
order: {
|
order: {
|
||||||
...order.toJSON(),
|
...formatOrderData(order),
|
||||||
status: 'paid',
|
status: 'paid',
|
||||||
paidTime: paidTime
|
paidTime: formatDateTime(paidTime)
|
||||||
},
|
},
|
||||||
tenant: paymentResult
|
tenant: paymentResult
|
||||||
});
|
});
|
||||||
|
|
@ -632,7 +652,11 @@ const getPayments = async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '获取支付记录成功', {
|
response.success(res, '获取支付记录成功', {
|
||||||
list: rows,
|
list: rows.map(r => ({
|
||||||
|
...(r.toJSON ? r.toJSON() : r),
|
||||||
|
createTime: formatDateTime(r.createTime),
|
||||||
|
paidAt: formatDateTime(r.paidAt)
|
||||||
|
})),
|
||||||
total: count,
|
total: count,
|
||||||
page: parseInt(page),
|
page: parseInt(page),
|
||||||
pageSize: parseInt(pageSize)
|
pageSize: parseInt(pageSize)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,29 @@ const RoleMenu = require('../models/RoleMenu');
|
||||||
const { logOperation } = require('../utils/logger');
|
const { logOperation } = require('../utils/logger');
|
||||||
const response = require('../utils/response');
|
const response = require('../utils/response');
|
||||||
|
|
||||||
|
// 格式化日期时间(年月日时分秒)
|
||||||
|
const formatDateTime = (date) => {
|
||||||
|
if (!date) return null;
|
||||||
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
|
if (isNaN(dateObj.getTime())) return null;
|
||||||
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
|
return beijingDate.toISOString().replace('T', ' ').slice(0, 19);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 格式化菜单数据(递归处理children)
|
||||||
|
const formatMenuData = (menu) => {
|
||||||
|
const data = menu.toJSON ? menu.toJSON() : menu;
|
||||||
|
const result = {
|
||||||
|
...data,
|
||||||
|
createTime: formatDateTime(data.createTime),
|
||||||
|
updateTime: formatDateTime(data.updateTime)
|
||||||
|
};
|
||||||
|
if (data.children && Array.isArray(data.children)) {
|
||||||
|
result.children = data.children.map(formatMenuData);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
// 获取菜单树
|
// 获取菜单树
|
||||||
exports.getMenuTree = async (req, res) => {
|
exports.getMenuTree = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -61,7 +84,7 @@ exports.getMenuList = async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '获取成功', {
|
response.success(res, '获取成功', {
|
||||||
list: rows,
|
list: rows.map(formatMenuData),
|
||||||
total: count,
|
total: count,
|
||||||
page: parseInt(page),
|
page: parseInt(page),
|
||||||
pageSize: parseInt(pageSize)
|
pageSize: parseInt(pageSize)
|
||||||
|
|
@ -85,7 +108,7 @@ exports.getMenuById = async (req, res) => {
|
||||||
return response.notFound(res, '菜单不存在');
|
return response.notFound(res, '菜单不存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
response.success(res, '获取成功', menu);
|
response.success(res, '获取成功', formatMenuData(menu));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取菜单详情失败:', error);
|
console.error('获取菜单详情失败:', error);
|
||||||
response.serverError(res, '获取菜单详情失败', error);
|
response.serverError(res, '获取菜单详情失败', error);
|
||||||
|
|
@ -149,7 +172,7 @@ exports.createMenu = async (req, res) => {
|
||||||
status: 'success'
|
status: 'success'
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '创建成功', menu);
|
response.success(res, '创建成功', formatMenuData(menu));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('创建菜单失败:', error);
|
console.error('创建菜单失败:', error);
|
||||||
response.serverError(res, '创建菜单失败', error);
|
response.serverError(res, '创建菜单失败', error);
|
||||||
|
|
@ -221,7 +244,7 @@ exports.updateMenu = async (req, res) => {
|
||||||
status: 'success'
|
status: 'success'
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '更新成功', menu);
|
response.success(res, '更新成功', formatMenuData(menu));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('更新菜单失败:', error);
|
console.error('更新菜单失败:', error);
|
||||||
response.serverError(res, '更新菜单失败', error);
|
response.serverError(res, '更新菜单失败', error);
|
||||||
|
|
@ -306,7 +329,7 @@ exports.getRoleMenus = async (req, res) => {
|
||||||
|
|
||||||
const menus = roleData ? roleData.menus : [];
|
const menus = roleData ? roleData.menus : [];
|
||||||
|
|
||||||
response.success(res, '获取成功', menus);
|
response.success(res, '获取成功', menus.map(formatMenuData));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取角色菜单失败:', error);
|
console.error('获取角色菜单失败:', error);
|
||||||
response.serverError(res, '获取角色菜单失败', error);
|
response.serverError(res, '获取角色菜单失败', error);
|
||||||
|
|
@ -446,7 +469,7 @@ function buildTree(menus, parentId = null) {
|
||||||
.filter(menu => menu.parentId === parentId)
|
.filter(menu => menu.parentId === parentId)
|
||||||
.map(menu => {
|
.map(menu => {
|
||||||
// 获取菜单的原始数据
|
// 获取菜单的原始数据
|
||||||
const menuData = menu.toJSON ? menu.toJSON() : menu;
|
const menuData = formatMenuData(menu);
|
||||||
return {
|
return {
|
||||||
...menuData,
|
...menuData,
|
||||||
children: buildTree(menus, menu.id)
|
children: buildTree(menus, menu.id)
|
||||||
|
|
|
||||||
|
|
@ -5,29 +5,36 @@ const response = require('../utils/response');
|
||||||
// 格式化时间(考虑时区,转换为北京时间)
|
// 格式化时间(考虑时区,转换为北京时间)
|
||||||
const formatDate = (date) => {
|
const formatDate = (date) => {
|
||||||
if (!date) return null;
|
if (!date) return null;
|
||||||
// 确保 date 是 Date 对象
|
|
||||||
const dateObj = date instanceof Date ? date : new Date(date);
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
if (isNaN(dateObj.getTime())) return null;
|
if (isNaN(dateObj.getTime())) return null;
|
||||||
// 创建一个新的Date对象,加上8小时的时区偏移
|
|
||||||
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
return beijingDate.toISOString().split('T')[0];
|
return beijingDate.toISOString().split('T')[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 格式化日期时间(年月日时分秒)
|
||||||
|
const formatDateTime = (date) => {
|
||||||
|
if (!date) return null;
|
||||||
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
|
if (isNaN(dateObj.getTime())) return null;
|
||||||
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
|
return beijingDate.toISOString().replace('T', ' ').slice(0, 19);
|
||||||
|
};
|
||||||
|
|
||||||
// 格式化租房数据
|
// 格式化租房数据
|
||||||
const formatRentalData = (rental) => {
|
const formatRentalData = (rental) => {
|
||||||
const formattedRental = {
|
const formattedRental = {
|
||||||
...rental.toJSON(),
|
...rental.toJSON(),
|
||||||
startDate: formatDate(rental.startDate),
|
startDate: formatDate(rental.startDate),
|
||||||
endDate: formatDate(rental.endDate),
|
endDate: formatDate(rental.endDate),
|
||||||
createTime: formatDate(rental.createTime),
|
createTime: formatDateTime(rental.createTime),
|
||||||
updateTime: formatDate(rental.updateTime)
|
updateTime: formatDateTime(rental.updateTime)
|
||||||
};
|
};
|
||||||
|
|
||||||
return formattedRental;
|
return formattedRental;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 检查并更新租房状态
|
// 检查并更新租房状态
|
||||||
const checkAndUpdateRentalStatus = async () => {
|
const checkAndUpdateRentalStatus = async (tenantId) => {
|
||||||
try {
|
try {
|
||||||
// 获取当前日期
|
// 获取当前日期
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
|
|
@ -35,9 +42,9 @@ const checkAndUpdateRentalStatus = async () => {
|
||||||
const fiveDaysLater = new Date();
|
const fiveDaysLater = new Date();
|
||||||
fiveDaysLater.setDate(currentDate.getDate() + 5);
|
fiveDaysLater.setDate(currentDate.getDate() + 5);
|
||||||
|
|
||||||
// 查找所有活跃的租房记录
|
// 查找该租户下所有活跃的租房记录
|
||||||
const rentals = await Rental.findAll({
|
const rentals = await Rental.findAll({
|
||||||
where: { status: 'active', isDeleted: 0 },
|
where: { tenantId, status: 'active', isDeleted: 0 },
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: Room,
|
model: Room,
|
||||||
|
|
@ -82,7 +89,7 @@ const checkAndUpdateRentalStatus = async () => {
|
||||||
const getAllRentals = async (req, res) => {
|
const getAllRentals = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 先检查并更新租房状态
|
// 先检查并更新租房状态
|
||||||
await checkAndUpdateRentalStatus();
|
await checkAndUpdateRentalStatus(req.user.tenantId);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
apartmentId,
|
apartmentId,
|
||||||
|
|
@ -98,7 +105,7 @@ const getAllRentals = async (req, res) => {
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
const where = { isDeleted: 0 };
|
const where = { tenantId: req.user.tenantId, isDeleted: 0 };
|
||||||
if (status) {
|
if (status) {
|
||||||
where.status = status;
|
where.status = status;
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +173,7 @@ const getRentalById = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const rental = await Rental.findOne({
|
const rental = await Rental.findOne({
|
||||||
where: { id, isDeleted: 0 },
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 },
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: Room,
|
model: Room,
|
||||||
|
|
@ -269,6 +276,7 @@ const createRental = async (req, res) => {
|
||||||
electricityMeterStart: body.electricityMeterStart || null,
|
electricityMeterStart: body.electricityMeterStart || null,
|
||||||
status: body.status || 'active',
|
status: body.status || 'active',
|
||||||
remark: body.remark,
|
remark: body.remark,
|
||||||
|
tenantId: req.user.tenantId,
|
||||||
createBy: req.user.id,
|
createBy: req.user.id,
|
||||||
updateBy: req.user.id
|
updateBy: req.user.id
|
||||||
});
|
});
|
||||||
|
|
@ -280,16 +288,17 @@ const createRental = async (req, res) => {
|
||||||
|
|
||||||
// 自动生成租金账单
|
// 自动生成租金账单
|
||||||
await Bill.create({
|
await Bill.create({
|
||||||
|
billNo: 'B' + Date.now(),
|
||||||
rentalId: rental.id,
|
rentalId: rental.id,
|
||||||
roomId: parsedRoomId,
|
roomId: parsedRoomId,
|
||||||
|
renterId: parsedRenterId,
|
||||||
type: 'income',
|
type: 'income',
|
||||||
category: 'rent',
|
category: 'rent',
|
||||||
amount: body.rent,
|
receivableAmount: body.rent,
|
||||||
paidAmount: 0,
|
receivedAmount: 0,
|
||||||
status: 'pending',
|
status: 'unpaid',
|
||||||
dueDate: body.endDate,
|
billDate: body.startDate,
|
||||||
periodStart: body.startDate,
|
billMonth: body.startDate.substring(0, 7),
|
||||||
periodEnd: body.endDate,
|
|
||||||
remark: `租约租金 - ${renterName}`,
|
remark: `租约租金 - ${renterName}`,
|
||||||
tenantId: req.user.tenantId,
|
tenantId: req.user.tenantId,
|
||||||
createBy: req.user.id,
|
createBy: req.user.id,
|
||||||
|
|
@ -299,14 +308,17 @@ const createRental = async (req, res) => {
|
||||||
// 自动生成押金账单(如果有押金)
|
// 自动生成押金账单(如果有押金)
|
||||||
if (deposit > 0) {
|
if (deposit > 0) {
|
||||||
await Bill.create({
|
await Bill.create({
|
||||||
|
billNo: 'B' + Date.now() + '1',
|
||||||
rentalId: rental.id,
|
rentalId: rental.id,
|
||||||
roomId: parsedRoomId,
|
roomId: parsedRoomId,
|
||||||
|
renterId: parsedRenterId,
|
||||||
type: 'income',
|
type: 'income',
|
||||||
category: 'deposit',
|
category: 'deposit',
|
||||||
amount: deposit,
|
receivableAmount: deposit,
|
||||||
paidAmount: 0,
|
receivedAmount: 0,
|
||||||
status: 'pending',
|
status: 'unpaid',
|
||||||
dueDate: body.startDate,
|
billDate: body.startDate,
|
||||||
|
billMonth: body.startDate.substring(0, 7),
|
||||||
remark: `租约押金 - ${renterName}`,
|
remark: `租约押金 - ${renterName}`,
|
||||||
tenantId: req.user.tenantId,
|
tenantId: req.user.tenantId,
|
||||||
createBy: req.user.id,
|
createBy: req.user.id,
|
||||||
|
|
@ -327,7 +339,7 @@ const updateRental = async (req, res) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const { roomId, renterId, startDate, endDate, paymentType, rent, deposit, operator, waterMeterStart, electricityMeterStart, waterMeterEnd, electricityMeterEnd, status, remark } = req.body;
|
const { roomId, renterId, startDate, endDate, paymentType, rent, deposit, operator, waterMeterStart, electricityMeterStart, waterMeterEnd, electricityMeterEnd, status, remark } = req.body;
|
||||||
const rental = await Rental.findOne({
|
const rental = await Rental.findOne({
|
||||||
where: { id, isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!rental) {
|
if (!rental) {
|
||||||
return response.notFound(res, '租房记录不存在');
|
return response.notFound(res, '租房记录不存在');
|
||||||
|
|
@ -362,7 +374,7 @@ const deleteRental = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const rental = await Rental.findOne({
|
const rental = await Rental.findOne({
|
||||||
where: { id, isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!rental) {
|
if (!rental) {
|
||||||
return response.notFound(res, '租房记录不存在');
|
return response.notFound(res, '租房记录不存在');
|
||||||
|
|
@ -384,7 +396,7 @@ const terminateRental = async (req, res) => {
|
||||||
const { waterMeterEnd, electricityMeterEnd, remark } = req.body;
|
const { waterMeterEnd, electricityMeterEnd, remark } = req.body;
|
||||||
|
|
||||||
const rental = await Rental.findOne({
|
const rental = await Rental.findOne({
|
||||||
where: { id, isDeleted: 0 },
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 },
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: Room,
|
model: Room,
|
||||||
|
|
@ -429,13 +441,16 @@ const terminateRental = async (req, res) => {
|
||||||
if (waterUsage > 0 && apartment.waterPrice) {
|
if (waterUsage > 0 && apartment.waterPrice) {
|
||||||
const waterAmount = waterUsage * parseFloat(apartment.waterPrice);
|
const waterAmount = waterUsage * parseFloat(apartment.waterPrice);
|
||||||
await Bill.create({
|
await Bill.create({
|
||||||
|
billNo: 'B' + Date.now(),
|
||||||
rentalId: rental.id,
|
rentalId: rental.id,
|
||||||
roomId: room.id,
|
roomId: room.id,
|
||||||
|
renterId: rental.renterId,
|
||||||
type: 'income',
|
type: 'income',
|
||||||
category: 'water',
|
category: 'water',
|
||||||
amount: waterAmount,
|
receivableAmount: waterAmount,
|
||||||
paidAmount: 0,
|
receivedAmount: 0,
|
||||||
status: 'pending',
|
status: 'unpaid',
|
||||||
|
billDate: new Date(),
|
||||||
remark: `退租水费 - ${renterName}(用量:${waterUsage.toFixed(2)}吨)`,
|
remark: `退租水费 - ${renterName}(用量:${waterUsage.toFixed(2)}吨)`,
|
||||||
tenantId: req.user.tenantId,
|
tenantId: req.user.tenantId,
|
||||||
createBy: req.user.id,
|
createBy: req.user.id,
|
||||||
|
|
@ -449,13 +464,16 @@ const terminateRental = async (req, res) => {
|
||||||
if (electricityUsage > 0 && apartment.electricityPrice) {
|
if (electricityUsage > 0 && apartment.electricityPrice) {
|
||||||
const electricityAmount = electricityUsage * parseFloat(apartment.electricityPrice);
|
const electricityAmount = electricityUsage * parseFloat(apartment.electricityPrice);
|
||||||
await Bill.create({
|
await Bill.create({
|
||||||
|
billNo: 'B' + Date.now() + '1',
|
||||||
rentalId: rental.id,
|
rentalId: rental.id,
|
||||||
roomId: room.id,
|
roomId: room.id,
|
||||||
|
renterId: rental.renterId,
|
||||||
type: 'income',
|
type: 'income',
|
||||||
category: 'electricity',
|
category: 'electricity',
|
||||||
amount: electricityAmount,
|
receivableAmount: electricityAmount,
|
||||||
paidAmount: 0,
|
receivedAmount: 0,
|
||||||
status: 'pending',
|
status: 'unpaid',
|
||||||
|
billDate: new Date(),
|
||||||
remark: `退租电费 - ${renterName}(用量:${electricityUsage.toFixed(2)}度)`,
|
remark: `退租电费 - ${renterName}(用量:${electricityUsage.toFixed(2)}度)`,
|
||||||
tenantId: req.user.tenantId,
|
tenantId: req.user.tenantId,
|
||||||
createBy: req.user.id,
|
createBy: req.user.id,
|
||||||
|
|
@ -481,7 +499,7 @@ const terminateRental = async (req, res) => {
|
||||||
const listRentals = async (req, res) => {
|
const listRentals = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 先检查并更新租房状态
|
// 先检查并更新租房状态
|
||||||
await checkAndUpdateRentalStatus();
|
await checkAndUpdateRentalStatus(req.user.tenantId);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
apartmentId,
|
apartmentId,
|
||||||
|
|
@ -495,7 +513,7 @@ const listRentals = async (req, res) => {
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
const where = { isDeleted: 0 };
|
const where = { tenantId: req.user.tenantId, isDeleted: 0 };
|
||||||
if (status) {
|
if (status) {
|
||||||
where.status = status;
|
where.status = status;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,25 @@ const { Renter, Rental, Room, Apartment } = require('../models');
|
||||||
const { Op } = require('sequelize');
|
const { Op } = require('sequelize');
|
||||||
const response = require('../utils/response');
|
const response = require('../utils/response');
|
||||||
|
|
||||||
|
// 格式化日期时间(年月日时分秒)
|
||||||
|
const formatDateTime = (date) => {
|
||||||
|
if (!date) return null;
|
||||||
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
|
if (isNaN(dateObj.getTime())) return null;
|
||||||
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
|
return beijingDate.toISOString().replace('T', ' ').slice(0, 19);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 格式化租客数据
|
||||||
|
const formatRenterData = (renter) => {
|
||||||
|
const data = renter.toJSON ? renter.toJSON() : renter;
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
createTime: formatDateTime(data.createTime),
|
||||||
|
updateTime: formatDateTime(data.updateTime)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// 获取租客列表(分页)
|
// 获取租客列表(分页)
|
||||||
const getRenters = async (req, res) => {
|
const getRenters = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -30,7 +49,7 @@ const getRenters = async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '获取成功', {
|
response.success(res, '获取成功', {
|
||||||
list: rows,
|
list: rows.map(formatRenterData),
|
||||||
total: count,
|
total: count,
|
||||||
page: parseInt(page),
|
page: parseInt(page),
|
||||||
pageSize: parseInt(pageSize)
|
pageSize: parseInt(pageSize)
|
||||||
|
|
@ -66,7 +85,7 @@ const getRenterList = async (req, res) => {
|
||||||
order: [['createTime', 'DESC']]
|
order: [['createTime', 'DESC']]
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '获取成功', rows);
|
response.success(res, '获取成功', rows.map(formatRenterData));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取租客列表失败:', error);
|
console.error('获取租客列表失败:', error);
|
||||||
response.serverError(res, '获取租客列表失败', error);
|
response.serverError(res, '获取租客列表失败', error);
|
||||||
|
|
@ -107,7 +126,13 @@ const getRenterById = async (req, res) => {
|
||||||
|
|
||||||
response.success(res, '获取成功', {
|
response.success(res, '获取成功', {
|
||||||
...renter.toJSON(),
|
...renter.toJSON(),
|
||||||
rentals
|
createTime: formatDateTime(renter.createTime),
|
||||||
|
updateTime: formatDateTime(renter.updateTime),
|
||||||
|
rentals: rentals.map(r => ({
|
||||||
|
...r.toJSON(),
|
||||||
|
createTime: formatDateTime(r.createTime),
|
||||||
|
updateTime: formatDateTime(r.updateTime)
|
||||||
|
}))
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取租客详情失败:', error);
|
console.error('获取租客详情失败:', error);
|
||||||
|
|
@ -167,7 +192,7 @@ const createRenter = async (req, res) => {
|
||||||
status: 'active'
|
status: 'active'
|
||||||
});
|
});
|
||||||
|
|
||||||
response.created(res, '创建成功', renter);
|
response.created(res, '创建成功', formatRenterData(renter));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('创建租客失败:', error);
|
console.error('创建租客失败:', error);
|
||||||
response.serverError(res, '创建租客失败', error);
|
response.serverError(res, '创建租客失败', error);
|
||||||
|
|
@ -230,7 +255,7 @@ const updateRenter = async (req, res) => {
|
||||||
updateBy
|
updateBy
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '更新成功', renter);
|
response.success(res, '更新成功', formatRenterData(renter));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('更新租客失败:', error);
|
console.error('更新租客失败:', error);
|
||||||
response.serverError(res, '更新租客失败', error);
|
response.serverError(res, '更新租客失败', error);
|
||||||
|
|
@ -254,7 +279,7 @@ const deleteRenter = async (req, res) => {
|
||||||
// 检查是否有进行中的租赁
|
// 检查是否有进行中的租赁
|
||||||
const activeRentals = await Rental.count({
|
const activeRentals = await Rental.count({
|
||||||
where: {
|
where: {
|
||||||
tenantName: renter.name,
|
renterId: id,
|
||||||
tenantId,
|
tenantId,
|
||||||
status: 'active'
|
status: 'active'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,35 @@ const response = require('../utils/response');
|
||||||
// 格式化时间(考虑时区,转换为北京时间)
|
// 格式化时间(考虑时区,转换为北京时间)
|
||||||
const formatDate = (date) => {
|
const formatDate = (date) => {
|
||||||
if (!date) return null;
|
if (!date) return null;
|
||||||
// 确保 date 是 Date 对象
|
|
||||||
const dateObj = date instanceof Date ? date : new Date(date);
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
if (isNaN(dateObj.getTime())) return null;
|
if (isNaN(dateObj.getTime())) return null;
|
||||||
// 创建一个新的Date对象,加上8小时的时区偏移
|
|
||||||
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
return beijingDate.toISOString().split('T')[0];
|
return beijingDate.toISOString().split('T')[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 格式化日期时间(年月日时分秒)
|
||||||
|
const formatDateTime = (date) => {
|
||||||
|
if (!date) return null;
|
||||||
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
|
if (isNaN(dateObj.getTime())) return null;
|
||||||
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
|
return beijingDate.toISOString().replace('T', ' ').slice(0, 19);
|
||||||
|
};
|
||||||
|
|
||||||
// 格式化房间数据
|
// 格式化房间数据
|
||||||
const formatRoomData = (room) => {
|
const formatRoomData = (room) => {
|
||||||
const formattedRoom = {
|
const formattedRoom = {
|
||||||
...room.toJSON(),
|
...room.toJSON(),
|
||||||
createTime: formatDate(room.createTime),
|
createTime: formatDateTime(room.createTime),
|
||||||
updateTime: formatDate(room.updateTime)
|
updateTime: formatDateTime(room.updateTime)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 格式化关联数据
|
// 格式化关联数据
|
||||||
if (formattedRoom.Apartment) {
|
if (formattedRoom.Apartment) {
|
||||||
formattedRoom.Apartment = {
|
formattedRoom.Apartment = {
|
||||||
...formattedRoom.Apartment,
|
...formattedRoom.Apartment,
|
||||||
createTime: formatDate(formattedRoom.Apartment.createTime),
|
createTime: formatDateTime(formattedRoom.Apartment.createTime),
|
||||||
updateTime: formatDate(formattedRoom.Apartment.updateTime)
|
updateTime: formatDateTime(formattedRoom.Apartment.updateTime)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,8 +45,8 @@ const formatRoomData = (room) => {
|
||||||
...rental,
|
...rental,
|
||||||
startDate: formatDate(rental.startDate),
|
startDate: formatDate(rental.startDate),
|
||||||
endDate: formatDate(rental.endDate),
|
endDate: formatDate(rental.endDate),
|
||||||
createTime: formatDate(rental.createTime),
|
createTime: formatDateTime(rental.createTime),
|
||||||
updateTime: formatDate(rental.updateTime)
|
updateTime: formatDateTime(rental.updateTime)
|
||||||
};
|
};
|
||||||
|
|
||||||
return formattedRental;
|
return formattedRental;
|
||||||
|
|
@ -50,7 +57,7 @@ const formatRoomData = (room) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 检查并更新租房状态
|
// 检查并更新租房状态
|
||||||
const checkAndUpdateRentalStatus = async () => {
|
const checkAndUpdateRentalStatus = async (tenantId) => {
|
||||||
try {
|
try {
|
||||||
// 获取当前日期
|
// 获取当前日期
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
|
|
@ -58,9 +65,9 @@ const checkAndUpdateRentalStatus = async () => {
|
||||||
const fiveDaysLater = new Date();
|
const fiveDaysLater = new Date();
|
||||||
fiveDaysLater.setDate(currentDate.getDate() + 5);
|
fiveDaysLater.setDate(currentDate.getDate() + 5);
|
||||||
|
|
||||||
// 查找所有在租的租房记录
|
// 查找该租户下所有在租的租房记录
|
||||||
const rentals = await Rental.findAll({
|
const rentals = await Rental.findAll({
|
||||||
where: { status: 'active', isDeleted: 0 }
|
where: { tenantId, status: 'active', isDeleted: 0 }
|
||||||
});
|
});
|
||||||
|
|
||||||
// 检查每个租房记录的状态
|
// 检查每个租房记录的状态
|
||||||
|
|
@ -99,12 +106,12 @@ const checkAndUpdateRentalStatus = async () => {
|
||||||
const getAllRooms = async (req, res) => {
|
const getAllRooms = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 先检查并更新租房状态
|
// 先检查并更新租房状态
|
||||||
await checkAndUpdateRentalStatus();
|
await checkAndUpdateRentalStatus(req.user.tenantId);
|
||||||
|
|
||||||
const { apartmentId, roomNumber, status, rentalStatus, page = 1, pageSize = 10 } = req.query;
|
const { apartmentId, roomNumber, status, rentalStatus, page = 1, pageSize = 10 } = req.query;
|
||||||
|
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
const where = { isDeleted: 0 };
|
const where = { tenantId: req.user.tenantId, isDeleted: 0 };
|
||||||
if (apartmentId) {
|
if (apartmentId) {
|
||||||
where.apartmentId = apartmentId;
|
where.apartmentId = apartmentId;
|
||||||
}
|
}
|
||||||
|
|
@ -142,6 +149,7 @@ const getAllRooms = async (req, res) => {
|
||||||
const rentals = await Rental.findAll({
|
const rentals = await Rental.findAll({
|
||||||
where: {
|
where: {
|
||||||
roomId: room.id,
|
roomId: room.id,
|
||||||
|
tenantId: req.user.tenantId,
|
||||||
status: { [Op.ne]: 'expired' },
|
status: { [Op.ne]: 'expired' },
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
},
|
},
|
||||||
|
|
@ -195,11 +203,11 @@ const getAllRooms = async (req, res) => {
|
||||||
const getRoomById = async (req, res) => {
|
const getRoomById = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 先检查并更新租房状态
|
// 先检查并更新租房状态
|
||||||
await checkAndUpdateRentalStatus();
|
await checkAndUpdateRentalStatus(req.user.tenantId);
|
||||||
|
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const room = await Room.findOne({
|
const room = await Room.findOne({
|
||||||
where: { id, isDeleted: 0 },
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 },
|
||||||
include: [Apartment]
|
include: [Apartment]
|
||||||
});
|
});
|
||||||
if (!room) {
|
if (!room) {
|
||||||
|
|
@ -213,6 +221,7 @@ const getRoomById = async (req, res) => {
|
||||||
const rentals = await Rental.findAll({
|
const rentals = await Rental.findAll({
|
||||||
where: {
|
where: {
|
||||||
roomId: room.id,
|
roomId: room.id,
|
||||||
|
tenantId: req.user.tenantId,
|
||||||
status: { [Op.ne]: 'expired' },
|
status: { [Op.ne]: 'expired' },
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
},
|
},
|
||||||
|
|
@ -232,7 +241,7 @@ const getRoomById = async (req, res) => {
|
||||||
...rentalData,
|
...rentalData,
|
||||||
startDate: formatDate(rental.startDate),
|
startDate: formatDate(rental.startDate),
|
||||||
endDate: formatDate(rental.endDate),
|
endDate: formatDate(rental.endDate),
|
||||||
createTime: formatDate(rental.createTime),
|
createTime: formatDateTime(rental.createTime),
|
||||||
// 兼容前端显示的字段
|
// 兼容前端显示的字段
|
||||||
tenantName: rentalData.Renter ? rentalData.Renter.name : '',
|
tenantName: rentalData.Renter ? rentalData.Renter.name : '',
|
||||||
tenantPhone: rentalData.Renter ? rentalData.Renter.phone : ''
|
tenantPhone: rentalData.Renter ? rentalData.Renter.phone : ''
|
||||||
|
|
@ -314,7 +323,7 @@ const updateRoom = async (req, res) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const { apartmentId, roomNumber, floor, roomType, area, monthlyPrice, yearlyPrice, deposit, sortOrder, status, rentalStatus } = req.body;
|
const { apartmentId, roomNumber, floor, roomType, area, monthlyPrice, yearlyPrice, deposit, sortOrder, status, rentalStatus } = req.body;
|
||||||
const room = await Room.findOne({
|
const room = await Room.findOne({
|
||||||
where: { id, isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return response.notFound(res, '房间不存在');
|
return response.notFound(res, '房间不存在');
|
||||||
|
|
@ -346,7 +355,7 @@ const deleteRoom = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const room = await Room.findOne({
|
const room = await Room.findOne({
|
||||||
where: { id, isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return response.notFound(res, '房间不存在');
|
return response.notFound(res, '房间不存在');
|
||||||
|
|
@ -365,12 +374,12 @@ const deleteRoom = async (req, res) => {
|
||||||
const listRooms = async (req, res) => {
|
const listRooms = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 先检查并更新租房状态
|
// 先检查并更新租房状态
|
||||||
await checkAndUpdateRentalStatus();
|
await checkAndUpdateRentalStatus(req.user.tenantId);
|
||||||
|
|
||||||
const { apartmentId, roomNumber, status, rentalStatus } = req.query;
|
const { apartmentId, roomNumber, status, rentalStatus } = req.query;
|
||||||
|
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
const where = { isDeleted: 0 };
|
const where = { tenantId: req.user.tenantId, isDeleted: 0 };
|
||||||
if (apartmentId) {
|
if (apartmentId) {
|
||||||
where.apartmentId = apartmentId;
|
where.apartmentId = apartmentId;
|
||||||
}
|
}
|
||||||
|
|
@ -403,6 +412,7 @@ const listRooms = async (req, res) => {
|
||||||
const rentals = await Rental.findAll({
|
const rentals = await Rental.findAll({
|
||||||
where: {
|
where: {
|
||||||
roomId: room.id,
|
roomId: room.id,
|
||||||
|
tenantId: req.user.tenantId,
|
||||||
status: { [Op.ne]: 'expired' },
|
status: { [Op.ne]: 'expired' },
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
},
|
},
|
||||||
|
|
@ -423,7 +433,7 @@ const listRooms = async (req, res) => {
|
||||||
...rentalData,
|
...rentalData,
|
||||||
startDate: formatDate(rental.startDate),
|
startDate: formatDate(rental.startDate),
|
||||||
endDate: formatDate(rental.endDate),
|
endDate: formatDate(rental.endDate),
|
||||||
createTime: formatDate(rental.createTime),
|
createTime: formatDateTime(rental.createTime),
|
||||||
// 兼容前端显示的字段
|
// 兼容前端显示的字段
|
||||||
tenantName: rentalData.Renter ? rentalData.Renter.name : '',
|
tenantName: rentalData.Renter ? rentalData.Renter.name : '',
|
||||||
tenantPhone: rentalData.Renter ? rentalData.Renter.phone : ''
|
tenantPhone: rentalData.Renter ? rentalData.Renter.phone : ''
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const { Setting, Category } = require('../models');
|
const { Setting, Category } = require('../models');
|
||||||
|
const { Op } = require('sequelize');
|
||||||
const response = require('../utils/response');
|
const response = require('../utils/response');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const { Room, Rental, Apartment, Bill } = require('../models');
|
const { Room, Rental, Apartment, Bill, Renter } = require('../models');
|
||||||
const { Op } = require('sequelize');
|
const { Op } = require('sequelize');
|
||||||
const response = require('../utils/response');
|
const response = require('../utils/response');
|
||||||
|
|
||||||
|
|
@ -27,9 +27,8 @@ const getRentStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
rentals = await Rental.findAll({
|
rentals = await Rental.findAll({
|
||||||
where: {
|
where: {
|
||||||
createTime: {
|
tenantId: req.user.tenantId,
|
||||||
[Op.gte]: startDate
|
createTime: { [Op.gte]: startDate },
|
||||||
},
|
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -66,10 +65,9 @@ const getRentStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const expenses = await Bill.findAll({
|
const expenses = await Bill.findAll({
|
||||||
where: {
|
where: {
|
||||||
|
tenantId: req.user.tenantId,
|
||||||
type: 'expense',
|
type: 'expense',
|
||||||
billDate: {
|
billDate: { [Op.gte]: startDate },
|
||||||
[Op.gte]: startDate
|
|
||||||
},
|
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -117,7 +115,7 @@ const getRentStatistics = async (req, res) => {
|
||||||
const getRoomStatusStatistics = async (req, res) => {
|
const getRoomStatusStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 获取所有房间(排除已删除的)
|
// 获取所有房间(排除已删除的)
|
||||||
const rooms = await Room.findAll({ where: { isDeleted: 0 } });
|
const rooms = await Room.findAll({ where: { tenantId: req.user.tenantId, isDeleted: 0 } });
|
||||||
|
|
||||||
// 初始化统计数据
|
// 初始化统计数据
|
||||||
let empty = 0;
|
let empty = 0;
|
||||||
|
|
@ -162,26 +160,26 @@ const getRoomStatusStatistics = async (req, res) => {
|
||||||
// Dashboard统计数据
|
// Dashboard统计数据
|
||||||
const getDashboardStatistics = async (req, res) => {
|
const getDashboardStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 导入所有需要的模型
|
const tenantId = req.user.tenantId;
|
||||||
const { Apartment, Room, WaterBill, Rental, Bill } = require('../models');
|
const baseWhere = { tenantId, isDeleted: 0 };
|
||||||
|
|
||||||
// 并行查询所有统计数据
|
// 并行查询所有统计数据
|
||||||
const [apartmentCount, roomCount, emptyRoomCount, reservedRoomCount, rentedRoomCount, soonExpireRoomCount, expiredRoomCount] = await Promise.all([
|
const [apartmentCount, roomCount, emptyRoomCount, reservedRoomCount, rentedRoomCount, soonExpireRoomCount, expiredRoomCount] = await Promise.all([
|
||||||
Apartment.count({ where: { isDeleted: 0 } }),
|
Apartment.count({ where: baseWhere }),
|
||||||
Room.count({ where: { isDeleted: 0 } }),
|
Room.count({ where: baseWhere }),
|
||||||
Room.count({ where: { status: 'empty', isDeleted: 0 } }),
|
Room.count({ where: { ...baseWhere, status: 'empty' } }),
|
||||||
Room.count({ where: { status: 'reserved', isDeleted: 0 } }),
|
Room.count({ where: { ...baseWhere, status: 'reserved' } }),
|
||||||
Room.count({ where: { status: 'rented', isDeleted: 0 } }),
|
Room.count({ where: { ...baseWhere, status: 'rented' } }),
|
||||||
Room.count({ where: { status: 'rented', rentalStatus: 'soon_expire', isDeleted: 0 } }),
|
Room.count({ where: { ...baseWhere, status: 'rented', rentalStatus: 'soon_expire' } }),
|
||||||
Room.count({ where: { status: 'rented', rentalStatus: 'expired', isDeleted: 0 } })
|
Room.count({ where: { ...baseWhere, status: 'rented', rentalStatus: 'expired' } })
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 安全地获取sum统计,处理表不存在或为空的情况
|
// 安全地获取sum统计
|
||||||
let collectedRentAmount = 0;
|
let collectedRentAmount = 0;
|
||||||
let collectedWaterAmount = 0;
|
let collectedWaterAmount = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const rentResult = await Rental.sum('rent', { where: { isDeleted: 0 } });
|
const rentResult = await Rental.sum('rent', { where: { tenantId, isDeleted: 0 } });
|
||||||
collectedRentAmount = rentResult || 0;
|
collectedRentAmount = rentResult || 0;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('统计租金失败:', e.message);
|
console.warn('统计租金失败:', e.message);
|
||||||
|
|
@ -189,13 +187,8 @@ const getDashboardStatistics = async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 尝试从Bill表统计水费收入
|
|
||||||
const waterResult = await Bill.sum('receivedAmount', {
|
const waterResult = await Bill.sum('receivedAmount', {
|
||||||
where: {
|
where: { tenantId, category: 'water', status: 'paid', isDeleted: 0 }
|
||||||
category: 'water',
|
|
||||||
status: 'paid',
|
|
||||||
isDeleted: 0
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
collectedWaterAmount = waterResult || 0;
|
collectedWaterAmount = waterResult || 0;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -227,10 +220,10 @@ const getDashboardStatistics = async (req, res) => {
|
||||||
const getApartmentRoomStatusStatistics = async (req, res) => {
|
const getApartmentRoomStatusStatistics = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 获取所有公寓(排除已删除的)
|
// 获取所有公寓(排除已删除的)
|
||||||
const apartments = await Apartment.findAll({ where: { isDeleted: 0 } });
|
const apartments = await Apartment.findAll({ where: { tenantId: req.user.tenantId, isDeleted: 0 } });
|
||||||
|
|
||||||
// 获取所有房间(排除已删除的)
|
// 获取所有房间(排除已删除的)
|
||||||
const rooms = await Room.findAll({ where: { isDeleted: 0 } });
|
const rooms = await Room.findAll({ where: { tenantId: req.user.tenantId, isDeleted: 0 } });
|
||||||
|
|
||||||
// 构建公寓房间状态分布数据
|
// 构建公寓房间状态分布数据
|
||||||
const apartmentRoomStatusStatistics = apartments.map(apartment => {
|
const apartmentRoomStatusStatistics = apartments.map(apartment => {
|
||||||
|
|
@ -280,11 +273,12 @@ const getApartmentRoomStatusStatistics = async (req, res) => {
|
||||||
const getEmptyRoomsByApartment = async (req, res) => {
|
const getEmptyRoomsByApartment = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 获取所有公寓(排除已删除的)
|
// 获取所有公寓(排除已删除的)
|
||||||
const apartments = await Apartment.findAll({ where: { isDeleted: 0 } });
|
const apartments = await Apartment.findAll({ where: { tenantId: req.user.tenantId, isDeleted: 0 } });
|
||||||
|
|
||||||
// 获取所有空房(排除已删除的)
|
// 获取所有空房(排除已删除的)
|
||||||
const emptyRooms = await Room.findAll({
|
const emptyRooms = await Room.findAll({
|
||||||
where: {
|
where: {
|
||||||
|
tenantId: req.user.tenantId,
|
||||||
status: 'empty',
|
status: 'empty',
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
}
|
}
|
||||||
|
|
@ -319,11 +313,12 @@ const getEmptyRoomsByApartment = async (req, res) => {
|
||||||
const getRentedRoomsByApartment = async (req, res) => {
|
const getRentedRoomsByApartment = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 获取所有公寓(排除已删除的)
|
// 获取所有公寓(排除已删除的)
|
||||||
const apartments = await Apartment.findAll({ where: { isDeleted: 0 } });
|
const apartments = await Apartment.findAll({ where: { tenantId: req.user.tenantId, isDeleted: 0 } });
|
||||||
|
|
||||||
// 获取所有在租房(排除已删除的)
|
// 获取所有在租房(排除已删除的)
|
||||||
const rentedRooms = await Room.findAll({
|
const rentedRooms = await Room.findAll({
|
||||||
where: {
|
where: {
|
||||||
|
tenantId: req.user.tenantId,
|
||||||
status: 'rented',
|
status: 'rented',
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
}
|
}
|
||||||
|
|
@ -357,26 +352,32 @@ const getRentedRoomsByApartment = async (req, res) => {
|
||||||
// 租客在租统计
|
// 租客在租统计
|
||||||
const getTenantRentalStats = async (req, res) => {
|
const getTenantRentalStats = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
const tenantId = req.user.tenantId;
|
||||||
|
|
||||||
// 获取所有在租的租赁记录(排除已删除的)
|
// 获取所有在租的租赁记录(排除已删除的)
|
||||||
const rentals = await Rental.findAll({
|
const rentals = await Rental.findAll({
|
||||||
where: {
|
where: {
|
||||||
|
tenantId,
|
||||||
status: 'active',
|
status: 'active',
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
},
|
},
|
||||||
include: [{
|
include: [{
|
||||||
model: Room,
|
model: Room,
|
||||||
where: { isDeleted: 0 }
|
where: { isDeleted: 0 }
|
||||||
|
}, {
|
||||||
|
model: Renter,
|
||||||
|
attributes: ['id', 'name']
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取所有公寓(排除已删除的)
|
// 获取所有公寓(排除已删除的)
|
||||||
const apartments = await Apartment.findAll({ where: { isDeleted: 0 } });
|
const apartments = await Apartment.findAll({ where: { tenantId, isDeleted: 0 } });
|
||||||
|
|
||||||
// 按租客分组
|
// 按租客分组
|
||||||
const tenantMap = new Map();
|
const tenantMap = new Map();
|
||||||
|
|
||||||
rentals.forEach(rental => {
|
rentals.forEach(rental => {
|
||||||
const tenantName = rental.tenantName;
|
const tenantName = rental.Renter ? rental.Renter.name : '未知租客';
|
||||||
const room = rental.Room;
|
const room = rental.Room;
|
||||||
|
|
||||||
if (!tenantMap.has(tenantName)) {
|
if (!tenantMap.has(tenantName)) {
|
||||||
|
|
@ -425,11 +426,12 @@ const getTenantRentalStats = async (req, res) => {
|
||||||
const getSoonExpireRoomsByApartment = async (req, res) => {
|
const getSoonExpireRoomsByApartment = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 获取所有公寓(排除已删除的)
|
// 获取所有公寓(排除已删除的)
|
||||||
const apartments = await Apartment.findAll({ where: { isDeleted: 0 } });
|
const apartments = await Apartment.findAll({ where: { tenantId: req.user.tenantId, isDeleted: 0 } });
|
||||||
|
|
||||||
// 获取所有即将到期的房间(排除已删除的)
|
// 获取所有即将到期的房间(排除已删除的)
|
||||||
const soonExpireRooms = await Room.findAll({
|
const soonExpireRooms = await Room.findAll({
|
||||||
where: {
|
where: {
|
||||||
|
tenantId: req.user.tenantId,
|
||||||
status: 'rented',
|
status: 'rented',
|
||||||
rentalStatus: 'soon_expire',
|
rentalStatus: 'soon_expire',
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
|
|
@ -465,11 +467,12 @@ const getSoonExpireRoomsByApartment = async (req, res) => {
|
||||||
const getExpiredRoomsByApartment = async (req, res) => {
|
const getExpiredRoomsByApartment = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// 获取所有公寓(排除已删除的)
|
// 获取所有公寓(排除已删除的)
|
||||||
const apartments = await Apartment.findAll({ where: { isDeleted: 0 } });
|
const apartments = await Apartment.findAll({ where: { tenantId: req.user.tenantId, isDeleted: 0 } });
|
||||||
|
|
||||||
// 获取所有已到期的房间(排除已删除的)
|
// 获取所有已到期的房间(排除已删除的)
|
||||||
const expiredRooms = await Room.findAll({
|
const expiredRooms = await Room.findAll({
|
||||||
where: {
|
where: {
|
||||||
|
tenantId: req.user.tenantId,
|
||||||
status: 'rented',
|
status: 'rented',
|
||||||
rentalStatus: 'expired',
|
rentalStatus: 'expired',
|
||||||
isDeleted: 0
|
isDeleted: 0
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,25 @@
|
||||||
const { Tenant, User, Apartment, Room, Category, Setting } = require('../models');
|
const { Tenant, User, Apartment, Room, Category, Setting } = require('../models');
|
||||||
const bcrypt = require('bcryptjs');
|
const bcrypt = require('bcryptjs');
|
||||||
|
|
||||||
|
// 格式化日期时间(年月日时分秒)
|
||||||
|
const formatDateTime = (date) => {
|
||||||
|
if (!date) return null;
|
||||||
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
|
if (isNaN(dateObj.getTime())) return null;
|
||||||
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
|
return beijingDate.toISOString().replace('T', ' ').slice(0, 19);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 格式化租户数据
|
||||||
|
const formatTenantData = (tenant) => {
|
||||||
|
const data = tenant.toJSON ? tenant.toJSON() : tenant;
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
createTime: formatDateTime(data.createTime),
|
||||||
|
updateTime: formatDateTime(data.updateTime)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// 获取租户列表(超级管理员)
|
// 获取租户列表(超级管理员)
|
||||||
const getTenantList = async (req, res) => {
|
const getTenantList = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -66,7 +85,7 @@ const getTenantDetail = async (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
code: 200,
|
code: 200,
|
||||||
data: {
|
data: {
|
||||||
...tenant.toJSON(),
|
...formatTenantData(tenant),
|
||||||
stats: {
|
stats: {
|
||||||
userCount,
|
userCount,
|
||||||
apartmentCount,
|
apartmentCount,
|
||||||
|
|
@ -297,7 +316,7 @@ const getCurrentTenant = async (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
code: 200,
|
code: 200,
|
||||||
data: {
|
data: {
|
||||||
...tenant.toJSON(),
|
...formatTenantData(tenant),
|
||||||
stats: {
|
stats: {
|
||||||
userCount,
|
userCount,
|
||||||
apartmentCount,
|
apartmentCount,
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,32 @@ const Tenant = require('../models/Tenant');
|
||||||
const { logOperation } = require('../utils/logger');
|
const { logOperation } = require('../utils/logger');
|
||||||
const response = require('../utils/response');
|
const response = require('../utils/response');
|
||||||
|
|
||||||
|
// 格式化日期时间(年月日时分秒)
|
||||||
|
const formatDateTime = (date) => {
|
||||||
|
if (!date) return null;
|
||||||
|
const dateObj = date instanceof Date ? date : new Date(date);
|
||||||
|
if (isNaN(dateObj.getTime())) return null;
|
||||||
|
const beijingDate = new Date(dateObj.getTime() + 8 * 60 * 60 * 1000);
|
||||||
|
return beijingDate.toISOString().replace('T', ' ').slice(0, 19);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 格式化用户数据
|
||||||
|
const formatUserData = (user) => {
|
||||||
|
const data = user.toJSON ? user.toJSON() : user;
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
createTime: formatDateTime(data.createTime),
|
||||||
|
updateTime: formatDateTime(data.updateTime)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// 获取用户列表
|
// 获取用户列表
|
||||||
exports.getUserList = async (req, res) => {
|
exports.getUserList = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { page = 1, pageSize = 10, username, roleId, status } = req.query;
|
const { page = 1, pageSize = 10, username, roleId, status } = req.query;
|
||||||
|
|
||||||
// 构建查询条件 - 只查询普通用户(不包括系统管理员)
|
// 构建查询条件 - 只查询普通用户(不包括系统管理员)
|
||||||
const where = { isDeleted: 0, userType: 'user' };
|
const where = { tenantId: req.user.tenantId, isDeleted: 0, userType: 'user' };
|
||||||
if (username) {
|
if (username) {
|
||||||
where.username = { [Op.like]: `%${username}%` };
|
where.username = { [Op.like]: `%${username}%` };
|
||||||
}
|
}
|
||||||
|
|
@ -38,7 +57,7 @@ exports.getUserList = async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '获取成功', {
|
response.success(res, '获取成功', {
|
||||||
list: rows,
|
list: rows.map(formatUserData),
|
||||||
total: count,
|
total: count,
|
||||||
page: parseInt(page),
|
page: parseInt(page),
|
||||||
pageSize: parseInt(pageSize)
|
pageSize: parseInt(pageSize)
|
||||||
|
|
@ -54,8 +73,8 @@ exports.getUserById = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
|
||||||
const user = await User.findByPk(id, {
|
const user = await User.findOne({
|
||||||
where: { isDeleted: 0 },
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 },
|
||||||
attributes: ['id', 'username', 'nickname', 'roleId', 'status', 'createTime', 'updateTime'],
|
attributes: ['id', 'username', 'nickname', 'roleId', 'status', 'createTime', 'updateTime'],
|
||||||
include: [{
|
include: [{
|
||||||
model: Role,
|
model: Role,
|
||||||
|
|
@ -68,7 +87,7 @@ exports.getUserById = async (req, res) => {
|
||||||
return response.notFound(res, '用户不存在');
|
return response.notFound(res, '用户不存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
response.success(res, '获取成功', user);
|
response.success(res, '获取成功', formatUserData(user));
|
||||||
|
|
||||||
// 记录操作日志
|
// 记录操作日志
|
||||||
await logOperation({
|
await logOperation({
|
||||||
|
|
@ -147,8 +166,8 @@ exports.createUser = async (req, res) => {
|
||||||
return response.badRequest(res, '角色不存在或已禁用');
|
return response.badRequest(res, '角色不存在或已禁用');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查用户名是否已存在
|
// 检查用户名是否已存在(同一租户下)
|
||||||
const existingUser = await User.findOne({ where: { username, isDeleted: 0 } });
|
const existingUser = await User.findOne({ where: { username, tenantId: req.user.tenantId, isDeleted: 0 } });
|
||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
return response.badRequest(res, '用户名已存在');
|
return response.badRequest(res, '用户名已存在');
|
||||||
}
|
}
|
||||||
|
|
@ -172,7 +191,7 @@ exports.createUser = async (req, res) => {
|
||||||
username: user.username,
|
username: user.username,
|
||||||
nickname: user.nickname,
|
nickname: user.nickname,
|
||||||
roleId: user.roleId,
|
roleId: user.roleId,
|
||||||
createTime: user.createTime,
|
createTime: formatDateTime(user.createTime),
|
||||||
warning: isOverage && tenant ? `当前已超出套餐限制(${tenant.maxUsers}人),续费时将收取超额费用` : null
|
warning: isOverage && tenant ? `当前已超出套餐限制(${tenant.maxUsers}人),续费时将收取超额费用` : null
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -201,8 +220,8 @@ exports.updateUser = async (req, res) => {
|
||||||
const { nickname, roleId, status } = req.body;
|
const { nickname, roleId, status } = req.body;
|
||||||
|
|
||||||
// 查找用户
|
// 查找用户
|
||||||
const user = await User.findByPk(id, {
|
const user = await User.findOne({
|
||||||
where: { isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return response.notFound(res, '用户不存在');
|
return response.notFound(res, '用户不存在');
|
||||||
|
|
@ -235,7 +254,7 @@ exports.updateUser = async (req, res) => {
|
||||||
nickname: user.nickname,
|
nickname: user.nickname,
|
||||||
roleId: user.roleId,
|
roleId: user.roleId,
|
||||||
status: user.status,
|
status: user.status,
|
||||||
updateTime: user.updateTime
|
updateTime: formatDateTime(user.updateTime)
|
||||||
});
|
});
|
||||||
|
|
||||||
// 记录操作日志
|
// 记录操作日志
|
||||||
|
|
@ -267,8 +286,8 @@ exports.deleteUser = async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找用户
|
// 查找用户
|
||||||
const user = await User.findByPk(id, {
|
const user = await User.findOne({
|
||||||
where: { isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return response.notFound(res, '用户不存在');
|
return response.notFound(res, '用户不存在');
|
||||||
|
|
@ -307,8 +326,8 @@ exports.resetUserPassword = async (req, res) => {
|
||||||
const defaultPassword = '123456';
|
const defaultPassword = '123456';
|
||||||
|
|
||||||
// 查找用户
|
// 查找用户
|
||||||
const user = await User.findByPk(id, {
|
const user = await User.findOne({
|
||||||
where: { isDeleted: 0 }
|
where: { id, tenantId: req.user.tenantId, isDeleted: 0 }
|
||||||
});
|
});
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return response.notFound(res, '用户不存在');
|
return response.notFound(res, '用户不存在');
|
||||||
|
|
@ -349,11 +368,11 @@ exports.resetUserPassword = async (req, res) => {
|
||||||
exports.getAllUsers = async (req, res) => {
|
exports.getAllUsers = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const users = await User.findAll({
|
const users = await User.findAll({
|
||||||
where: { isDeleted: 0, status: 'active' },
|
where: { tenantId: req.user.tenantId, isDeleted: 0, status: 'active' },
|
||||||
attributes: ['id', 'username', 'nickname']
|
attributes: ['id', 'username', 'nickname']
|
||||||
});
|
});
|
||||||
|
|
||||||
response.success(res, '获取用户列表成功', users);
|
response.success(res, '获取用户列表成功', users.map(formatUserData));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取用户列表错误:', error);
|
console.error('获取用户列表错误:', error);
|
||||||
response.serverError(res, '获取用户列表失败', error);
|
response.serverError(res, '获取用户列表失败', error);
|
||||||
|
|
@ -376,7 +395,7 @@ exports.getCurrentUserInfo = async (req, res) => {
|
||||||
return response.notFound(res, '用户不存在');
|
return response.notFound(res, '用户不存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
response.success(res, '获取用户信息成功', user);
|
response.success(res, '获取用户信息成功', formatUserData(user));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取用户信息失败:', error);
|
console.error('获取用户信息失败:', error);
|
||||||
response.serverError(res, '获取用户信息失败', error);
|
response.serverError(res, '获取用户信息失败', error);
|
||||||
|
|
@ -422,8 +441,8 @@ exports.updateUserProfile = async (req, res) => {
|
||||||
username: user.username,
|
username: user.username,
|
||||||
nickname: user.nickname,
|
nickname: user.nickname,
|
||||||
status: user.status,
|
status: user.status,
|
||||||
createTime: user.createTime,
|
createTime: formatDateTime(user.createTime),
|
||||||
updateTime: user.updateTime
|
updateTime: formatDateTime(user.updateTime)
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('更新个人资料失败:', error);
|
console.error('更新个人资料失败:', error);
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,23 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const settingController = require('../controllers/settingController');
|
const settingController = require('../controllers/settingController');
|
||||||
|
const { authMiddleware, adminMiddleware } = require('../middleware/auth');
|
||||||
|
|
||||||
// 设置相关接口
|
// 所有设置接口都需要认证
|
||||||
|
router.use(authMiddleware);
|
||||||
|
|
||||||
|
// 设置相关接口(读取)
|
||||||
router.get('/', settingController.getSettings);
|
router.get('/', settingController.getSettings);
|
||||||
router.put('/', settingController.updateSettings);
|
|
||||||
|
|
||||||
// 类目相关接口
|
// 设置相关接口(写入需要管理员权限)
|
||||||
|
router.put('/', adminMiddleware, settingController.updateSettings);
|
||||||
|
|
||||||
|
// 类目相关接口(读取)
|
||||||
router.get('/categories', settingController.getCategories);
|
router.get('/categories', settingController.getCategories);
|
||||||
router.post('/categories', settingController.createCategory);
|
|
||||||
router.put('/categories/:id', settingController.updateCategory);
|
// 类目相关接口(写入需要管理员权限)
|
||||||
router.delete('/categories/:id', settingController.deleteCategory);
|
router.post('/categories', adminMiddleware, settingController.createCategory);
|
||||||
|
router.put('/categories/:id', adminMiddleware, settingController.updateCategory);
|
||||||
|
router.delete('/categories/:id', adminMiddleware, settingController.deleteCategory);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const statisticsController = require('../controllers/statisticsController');
|
const statisticsController = require('../controllers/statisticsController');
|
||||||
|
const { authMiddleware } = require('../middleware/auth');
|
||||||
|
|
||||||
|
// 所有统计接口都需要认证
|
||||||
|
router.use(authMiddleware);
|
||||||
|
|
||||||
// 路由
|
// 路由
|
||||||
router.get('/rent', statisticsController.getRentStatistics);
|
router.get('/rent', statisticsController.getRentStatistics);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue