const express = require('express'); const { getDB } = require('../database'); const { auth, adminAuth } = require('../middleware/auth'); const router = express.Router(); // 生成订单号 function generateOrderNo() { const timestamp = Date.now().toString(); const random = Math.random().toString(36).substr(2, 5); return `ORD${timestamp}${random}`.toUpperCase(); } // 获取订单列表 router.get('/', auth, async (req, res) => { try { const { page = 1, limit = 10, search = '', orderNumber = '', username = '', status = '', startDate = '', endDate = '' } = req.query; // 确保参数为有效数字 const pageNum = parseInt(page) || 1; const limitNum = parseInt(limit) || 10; const offset = (pageNum - 1) * limitNum; const isAdmin = req.user.role === 'admin'; let whereClause = 'WHERE 1=1'; const params = []; // 非管理员只能查看自己的订单 if (!isAdmin) { whereClause += ' AND o.user_id = ?'; params.push(req.user.id); } if (search) { whereClause += ' AND (o.order_no LIKE ? OR u.username LIKE ?)'; params.push(`%${search}%`, `%${search}%`); } if (orderNumber) { whereClause += ' AND o.order_no LIKE ?'; params.push(`%${orderNumber}%`); } if (username ) { whereClause += ' AND u.username LIKE ?'; params.push(`%${username}%`); } if (status && status.trim()) { whereClause += ' AND o.status = ?'; params.push(status); } if (startDate && startDate.trim()) { whereClause += ' AND DATE(o.created_at) >= ?'; params.push(startDate); } if (endDate && endDate.trim()) { whereClause += ' AND DATE(o.created_at) <= ?'; params.push(endDate); } // 获取总数 const countQuery = ` SELECT COUNT(*) as total FROM orders as o LEFT JOIN users u ON o.user_id = u.id ${whereClause} `; console.log(countQuery,params); const [countResult] = await getDB().execute(countQuery, params); const total = countResult[0].total; console.log(total,'数量'); // 获取订单列表 const query = ` SELECT o.id, o.order_no, o.user_id, o.total_amount, o.total_points, o.status, o.address, o.created_at, o.updated_at, u.username FROM orders o LEFT JOIN users u ON o.user_id = u.id ${whereClause} ORDER BY o.created_at DESC LIMIT ${limitNum} OFFSET ${offset} `; const [orders] = await getDB().execute(query, [...params]); res.json({ success: true, data: { orders, pagination: { page: pageNum, limit: limitNum, total, pages: Math.ceil(total / limitNum) } } }); } catch (error) { console.error('获取订单列表失败:', error); res.status(500).json({ success: false, message: '获取订单列表失败' }); } }); // 获取单个订单详情 router.get('/:id', auth, async (req, res) => { try { const { id } = req.params; const isAdmin = req.user.role === 'admin'; let whereClause = 'WHERE o.id = ?'; const params = [id]; // 非管理员只能查看自己的订单 if (!isAdmin) { whereClause += ' AND o.user_id = ?'; params.push(req.user.id); } const query = ` SELECT o.id, o.order_no, o.user_id, o.total_amount, o.total_points, o.status, o.address, o.created_at, o.updated_at, u.username, u.phone FROM orders o LEFT JOIN users u ON o.user_id = u.id ${whereClause} `; const [orders] = await getDB().execute(query, params); if (orders.length === 0) { return res.status(404).json({ success: false, message: '订单不存在' }); } res.json({ success: true, data: { order: orders[0] } }); } catch (error) { console.error('获取订单详情失败:', error); res.status(500).json({ success: false, message: '获取订单详情失败' }); } }); // 创建订单 router.post('/', auth, async (req, res) => { const db = getDB(); await db.query('START TRANSACTION'); try { const { product_id, quantity, shipping_address } = req.body; const user_id = req.user.id; // 验证必填字段 if (!product_id || !quantity || !shipping_address) { return res.status(400).json({ success: false, message: '请填写所有必填字段' }); } // 检查商品是否存在且有效 const [products] = await db.execute( 'SELECT id, name, points_price, stock, status FROM products WHERE id = ?', [product_id] ); if (products.length === 0 || products[0].status !== 'active') { await db.query('ROLLBACK'); return res.status(404).json({ success: false, message: '商品不存在或已下架' }); } const product = products[0]; // 检查库存 if (product.stock < quantity) { await db.query('ROLLBACK'); return res.status(400).json({ success: false, message: '库存不足' }); } // 计算总积分 const totalPoints = product.points_price * quantity; // 检查用户积分是否足够 const [users] = await db.execute( 'SELECT id, username, points FROM users WHERE id = ?', [user_id] ); if (users.length === 0) { await db.query('ROLLBACK'); return res.status(404).json({ success: false, message: '用户不存在' }); } const user = users[0]; if (user.points < totalPoints) { await db.query('ROLLBACK'); return res.status(400).json({ success: false, message: '积分不足' }); } // 生成订单号 const orderNumber = 'ORD' + Date.now() + Math.random().toString(36).substr(2, 4).toUpperCase(); // 创建订单 const [orderResult] = await db.execute( `INSERT INTO orders (order_no, user_id, total_amount, total_points, status, address, created_at, updated_at) VALUES (?, ?, ?, ?, 'pending', ?, NOW(), NOW())`, [orderNumber, user_id, 0, totalPoints, shipping_address] ); // 扣除用户积分 await db.execute( 'UPDATE users SET points = points - ? WHERE id = ?', [totalPoints, user_id] ); // 减少商品库存 await db.execute( 'UPDATE products SET stock = stock - ? WHERE id = ?', [quantity, product_id] ); // 记录积分历史 await db.execute( `INSERT INTO points_history (user_id, amount, type, description, created_at) VALUES (?, ?, 'spend', ?, NOW())`, [user_id, -totalPoints, `购买商品:${product.name}`] ); await db.query('COMMIT'); res.status(201).json({ success: true, message: '订单创建成功', data: { orderId: orderResult.insertId, orderNumber, pointsUsed: totalPoints } }); } catch (error) { await db.query('ROLLBACK'); console.error('创建订单失败:', error); res.status(500).json({ success: false, message: '创建订单失败' }); } }); // 用户取消订单 router.put('/:id/cancel', auth, async (req, res) => { const db = getDB(); await db.query('START TRANSACTION'); try { const orderId = req.params.id; const userId = req.user.id; // 检查订单是否存在且属于当前用户 const [orders] = await db.execute( 'SELECT id, user_id, total_points, status FROM orders WHERE id = ? AND user_id = ?', [orderId, userId] ); if (orders.length === 0) { await db.query('ROLLBACK'); return res.status(404).json({ success: false, message: '订单不存在' }); } const order = orders[0]; if (order.status !== 'pending') { await db.query('ROLLBACK'); return res.status(400).json({ success: false, message: '只能取消待处理的订单' }); } // 退还用户积分 await db.execute( 'UPDATE users SET points = points + ? WHERE id = ?', [order.total_points, userId] ); // 记录积分历史 await db.execute( `INSERT INTO points_history (user_id, amount, type, description, created_at) VALUES (?, ?, 'refund', '订单取消退还积分', NOW())`, [userId, order.total_points] ); // 更新订单状态 await db.execute( 'UPDATE orders SET status = "cancelled", updated_at = NOW() WHERE id = ?', [orderId] ); await db.query('COMMIT'); res.json({ success: true, message: '订单已取消' }); } catch (error) { await db.query('ROLLBACK'); console.error('取消订单失败:', error); res.status(500).json({ success: false, message: '取消订单失败' }); } }); // 确认收货 router.put('/:id/confirm', auth, async (req, res) => { try { const orderId = req.params.id; const userId = req.user.id; // 检查订单是否存在且属于当前用户 const [orders] = await getDB().execute( 'SELECT id, status FROM orders WHERE id = ? AND user_id = ?', [orderId, userId] ); if (orders.length === 0) { return res.status(404).json({ success: false, message: '订单不存在' }); } const order = orders[0]; if (order.status !== 'shipped') { return res.status(400).json({ success: false, message: '只能确认已发货的订单' }); } // 更新订单状态 await getDB().execute( 'UPDATE orders SET status = "completed", updated_at = NOW() WHERE id = ?', [orderId] ); res.json({ success: true, message: '确认收货成功' }); } catch (error) { console.error('确认收货失败:', error); res.status(500).json({ success: false, message: '确认收货失败' }); } }); // 更新订单状态(管理员) router.put('/:id/status', auth, adminAuth, async (req, res) => { const db = getDB(); await db.query('START TRANSACTION'); try { const orderId = req.params.id; const { status } = req.body; const validStatuses = ['pending', 'shipped', 'completed', 'cancelled']; if (!validStatuses.includes(status)) { await db.query('ROLLBACK'); return res.status(400).json({ success: false, message: '无效的订单状态' }); } // 检查订单是否存在 const [orders] = await db.execute( 'SELECT id, user_id, total_points, status FROM orders WHERE id = ?', [orderId] ); if (orders.length === 0) { await db.query('ROLLBACK'); return res.status(404).json({ success: false, message: '订单不存在' }); } const order = orders[0]; // 如果是取消订单,需要退还积分 if (status === 'cancelled' && order.status !== 'cancelled') { // 退还用户积分 await db.execute( 'UPDATE users SET points = points + ? WHERE id = ?', [order.total_points, order.user_id] ); // 记录积分历史 await db.execute( `INSERT INTO points_history (user_id, amount, type, description, created_at) VALUES (?, ?, 'earn', '订单取消退还积分', NOW())`, [order.user_id, order.points_cost] ); } // 更新订单状态 await db.execute( 'UPDATE orders SET status = ?, updated_at = NOW() WHERE id = ?', [status, orderId] ); await db.query('COMMIT'); res.json({ success: true, message: '订单状态已更新' }); } catch (error) { await db.query('ROLLBACK'); console.error('更新订单状态失败:', error); res.status(500).json({ success: false, message: '更新订单状态失败' }); } }); // 获取订单统计信息(管理员权限) router.get('/stats', auth, adminAuth, async (req, res) => { try { // 总订单数 const [totalOrders] = await getDB().execute('SELECT COUNT(*) as count FROM orders'); // 待发货订单数 const [pendingOrders] = await getDB().execute('SELECT COUNT(*) as count FROM orders WHERE status = "pending"'); // 已完成订单数 const [completedOrders] = await getDB().execute('SELECT COUNT(*) as count FROM orders WHERE status = "completed"'); // 本月新增订单 const [monthOrders] = await getDB().execute( 'SELECT COUNT(*) as count FROM orders WHERE YEAR(created_at) = YEAR(NOW()) AND MONTH(created_at) = MONTH(NOW())' ); // 上月订单数(用于计算增长率) const [lastMonthOrders] = await getDB().execute( 'SELECT COUNT(*) as count FROM orders WHERE YEAR(created_at) = YEAR(DATE_SUB(NOW(), INTERVAL 1 MONTH)) AND MONTH(created_at) = MONTH(DATE_SUB(NOW(), INTERVAL 1 MONTH))' ); // 计算月增长率 const lastMonthCount = lastMonthOrders[0].count; const currentMonthCount = monthOrders[0].count; let monthGrowthRate = 0; if (lastMonthCount > 0) { monthGrowthRate = ((currentMonthCount - lastMonthCount) / lastMonthCount * 100).toFixed(1); } // 总积分消费 const [totalPointsConsumed] = await getDB().execute('SELECT SUM(points_cost) as total FROM orders WHERE status != "cancelled"'); res.json({ success: true, data: { totalOrders: totalOrders[0].count, pendingOrders: pendingOrders[0].count, completedOrders: completedOrders[0].count, monthOrders: monthOrders[0].count, monthGrowthRate: parseFloat(monthGrowthRate), totalPointsConsumed: totalPointsConsumed[0].total || 0 } }); } catch (error) { console.error('获取订单统计失败:', error); res.status(500).json({ success: false, message: '获取订单统计失败' }); } }); module.exports = router;