diff --git a/admin-system/src/pages/animal/index.vue b/admin-system/src/pages/animal/index.vue new file mode 100644 index 0000000..ce22fc1 --- /dev/null +++ b/admin-system/src/pages/animal/index.vue @@ -0,0 +1,431 @@ + + + + + \ No newline at end of file diff --git a/backend/src/models/Animal.js b/backend/src/models/Animal.js index e37c80a..0ee5551 100644 --- a/backend/src/models/Animal.js +++ b/backend/src/models/Animal.js @@ -1,4 +1,4 @@ -const db = require('../config/database'); +const { query } = require('../config/database'); /** * 动物模型类 @@ -12,7 +12,7 @@ class Animal { */ static async findById(id) { try { - const [rows] = await db.execute( + const [rows] = await query( 'SELECT * FROM animals WHERE id = ?', [id] ); @@ -52,7 +52,7 @@ class Animal { LIMIT ? OFFSET ? `; - const [rows] = await db.execute(query, [...params, limit, offset]); + const [rows] = await query(query, [...params, limit, offset]); return rows; } catch (error) { console.error('获取动物列表失败:', error); @@ -75,7 +75,7 @@ class Animal { WHERE 1=1 ${whereClause} `; - const [rows] = await db.execute(query, params); + const [rows] = await query(query, params); return rows[0].count; } catch (error) { console.error('获取动物数量失败:', error); @@ -102,7 +102,7 @@ class Animal { WHERE a.id = ? `; - const [rows] = await db.execute(query, [id]); + const [rows] = await query(query, [id]); return rows[0] || null; } catch (error) { console.error('获取动物详情失败:', error); @@ -126,11 +126,11 @@ class Animal { WHERE id = ? `; - const [result] = await db.execute(query, [status, id]); + const [result] = await query(query, [status, id]); // 记录状态变更日志 if (reason) { - await db.execute( + await query( `INSERT INTO animal_status_logs (animal_id, old_status, new_status, admin_id, reason, created_at) SELECT ?, status, ?, ?, ?, NOW() FROM animals WHERE id = ?`, [id, status, adminId, reason, id] @@ -161,7 +161,7 @@ class Animal { WHERE id IN (${placeholders}) `; - const [result] = await db.execute(query, [status, ...ids]); + const [result] = await query(query, [status, ...ids]); return result; } catch (error) { console.error('批量更新动物状态失败:', error); @@ -187,7 +187,7 @@ class Animal { FROM animals `; - const [rows] = await db.execute(query); + const [rows] = await query(query); return rows[0]; } catch (error) { console.error('获取动物总体统计失败:', error); @@ -212,7 +212,7 @@ class Animal { ORDER BY count DESC `; - const [rows] = await db.execute(query); + const [rows] = await query(query); return rows; } catch (error) { console.error('获取动物统计信息失败:', error); @@ -236,7 +236,7 @@ class Animal { ORDER BY count DESC `; - const [rows] = await db.execute(query); + const [rows] = await query(query); return rows; } catch (error) { console.error('获取按状态分类的统计失败:', error); @@ -264,7 +264,7 @@ class Animal { ORDER BY animal_count DESC `; - const [rows] = await db.execute(query); + const [rows] = await query(query); return rows; } catch (error) { console.error('获取按商家分类的统计失败:', error); @@ -290,7 +290,7 @@ class Animal { ORDER BY month ASC `; - const [rows] = await db.execute(query); + const [rows] = await query(query); return rows; } catch (error) { console.error('获取月度趋势数据失败:', error); @@ -325,7 +325,7 @@ class Animal { ORDER BY a.created_at DESC `; - const [rows] = await db.execute(query, params); + const [rows] = await query(query, params); return rows; } catch (error) { console.error('获取导出数据失败:', error); @@ -366,7 +366,7 @@ class Animal { ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW()) `; - const [result] = await db.execute(query, [ + const [result] = await query(query, [ name, type, breed, age, gender, weight, price, description, health_status, JSON.stringify(vaccination_records || []), JSON.stringify(images || []), merchant_id, farm_location, @@ -406,7 +406,7 @@ class Animal { values.push(id); const query = `UPDATE animals SET ${fields.join(', ')} WHERE id = ?`; - const [result] = await db.execute(query, values); + const [result] = await query(query, values); return result; } catch (error) { @@ -422,7 +422,7 @@ class Animal { */ static async delete(id) { try { - const [result] = await db.execute('DELETE FROM animals WHERE id = ?', [id]); + const [result] = await query('DELETE FROM animals WHERE id = ?', [id]); return result; } catch (error) { console.error('删除动物失败:', error); diff --git a/backend/src/models/AnimalClaim.js b/backend/src/models/AnimalClaim.js index 3f5c07a..aaf9574 100644 --- a/backend/src/models/AnimalClaim.js +++ b/backend/src/models/AnimalClaim.js @@ -1,4 +1,4 @@ -const db = require('../config/database'); +const { query } = require('../config/database'); class AnimalClaim { /** @@ -26,7 +26,7 @@ class AnimalClaim { ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW()) `; - const [result] = await db.execute(query, [ + const [result] = await query(query, [ claim_no, animal_id, user_id, @@ -68,7 +68,7 @@ class AnimalClaim { WHERE ac.id = ? AND ac.deleted_at IS NULL `; - const [rows] = await db.execute(query, [id]); + const [rows] = await query(query, [id]); return rows[0] || null; } catch (error) { console.error('查找认领申请数据库错误:', error); @@ -97,7 +97,7 @@ class AnimalClaim { WHERE ac.claim_no = ? AND ac.deleted_at IS NULL `; - const [rows] = await db.execute(query, [claimNo]); + const [rows] = await query(query, [claimNo]); return rows[0] || null; } catch (error) { console.error('根据订单号查找认领申请数据库错误:', error); @@ -122,7 +122,7 @@ class AnimalClaim { LIMIT 1 `; - const [rows] = await db.execute(query, [userId, animalId]); + const [rows] = await query(query, [userId, animalId]); return rows[0] || null; } catch (error) { console.error('查找活跃认领申请数据库错误:', error); @@ -158,7 +158,7 @@ class AnimalClaim { WHERE id = ? `; - await db.execute(query, values); + await query(query, values); return await this.findById(id); } catch (error) { console.error('更新认领申请状态数据库错误:', error); @@ -225,7 +225,7 @@ class AnimalClaim { LIMIT ? OFFSET ? `; - const [dataRows] = await db.execute(dataQuery, [...queryParams, limit, offset]); + const [dataRows] = await query(dataQuery, [...queryParams, limit, offset]); // 查询总数 const countQuery = ` @@ -235,7 +235,7 @@ class AnimalClaim { WHERE ${whereClause} `; - const [countRows] = await db.execute(countQuery, queryParams); + const [countRows] = await query(countQuery, queryParams); const total = countRows[0].total; return { @@ -292,7 +292,7 @@ class AnimalClaim { LIMIT ? OFFSET ? `; - const [dataRows] = await db.execute(dataQuery, [...queryParams, limit, offset]); + const [dataRows] = await query(dataQuery, [...queryParams, limit, offset]); // 查询总数 const countQuery = ` @@ -301,7 +301,7 @@ class AnimalClaim { WHERE ${whereClause} `; - const [countRows] = await db.execute(countQuery, queryParams); + const [countRows] = await query(countQuery, queryParams); const total = countRows[0].total; return { @@ -396,7 +396,7 @@ class AnimalClaim { LIMIT ? OFFSET ? `; - const [dataRows] = await db.execute(dataQuery, [...queryParams, limit, offset]); + const [dataRows] = await query(dataQuery, [...queryParams, limit, offset]); // 查询总数 const countQuery = ` @@ -407,7 +407,7 @@ class AnimalClaim { WHERE ${whereClause} `; - const [countRows] = await db.execute(countQuery, queryParams); + const [countRows] = await query(countQuery, queryParams); const total = countRows[0].total; return { @@ -446,7 +446,7 @@ class AnimalClaim { ) VALUES (?, ?, ?, ?, ?, NOW(), NOW()) `; - const [result] = await db.execute(query, [ + const [result] = await query(query, [ claim_id, duration, amount, @@ -511,7 +511,7 @@ class AnimalClaim { WHERE ${whereClause} `; - const [basicStats] = await db.execute(basicStatsQuery, queryParams); + const [basicStats] = await query(basicStatsQuery, queryParams); // 按动物类型统计 const typeStatsQuery = ` @@ -527,7 +527,7 @@ class AnimalClaim { ORDER BY claim_count DESC `; - const [typeStats] = await db.execute(typeStatsQuery, queryParams); + const [typeStats] = await query(typeStatsQuery, queryParams); // 按月份统计 const monthlyStatsQuery = ` @@ -544,7 +544,7 @@ class AnimalClaim { LIMIT 12 `; - const [monthlyStats] = await db.execute(monthlyStatsQuery, queryParams); + const [monthlyStats] = await query(monthlyStatsQuery, queryParams); return { basic: basicStats[0], @@ -570,7 +570,7 @@ class AnimalClaim { WHERE id = ? `; - const [result] = await db.execute(query, [id]); + const [result] = await query(query, [id]); return result.affectedRows > 0; } catch (error) { console.error('软删除认领申请数据库错误:', error); diff --git a/backend/src/models/Merchant.js b/backend/src/models/Merchant.js index ef50638..2759379 100644 --- a/backend/src/models/Merchant.js +++ b/backend/src/models/Merchant.js @@ -9,7 +9,7 @@ class Merchant { static async findById(id) { try { const sql = 'SELECT * FROM merchants WHERE id = ?'; - const [rows] = await query(sql, [id]); + const rows = await query(sql, [id]); return rows.length > 0 ? rows[0] : null; } catch (error) { console.error('查找商户失败:', error); @@ -53,17 +53,12 @@ class Merchant { // 查询总数 const countSql = `SELECT COUNT(*) as total FROM merchants ${whereClause}`; - const [countResult] = await query(countSql, params); - const total = countResult[0].total; + const countResult = await query(countSql, params); + const total = countResult && countResult.length > 0 ? countResult[0].total : 0; // 查询数据 - const dataSql = ` - SELECT * FROM merchants - ${whereClause} - ORDER BY created_at DESC - LIMIT ? OFFSET ? - `; - const [rows] = await query(dataSql, [...params, limit, offset]); + const dataSql = `SELECT * FROM merchants ${whereClause} ORDER BY created_at DESC LIMIT ${parseInt(limit)} OFFSET ${parseInt(offset)}`; + const rows = await query(dataSql, params); return { data: rows, @@ -99,7 +94,7 @@ class Merchant { `; const params = [name, type, contact_person, contact_phone, email, address, description]; - const [result] = await query(sql, params); + const result = await query(sql, params); // 返回创建的商户信息 return await this.findById(result.insertId); @@ -133,7 +128,7 @@ class Merchant { params.push(id); const sql = `UPDATE merchants SET ${updateFields.join(', ')} WHERE id = ?`; - const [result] = await query(sql, params); + const result = await query(sql, params); if (result.affectedRows === 0) { throw new Error('商户不存在或更新失败'); @@ -151,7 +146,7 @@ class Merchant { static async delete(id) { try { const sql = 'DELETE FROM merchants WHERE id = ?'; - const [result] = await query(sql, [id]); + const result = await query(sql, [id]); if (result.affectedRows === 0) { throw new Error('商户不存在或删除失败'); @@ -174,16 +169,16 @@ class Merchant { // 获取关联的动物数量 const animalCountSql = 'SELECT COUNT(*) as count FROM animals WHERE merchant_id = ?'; - const [animalResult] = await query(animalCountSql, [id]); + const animalResult = await query(animalCountSql, [id]); // 获取关联的订单数量 const orderCountSql = 'SELECT COUNT(*) as count FROM orders WHERE merchant_id = ?'; - const [orderResult] = await query(orderCountSql, [id]); + const orderResult = await query(orderCountSql, [id]); return { ...merchant, - animal_count: animalResult[0].count, - order_count: orderResult[0].count + animal_count: animalResult && animalResult.length > 0 ? animalResult[0].count : 0, + order_count: orderResult && orderResult.length > 0 ? orderResult[0].count : 0 }; } catch (error) { console.error('获取商户详情失败:', error); @@ -205,7 +200,7 @@ class Merchant { FROM merchants `; - const [rows] = await query(sql); + const rows = await query(sql); return rows[0]; } catch (error) { console.error('获取商户统计信息失败:', error); diff --git a/backend/src/models/Payment.js b/backend/src/models/Payment.js index 4348d1c..16fffbc 100644 --- a/backend/src/models/Payment.js +++ b/backend/src/models/Payment.js @@ -1,4 +1,4 @@ -const db = require('../config/database'); +const { query } = require('../config/database'); class Payment { /** @@ -24,7 +24,7 @@ class Payment { ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', NOW(), NOW()) `; - const [result] = await db.execute(query, [ + const [result] = await query(query, [ payment_no, order_id, user_id, amount, payment_method, return_url, notify_url ]); @@ -46,7 +46,7 @@ class Payment { WHERE p.id = ? AND p.deleted_at IS NULL `; - const [rows] = await db.execute(query, [id]); + const [rows] = await query(query, [id]); return rows[0] || null; } @@ -64,7 +64,7 @@ class Payment { WHERE p.payment_no = ? AND p.deleted_at IS NULL `; - const [rows] = await db.execute(query, [paymentNo]); + const [rows] = await query(query, [paymentNo]); return rows[0] || null; } @@ -80,7 +80,7 @@ class Payment { ORDER BY created_at DESC `; - const [rows] = await db.execute(query, [orderId]); + const [rows] = await query(query, [orderId]); return rows; } @@ -106,7 +106,7 @@ class Payment { WHERE id = ? AND deleted_at IS NULL `; - await db.execute(query, [ + await query(query, [ status, transaction_id, paid_amount, paid_at, failure_reason, id ]); @@ -163,7 +163,7 @@ class Payment { FROM payments p WHERE ${whereClause} `; - const [countResult] = await db.execute(countQuery, params); + const [countResult] = await query(countQuery, params); const total = countResult[0].total; // 查询数据 @@ -176,7 +176,7 @@ class Payment { LIMIT ? OFFSET ? `; params.push(limit, offset); - const [rows] = await db.execute(dataQuery, params); + const [rows] = await query(dataQuery, params); return { data: rows, @@ -252,7 +252,7 @@ class Payment { LEFT JOIN users u ON p.user_id = u.id WHERE ${whereClause} `; - const [countResult] = await db.execute(countQuery, params); + const [countResult] = await query(countQuery, params); const total = countResult[0].total; // 查询数据 @@ -267,7 +267,7 @@ class Payment { LIMIT ? OFFSET ? `; params.push(limit, offset); - const [rows] = await db.execute(dataQuery, params); + const [rows] = await query(dataQuery, params); return { data: rows, @@ -301,7 +301,7 @@ class Payment { ) VALUES (?, ?, ?, ?, ?, 'pending', NOW(), NOW()) `; - const [result] = await db.execute(query, [ + const [result] = await query(query, [ refund_no, payment_id, user_id, refund_amount, refund_reason ]); @@ -325,7 +325,7 @@ class Payment { WHERE r.id = ? AND r.deleted_at IS NULL `; - const [rows] = await db.execute(query, [id]); + const [rows] = await query(query, [id]); return rows[0] || null; } @@ -352,7 +352,7 @@ class Payment { WHERE id = ? AND deleted_at IS NULL `; - await db.execute(query, [ + await query(query, [ status, processed_by, process_remark, refund_transaction_id, refunded_at, id ]); @@ -402,7 +402,7 @@ class Payment { FROM payments WHERE ${whereClause} `; - const [totalResult] = await db.execute(totalQuery, params); + const [totalResult] = await query(totalQuery, params); // 退款统计 const refundQuery = ` @@ -421,7 +421,7 @@ class Payment { if (end_date) refundParams.push(end_date); if (payment_method) refundParams.push(payment_method); - const [refundResult] = await db.execute(refundQuery, refundParams); + const [refundResult] = await query(refundQuery, refundParams); // 按支付方式统计 const methodQuery = ` @@ -433,7 +433,7 @@ class Payment { WHERE ${whereClause} GROUP BY payment_method `; - const [methodResult] = await db.execute(methodQuery, params); + const [methodResult] = await query(methodQuery, params); return { total_count: totalResult[0].total_count, @@ -457,7 +457,7 @@ class Payment { */ static async exists(id) { const query = 'SELECT 1 FROM payments WHERE id = ? AND deleted_at IS NULL'; - const [rows] = await db.execute(query, [id]); + const [rows] = await query(query, [id]); return rows.length > 0; } @@ -473,7 +473,7 @@ class Payment { WHERE id = ? AND deleted_at IS NULL `; - const [result] = await db.execute(query, [id]); + const [result] = await query(query, [id]); return result.affectedRows > 0; } @@ -491,7 +491,7 @@ class Payment { AND deleted_at IS NULL `; - const [result] = await db.execute(query, [hours]); + const [result] = await query(query, [hours]); return result.affectedRows; } } diff --git a/backend/src/models/Travel.js b/backend/src/models/Travel.js index 0e21fc1..2a87ac0 100644 --- a/backend/src/models/Travel.js +++ b/backend/src/models/Travel.js @@ -354,7 +354,7 @@ class Travel { SET current_participants = GREATEST(0, current_participants - ?), updated_at = NOW() WHERE id = ? `; - const [result] = await query(sql, [count, id]); + const [result] = await query(query, [count, id]); return result.affectedRows > 0; } @@ -372,7 +372,7 @@ class Travel { FROM travel_plans WHERE id = ? `; - const [rows] = await query(sql, [id]); + const [rows] = await query(query, [id]); if (rows.length === 0) { return false; @@ -403,7 +403,7 @@ class Travel { LIMIT ? `; - const [rows] = await query(sql, [limit]); + const [rows] = await query(query, [limit]); // 解析JSON字段 return rows.map(travel => { diff --git a/backend/src/models/TravelRegistration.js b/backend/src/models/TravelRegistration.js index f941fb4..a38228d 100644 --- a/backend/src/models/TravelRegistration.js +++ b/backend/src/models/TravelRegistration.js @@ -1,4 +1,4 @@ -const db = require('../config/database'); +const { query } = require('../config/database'); /** * 旅行报名数据模型 @@ -25,7 +25,7 @@ class TravelRegistration { VALUES (?, ?, ?, ?, ?, 'pending', NOW()) `; - const [result] = await db.execute(query, [ + const [result] = await query(query, [ travel_plan_id, user_id, message || null, @@ -58,7 +58,7 @@ class TravelRegistration { WHERE tr.id = ? `; - const [rows] = await db.execute(query, [id]); + const [rows] = await query(query, [id]); return rows[0] || null; } @@ -74,7 +74,7 @@ class TravelRegistration { WHERE user_id = ? AND travel_plan_id = ? AND status != 'cancelled' `; - const [rows] = await db.execute(query, [userId, travelPlanId]); + const [rows] = await query(query, [userId, travelPlanId]); return rows[0] || null; } @@ -106,7 +106,7 @@ class TravelRegistration { FROM travel_registrations tr ${whereClause} `; - const [countResult] = await db.execute(countQuery, params); + const [countResult] = await query(countQuery, params); const total = countResult[0].total; // 获取数据 @@ -127,7 +127,7 @@ class TravelRegistration { `; params.push(pageSize, offset); - const [rows] = await db.execute(query, params); + const [rows] = await query(query, params); return { registrations: rows, @@ -168,7 +168,7 @@ class TravelRegistration { FROM travel_registrations tr ${whereClause} `; - const [countResult] = await db.execute(countQuery, params); + const [countResult] = await query(countQuery, params); const total = countResult[0].total; // 获取数据 @@ -188,7 +188,7 @@ class TravelRegistration { `; params.push(pageSize, offset); - const [rows] = await db.execute(query, params); + const [rows] = await query(query, params); return { registrations: rows, @@ -215,7 +215,7 @@ class TravelRegistration { WHERE id = ? `; - await db.execute(query, [status, rejectReason, id]); + await query(query, [status, rejectReason, id]); return this.findById(id); } @@ -245,7 +245,7 @@ class TravelRegistration { WHERE travel_plan_id = ? `; - const [rows] = await db.execute(query, [travelPlanId]); + const [rows] = await query(query, [travelPlanId]); return rows[0]; } @@ -261,7 +261,7 @@ class TravelRegistration { WHERE id = ? AND created_by = ? `; - const [rows] = await db.execute(query, [travelPlanId, userId]); + const [rows] = await query(query, [travelPlanId, userId]); return rows.length > 0; } @@ -279,7 +279,7 @@ class TravelRegistration { WHERE tr.id = ? AND tp.created_by = ? `; - const [rows] = await db.execute(query, [registrationId, userId]); + const [rows] = await query(query, [registrationId, userId]); return rows.length > 0; } @@ -295,7 +295,7 @@ class TravelRegistration { WHERE travel_plan_id = ? AND status = 'approved' `; - const [rows] = await db.execute(query, [travelPlanId]); + const [rows] = await query(query, [travelPlanId]); return rows[0].count; } diff --git a/backend/src/services/order/index.js b/backend/src/services/order/index.js index cdf1648..af5e8dd 100644 --- a/backend/src/services/order/index.js +++ b/backend/src/services/order/index.js @@ -342,7 +342,8 @@ class OrderService { pageSize = 10, status, merchantId, - userId + userId, + order_no } = filters; const offset = (page - 1) * pageSize; @@ -390,6 +391,13 @@ class OrderService { countParams.push(userId); } + if (order_no) { + query += ' AND o.order_no = ?'; + countQuery += ' AND o.order_no = ?'; + params.push(order_no); + countParams.push(order_no); + } + query += ' ORDER BY o.created_at DESC LIMIT ? OFFSET ?'; params.push(pageSize, offset); @@ -410,6 +418,36 @@ class OrderService { throw new Error('获取所有订单失败'); } } + + /** + * 获取订单统计信息(管理员) + * @returns {Promise} 统计信息 + */ + async getOrderStatistics() { + try { + const query = ` + SELECT + COUNT(*) as total_orders, + SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_orders, + SUM(CASE WHEN status = 'paid' THEN 1 ELSE 0 END) as paid_orders, + SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END) as processing_orders, + SUM(CASE WHEN status = 'shipped' THEN 1 ELSE 0 END) as shipped_orders, + SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed_orders, + SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled_orders, + SUM(CASE WHEN status = 'refunded' THEN 1 ELSE 0 END) as refunded_orders, + SUM(total_amount) as total_revenue + FROM orders + WHERE is_deleted = 0 + `; + + const [stats] = await database.query(query); + + return stats; + } catch (error) { + console.error('获取订单统计失败:', error); + throw new Error('获取订单统计失败'); + } + } } module.exports = new OrderService(); \ No newline at end of file