e-scooter-rental-system/server/routes/storeAuth.js

218 lines
8.0 KiB
JavaScript

const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const rateLimit = require('express-rate-limit');
const Store = require('../models/Store');
const StoreAuth = require('../models/StoreAuth');
const Order = require('../models/Order');
const Vehicle = require('../models/Vehicle');
const { comparePassword } = require('../utils/password');
const { authMiddleware } = require('../middleware/auth');
const { validate } = require('../middleware/validate');
const { schemas } = require('../middleware/validate');
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
standardHeaders: true,
legacyHeaders: false,
message: { success: false, message: '登录尝试过于频繁,请稍后再试' }
});
router.post('/login', loginLimiter, validate(schemas.storeLogin), async (req, res) => {
try {
const { username, password } = req.body;
const trimmedUsername = username ? username.trim() : '';
const trimmedPassword = password ? password.trim() : '';
const auth = await StoreAuth.findOne({ username: trimmedUsername }).select('+password');
if (!auth) {
return res.status(401).json({ success: false, message: '用户名或密码错误' });
}
const isMatch = await comparePassword(trimmedPassword, auth.password);
if (!isMatch) {
return res.status(401).json({ success: false, message: '用户名或密码错误' });
}
const token = jwt.sign(
{ id: auth._id, role: 'store', type: 'store', username: auth.username, storeId: auth.storeId, jti: Math.random().toString(36) },
process.env.JWT_SECRET,
{ expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
);
res.json({
success: true,
data: { id: auth._id, storeId: auth.storeId, username: auth.username, name: auth.name, status: auth.status, role: auth.role, token }
});
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.get('/store/info', authMiddleware, async (req, res) => {
try {
const store = await Store.findOne({ storeId: req.user.storeId });
if (!store) {
return res.status(404).json({ success: false, message: '门店不存在' });
}
res.json({ success: true, data: store });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.put('/store/info', authMiddleware, async (req, res) => {
try {
const { name, address, phone, manager, status } = req.body;
const store = await Store.findOneAndUpdate(
{ storeId: req.user.storeId },
{ name, address, phone, manager, status },
{ new: true, runValidators: true }
);
if (!store) {
return res.status(404).json({ success: false, message: '门店不存在' });
}
res.json({ success: true, data: store });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.get('/orders', authMiddleware, async (req, res) => {
try {
const orders = await Order.find({ storeId: req.user.storeId })
.populate('customer', 'name phone')
.populate('vehicle', 'model color vehicleId plateNumber')
.sort({ createdAt: -1 });
res.json({ success: true, data: orders });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.post('/orders', authMiddleware, async (req, res) => {
try {
const { customerName, customerPhone, vehicleId, startDate, endDate, deposit, totalAmount, notes } = req.body;
if (!customerName || !customerPhone || !vehicleId || !totalAmount) {
return res.status(400).json({ success: false, message: '请填写必填项' });
}
const vehicle = await Vehicle.findOne({ _id: vehicleId, storeId: req.user.storeId });
if (!vehicle) {
return res.status(404).json({ success: false, message: '车辆不存在或不属于本门店' });
}
const order = await Order.create({
storeId: req.user.storeId,
customer: { name: customerName, phone: customerPhone },
vehicle: vehicleId,
startDate,
endDate,
deposit: deposit || 0,
totalAmount,
notes,
status: '待支付'
});
res.json({ success: true, data: order });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.put('/orders/:id', authMiddleware, async (req, res) => {
try {
const { status, notes } = req.body;
const order = await Order.findOneAndUpdate(
{ _id: req.params.id, storeId: req.user.storeId },
{ status, notes },
{ new: true, runValidators: true }
);
if (!order) {
return res.status(404).json({ success: false, message: '订单不存在' });
}
if (status === '已完成') {
await Vehicle.findByIdAndUpdate(order.vehicle, { status: '空闲' });
}
res.json({ success: true, data: order });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.delete('/orders/:id', authMiddleware, async (req, res) => {
try {
const order = await Order.findOneAndDelete({ _id: req.params.id, storeId: req.user.storeId });
if (!order) {
return res.status(404).json({ success: false, message: '订单不存在' });
}
res.json({ success: true });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.get('/vehicles', authMiddleware, async (req, res) => {
try {
const vehicles = await Vehicle.find({ storeId: req.user.storeId }).sort({ createdAt: -1 });
res.json({ success: true, data: vehicles });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.post('/vehicles', authMiddleware, async (req, res) => {
try {
const { vehicleId, plateNumber, model, color, batteryType, purchasePrice, notes } = req.body;
if (!vehicleId || !plateNumber || !model) {
return res.status(400).json({ success: false, message: '请填写必填项' });
}
const existing = await Vehicle.findOne({ $or: [{ vehicleId }, { plateNumber }] });
if (existing) {
return res.status(400).json({ success: false, message: '车架号或车牌号已存在' });
}
const vehicle = await Vehicle.create({
vehicleId, plateNumber, model, color: color || '', batteryType: batteryType || '',
purchasePrice: purchasePrice || 0, notes, status: '空闲', storeId: req.user.storeId
});
res.json({ success: true, data: vehicle });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.put('/vehicles/:id', authMiddleware, async (req, res) => {
try {
const { plateNumber, model, color, batteryType, purchasePrice, notes, status } = req.body;
const vehicle = await Vehicle.findOneAndUpdate(
{ _id: req.params.id, storeId: req.user.storeId },
{ plateNumber, model, color, batteryType, purchasePrice, notes, status },
{ new: true, runValidators: true }
);
if (!vehicle) {
return res.status(404).json({ success: false, message: '车辆不存在' });
}
res.json({ success: true, data: vehicle });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.delete('/vehicles/:id', authMiddleware, async (req, res) => {
try {
const vehicle = await Vehicle.findOneAndDelete({ _id: req.params.id, storeId: req.user.storeId });
if (!vehicle) {
return res.status(404).json({ success: false, message: '车辆不存在' });
}
res.json({ success: true });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
router.get('/vehicle-types', authMiddleware, async (req, res) => {
try {
const VehicleType = require('../models/VehicleType');
const types = await VehicleType.find().sort({ name: 1 });
res.json({ success: true, data: types });
} catch (error) {
res.status(500).json({ success: false, message: "服务器内部错误" });
}
});
module.exports = router;