const express = require('express'); const router = express.Router(); const jwt = require('jsonwebtoken'); const rateLimit = require('express-rate-limit'); const Rider = require('../models/Rider'); const Order = require('../models/Order'); const { comparePassword } = require('../utils/password'); const { authMiddleware, requireRole } = require('../middleware/auth'); const { validate } = require('../middleware/validate'); const { schemas } = require('../middleware/validate'); // 登录限流(单独,更严格) const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 20, standardHeaders: true, legacyHeaders: false, message: { success: false, message: '登录尝试过于频繁,请15分钟后再试' } }); // 骑手登录(无需鉴权) router.post('/login', loginLimiter, validate(schemas.login), async (req, res) => { try { const { phone, password } = req.body; // 用 select(false) 主动拉取 password 字段 const rider = await Rider.findOne({ phone }).select('+password'); if (!rider) { return res.status(401).json({ success: false, message: '手机号或密码错误' }); } // bcrypt 比对密码 const isMatch = await comparePassword(password, rider.password); if (!isMatch) { return res.status(401).json({ success: false, message: '手机号或密码错误' }); } // 签发 JWT(包含 id、role、jti) const token = jwt.sign( { id: rider._id, role: rider.role, type: 'rider', phone: rider.phone, jti: Math.random().toString(36) }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRES_IN || '7d' } ); res.json({ success: true, data: { id: rider._id, riderId: rider.riderId, name: rider.name, phone: rider.phone, status: rider.status, role: rider.role, rating: rider.rating, totalOrders: rider.totalOrders, totalIncome: rider.totalIncome, token } }); } catch (error) { res.status(500).json({ success: false, message: "服务器内部错误" }); } }); // 获取骑手信息(需登录,且只能查看自己;admin/store 可查看任意骑手) router.get('/:id', authMiddleware, async (req, res) => { try { const isSelf = req.params.id === req.user.id; const isPrivileged = ['admin', 'store'].includes(req.user.role); if (!isSelf && !isPrivileged) { return res.status(403).json({ success: false, message: '无权查看该骑手信息' }); } const rider = await Rider.findById(req.params.id); if (!rider) { return res.status(404).json({ success: false, message: '骑手不存在' }); } res.json({ success: true, data: rider }); } catch (error) { res.status(500).json({ success: false, message: "服务器内部错误" }); } }); // 更新骑手信息(需登录本人,或 admin/store) router.put('/:id', authMiddleware, async (req, res) => { try { const isSelf = req.params.id === req.user.id; const isPrivileged = ['admin', 'store'].includes(req.user.role); if (!isSelf && !isPrivileged) { return res.status(403).json({ success: false, message: '无权修改该骑手信息' }); } // 不允许通过 PUT 修改密码和 role(仅 admin 可改 role) const { password, ...safeBody } = req.body; if (req.body.role && !isPrivileged) { return res.status(403).json({ success: false, message: '无权修改角色' }); } const updateData = isPrivileged ? req.body : safeBody; const rider = await Rider.findByIdAndUpdate( req.params.id, updateData, { new: true, runValidators: true } ); if (!rider) { return res.status(404).json({ success: false, message: '骑手不存在' }); } res.json({ success: true, data: rider }); } catch (error) { res.status(400).json({ success: false, message: "服务器内部错误" }); } }); // 获取骑手的订单(需登录本人,或 admin/store) router.get('/:id/orders', authMiddleware, async (req, res) => { try { const isSelf = req.params.id === req.user.id; const isPrivileged = ['admin', 'store'].includes(req.user.role); if (!isSelf && !isPrivileged) { return res.status(403).json({ success: false, message: '无权查看该骑手的订单' }); } const orders = await Order.find({ rider: req.params.id }) .populate('customer', 'name phone') .populate('vehicle', 'vehicleId model color') .sort({ createdAt: -1 }); res.json({ success: true, data: orders }); } catch (error) { res.status(500).json({ success: false, message: "服务器内部错误" }); } }); module.exports = router;