/** * 菜品数据模型 * * 功能:封装菜品表的数据库操作 */ const { pool } = require('../config/database'); /** * 菜品模型类 */ class Dish { /** * 根据ID查找菜品 * @param {number} id - 菜品ID * @returns {Promise} 菜品对象或null */ static async findById(id) { try { const [rows] = await pool.query( `SELECT d.*, dc.name as category_name FROM dishes d LEFT JOIN dish_categories dc ON d.category_id = dc.id WHERE d.id = ?`, [id] ); return rows[0] || null; } catch (error) { throw new Error('查询菜品失败: ' + error.message); } } /** * 获取菜品列表(分页、筛选) * @param {object} options - 查询选项 * @returns {Promise} 菜品列表和总数 */ static async findAll(options = {}) { try { const { page = 1, pageSize = 10, category_id, is_available, status, search } = options; const offset = (page - 1) * pageSize; // 构建WHERE条件 const conditions = []; const params = []; if (category_id) { conditions.push('d.category_id = ?'); params.push(category_id); } if (is_available !== undefined) { conditions.push('d.is_available = ?'); params.push(is_available); } if (status !== undefined) { conditions.push('d.status = ?'); params.push(status); } if (search) { conditions.push('(d.name LIKE ? OR d.description LIKE ?)'); params.push(`%${search}%`, `%${search}%`); } const whereClause = conditions.length > 0 ? 'WHERE ' + conditions.join(' AND ') : ''; // 查询总数 const [countResult] = await pool.query( `SELECT COUNT(*) as total FROM dishes d ${whereClause}`, params ); const total = countResult[0].total; // 查询列表 const [rows] = await pool.query( `SELECT d.*, dc.name as category_name FROM dishes d LEFT JOIN dish_categories dc ON d.category_id = dc.id ${whereClause} ORDER BY d.created_at DESC LIMIT ? OFFSET ?`, [...params, pageSize, offset] ); return { list: rows, total, page: parseInt(page), pageSize: parseInt(pageSize) }; } catch (error) { throw new Error('查询菜品列表失败: ' + error.message); } } /** * 创建新菜品 * @param {object} dishData - 菜品数据 * @returns {Promise} 创建的菜品 */ static async create(dishData) { try { const { category_id, name, price, image, description, taste, ingredients, cooking_time, is_available = 1 } = dishData; const [result] = await pool.query( `INSERT INTO dishes (category_id, name, price, image, description, taste, ingredients, cooking_time, is_available) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [category_id, name, price, image, description, taste, ingredients, cooking_time, is_available] ); return await this.findById(result.insertId); } catch (error) { throw new Error('创建菜品失败: ' + error.message); } } /** * 更新菜品 * @param {number} id - 菜品ID * @param {object} dishData - 要更新的数据 * @returns {Promise} 更新后的菜品 */ static async update(id, dishData) { try { const { category_id, name, price, image, description, taste, ingredients, cooking_time, is_available, status } = dishData; const updates = []; const values = []; if (category_id !== undefined) { updates.push('category_id = ?'); values.push(category_id); } if (name !== undefined) { updates.push('name = ?'); values.push(name); } if (price !== undefined) { updates.push('price = ?'); values.push(price); } if (image !== undefined) { updates.push('image = ?'); values.push(image); } if (description !== undefined) { updates.push('description = ?'); values.push(description); } if (taste !== undefined) { updates.push('taste = ?'); values.push(taste); } if (ingredients !== undefined) { updates.push('ingredients = ?'); values.push(ingredients); } if (cooking_time !== undefined) { updates.push('cooking_time = ?'); values.push(cooking_time); } if (is_available !== undefined) { updates.push('is_available = ?'); values.push(is_available); } if (status !== undefined) { updates.push('status = ?'); values.push(status); } if (updates.length === 0) { throw new Error('没有要更新的数据'); } values.push(id); await pool.query( `UPDATE dishes SET ${updates.join(', ')} WHERE id = ?`, values ); return await this.findById(id); } catch (error) { throw new Error('更新菜品失败: ' + error.message); } } /** * 删除菜品 * @param {number} id - 菜品ID * @returns {Promise} 是否成功 */ static async delete(id) { try { await pool.query('DELETE FROM dishes WHERE id = ?', [id]); return true; } catch (error) { throw new Error('删除菜品失败: ' + error.message); } } /** * 更新菜品可售状态 * @param {number} id - 菜品ID * @param {number} is_available - 是否可售(1是/0否) * @returns {Promise} 是否成功 */ static async updateAvailability(id, is_available) { try { await pool.query( 'UPDATE dishes SET is_available = ? WHERE id = ?', [is_available, id] ); return true; } catch (error) { throw new Error('更新菜品状态失败: ' + error.message); } } /** * 根据分类ID获取菜品列表 * @param {number} categoryId - 分类ID * @returns {Promise} 菜品列表 */ static async findByCategory(categoryId) { try { const [rows] = await pool.query( `SELECT * FROM dishes WHERE category_id = ? AND status = 1 ORDER BY created_at DESC`, [categoryId] ); return rows; } catch (error) { throw new Error('查询分类菜品失败: ' + error.message); } } /** * 获取热门菜品 * @param {number} limit - 数量限制 * @returns {Promise} 菜品列表 */ static async findPopular(limit = 10) { try { // 这里简化处理,实际应该根据订单数据统计 // 暂时返回最新的菜品 const [rows] = await pool.query( `SELECT d.*, dc.name as category_name FROM dishes d LEFT JOIN dish_categories dc ON d.category_id = dc.id WHERE d.status = 1 AND d.is_available = 1 ORDER BY d.created_at DESC LIMIT ?`, [limit] ); return rows; } catch (error) { throw new Error('查询热门菜品失败: ' + error.message); } } } module.exports = Dish;