Files
2025-11-28 15:18:10 +08:00

624 lines
20 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"dianshang/internal/model"
"fmt"
"time"
"gorm.io/gorm"
)
// OrderRepository 订单仓储
type OrderRepository struct {
db *gorm.DB
}
// NewOrderRepository 创建订单仓储
func NewOrderRepository(db *gorm.DB) *OrderRepository {
return &OrderRepository{db: db}
}
// Create 创建订单
func (r *OrderRepository) Create(order *model.Order) error {
return r.db.Create(order).Error
}
// GetByID 根据ID获取订单
func (r *OrderRepository) GetByID(id uint) (*model.Order, error) {
var order model.Order
fmt.Printf("🔍 [OrderRepository.GetByID] 开始查询订单 - 查询ID: %d\n", id)
// 启用 SQL 调试
db := r.db.Debug()
err := db.Preload("OrderItems").Preload("OrderItems.Product").Preload("OrderItems.SKU").Preload("Store").Where("id = ?", id).First(&order).Error
if err == nil {
fmt.Printf("✅ [OrderRepository.GetByID] 查询成功 - ID: %d, 状态: %d, 订单号: %s\n", order.ID, order.Status, order.OrderNo)
// 直接查询验证
var directOrder model.Order
r.db.Raw("SELECT id, order_no, status FROM ai_orders WHERE id = ?", id).Scan(&directOrder)
fmt.Printf("🔍 [直接SQL查询] ID: %d, 状态: %d, 订单号: %s\n", directOrder.ID, directOrder.Status, directOrder.OrderNo)
} else {
fmt.Printf("❌ [OrderRepository.GetByID] 查询失败 - ID: %d, 错误: %v\n", id, err)
}
return &order, err
}
// GetByOrderNo 根据订单号获取订单
func (r *OrderRepository) GetByOrderNo(orderNo string) (*model.Order, error) {
var order model.Order
err := r.db.Preload("OrderItems").Preload("OrderItems.Product").Preload("OrderItems.SKU").Preload("Store").Where("order_no = ?", orderNo).First(&order).Error
return &order, err
}
// GetUserOrders 获取用户订单列表
func (r *OrderRepository) GetUserOrders(userID uint, status int, offset, limit int) ([]model.Order, int64, error) {
var orders []model.Order
var total int64
query := r.db.Model(&model.Order{}).Where("user_id = ?", userID)
if status > 0 {
// 前端状态映射:
// 前端status=3表示"待发货"对应数据库status=2已付款/待发货和status=3待发货
if status == 3 {
query = query.Where("status IN ?", []int{2, 3})
} else {
query = query.Where("status = ?", status)
}
}
// 获取总数
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// 获取列表,预加载订单项和店铺信息
err := query.Preload("OrderItems").Preload("OrderItems.Product").Preload("OrderItems.Product.SKUs", "status = ?", 1).Preload("OrderItems.SKU").Preload("Store").
Offset(offset).Limit(limit).Order("created_at DESC").Find(&orders).Error
return orders, total, err
}
// GetUserOrderStatistics 获取用户订单统计
func (r *OrderRepository) GetUserOrderStatistics(userID uint) (map[string]interface{}, error) {
var result struct {
OrderCount int64 `json:"order_count"`
TotalAmount float64 `json:"total_amount"`
}
// 查询用户的订单数量和总消费金额
err := r.db.Model(&model.Order{}).
Select("COUNT(*) as order_count, COALESCE(SUM(total_amount), 0) as total_amount").
Where("user_id = ? AND status != ?", userID, 0). // 排除已取消的订单
Scan(&result).Error
if err != nil {
return nil, err
}
return map[string]interface{}{
"order_count": result.OrderCount,
"total_amount": result.TotalAmount,
}, nil
}
// Update 更新订单
func (r *OrderRepository) Update(id uint, updates map[string]interface{}) error {
fmt.Printf("🔄 [OrderRepository.Update] 执行数据库更新订单ID: %d\n", id)
fmt.Printf("🔄 [OrderRepository.Update] 更新字段: %+v\n", updates)
result := r.db.Model(&model.Order{}).Where("id = ?", id).Updates(updates)
fmt.Printf("🔄 [OrderRepository.Update] 影响行数: %d\n", result.RowsAffected)
fmt.Printf("🔄 [OrderRepository.Update] 错误信息: %v\n", result.Error)
return result.Error
}
// UpdateByID 根据ID更新订单记录
func (r *OrderRepository) UpdateByID(orderID uint, updates map[string]interface{}) error {
return r.Update(orderID, updates)
}
// UpdateByOrderNo 根据订单号更新订单
func (r *OrderRepository) UpdateByOrderNo(orderNo string, updates map[string]interface{}) error {
fmt.Printf("🔄 [UpdateByOrderNo] 执行数据库更新,订单号: %s\n", orderNo)
fmt.Printf("🔄 [UpdateByOrderNo] 更新字段: %+v\n", updates)
result := r.db.Model(&model.Order{}).Where("order_no = ?", orderNo).Updates(updates)
fmt.Printf("🔄 [UpdateByOrderNo] 影响行数: %d\n", result.RowsAffected)
fmt.Printf("🔄 [UpdateByOrderNo] 错误信息: %v\n", result.Error)
return result.Error
}
// Delete 删除订单(软删除)
func (r *OrderRepository) Delete(id uint) error {
return r.db.Where("id = ?", id).Delete(&model.Order{}).Error
}
// GetList 获取订单列表(管理员)
func (r *OrderRepository) GetList(offset, limit int, conditions map[string]interface{}) ([]model.Order, int64, error) {
var orders []model.Order
var total int64
query := r.db.Model(&model.Order{})
// 添加查询条件
for key, value := range conditions {
switch key {
case "status":
query = query.Where("status = ?", value)
case "user_id":
query = query.Where("user_id = ?", value)
case "order_no":
query = query.Where("order_no LIKE ?", "%"+value.(string)+"%")
case "start_date":
query = query.Where("created_at >= ?", value)
case "end_date":
query = query.Where("created_at <= ?", value)
}
}
// 获取总数
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// 获取列表预加载订单项、商品信息、SKU信息、用户信息和店铺信息
err := query.Preload("OrderItems").Preload("OrderItems.Product").Preload("OrderItems.SKU").Preload("User").Preload("Store").
Offset(offset).Limit(limit).Order("created_at DESC").Find(&orders).Error
return orders, total, err
}
// CreateOrderItem 创建订单项
func (r *OrderRepository) CreateOrderItem(item *model.OrderItem) error {
return r.db.Create(item).Error
}
// GetOrderItems 获取订单项列表
func (r *OrderRepository) GetOrderItems(orderID uint) ([]model.OrderItem, error) {
var items []model.OrderItem
err := r.db.Preload("Product").Where("order_id = ?", orderID).Find(&items).Error
return items, err
}
// UpdateOrderItem 更新订单项
func (r *OrderRepository) UpdateOrderItem(id uint, updates map[string]interface{}) error {
return r.db.Model(&model.OrderItem{}).Where("id = ?", id).Updates(updates).Error
}
// GetCart 获取购物车
// 优化: 减少不必要的Preload,只加载必需的关联数据
func (r *OrderRepository) GetCart(userID uint) ([]model.Cart, error) {
var cart []model.Cart
// 移除 Product.SKUs 的预加载,因为购物车已经有单独的SKU字段
// 只保留必要的Product和SKU信息
err := r.db.Preload("Product").Preload("SKU").Where("user_id = ?", userID).Find(&cart).Error
return cart, err
}
// GetCartItem 获取购物车项
func (r *OrderRepository) GetCartItem(userID, productID uint) (*model.Cart, error) {
var cart model.Cart
err := r.db.Where("user_id = ? AND product_id = ?", userID, productID).First(&cart).Error
return &cart, err
}
// GetCartItemBySKU 根据SKU获取购物车项
func (r *OrderRepository) GetCartItemBySKU(userID, productID, skuID uint) (*model.Cart, error) {
var cart model.Cart
query := r.db.Where("user_id = ? AND product_id = ?", userID, productID)
fmt.Printf("🔍 [GetCartItemBySKU] 查询条件 - 用户ID: %d, 产品ID: %d, SKU ID: %d\n",
userID, productID, skuID)
if skuID > 0 {
// 查找指定的SKU ID
query = query.Where("sk_uid = ?", skuID)
fmt.Printf("🔍 [GetCartItemBySKU] 查找指定SKU: %d\n", skuID)
} else {
// 查找没有SKU的商品sk_uid为NULL或0
query = query.Where("sk_uid IS NULL OR sk_uid = 0")
fmt.Printf("🔍 [GetCartItemBySKU] 查找无SKU商品 (sk_uid IS NULL OR sk_uid = 0)\n")
}
err := query.First(&cart).Error
if err != nil {
fmt.Printf("❌ [GetCartItemBySKU] 查询失败: %v\n", err)
return nil, err
}
fmt.Printf("✅ [GetCartItemBySKU] 找到购物车项 - ID: %d, SKU ID: %v\n",
cart.ID, cart.SKUID)
return &cart, nil
}
// AddToCart 添加到购物车
func (r *OrderRepository) AddToCart(cart *model.Cart) error {
return r.db.Create(cart).Error
}
// UpdateCartItem 更新购物车项
func (r *OrderRepository) UpdateCartItem(id uint, quantity int) error {
return r.db.Model(&model.Cart{}).Where("id = ?", id).Update("quantity", quantity).Error
}
// RemoveFromCart 从购物车移除
func (r *OrderRepository) RemoveFromCart(userID, productID uint) error {
return r.db.Where("user_id = ? AND product_id = ?", userID, productID).Delete(&model.Cart{}).Error
}
// RemoveFromCartBySKU 根据SKU从购物车移除
func (r *OrderRepository) RemoveFromCartBySKU(userID, productID, skuID uint) error {
query := r.db.Where("user_id = ? AND product_id = ?", userID, productID)
if skuID > 0 {
// 删除指定的SKU ID使用sk_uid字段
query = query.Where("sk_uid = ?", skuID)
} else {
// 删除没有SKU的商品sk_uid为NULL或0
query = query.Where("sk_uid IS NULL OR sk_uid = 0")
}
return query.Delete(&model.Cart{}).Error
}
// ClearCart 清空购物车
func (r *OrderRepository) ClearCart(userID uint) error {
return r.db.Where("user_id = ?", userID).Delete(&model.Cart{}).Error
}
// GetOrderStatistics 获取订单统计
func (r *OrderRepository) GetOrderStatistics() (map[string]interface{}, error) {
var result map[string]interface{} = make(map[string]interface{})
// 总订单数
var totalOrders int64
r.db.Model(&model.Order{}).Count(&totalOrders)
result["total_orders"] = totalOrders
// 待付款订单数
var pendingOrders int64
r.db.Model(&model.Order{}).Where("status = ?", 1).Count(&pendingOrders)
result["pending_orders"] = pendingOrders
// 待发货订单数状态2和3都是待发货
var toShipOrders int64
r.db.Model(&model.Order{}).Where("status IN (?)", []int{2, 3}).Count(&toShipOrders)
result["to_ship_orders"] = toShipOrders
// 已发货订单数
var shippedOrders int64
r.db.Model(&model.Order{}).Where("status = ?", 4).Count(&shippedOrders)
result["shipped_orders"] = shippedOrders
// 已完成订单数
var completedOrders int64
r.db.Model(&model.Order{}).Where("status = ?", 6).Count(&completedOrders)
result["completed_orders"] = completedOrders
// 总销售额(包含待发货、已发货、待收货、已完成状态)
var totalAmount float64
r.db.Model(&model.Order{}).Where("status IN (?)", []int{2, 3, 4, 5, 6}).Select("COALESCE(SUM(total_amount), 0)").Scan(&totalAmount)
result["total_amount"] = totalAmount
return result, nil
}
// GetDailyOrderStatistics 获取每日订单统计
func (r *OrderRepository) GetDailyOrderStatistics(days int) ([]map[string]interface{}, error) {
var results []map[string]interface{}
query := `
SELECT
DATE(created_at) as date,
COUNT(*) as order_count,
COALESCE(SUM(total_amount), 0) as total_amount
FROM ai_orders
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY)
GROUP BY DATE(created_at)
ORDER BY date DESC
`
err := r.db.Raw(query, days).Scan(&results).Error
return results, err
}
// SelectCartItem 选择/取消选择购物车项
func (r *OrderRepository) SelectCartItem(userID, cartID uint, selected bool) error {
return r.db.Model(&model.Cart{}).
Where("id = ? AND user_id = ?", cartID, userID).
Update("selected", selected).Error
}
// SelectAllCartItems 全选/取消全选购物车
func (r *OrderRepository) SelectAllCartItems(userID uint, selected bool) error {
return r.db.Model(&model.Cart{}).
Where("user_id = ?", userID).
Update("selected", selected).Error
}
// UpdateOrderStatus 更新订单状态
func (r *OrderRepository) UpdateOrderStatus(orderID uint, status int) error {
updates := map[string]interface{}{
"status": status,
}
// 根据状态设置相应的时间字段
now := time.Now()
switch status {
case 2: // 已支付
updates["paid_at"] = now
case 3: // 已发货
updates["shipped_at"] = now
case 4: // 已完成
updates["completed_at"] = now
case 5: // 已取消
updates["cancelled_at"] = now
case 6: // 已退款
updates["refunded_at"] = now
}
return r.db.Model(&model.Order{}).Where("id = ?", orderID).Updates(updates).Error
}
// BatchUpdateOrderStatus 批量更新订单状态
func (r *OrderRepository) BatchUpdateOrderStatus(orderIDs []uint, status int) error {
updates := map[string]interface{}{
"status": status,
}
// 根据状态设置相应的时间字段
now := time.Now()
switch status {
case 2: // 已支付
updates["paid_at"] = now
case 3: // 已发货
updates["shipped_at"] = now
case 4: // 已完成
updates["completed_at"] = now
case 5: // 已取消
updates["cancelled_at"] = now
case 6: // 已退款
updates["refunded_at"] = now
}
return r.db.Model(&model.Order{}).Where("id IN ?", orderIDs).Updates(updates).Error
}
// GetOrdersByDateRange 根据日期范围获取订单
func (r *OrderRepository) GetOrdersByDateRange(startDate, endDate string, status, offset, limit int) ([]*model.Order, int64, error) {
var orders []*model.Order
var total int64
query := r.db.Model(&model.Order{})
if startDate != "" {
query = query.Where("created_at >= ?", startDate+" 00:00:00")
}
if endDate != "" {
query = query.Where("created_at <= ?", endDate+" 23:59:59")
}
if status > 0 {
query = query.Where("status = ?", status)
}
// 获取总数
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// 获取分页数据
err := query.Offset(offset).Limit(limit).Order("created_at DESC").Find(&orders).Error
return orders, total, err
}
// GetOrdersForExport 获取用于导出的订单数据
func (r *OrderRepository) GetOrdersForExport(conditions map[string]interface{}) ([]*model.Order, error) {
var orders []*model.Order
query := r.db.Model(&model.Order{})
if startDate, ok := conditions["start_date"]; ok {
query = query.Where("created_at >= ?", startDate.(string)+" 00:00:00")
}
if endDate, ok := conditions["end_date"]; ok {
query = query.Where("created_at <= ?", endDate.(string)+" 23:59:59")
}
if status, ok := conditions["status"]; ok {
query = query.Where("status = ?", status)
}
if orderNo, ok := conditions["order_no"]; ok {
query = query.Where("order_no LIKE ?", "%"+orderNo.(string)+"%")
}
err := query.Order("created_at DESC").Find(&orders).Error
return orders, err
}
// GetOrderTrendData 获取订单趋势数据
func (r *OrderRepository) GetOrderTrendData(days int) ([]map[string]interface{}, error) {
var results []map[string]interface{}
query := `
SELECT
DATE(created_at) as date,
COUNT(*) as order_count,
SUM(total_amount) as total_amount,
COUNT(CASE WHEN status = 6 THEN 1 END) as completed_count
FROM ai_orders
WHERE created_at >= DATE_SUB(NOW(), INTERVAL ? DAY)
GROUP BY DATE(created_at)
ORDER BY date ASC
`
err := r.db.Raw(query, days).Scan(&results).Error
return results, err
}
// GetPendingOrdersCount 获取待处理订单数量
func (r *OrderRepository) GetPendingOrdersCount() (int64, error) {
var count int64
// 待处理订单包括:待支付(1)、待发货(2,3)、已发货(4)、待收货(5)
err := r.db.Model(&model.Order{}).Where("status IN ?", []int{1, 2, 3, 4, 5}).Count(&count).Error
return count, err
}
// UpdateOrderLogistics 更新订单物流信息
func (r *OrderRepository) UpdateOrderLogistics(orderID uint, logisticsCompany, trackingNumber string) error {
updates := map[string]interface{}{
"logistics_company": logisticsCompany,
"tracking_number": trackingNumber,
"shipped_at": time.Now(),
"status": 3, // 已发货
}
return r.db.Model(&model.Order{}).Where("id = ?", orderID).Updates(updates).Error
}
// GetOrderByOrderNo 根据订单号获取订单
func (r *OrderRepository) GetOrderByOrderNo(orderNo string) (*model.Order, error) {
var order model.Order
err := r.db.Where("order_no = ?", orderNo).First(&order).Error
if err != nil {
return nil, err
}
return &order, nil
}
// GetOrderByWechatOutTradeNo 根据微信支付订单号获取订单
func (r *OrderRepository) GetOrderByWechatOutTradeNo(wechatOutTradeNo string) (*model.Order, error) {
var order model.Order
err := r.db.Where("wechat_out_trade_no = ?", wechatOutTradeNo).First(&order).Error
if err != nil {
return nil, err
}
return &order, nil
}
// GetOrderItemByID 根据ID获取订单项
func (r *OrderRepository) GetOrderItemByID(id uint) (*model.OrderItem, error) {
var orderItem model.OrderItem
err := r.db.Preload("Product").Preload("Order").First(&orderItem, id).Error
return &orderItem, err
}
// SaveOrderItem 保存订单项
func (r *OrderRepository) SaveOrderItem(orderItem *model.OrderItem) error {
return r.db.Save(orderItem).Error
}
// GetUncommentedOrderItems 获取用户未评论的订单项
func (r *OrderRepository) GetUncommentedOrderItems(userID uint) ([]model.OrderItem, error) {
var orderItems []model.OrderItem
// 查询已完成订单中未评论的订单项
err := r.db.Joins("JOIN ai_orders ON order_items.order_id = ai_orders.id").
Where("ai_orders.user_id = ? AND ai_orders.status = ? AND order_items.is_commented = ?",
userID, model.OrderStatusCompleted, false).
Preload("Product").Preload("Order").
Find(&orderItems).Error
return orderItems, err
}
// UpdateOrderRefund 更新订单退款信息
func (r *OrderRepository) UpdateOrderRefund(orderID uint, refundAmount float64, refundReason string) error {
updates := map[string]interface{}{
"refund_amount": refundAmount,
"refund_reason": refundReason,
"refunded_at": time.Now(),
"status": 6, // 已退款
}
return r.db.Model(&model.Order{}).Where("id = ?", orderID).Updates(updates).Error
}
// GetOrderStatisticsByStatus 根据状态获取订单统计
func (r *OrderRepository) GetOrderStatisticsByStatus() (map[string]interface{}, error) {
var results []struct {
Status int `json:"status"`
Count int64 `json:"count"`
Amount float64 `json:"amount"`
}
query := `
SELECT
status,
COUNT(*) as count,
COALESCE(SUM(total_amount), 0) as amount
FROM ai_orders
GROUP BY status
`
if err := r.db.Raw(query).Scan(&results).Error; err != nil {
return nil, err
}
statistics := make(map[string]interface{})
for _, result := range results {
statusKey := fmt.Sprintf("status_%d", result.Status)
statistics[statusKey] = map[string]interface{}{
"count": result.Count,
"amount": result.Amount,
}
}
return statistics, nil
}
// GetTotalOrderStatistics 获取总订单统计
func (r *OrderRepository) GetTotalOrderStatistics() (map[string]interface{}, error) {
var result struct {
TotalCount int64 `json:"total_count"`
TotalAmount float64 `json:"total_amount"`
}
query := `
SELECT
COUNT(*) as total_count,
COALESCE(SUM(total_amount), 0) as total_amount
FROM ai_orders
`
if err := r.db.Raw(query).Scan(&result).Error; err != nil {
return nil, err
}
return map[string]interface{}{
"total_count": result.TotalCount,
"total_amount": result.TotalAmount,
}, nil
}
// BatchRemoveFromCart 批量从购物车移除
func (r *OrderRepository) BatchRemoveFromCart(userID uint, cartIDs []uint) error {
return r.db.Where("user_id = ? AND id IN ?", userID, cartIDs).Delete(&model.Cart{}).Error
}
// GetCartItemByID 根据ID获取购物车项
func (r *OrderRepository) GetCartItemByID(userID, cartID uint) (*model.Cart, error) {
var cart model.Cart
err := r.db.Where("user_id = ? AND id = ?", userID, cartID).First(&cart).Error
if err != nil {
return nil, err
}
return &cart, nil
}
// RemoveCartItem 移除购物车项
func (r *OrderRepository) RemoveCartItem(cartID uint) error {
return r.db.Delete(&model.Cart{}, cartID).Error
}
// GetSelectedCartItems 获取选中的购物车项
func (r *OrderRepository) GetSelectedCartItems(userID uint) ([]model.Cart, error) {
var cart []model.Cart
err := r.db.Where("user_id = ? AND selected = ?", userID, true).
Preload("Product").
Preload("ProductSKU").
Find(&cart).Error
return cart, err
}