252 lines
7.6 KiB
JavaScript
252 lines
7.6 KiB
JavaScript
const express = require('express');
|
||
const router = express.Router();
|
||
const Order = require('../models/Order');
|
||
const Vehicle = require('../models/Vehicle');
|
||
const Customer = require('../models/Customer');
|
||
|
||
// 获取所有订单
|
||
router.get('/', async (req, res) => {
|
||
try {
|
||
const orders = await Order.find()
|
||
.populate('customer', 'name phone')
|
||
.populate('vehicle', 'model vehicleId');
|
||
res.json({ success: true, data: orders });
|
||
} catch (error) {
|
||
res.status(500).json({ success: false, message: error.message });
|
||
}
|
||
});
|
||
|
||
// 获取单个订单
|
||
router.get('/:id', async (req, res) => {
|
||
try {
|
||
const order = await Order.findById(req.params.id)
|
||
.populate('customer')
|
||
.populate('vehicle');
|
||
if (!order) {
|
||
return res.status(404).json({ success: false, message: '订单不存在' });
|
||
}
|
||
res.json({ success: true, data: order });
|
||
} catch (error) {
|
||
res.status(500).json({ success: false, message: error.message });
|
||
}
|
||
});
|
||
|
||
// 创建订单(支持门店端新客创建订单)
|
||
router.post('/', async (req, res) => {
|
||
try {
|
||
const {
|
||
customerName, customer, // customerName=新客姓名(字符串),customer=已有客户ID
|
||
vehicleId, vehicle, // vehicleId=前端字段名,vehicle=后端字段名
|
||
contractMonths, startDate, endDate, rentalFee, deposit, orderType
|
||
} = req.body;
|
||
|
||
// 解析车辆 ID(兼容前端 vehicleId 字段名)
|
||
const vehicleObjectId = vehicle || vehicleId;
|
||
|
||
// 解析客户:优先用已有客户ID,否则用姓名查找或创建新客户
|
||
let customerObjectId = customer;
|
||
if (!customerObjectId && customerName) {
|
||
// 查找同名客户
|
||
let customerDoc = await Customer.findOne({ name: customerName });
|
||
if (!customerDoc) {
|
||
// 创建新客户(phone 必填,设为默认值)
|
||
customerDoc = await Customer.create({
|
||
name: customerName,
|
||
phone: '00000000000',
|
||
customerId: `CUST${Date.now()}`
|
||
});
|
||
}
|
||
customerObjectId = customerDoc._id;
|
||
}
|
||
|
||
// 检查车辆是否存在
|
||
const vehicleDoc = await Vehicle.findById(vehicleObjectId);
|
||
if (!vehicleDoc) {
|
||
return res.status(404).json({ success: false, message: '车辆不存在' });
|
||
}
|
||
if (vehicleDoc.status !== '空闲') {
|
||
return res.status(400).json({ success: false, message: '车辆不可用,当前状态:' + vehicleDoc.status });
|
||
}
|
||
|
||
// 日期处理:startDate/endDate 或根据 contractMonths 计算
|
||
const start = startDate ? new Date(startDate) : new Date();
|
||
let end = endDate ? new Date(endDate) : null;
|
||
let months = Number(contractMonths) || 0;
|
||
|
||
if (!end && months > 0) {
|
||
end = new Date(start);
|
||
end.setMonth(end.getMonth() + months);
|
||
}
|
||
|
||
// 租金计算:使用传入的 rentalFee,若未传则为 0
|
||
let fee = Number(rentalFee) || 0;
|
||
|
||
const depositAmt = Number(deposit) || 0;
|
||
const totalAmount = fee + depositAmt;
|
||
|
||
// 创建订单
|
||
const order = new Order({
|
||
customer: customerObjectId,
|
||
vehicle: vehicleObjectId,
|
||
startDate: start,
|
||
endDate: end || new Date(start.getTime() + 30 * 24 * 60 * 60 * 1000),
|
||
rentalFee: fee,
|
||
deposit: depositAmt,
|
||
totalAmount,
|
||
status: '进行中'
|
||
});
|
||
|
||
await order.save();
|
||
|
||
// 更新车辆状态
|
||
vehicleDoc.status = '在租';
|
||
vehicleDoc.isRented = true;
|
||
vehicleDoc.currentOrderId = order._id;
|
||
await vehicleDoc.save();
|
||
|
||
// 更新客户统计(如客户已存在)
|
||
if (customerObjectId) {
|
||
const cust = await Customer.findById(customerObjectId);
|
||
if (cust) {
|
||
cust.totalRentals += 1;
|
||
cust.currentRentals = (cust.currentRentals || 0) + 1;
|
||
cust.totalSpent = (cust.totalSpent || 0) + totalAmount;
|
||
await cust.save();
|
||
}
|
||
}
|
||
|
||
res.status(201).json({ success: true, data: order });
|
||
} catch (error) {
|
||
res.status(400).json({ success: false, message: error.message });
|
||
}
|
||
});
|
||
|
||
// 更新订单
|
||
router.put('/:id', async (req, res) => {
|
||
try {
|
||
const order = await Order.findByIdAndUpdate(
|
||
req.params.id,
|
||
req.body,
|
||
{ new: true, runValidators: true }
|
||
);
|
||
if (!order) {
|
||
return res.status(404).json({ success: false, message: '订单不存在' });
|
||
}
|
||
res.json({ success: true, data: order });
|
||
} catch (error) {
|
||
res.status(400).json({ success: false, message: error.message });
|
||
}
|
||
});
|
||
|
||
// 结束订单
|
||
router.patch('/:id/complete', async (req, res) => {
|
||
try {
|
||
const order = await Order.findById(req.params.id);
|
||
if (!order) {
|
||
return res.status(404).json({ success: false, message: '订单不存在' });
|
||
}
|
||
|
||
order.status = '已完成';
|
||
order.actualEndDate = new Date();
|
||
await order.save();
|
||
|
||
// 更新车辆状态
|
||
const vehicle = await Vehicle.findById(order.vehicle);
|
||
if (vehicle) {
|
||
vehicle.status = '空闲';
|
||
vehicle.isRented = false;
|
||
vehicle.currentOrderId = null;
|
||
vehicle.totalRentDays += Math.ceil((new Date(order.endDate) - new Date(order.startDate)) / (1000 * 60 * 60 * 24));
|
||
await vehicle.save();
|
||
}
|
||
|
||
// 更新客户信息
|
||
const customer = await Customer.findById(order.customer);
|
||
if (customer) {
|
||
customer.currentRentals -= 1;
|
||
await customer.save();
|
||
}
|
||
|
||
res.json({ success: true, data: order });
|
||
} catch (error) {
|
||
res.status(500).json({ success: false, message: error.message });
|
||
}
|
||
});
|
||
|
||
// 取消订单
|
||
router.patch('/:id/cancel', async (req, res) => {
|
||
try {
|
||
const order = await Order.findById(req.params.id);
|
||
if (!order) {
|
||
return res.status(404).json({ success: false, message: '订单不存在' });
|
||
}
|
||
if (order.status === '已完成' || order.status === '已取消') {
|
||
return res.status(400).json({ success: false, message: '当前状态无法取消' });
|
||
}
|
||
|
||
order.status = '已取消';
|
||
order.actualEndDate = new Date();
|
||
await order.save();
|
||
|
||
// 更新车辆状态
|
||
const vehicle = await Vehicle.findById(order.vehicle);
|
||
if (vehicle) {
|
||
vehicle.status = '空闲';
|
||
vehicle.isRented = false;
|
||
vehicle.currentOrderId = null;
|
||
await vehicle.save();
|
||
}
|
||
|
||
// 更新客户信息
|
||
const customer = await Customer.findById(order.customer);
|
||
if (customer) {
|
||
customer.currentRentals = Math.max((customer.currentRentals || 0) - 1, 0);
|
||
await customer.save();
|
||
}
|
||
|
||
res.json({ success: true, data: order });
|
||
} catch (error) {
|
||
res.status(500).json({ success: false, message: error.message });
|
||
}
|
||
});
|
||
|
||
// 获取逾期订单
|
||
router.get('/status/overdue', async (req, res) => {
|
||
try {
|
||
const now = new Date();
|
||
const orders = await Order.find({
|
||
status: '进行中',
|
||
endDate: { $lt: now }
|
||
})
|
||
.populate('customer', 'name phone')
|
||
.populate('vehicle', 'model vehicleId');
|
||
|
||
// 更新逾期天数和费用
|
||
for (const order of orders) {
|
||
const overdueDays = Math.ceil((now - order.endDate) / (1000 * 60 * 60 * 24));
|
||
order.overdueDays = overdueDays;
|
||
order.overdueFee = overdueDays * order.rentalFee * 0.1; // 10% 滞纳金
|
||
order.status = '逾期';
|
||
await order.save();
|
||
}
|
||
|
||
res.json({ success: true, data: orders });
|
||
} catch (error) {
|
||
res.status(500).json({ success: false, message: error.message });
|
||
}
|
||
});
|
||
|
||
// 按状态筛选订单
|
||
router.get('/status/:status', async (req, res) => {
|
||
try {
|
||
const orders = await Order.find({ status: req.params.status })
|
||
.populate('customer', 'name phone')
|
||
.populate('vehicle', 'model vehicleId');
|
||
res.json({ success: true, data: orders });
|
||
} catch (error) {
|
||
res.status(500).json({ success: false, message: error.message });
|
||
}
|
||
});
|
||
|
||
module.exports = router;
|