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;