package models

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/wechatpay-apiv3/wechatpay-go/core"
	"github.com/wechatpay-apiv3/wechatpay-go/core/option"
	"github.com/wechatpay-apiv3/wechatpay-go/services/certificates"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
	wechatpayutils "github.com/wechatpay-apiv3/wechatpay-go/utils"
	"github.com/xuri/excelize/v2"
	"go-admin/app/admin/models/kuaidi"
	orm "go-admin/common/global"
	"go-admin/logger"
	"go-admin/tools"
	"go-admin/tools/config"
	"golang.org/x/sync/errgroup"
	"strconv"
	"time"
)

const (
	OrderCardStatusUnPick       = 1 // 待取货中
	OrderCardStatusPlaying      = 2 // 游玩中
	OrderCardStatusReturning    = 3 // 归还中
	OrderCardStatusCompleted    = 4 // 已完成
	OrderCardStatusCancel       = 5 // 已取消
	OrderCardStatusRefund       = 6 // 已退款
	OrderCardStatusSystemReturn = 7 // 系统处理（超期卡）

	DeliveryTypeStorePick = 1 // 门店取货
	DeliveryTypeExpress   = 2 // 快递取货

	ExpressFeeProvince        = 10 * 100 // 省内
	ExpressFeeOutsideProvince = 15 * 100 // 省外

	PayStatusUnPay = 1 // 未支付
	PayStatusPaid  = 2 // 已支付
)

// gen:qs
//
//go:generate goqueryset -in order.go
type Order struct {
	Model

	Uid                    uint64    `json:"uid" gorm:"index"`
	GameCardId             uint64    `json:"game_card_id" gorm:"index"`                                 // 游戏id
	GameCardGoodsId        uint64    `json:"game_card_goods_id" gorm:"index"`                           // 游戏卡id
	GameCardSerialNumber   string    `json:"game_card_serial_number" gorm:"index"`                      // 游戏卡编号
	StoreId                uint64    `json:"store_id" gorm:"index"`                                     // 门店id
	UserAddressId          uint64    `json:"user_address_id"`                                           // 地址id
	DeliveryType           uint8     `json:"delivery_type"`                                             // 取货类型 1-门店自取 2-快递
	Count                  uint32    `json:"count"`                                                     // 数量
	PickupCode             string    `json:"pickup_code"`                                               // 取货码
	CardStatus             uint8     `json:"card_status"`                                               // 1-待取货中 2-游玩中 3-归还中 4-已完成 5-已取消
	DeliveryTime           time.Time `json:"delivery_time"`                                             // 发货时间
	ReceiptTime            time.Time `json:"receipt_time"`                                              // 收货时间 签收时间
	PayTime                time.Time `json:"pay_time"`                                                  // 支付时间
	PayStatus              uint8     `json:"pay_status"`                                                // 支付状态 1-未支付  2-已支付
	OrderSn                string    `json:"order_sn" gorm:"type:varchar(255);not null;COMMENT:'订单编号'"` // 订单编号
	PayPrice               uint32    `json:"pay_price"`                                                 // 实际付款金额(包含运费)
	Postage                uint32    `json:"postage"`                                                   // 邮费
	ExpressCompany         string    `json:"express_company"`                                           // 物流公司
	ExpressCompanyNo       string    `json:"express_company_no"`                                        // 物流公司编号
	ExpressNo              string    `json:"express_no"`                                                // 物流单号
	ExpressDuration        uint64    `json:"express_duration"`                                          // 物流时长
	RevertStoreId          uint64    `json:"revert_store_id"`                                           // 归还门店id
	RevertTime             time.Time `json:"revert_time"`                                               // 归还时间
	RevertExpressCompany   string    `json:"revert_express_company"`                                    // 归还物流公司
	RevertExpressCompanyNo string    `json:"revert_express_company_no"`                                 // 归还物流公司编号
	RevertExpressNo        string    `json:"revert_express_no"`                                         // 归还物流单号
	RevertExpressDuration  uint64    `json:"revert_express_duration"`                                   // 归还物流时长
	CooperativeBusinessId  uint32    `json:"cooperative_business_id"`                                   // 合作商id
	CooperativeName        string    `json:"cooperative_name"`                                          // 合作商名称
	//收货店员码

	GameCardSerialNumbers []string    `json:"game_card_serial_numbers" gorm:"-"`
	OrderCards            []OrderCard `json:"order_cards" gorm:"-"`
	DeliverShopperCode    string      `json:"deliver_shopper_code" gorm:"-"` // 发货店员码
	RevertShopperCode     string      `json:"revert_shopper_code" gorm:"-"`  // 店员识别码
	PhoneExt              string      `json:"phone_ext" gorm:"-"`            // 用户手机号后四位
	OverdueFlag           uint32      `json:"overdue_flag" gorm:"-"`         // 超期处理标志：1
	User                  *UserInfo   `json:"user" gorm:"foreignKey:uid;references:uid"`
}

func (*Order) TableName() string {
	return "order"
}

// gen:qs
type OrderCard struct {
	Model
	OrderId         uint32    `json:"order_id" gorm:"index"`
	Uid             uint32    `json:"uid" gorm:"index"`
	GameCardId      uint32    `json:"game_card_id" gorm:"index"`       // 游戏id
	GameCardGoodsId uint32    `json:"game_card_goods_id" gorm:"index"` // 游戏卡id
	StoreId         uint32    `json:"store_id"  gorm:"index"`          // 门店id
	CardStatus      uint8     `json:"card_status"`                     // 1-待取货中 2-游玩中 3-归还中 4-已完成 5-已取消
	DeliveryTime    time.Time `json:"delivery_time"`                   // 发货时间
	ReceiptTime     time.Time `json:"receipt_time"`                    // 收货时间 签收时间
	DeliveryType    uint8     `json:"delivery_type"`                   // 取货类型 1-门店自取 2-快递
	SerialNumber    string    `json:"serial_number" gorm:"index"`      // 编号
	PayStatus       uint8     `json:"pay_status"`                      // 支付状态 1-未支付  2-已支付

	RevertStoreId          uint64    `json:"revert_store_id"`             // 归还门店id
	RevertTime             time.Time `json:"revert_time"`                 // 归还时间
	RevertExpressCompany   string    `json:"revert_express_company"`      // 归还物流公司
	RevertExpressCompanyNo string    `json:"revert_express_company_no"`   // 归还物流公司编号
	RevertExpressNo        string    `json:"revert_express_no"`           // 归还物流单号
	RevertExpressDuration  uint64    `json:"revert_express_duration"`     // 归还物流时长
	IssueType              uint32    `json:"issue_type"`                  // 问题类型: 1-问题反馈 2-正常
	Postage                uint32    `json:"postage" gorm:"-"`            // 邮费
	ExpressCompany         string    `json:"express_company" gorm:"-"`    // 物流公司
	ExpressCompanyNo       string    `json:"express_company_no" gorm:"-"` // 物流公司编号
	ExpressNo              string    `json:"express_no" gorm:"-"`         // 物流单号
	CooperativeBusinessId  uint32    `json:"cooperative_business_id"`     // 合作商id
	CooperativeName        string    `json:"cooperative_name"`            // 合作商名称

	GameName     string `json:"name" gorm:"-"`         // 名称
	GamePrice    uint32 `json:"price" gorm:"-"`        // 价格
	GameCoverImg string `json:"cover_img" gorm:"-"`    // 封面
	Order        *Order `json:"order" gorm:"-"`        // 订单
	RevertStore  *Store `json:"revert_store" gorm:"-"` // 归还门店

	DeliverShopperCode string                `json:"deliver_shopper_code"`                                                   //发货店员码
	RevertShopperCode  string                `json:"revert_shopper_code"`                                                    //收货识别码
	DeliverShopper     *ShopperPromotionCode `json:"deliver_shopper" gorm:"foreignKey:deliver_shopper_code;references:code"` //发货店员
	RevertShopper      *ShopperPromotionCode `json:"revert_shopper" gorm:"foreignKey:revert_shopper_code;references:code"`   //收货店员
	GameCard           *GameCard             `json:"game_card" gorm:"foreignKey:game_card_id;references:id"`                 //卡带信息
}

func (*OrderCard) TableName() string {
	return "order_card"
}

func (m *Order) ToInfo(card *GameCard) OrderInfo {
	return OrderInfo{
		Order:        *m,
		GameName:     card.Name,
		GamePrice:    card.Price,
		GameCoverImg: card.CoverImg,
	}
}

type OrderInfo struct {
	Order
	GameName     string `json:"name" gorm:"index"`  // 名称
	GamePrice    uint32 `json:"price" gorm:"index"` // 价格
	GameCoverImg string `json:"cover_img"`          // 封面
}

const (
	LogCorrelationOrderId            = "order_id"
	LogCorrelationOrderCard          = "order_card_id"
	LogCorrelationRecycleCardOrderId = "recycle_card_order_id"
)

const (
	OperationTypeRevertRentCard              = "revert_rent_card"                // 归还租卡
	OperationTypeUserShareCard               = "user_share_card"                 // 用户共享卡
	OperationTypeIssueCard                   = "issue_card"                      // 问题卡反馈
	OperationTypeRecycleCardOrderImageUpdate = "recycle_card_order_image_update" // 回收卡上传图片
)

type ExpressNoInfo struct {
	ExpressCompany   string `json:"express_company" gorm:"-"`    // 物流公司
	ExpressCompanyNo string `json:"express_company_no" gorm:"-"` // 物流公司编号
	ExpressNo        string `json:"express_no" gorm:"-"`         // 物流单号
	StoreId          uint32 `json:"store_id" gorm:"-"`
	OperationType    string `json:"operation_type" gorm:"-"`
	CorrelationId    uint32 `json:"correlation_id" gorm:"-"`
	Store            *Store `json:"store" gorm:"-"`
}

// gen:qs
type ExpressCompany struct {
	Model

	CompanyName string `json:"company_name"`
	CompanyCode string `json:"company_code"`
}

func (*ExpressCompany) TableName() string {
	return "express_company"
}

type OrderListReq struct {
	Uid          uint64    `json:"uid" `
	OrderId      uint64    `json:"order_id"`
	GameCardId   uint64    `json:"game_card_id" `
	StoreId      uint64    `json:"store_id" `      // 门店id// 游戏id
	CardStatus   uint8     `json:"card_status"`    // 1-待取货中 2-游玩中 3-归还中 4-已完成 5-已取消
	PayStatus    uint8     `json:"pay_status"`     // 支付状态 1-未支付  2-已支付
	DeliveryType uint8     `json:"delivery_type"`  // 取货类型 1-门店自取 2-快递
	SerialNumber string    `json:"serial_number" ` // 编号
	PickupCode   string    `json:"pickup_code"`    // 取货码
	StartTime    time.Time `json:"start_time"`     // 开始时间
	EndTime      time.Time `json:"end_time"`       // 结束时间
	Page         int       `json:"pageIndex"`
	PageSize     int       `json:"pageSize"`
}

func (m *OrderListReq) List(exportFlag int, c *gin.Context) ([]Order, int64, string, error) {
	orders := make([]Order, 0)
	if m.PageSize == 0 {
		m.PageSize = 10
	}

	var count int64
	var err error
	// 如果卡片类型不为空，则优先查询order_card表
	if m.CardStatus != 0 {
		orders, count, err = m.queryListFormOrderCard(exportFlag, c)
	} else {
		orders, count, err = m.queryListFormOrder(exportFlag, c)
	}

	filePath := ""
	if exportFlag == 1 {
		filePath, err = OrderListExport(orders)
		if err != nil {
			logger.Error("OrderListExport err:", logger.Field("err", err))
			return orders, 0, "", err
		}
	}

	return orders, count, filePath, nil
}

//func (m *OrderListReq) queryListFormOrderCard(exportFlag int, c *gin.Context) ([]Order, int64, error) {
//	var orderCards []OrderCard
//	orders := make([]Order, 0)
//
//	qs := orm.Eloquent.Table("order_card").Where("card_status=?", m.CardStatus)
//
//	// 非管理员才判断所属门店
//	if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
//		sysUser, err := GetSysUserByCtx(c)
//		if err != nil {
//			return nil, 0, err
//		}
//
//		// 返回sysUser未过期的门店id列表
//		storeList := GetValidStoreIDs(sysUser.StoreData)
//		if m.StoreId != 0 {
//			if !Contains(storeList, uint32(m.StoreId)) {
//				return nil, 0, errors.New("您没有该门店权限")
//			}
//		} else {
//			if len(storeList) > 0 {
//				if len(storeList) == 1 {
//					qs = qs.Where("store_id = ? OR revert_store_id = ?", storeList[0], storeList[0])
//				} else {
//					qs = qs.Where("store_id IN (?) OR revert_store_id IN (?)", storeList, storeList)
//				}
//			} else {
//				return nil, 0, errors.New("用户未绑定门店")
//			}
//		}
//	}
//
//	if m.SerialNumber != "" {
//		qs = qs.Where("serial_number=?", m.SerialNumber)
//	}
//
//	if m.DeliveryType != 0 { // 共有
//		qs = qs.Where("delivery_type", m.DeliveryType)
//	}
//
//	if m.Uid != 0 { // 用户id，共有
//		qs = qs.Where("uid", m.Uid)
//	}
//	if m.GameCardId != 0 { // 游戏卡id，共有
//		qs = qs.Where("game_card_id", m.GameCardId)
//	}
//
//	if m.StoreId != 0 { // 门店id，共有
//		qs = qs.Where("store_id = ? OR revert_store_id = ?", m.StoreId, m.StoreId)
//	}
//	if !m.StartTime.IsZero() { // 共有
//		fmt.Println("起始时间:", m.StartTime.Unix())
//		qs = qs.Where("created_at > ?", m.StartTime)
//	}
//	if !m.EndTime.IsZero() { // 共有
//		fmt.Println("时间:", m.StartTime.Unix())
//		qs = qs.Where("created_at < ?", m.EndTime)
//	}
//
//	err := qs.Find(&orderCards).Error
//	if err != nil {
//		logger.Error("err:", logger.Field("err", err))
//		return nil, 0, err
//	}
//
//	orderIds := make([]uint32, 0)
//	for i, _ := range orderCards {
//		orderIds = append(orderIds, orderCards[i].OrderId)
//	}
//
//	orderQs := orm.Eloquent.Table("order").Where("pay_status", 2).Where("id in (?)", orderIds)
//	var count int64
//	err = orderQs.Count(&count).Error
//	if err != nil {
//		logger.Errorf("err:", logger.Field("err", err))
//		return nil, 0, err
//	}
//
//	page := m.Page
//	pageSize := m.PageSize
//	page -= 1
//	if page < 0 {
//		page = 0
//	}
//
//	if exportFlag == 1 { //一次性导出excel
//		orderQs = orderQs.Preload("User").Order("created_at DESC")
//	} else {
//		orderQs = orderQs.Preload("User").Order("created_at DESC").Offset(page * pageSize).Limit(pageSize)
//	}
//	err = orderQs.Find(&orders).Error
//	if err != nil {
//		logger.Errorf("err:", logger.Field("err", err))
//		return nil, 0, err
//	}
//
//	ids := make([]uint32, 0, len(orders))
//	for i, _ := range orders {
//		ids = append(ids, uint32(orders[i].ID))
//	}
//	if len(ids) == 0 {
//		logger.Error("gameIds is nil")
//		return nil, 0, err
//	}
//
//	err = orm.Eloquent.Table("order_card").Where("order_id in (?)", ids).Find(&orderCards).Error
//	if err != nil {
//		logger.Error("err:", logger.Field("err", err))
//		return nil, 0, err
//	}
//	orderCards = OrderCardListSetGameInfo(orderCards)
//	orderCardsMap := make(map[uint32][]OrderCard, 0)
//	for i, _ := range orderCards {
//		if orderCards[i].CardStatus == OrderCardStatusSystemReturn {
//			orderCards[i].CardStatus = OrderCardStatusCompleted
//		}
//
//		if orderCards[i].CardStatus == m.CardStatus { //卡片状态相同的租卡订单才返回，方便财务导出数据
//			orderCardsMap[orderCards[i].OrderId] = append(orderCardsMap[orderCards[i].OrderId], orderCards[i])
//		}
//	}
//	for i, _ := range orders {
//		//2023-12-12 跟产品讨论后确认状态按原来的5种进行展示
//		//if orders[i].CardStatus == 2 || orders[i].CardStatus == 3 {
//		//	orders[i].CardStatus = 4
//		//}
//		v, ok := orderCardsMap[orders[i].ID]
//		if ok {
//			orders[i].OrderCards = v
//		}
//	}
//
//	return orders, count, nil
//}

func (m *OrderListReq) queryListFormOrderCard(exportFlag int, c *gin.Context) ([]Order, int64, error) {
	orders := make([]Order, 0)
	var orderIds []uint32

	// 初始 card 表查询
	cardQs := orm.Eloquent.Table("order_card").Select("DISTINCT order_id")
	if m.CardStatus == OrderCardStatusCompleted {
		cardQs = cardQs.Where("pay_status = 2 and card_status in (?)", []int{OrderCardStatusCompleted, OrderCardStatusSystemReturn})
	} else {
		cardQs = cardQs.Where("pay_status = 2 and card_status = ?", m.CardStatus)
	}

	// 权限控制
	if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
		sysUser, err := GetSysUserByCtx(c)
		if err != nil {
			return nil, 0, err
		}
		storeList := GetValidStoreIDs(sysUser.StoreData)
		if m.StoreId != 0 {
			if !Contains(storeList, uint32(m.StoreId)) {
				return nil, 0, errors.New("您没有该门店权限")
			}
		} else {
			if len(storeList) > 0 {
				if len(storeList) == 1 {
					cardQs = cardQs.Where("store_id = ? OR revert_store_id = ?", storeList[0], storeList[0])
				} else {
					cardQs = cardQs.Where("store_id IN (?) OR revert_store_id IN (?)", storeList, storeList)
				}
			} else {
				return nil, 0, errors.New("用户未绑定门店")
			}
		}
	}

	// 其他筛选条件
	if m.SerialNumber != "" {
		cardQs = cardQs.Where("serial_number = ?", m.SerialNumber)
	}
	if m.DeliveryType != 0 {
		cardQs = cardQs.Where("delivery_type = ?", m.DeliveryType)
	}
	if m.Uid != 0 {
		cardQs = cardQs.Where("uid = ?", m.Uid)
	}
	if m.GameCardId != 0 {
		cardQs = cardQs.Where("game_card_id = ?", m.GameCardId)
	}
	if m.StoreId != 0 {
		cardQs = cardQs.Where("store_id = ? OR revert_store_id = ?", m.StoreId, m.StoreId)
	}
	if !m.StartTime.IsZero() {
		cardQs = cardQs.Where("created_at > ?", m.StartTime)
	}
	if !m.EndTime.IsZero() {
		cardQs = cardQs.Where("created_at < ?", m.EndTime)
	}

	// 统计总数（订单数）
	var count int64
	err := cardQs.Count(&count).Error
	if err != nil {
		logger.Error("统计订单数量失败:", logger.Field("err", err))
		return nil, 0, err
	}
	if count == 0 {
		return []Order{}, 0, nil
	}

	// 分页参数
	page := m.Page
	pageSize := m.PageSize
	if page < 1 {
		page = 1
	}
	offset := (page - 1) * pageSize

	// 查询分页的 order_id（distinct 结果）
	cardQs = cardQs.Order("order_id DESC")
	if exportFlag == 0 {
		cardQs = cardQs.Offset(offset).Limit(pageSize)
	}
	err = cardQs.Pluck("order_id", &orderIds).Error
	if err != nil {
		logger.Error("分页查询 order_card 失败:", logger.Field("err", err))
		return nil, 0, err
	}

	if len(orderIds) == 0 {
		return []Order{}, count, nil
	}

	// 查询订单
	orderQs := orm.Eloquent.Table("order").
		Where("pay_status = ?", 2).
		Where("id IN (?)", orderIds).
		Preload("User").
		Order("created_at DESC")

	err = orderQs.Find(&orders).Error
	if err != nil {
		logger.Error("查询 order 失败:", logger.Field("err", err))
		return nil, 0, err
	}

	// 反查关联的卡片
	var orderCards []OrderCard
	if m.CardStatus == OrderCardStatusCompleted {
		err = orm.Eloquent.Table("order_card").
			Where("order_id IN (?) AND card_status IN (?)", orderIds, []int{OrderCardStatusCompleted, OrderCardStatusSystemReturn}).
			Find(&orderCards).Error
	} else {
		err = orm.Eloquent.Table("order_card").
			Where("order_id IN (?) AND card_status = ?", orderIds, m.CardStatus).
			Find(&orderCards).Error
	}

	if err != nil {
		logger.Error("查询 order_card 失败:", logger.Field("err", err))
		return nil, 0, err
	}

	orderCards = OrderCardListSetGameInfo(orderCards)

	// 绑定卡片到订单
	orderCardsMap := make(map[uint32][]OrderCard)
	for _, oc := range orderCards {
		if oc.CardStatus == OrderCardStatusSystemReturn {
			oc.CardStatus = OrderCardStatusCompleted
		}
		orderCardsMap[oc.OrderId] = append(orderCardsMap[oc.OrderId], oc)
	}

	for i := range orders {
		if v, ok := orderCardsMap[orders[i].ID]; ok {
			orders[i].OrderCards = v
		}
	}

	return orders, count, nil
}

func (m *OrderListReq) queryListFormOrder(exportFlag int, c *gin.Context) ([]Order, int64, error) {
	var orderCards []OrderCard
	orders := make([]Order, 0)
	if m.PageSize == 0 {
		m.PageSize = 10
	}

	qs := orm.Eloquent.Table("order").Select("DISTINCT `order`.*").Joins("JOIN order_card ON order.id = order_card.order_id").
		Where("order.pay_status = ?", 2)

	orderQs := orm.Eloquent.Table("(?) as unique_orders", qs).Order("unique_orders.created_at DESC")

	//qs = orm.Eloquent.Table("order").Where("pay_status", 2)

	// 非管理员才判断所属门店
	if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
		sysUser, err := GetSysUserByCtx(c)
		if err != nil {
			return nil, 0, err
		}

		// 返回sysUser未过期的门店id列表
		storeList := GetValidStoreIDs(sysUser.StoreData)
		if m.StoreId != 0 {
			if !Contains(storeList, uint32(m.StoreId)) {
				return nil, 0, errors.New("您没有该门店权限")
			}
		} else {
			if len(storeList) > 0 {
				if len(storeList) == 1 {
					qs = qs.Where("order.store_id = ? OR order_card.revert_store_id = ?", storeList[0], storeList[0])
				} else {
					qs = qs.Where("order.store_id IN (?) OR order_card.revert_store_id IN (?)", storeList, storeList)
				}
			} else {
				return nil, 0, errors.New("用户未绑定门店")
			}
		}
	}

	isDeliver := true
	if m.SerialNumber != "" {
		isDeliver = false

		err := orm.Eloquent.Table("order_card").Where("serial_number=?", m.SerialNumber).
			Order("id DESC").Order("card_status ASC").Find(&orderCards).Error
		//Where("card_status in (?)", []uint32{2, 3}).Order("id DESC").Order("card_status DESC").Limit(30).Find(&orderCards).Error
		if err != nil {
			logger.Error("err:", logger.Field("err", err))
			return nil, 0, err
		}
		orderIds := make([]uint32, 0)
		for i, _ := range orderCards {
			orderIds = append(orderIds, orderCards[i].OrderId)
		}

		qs = qs.Where("order.id in (?)", orderIds)
	}

	if m.PickupCode != "" {
		isDeliver = false
		qs = qs.Where("order.pickup_code", m.PickupCode)
	}
	if m.PayStatus != 0 {
		qs = qs.Where("order.pay_status", m.PayStatus)
	}
	if m.DeliveryType != 0 {
		qs = qs.Where("order.delivery_type", m.DeliveryType)
	}
	if m.OrderId != 0 {
		isDeliver = false
		qs = qs.Where("order.id", m.OrderId)
	}
	if isDeliver {
		if m.Uid != 0 {
			qs = qs.Where("order.uid", m.Uid)
		}
		if m.GameCardId != 0 {
			qs = qs.Where("order.game_card_id", m.GameCardId)
		}

		if m.StoreId != 0 {
			qs = qs.Where("order.store_id = ? OR order_card.revert_store_id = ?", m.StoreId, m.StoreId)
		}
		if !m.StartTime.IsZero() {
			fmt.Println("起始时间:", m.StartTime.Unix())
			qs = qs.Where("order.created_at > ?", m.StartTime)
		}
		if !m.EndTime.IsZero() {
			fmt.Println("时间:", m.StartTime.Unix())
			qs = qs.Where("order.created_at < ?", m.EndTime)
		}
	}

	var count int64
	err := orderQs.Count(&count).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return nil, 0, err
	}
	page := m.Page
	pageSize := m.PageSize
	page -= 1
	if page < 0 {
		page = 0
	}

	if exportFlag == 1 { //一次性导出excel
		orderQs = orderQs.Preload("User")
	} else {
		orderQs = orderQs.Preload("User").Offset(page * pageSize).Limit(pageSize)
	}
	err = orderQs.Find(&orders).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return nil, 0, err
	}

	ids := make([]uint32, 0, len(orders))
	for i, _ := range orders {
		ids = append(ids, uint32(orders[i].ID))
	}
	if len(ids) == 0 {
		logger.Error("gameIds is nil")
		return nil, 0, err
	}

	err = orm.Eloquent.Table("order_card").Where("order_id in (?)", ids).Find(&orderCards).Error
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return nil, 0, err
	}
	orderCards = OrderCardListSetGameInfo(orderCards)
	orderCardsMap := make(map[uint32][]OrderCard, 0)
	for i, _ := range orderCards {
		if orderCards[i].CardStatus == OrderCardStatusSystemReturn {
			orderCards[i].CardStatus = OrderCardStatusCompleted
		}
		orderCardsMap[orderCards[i].OrderId] = append(orderCardsMap[orderCards[i].OrderId], orderCards[i])
	}
	for i, _ := range orders {
		//2023-12-12 跟产品讨论后确认状态按原来的5种进行展示
		//if orders[i].CardStatus == 2 || orders[i].CardStatus == 3 {
		//	orders[i].CardStatus = 4
		//}
		v, ok := orderCardsMap[orders[i].ID]
		if ok {
			orders[i].OrderCards = v
		}
	}

	return orders, count, nil
}

// OrderListExport 导出订单列表
func OrderListExport(list []Order) (string, error) {
	file := excelize.NewFile()
	streamWriter, err := file.NewStreamWriter("Sheet1")
	if err != nil {
		fmt.Println(err)
	}

	url := config.ExportConfig.Url
	fileName := time.Now().Format(TimeFormat) + "租赁订单" + ".xlsx"
	fmt.Println("url fileName:", url+fileName)

	title := []interface{}{"租赁ID", "用户ID", "会员剩余时长", "取货方式", "状态", "取货码", "实付款", "下单时间", "游戏卡ID",
		"游戏名称", "游戏卡状态", "商品串码"}
	cell, _ := excelize.CoordinatesToCellName(1, 1)
	if err = streamWriter.SetRow(cell, title); err != nil {
		fmt.Println(err)
	}
	var row []interface{}
	nExcelStartRow := 0
	for rowId := 0; rowId < len(list); rowId++ {
		state := "待取货"
		switch list[rowId].CardStatus {
		case 2:
			state = "游玩中"
		case 3:
			state = "归还中"
		case 4:
			state = "已完成"
		case 5:
			state = "已取消"
		}

		deliveryType := "门店自提"
		switch list[rowId].DeliveryType {
		case 1:
			deliveryType = "门店自提"
		case 2:
			deliveryType = "物流配送"
		}

		// user有可能为空
		memberExpire := ""
		if list[rowId].User != nil {
			memberExpire = calculateRemainingDays(*list[rowId].User.MemberExpire)
		}

		for i := 0; i < len(list[rowId].OrderCards); i++ {
			cardState := "待取货"
			switch list[rowId].OrderCards[i].CardStatus {
			case 2:
				cardState = "游玩中"
			case 3:
				cardState = "归还中"
			case 4:
				cardState = "已完成"
			case 5:
				cardState = "已取消"
			}

			row = []interface{}{
				list[rowId].ID,
				list[rowId].Uid,
				memberExpire,
				deliveryType,
				state,
				list[rowId].PickupCode,
				list[rowId].PayPrice,
				list[rowId].PayTime,
				//list[rowId].OrderCards[i].ID, // 租赁卡ID不导出
				list[rowId].OrderCards[i].GameCardId,
				list[rowId].OrderCards[i].GameName,
				cardState,
				list[rowId].OrderCards[i].SerialNumber,
			}

			cell, _ := excelize.CoordinatesToCellName(1, nExcelStartRow+2)
			if err := streamWriter.SetRow(cell, row); err != nil {
				fmt.Println(err)
			}
			nExcelStartRow++
		}

	}
	if err := streamWriter.Flush(); err != nil {
		fmt.Println(err)
	}
	fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
	if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
		fmt.Println(err)
	}
	return url + fileName, nil
}

// 计算剩余时长
func calculateRemainingDays(expirationTime time.Time) string {
	currentTime := time.Now()
	remainingTime := expirationTime.Sub(currentTime)

	// 如果过期时间在当前时间之前，返回0天
	if remainingTime < 0 {
		return "0天"
	}

	remainingDays := int(remainingTime.Hours() / 24)
	return fmt.Sprintf("%d天", remainingDays)
}

func (m *Order) Info() (map[string]interface{}, error) {
	ret := make(map[string]interface{}, 0)
	err := orm.Eloquent.Table("order").Where("id", m.ID).Find(m).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return ret, err
	}

	var orderCards []OrderCard
	err = orm.Eloquent.Table("order_card").
		Preload("DeliverShopper").
		Preload("DeliverShopper.User").
		Preload("RevertShopper").
		Preload("RevertShopper.User").
		Where("order_id=?", m.ID).
		Find(&orderCards).
		Error
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return ret, err
	}

	var (
		eg      errgroup.Group
		storeCh = make(chan Store, 1)
		//revertStoreCh = make(chan Store, 1)
		userAddressCh = make(chan UserAddress, 1)
		userInfoCh    = make(chan UserInfo, 1)
	)
	eg.Go(func() error {
		var store Store
		err := orm.Eloquent.Table("store").Where("id", m.StoreId).Find(&store).Error
		if err != nil && err != RecordNotFound {
			storeCh <- store
			logger.Errorf("err:", logger.Field("err", err))
			return err
		}
		storeCh <- store
		return nil
	})
	//eg.Go(func() error {
	//	var revertStore Store
	//	err := orm.Eloquent.Table("store").Where("id", m.RevertStoreId).Find(&revertStore).Error
	//	if err != nil && err != RecordNotFound {
	//		storeCh <- revertStore
	//		logger.Errorf("err:",logger.Field("err",err))
	//		return err
	//	}
	//	revertStoreCh <- revertStore
	//	return nil
	//})
	eg.Go(func() error {
		var userAddress UserAddress
		err := orm.Eloquent.Table("user_address").Where("id", m.UserAddressId).Find(&userAddress).Error
		if err != nil && err != RecordNotFound {
			userAddressCh <- userAddress
			logger.Errorf("err:", logger.Field("err", err))
			return err
		}
		userAddressCh <- userAddress
		return nil
	})
	eg.Go(func() error {
		var userInfo UserInfo
		err := orm.Eloquent.Table("user").Where("id", m.Uid).Find(&userInfo).Error
		if err != nil && err != RecordNotFound {
			userInfoCh <- userInfo
			logger.Errorf("err:", logger.Field("err", err))
			return err
		}
		userInfoCh <- userInfo
		return nil
	})
	err = eg.Wait()
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return ret, err
	}

	m.OrderCards = OrderCardListSetGameInfo(orderCards)

	if m.CardStatus == 2 || m.CardStatus == 3 {
		m.CardStatus = 4
	}

	ret["order"] = *m
	ret["store"] = <-storeCh
	//ret["revert_store"] = <-revertStoreCh
	ret["userAddress"] = <-userAddressCh
	ret["user"] = <-userInfoCh
	return ret, nil
}

func (m *Order) Deliver() (error, string) {
	paraMap := make(map[string]interface{}, 0)
	// TODO 减库存
	// TODO 更新卡的状态
	var order Order
	err := orm.Eloquent.Table("order").Where("id", m.ID).Find(&order).Error
	if err != nil && err != RecordNotFound {
		logger.Errorf("err:", logger.Field("err", err))
		return err, ""
	}
	fmt.Println("Order:", m)
	cards, err := m.GetOrderCardGameCardIdList()
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return err, ""
	}
	if len(m.GameCardSerialNumbers) != len(cards) {
		logger.Errorf("发货卡的数量与订单游戏卡数量不一致")
		return errors.New("发货卡的数量与订单游戏卡数量不一致"), "发货卡的数量与订单游戏卡数量不一致"
	}
	var user UserInfo
	err = orm.Eloquent.Table("user").Where("uid", order.Uid).Find(&user).Error
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return err, ""
	}
	if user.MemberExpire.Before(time.Now()) {
		logger.Errorf("会员已过期，不能发货")
		return errors.New("会员已过期，不能发货"), "会员已过期，不能发货"
	}
	fmt.Println("m.GameCardSerialNumbers:", m.GameCardSerialNumbers)
	orderCardMaps := make(map[uint32]OrderCard, 0)
	for i, _ := range cards {
		orderCardMaps[cards[i].ID] = cards[i]
	}
	receiptTime := time.Time{}
	if order.DeliveryType == 1 {
		receiptTime = time.Now()
	}

	isUpdateOrder := false
	begin := orm.Eloquent.Begin()

	for _, serialNumber := range m.GameCardSerialNumbers {
		//cards, err = m.GetOrderCardGameCardIdList()
		//if err != nil {
		//	logger.Error("err:",logger.Field("err",err))
		//	return err, ""
		//}

		var (
			gameCardGoods GameCardGoods
			orderCard     *OrderCard
		)
		if serialNumber != "" {
			paraMap["game_card_serial_number"] = serialNumber
			//var count int64
			err := orm.Eloquent.Table("game_card_goods").Where("serial_number", serialNumber).Find(&gameCardGoods).Error
			if err != nil && err != RecordNotFound {
				begin.Rollback()
				logger.Errorf("err:", logger.Field("err", err))
				return err, ""
			}
			if err == RecordNotFound {
				begin.Rollback()
				logger.Errorf("游戏编号卡未找到:%s", serialNumber)
				return errors.New("游戏卡未找到"), "编号的游戏卡不存在"
			}
			if gameCardGoods.Status == GameCardGoodsStatusCannibalize {
				begin.Rollback()
				return errors.New("card goods status err"), "该卡在调拨中,不能发货"
			}
			if gameCardGoods.Status != GameCardGoodsStatusStock {
				begin.Rollback()
				return errors.New("card goods status err"), "该卡状态,不能发货"
			}
			//err = orm.Eloquent.Table("order").Where("id", m.ID).Find(&order).Error
			//if err != nil && err != RecordNotFound {
			//	begin.Rollback()
			//	logger.Errorf("err:",logger.Field("err",err))
			//	return err, ""
			//}
			if order.CardStatus != OrderCardStatusUnPick {
				begin.Rollback()
				logger.Errorf("order not unpick")
				return errors.New("order not unpick"), "订单不是待取货状态"
			}
			if order.PayStatus != PayStatusPaid {
				begin.Rollback()
				logger.Errorf("order not pay")
				return errors.New("order not pay"), "订单未支付"
			}
			//if order.GameCardId != gameCardGoods.GameCardId {
			//	logger.Errorf("游戏id卡未找到")
			//	return errors.New("游戏卡与订单游戏不一致"), "编号的游戏卡不存在"
			//}
			orderCard = GetOrderCardMapSerialNumberUnset(orderCardMaps, uint32(gameCardGoods.GameCardId))
			//orderCard, ok := cardMap[uint32(gameCardGoods.GameCardId)]
			if orderCard == nil {
				begin.Rollback()
				//logger.Errorf("订单游戏卡已发货")
				//return errors.New("订单游戏卡已发货"), "订单游戏卡已发货"
				logger.Errorf("发货游戏卡错误")
				return errors.New("发货游戏卡错误"), "发货游戏卡错误"
			}
			//orderCard, ok := orderCardMaps[uint32(gameCardGoods.GameCardId)]
			//if !ok {
			//	logger.Errorf("发货游戏卡错误")
			//	return errors.New("发货游戏卡错误"), "发货游戏卡错误"
			//}
			if m.StoreId != gameCardGoods.StoreId {
				begin.Rollback()
				logger.Errorf("游戏编号卡不是该门店")
				return errors.New("游戏编号卡不是该门店"), "该门店没有该游戏卡"
			}
			//fmt.Println("m.StoreId", m.StoreId)
			//fmt.Println("m.RevertStoreId", m.RevertStoreId)
			//fmt.Printf("m:%#v \n", m)
			//fmt.Println("orderCard.StoreId", orderCard.StoreId)
			if uint32(m.StoreId) != orderCard.StoreId {
				begin.Rollback()
				// 订单锁库存
				logger.Errorf("订单门店与发货门店不一致")
				return errors.New("订单门店与发货门店不一致"), "订单门店与发货门店不一致,请取消订单后重新下单"
			}
		}
		if !isUpdateOrder {
			if m.StoreId != 0 {
				paraMap["store_id"] = m.StoreId
				paraMap["pickup_code"] = "已取货"
				paraMap["card_status"] = 4
				paraMap["store_id"] = m.StoreId
				paraMap["delivery_time"] = time.Now()
			}
			if m.ExpressCompany != "" {
				paraMap["express_company"] = m.ExpressCompany
			}
			if m.ExpressCompanyNo != "" {
				paraMap["express_company_no"] = m.ExpressCompanyNo
			}
			if m.ExpressNo != "" {
				paraMap["express_no"] = m.ExpressNo
			}
			err := begin.Table("order").Where("id", m.ID).Updates(paraMap).Error
			if err != nil {
				begin.Rollback()
				logger.Errorf("err:", logger.Field("err", err))
				return err, ""
			}
			isUpdateOrder = true
		}

		//goodsStatus := GameCardGoodsStatusInWay
		//if m.DeliveryType == 1 {
		goodsStatus := GameCardGoodsStatusCustomerHold
		//}
		var eg errgroup.Group
		eg.Go(func() error {
			err := begin.Table("game_card_goods").Where("serial_number", serialNumber).
				Update("status", goodsStatus).Error
			if err != nil {
				begin.Rollback()
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}
			return nil
		})
		eg.Go(func() error {
			sql := fmt.Sprintf("UPDATE game_card_goods_stock SET user_hold_stock= user_hold_stock+1 WHERE store_id=%d AND game_card_id=%d;", m.StoreId, gameCardGoods.GameCardId)
			fmt.Println("sql:", sql)
			err := begin.Exec(sql).Error
			if err != nil {
				begin.Rollback()
				logger.Errorf("err:%s", err.Error())
				return err
			}
			return nil
		})
		// 归还加库存
		//eg.Go(func() error {
		//	if order.GameCardId != 0 {
		//		sql := fmt.Sprintf("UPDATE game_card SET order_count = order_count+1 WHERE id = %d", order.GameCardId)
		//		err := orm.Eloquent.Exec(sql).Error
		//		if err != nil {
		//			logger.Errorf("err:",logger.Field("err",err))
		//			return err
		//		}
		//	}
		//
		//	return nil
		//})

		eg.Go(func() error {
			var userInfo UserInfo
			err := orm.Eloquent.Table("user").Where("uid=?", order.Uid).Find(&userInfo).Error
			if err != nil {
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}
			if userInfo.StoreId == 0 {
				sql := fmt.Sprintf("UPDATE `user` SET store_id = %d WHERE uid =%d", order.StoreId, order.Uid)
				err := begin.Exec(sql).Error
				if err != nil {
					begin.Rollback()
					logger.Errorf("err:", logger.Field("err", err))
					return err
				}
			}
			//var userInvite UserInvite
			//err = orm.Eloquent.Table("user_11invite").Where("uid=?", order.Uid).Find(&userInvite).Error
			//if err == RecordNotFound {
			//	invite := &UserInvite{
			//		FromUid:        0,
			//		UserType:       0,
			//		StoreId:        order.StoreId,
			//		MemberOpenTime: userInfo.MemberExpire.AddDate(-1, 0, 0),
			//		MemberType:     2,
			//		MemberStatus:   2,
			//		ToUid:          uint32(order.Uid),
			//		StoreType:      1,
			//	}
			//	err := orm.Eloquent.Create(invite).Error
			//	if err != nil {
			//		logger.Errorf("err:",logger.Field("err",err))
			//		return err
			//	}
			//}
			return nil
		})
		eg.Go(func() error {
			//var orderCard OrderCard
			//err := orm.Eloquent.Table("order_card").Where("order_id=?", m.ID).Where("uid=?", order.Uid).
			//	Where("game_card_id=?", gameCardGoods.GameCardId).Where("serial_number=''").Limit(1).Find(&orderCard).Error
			//if err != nil {
			//	logger.Errorf("err:",logger.Field("err",err))
			//	return err
			//}
			//err = begin.Table("order_card").Where("id=?", orderCard.ID).Updates(&map[string]interface{}{
			//	"game_card_goods_id": gameCardGoods.ID,
			//	"serial_number":      gameCardGoods.SerialNumber,
			//	"card_status":        2,
			//}).Error

			err = begin.Table("order_card").Where("id=?", orderCard.ID).Updates(&map[string]interface{}{
				"store_id":             m.StoreId,
				"delivery_time":        time.Now(),
				"game_card_goods_id":   gameCardGoods.ID,
				"serial_number":        gameCardGoods.SerialNumber,
				"card_status":          2,
				"receipt_time":         receiptTime,
				"deliver_shopper_code": m.DeliverShopperCode,
			}).Error
			if err != nil {
				begin.Rollback()
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}
			delete(orderCardMaps, orderCard.ID)
			return nil
		})

		err = eg.Wait()
		if err != nil {
			begin.Rollback()
			logger.Errorf("err:", logger.Field("err", err))
			return err, ""
		}
	}

	err = begin.Table("order_card").Where("order_id=?", m.ID).Where("uid=?", order.Uid).
		Where("serial_number=''").Updates(&map[string]interface{}{
		"card_status": 5,
	}).Error
	err = begin.Commit().Error
	if err != nil {
		begin.Rollback()
		logger.Error("err:", logger.Field("err", err))
		return err, ""
	}

	if m.ExpressCompanyNo != "" && m.ExpressNo != "" {
		_, err = kuaidi.SubscribeExpressState(m.ExpressCompanyNo, m.ExpressNo)
		if err != nil {
			logger.Error("subscribe express state err:", logger.Field("err", err))
		}
	}
	//DeliverTask{}
	//err := orm.Eloquent.Table("order").Where("id", m.ID).Find(&order).Error

	UpdateDeliverTaskSubState(order.ID)

	if user.OpenMemberChannel == OpenMemberChannelStorePromotion {
		go func() {
			var orders []Order
			err = orm.Eloquent.Table("order").Where("uid=?", user.Uid).
				Where("card_status!=?", OrderCardStatusCancel).Where("pay_status=?", 2).Find(&orders).Error
			if err != nil {
				logger.Error("order err:", logger.Field("err", err))
				return
			}

			if len(orders) == 1 && orders[0].CardStatus == 4 {
				err = orm.Eloquent.Table("user").Where("uid=?", user.Uid).
					Update("store_id", orders[0].StoreId).Error
				if err != nil {
					logger.Error("update store err:", logger.Field("err", err))
				}
			}
			//if !exist && user.OpenMemberTime.Format(DateTimeFormat) == time.Now().Format(DateTimeFormat) {
			//	//_, err = NewUserQuerySet(model.DB).UidEq(uc.Uid).GetUpdater().SetStoreId(uint64(req.StoreId)).UpdateNum()
			//	if err != nil {
			//		logger.Error("update user err:",logger.Field("err",err))
			//	}
			//}
		}()
	}

	return nil, ""
}

func (m *Order) Revert() error {
	OrderJson, _ := json.Marshal(m)
	fmt.Println("归还订单:", string(OrderJson))
	var order Order
	err := orm.Eloquent.Table("order").Preload("User").Where("id", m.ID).Find(&order).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return err
	}
	if m.PhoneExt != "" && !order.User.CheckPhoneExt(m.PhoneExt, 4) {
		return errors.New("手机尾号校验不正确")
	}
	cardMap, err := order.GetOrderCardMap()
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return err
	}
	orderCardIds := make([]uint32, 0, len(cardMap))
	for _, card := range cardMap {
		orderCardIds = append(orderCardIds, card.ID)
	}
	//CardIssueFeedback{}
	var issueCount int64
	err = orm.Eloquent.Table("card_issue_feedback").Where("relevance_id in (?)", orderCardIds).
		Where("state=?", CardIssueStateFollowing).Count(&issueCount).Error
	if err != nil {
		logger.Errorf("err:%#v", logger.Field("err", err))
		return err
	}
	if issueCount > 0 {
		logger.Error("untreated_issue_feedback")
		return errors.New("请先检测用户反馈问题卡")
	}
	//for _, serialNumber := range m.GameCardSerialNumbers {
	serialNumber := m.GameCardSerialNumber

	orderCard, ok := cardMap[serialNumber]
	if !ok {
		logger.Error("order card is not revert card")
		return errors.New("order card is not revert card")
	}
	if m.RevertStoreId == 0 {
		logger.Error("revert store id null")
		return errors.New("revert store id null")
	}
	if orderCard.CardStatus != OrderCardStatusReturning && orderCard.CardStatus != OrderCardStatusPlaying {
		logger.Error("order card status not returning playing ")
		return errors.New("order card status not returning playing ")
	}

	var gameCardGoods GameCardGoods
	//err := orm.Eloquent.Table("order").Where("game_card_serial_number", m.GameCardSerialNumber).Find(&gameCardGoods).Error
	err = orm.Eloquent.Table("game_card_goods").Where("serial_number", serialNumber).Find(&gameCardGoods).Error
	if err != nil {
		logger.Errorf("err:%#v", logger.Field("err", err))
		return err
	}

	if order.StoreId != gameCardGoods.StoreId {
		logger.Error("order store id not game card goods store id")
		return errors.New("order store id not game card goods store id")
	}

	// 判断是否有超期还卡标志
	cardStatusFlag := OrderCardStatusCompleted
	if m.OverdueFlag == 1 {
		cardStatusFlag = OrderCardStatusSystemReturn
	}

	begin := orm.Eloquent.Begin()
	var eg errgroup.Group
	//eg.Go(func() error {
	//	fmt.Println("GameCardSerialNumber", serialNumber)
	//	fmt.Println("GameCardSerialNumber 更新订单信息:")
	//	// TODO
	//	err := orm.Eloquent.Table("order").Where("game_card_serial_number", serialNumber).Where("card_status in (?)", []int{OrderCardStatusReturning, OrderCardStatusPlaying}).
	//		Updates(map[string]interface{}{
	//			"card_status":     OrderCardStatusCompleted,
	//			"revert_store_id": m.RevertStoreId,
	//			"revert_time":     time.Now(),
	//		}).Error
	//	if err != nil {
	//		logger.Errorf("err:",logger.Field("err",err))
	//		return err
	//	}
	//	return nil
	//})

	eg.Go(func() error {
		//err := orm.Eloquent.Table("game_card_goods").Where("serial_number", m.GameCardSerialNumber).
		//	Update("status", GameCardGoodsStatusStock,).Error
		goodsStatus := GameCardGoodsStatusStock
		if gameCardGoods.Status == 7 {
			goodsStatus = GameCardGoodsStatusUnusual
		}

		err := orm.Eloquent.Table("game_card_goods").Where("serial_number", serialNumber).
			Updates(map[string]interface{}{
				"status":     goodsStatus,
				"store_id":   m.RevertStoreId,
				"stock_time": time.Now(),
			}).Error

		if err != nil {
			logger.Errorf("err:", logger.Field("err", err))
			return err
		}

		return nil
	})
	eg.Go(func() error {
		if gameCardGoods.StoreId != m.RevertStoreId {
			sqlStore := fmt.Sprintf(
				"UPDATE game_card_goods_stock SET user_hold_stock= user_hold_stock-1,order_count=order_count+1,total_stock=total_stock-1 WHERE store_id=%d AND game_card_id=%d;",
				order.StoreId, gameCardGoods.GameCardId)
			fmt.Println("sqlStore:", sqlStore)
			err = orm.Eloquent.Exec(sqlStore).Error
			if err != nil {
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}

			var count int64
			err := orm.Eloquent.Table("game_card_goods_stock").Where("store_id", m.RevertStoreId).
				Where("game_card_id", gameCardGoods.GameCardId).Count(&count).Error
			if err != nil {
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}
			if count == 0 && (gameCardGoods.Status != 7 || gameCardGoods.FunctionState != 1) {
				goodsStock := &GameCardGoodsStock{
					StoreId:       m.RevertStoreId,
					GameCardId:    gameCardGoods.GameCardId,
					StoreStock:    0,
					RentStock:     1,
					UserHoldStock: 0,
					OrderCount:    0,
					TotalStock:    1,
				}
				err := orm.Eloquent.Create(goodsStock).Error
				if err != nil {
					logger.Errorf("err:", logger.Field("err", err))
					return err
				}
				return nil
			} else {
				if gameCardGoods.Status != 7 || gameCardGoods.FunctionState != 1 {
					sql := fmt.Sprintf(
						"UPDATE game_card_goods_stock SET rent_stock= rent_stock+1,total_stock=total_stock+1 WHERE store_id=%d AND game_card_id=%d;",
						m.RevertStoreId, gameCardGoods.GameCardId)
					fmt.Println("sql:", sql)
					err = orm.Eloquent.Exec(sql).Error
					if err != nil {
						logger.Errorf("err:", logger.Field("err", err))
						return err
					}
				}
			}
		} else {
			//sqlStore := fmt.Sprintf("UPDATE game_card_goods_stock SET user_hold_stock= user_hold_stock-1,order_count=order_count+1,order_count=order_count+1 WHERE store_id=%d AND game_card_id=%d;", order.StoreId, gameCardGoods.GameCardId)
			sqlStore := fmt.Sprintf(
				"UPDATE game_card_goods_stock SET user_hold_stock= user_hold_stock-1,order_count=order_count+1 WHERE store_id=%d AND game_card_id=%d;",
				order.StoreId, gameCardGoods.GameCardId)
			fmt.Println("sqlStore:", sqlStore)
			err = orm.Eloquent.Exec(sqlStore).Error
			if err != nil {
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}
			if gameCardGoods.Status != 7 || gameCardGoods.FunctionState != 1 {
				//sql := fmt.Sprintf("UPDATE game_card_goods_stock SET rent_stock= rent_stock+1,user_hold_stock= user_hold_stock-1 WHERE store_id=%d AND game_card_id=%d;", m.RevertStoreId, gameCardGoods.GameCardId)
				sql := fmt.Sprintf(
					"UPDATE game_card_goods_stock SET rent_stock= rent_stock+1 WHERE store_id=%d AND game_card_id=%d;",
					m.RevertStoreId, gameCardGoods.GameCardId)
				fmt.Println("sql:", sql)
				err = orm.Eloquent.Exec(sql).Error
				if err != nil {
					logger.Errorf("err:", logger.Field("err", err))
					return err
				}
			}
		}

		return nil
	})
	eg.Go(func() error {
		if order.GameCardId != 0 {
			sql := fmt.Sprintf("UPDATE game_card SET order_count = order_count+1 WHERE id = %d", order.GameCardId)
			err := orm.Eloquent.Exec(sql).Error
			if err != nil {
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}
		}

		return nil
	})
	eg.Go(func() error {
		if m.RevertExpressNo != "" { // 物流单号不为空则记录到数据库；2024/2/1 产品新需求，解决用户物流归还但小程序不提交归还信息，店员要输入手机号的问题
			err = begin.Table("order_card").Where("id=?", orderCard.ID).Updates(&map[string]interface{}{
				//"store_id":        m.StoreId,
				"card_status":         cardStatusFlag,
				"revert_store_id":     m.RevertStoreId,
				"revert_time":         time.Now(),
				"revert_shopper_code": m.RevertShopperCode,
				"revert_express_no":   m.RevertExpressNo,
			}).Error
			if err != nil {
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}
		} else {
			err = begin.Table("order_card").Where("id=?", orderCard.ID).Updates(&map[string]interface{}{
				//"store_id":        m.StoreId,
				"card_status":         cardStatusFlag,
				"revert_store_id":     m.RevertStoreId,
				"revert_time":         time.Now(),
				"revert_shopper_code": m.RevertShopperCode,
			}).Error
			if err != nil {
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}
		}
		var count int64
		err = orm.Eloquent.Table("order_card").Where("order_id=?", orderCard.OrderId).
			Where("card_status in (?)", []uint32{1, 2, 3}).Count(&count).Error
		//NewOrderCardQuerySet(DB).OrderIdEq(order.ID).CardStatusIn(1, 2, 3).Total()
		if err != nil {
			logger.Error("err:", logger.Field("err", err))
			return err
		}
		if count == 0 {
			err := begin.Table("order").Where("id=?", orderCard.OrderId).Updates(&map[string]interface{}{
				"card_status": OrderCardStatusCompleted,
			}).Error
			if err != nil {
				logger.Error("err:", logger.Field("err", err))
				return err
			}
		}
		return nil
	})
	eg.Go(func() error {
		sql := fmt.Sprintf(
			"UPDATE user_rent_card SET have_rent_count = have_rent_count-1,can_rent_count=can_rent_count+1 WHERE uid =%d;",
			orderCard.Uid)
		//sql := fmt.Sprintf("UPDATE user_rent_card SET have_rent_count = have_rent_count-1,can_rent_count=can_rent_count+1 WHERE uid =%d;", m.Uid)
		fmt.Println("sql:", sql)
		err = begin.Exec(sql).Error
		if err != nil {
			logger.Errorf("err:", logger.Field("err", err))
			return err
		}
		return nil
	})
	if m.OverdueFlag == 1 { // 押金清零
		eg.Go(func() error {
			sql := fmt.Sprintf(
				"UPDATE user SET deposit = 0, mark = 1 WHERE uid =%d;",
				orderCard.Uid)
			fmt.Println("sql:", sql)
			err = begin.Exec(sql).Error
			if err != nil {
				logger.Errorf("err:", logger.Field("err", err))
				return err
			}
			return nil
		})
	}

	err = eg.Wait()
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return err
	}
	err = begin.Commit().Error
	if err != nil {
		begin.Rollback()
		logger.Error("err:", logger.Field("err", err))
		return err
	}

	return nil
}

func (*ExpressCompany) List() ([]ExpressCompany, error) {
	companys := make([]ExpressCompany, 0)
	err := orm.Eloquent.Table("express_company").Order("id desc").Find(&companys).Error
	if err != nil && err != RecordNotFound {
		logger.Error("err:", logger.Field("err", err))
		return companys, err
	}
	return companys, nil
}

func (m *Order) Del() error {
	err := orm.Eloquent.Table("order").Where("id", m.ID).Delete(m).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return err
	}

	return nil
}

func (m *Order) Refund() error {
	var order Order
	err := orm.Eloquent.Table("order").Where("id", m.ID).Find(&order).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return err
	}
	if order.CardStatus != OrderCardStatusCancel || order.PayStatus != PayStatusPaid {
		logger.Error("order card status not cancel paid")
		return errors.New("order card status not cancel paid ")
	}
	err = orm.Eloquent.Table("order").Where("id", m.ID).Update("card_status", OrderCardStatusRefund).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return err
	}

	return nil
}

func WxPayTransactionOrderClose(outTradeNo string) error {
	var (
		mchID                      string = "1609877389"                               // 商户号
		mchCertificateSerialNumber string = "7540301D8FD52CCF7D6267DCF7CD2BC0AB467EFF" // 商户证书序列号
		mchAPIv3Key                string = "DeovoMingHuiRengTianTang45675123"         // 商户APIv3密钥
	)
	//	微信商户
	//	商户ID：1609877389
	//	操作密码：456755
	//	密钥API：DeovoMingHuiRengTianTang45675456
	//	密钥APIv3: DeovoMingHuiRengTianTang45675123
	//	证书序列号：7540301D8FD52CCF7D6267DCF7CD2BC0AB467EFF
	//  使用 utils 提供的函数从本地文件中加载商户私钥，商户私钥会用来生成请求的签名
	//privatePath := "/www/wwwroot/dev.admin.deovo.com/admin_server/go-admin/config/merchant/apiclient_key.pem" // TODO 测试
	privatePath := "/www/wwwroot/admin.deovo.com/admin_server/go-admin/config/merchant/apiclient_key.pem" // TODO 正式
	mchPrivateKey, err := wechatpayutils.LoadPrivateKeyWithPath(privatePath)
	if err != nil {
		//log.Fatal("load merchant private key error")
		logger.Errorf("err:", logger.Field("err", err))
	}

	ctx := context.Background()
	// 使用商户私钥等初始化 client，并使它具有自动定时获取微信支付平台证书的能力
	opts := []core.ClientOption{
		option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
	}
	client, err := core.NewClient(ctx, opts...)
	if err != nil {
		//log.Fatalf("new wechat pay client err:%s",logger.Field("err",err))
		logger.Errorf("err:", logger.Field("err", err))
	}

	// 发送请求，以下载微信支付平台证书为例
	// https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay5_1.shtml
	svc := certificates.CertificatesApiService{Client: client}
	resp, result, err := svc.DownloadCertificates(context.Background())
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return err
	}
	//log.Printf("status=%d resp=%s", result.Response.StatusCode, resp)
	logger.Info("WxPayTransactionOrderClose", logger.Field("status", result.Response.StatusCode), logger.Field("resp", resp))

	svcClient := jsapi.JsapiApiService{Client: client}
	apiResult, err := svcClient.CloseOrder(ctx, jsapi.CloseOrderRequest{
		OutTradeNo: &outTradeNo,
		Mchid:      &mchID,
	})
	if err != nil {
		fmt.Println("err:", logger.Field("err", err))
		logger.Error(err.Error())
		return err
	}

	fmt.Println("StatusCode:", (*apiResult).Response.StatusCode)
	//bodyCloseOrder,_ := ioutil.ReadAll((*apiResult.Response.Body))
	fmt.Println("apiResult:", (*apiResult).Response.StatusCode)
	return nil
}

func IsUserHaveUnreturnedOrders(uid uint32) (bool, error) {
	fmt.Println("uid", uid)

	sql := fmt.Sprintf("SELECT COUNT(*) AS count FROM order_card WHERE uid = %d AND pay_status=2 AND card_status IN (1,2,3) ;", uid)
	//sql := fmt.Sprintf("SELECT COUNT(*) AS count FROM order_card WHERE uid = %d AND pay_status IN (1,2) AND card_status IN (1,2,3) ;", uid)
	//count, err := NewOrderQuerySet(DB).UidEq(uint64(uid)).PayStatusEq(PayStatusPaid).CardStatusIn(1, 2, 3).Total()
	//if err != nil {
	//	logger.Error("err:",logger.Field("err",err))
	//	return false, err
	//}
	unreturned := &struct {
		Count int `json:"count"`
	}{}
	orm.Eloquent.Raw(sql).Scan(unreturned)
	fmt.Println("订单数量count:", unreturned.Count)
	return unreturned.Count != 0, nil
}

func (m *Order) GetOrderCardMap() (map[string]OrderCard, error) {
	cardMap := make(map[string]OrderCard, 0)
	var orderCards []OrderCard
	err := orm.Eloquent.Table("order_card").
		Where("order_id=?", m.ID).
		//Where("uid=?", m.Uid).
		Find(&orderCards).Error
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return cardMap, err
	}
	for i, _ := range orderCards {
		cardMap[orderCards[i].SerialNumber] = orderCards[i]
	}

	return cardMap, nil
}

func (m *Order) GetOrderCardGameCardIdList() ([]OrderCard, error) {
	var orderCards []OrderCard
	err := orm.Eloquent.Table("order_card").
		Where("order_id=?", m.ID).
		Where("card_status=?", OrderCardStatusUnPick).
		//Where("serial_number=''").
		Find(&orderCards).Error
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return orderCards, err
	}
	return orderCards, nil
}

//func GetOrderCardSerialNumberUnset(list []OrderCard, gameCardId uint32) *OrderCard {
//	for i, _ := range list {
//		if list[i].GameCardId == gameCardId && list[i].SerialNumber == "" {
//			return &list[i]
//		}
//	}
//	return nil
//}

func GetOrderCardMapSerialNumberUnset(list map[uint32]OrderCard, gameCardId uint32) *OrderCard {
	for _, v := range list {
		if v.GameCardId == gameCardId && v.SerialNumber == "" {
			return &v
		}
	}
	return nil
}

func OrderCardListSetGameInfo(list []OrderCard) []OrderCard {
	ids := make([]uint32, 0, len(list))
	revertStoreIds := make([]uint32, 0, len(list))
	for i, _ := range list {
		ids = append(ids, list[i].GameCardId)
		revertStoreIds = append(revertStoreIds, uint32(list[i].RevertStoreId))
	}
	if len(ids) == 0 {
		return list
	}

	fmt.Println("ids:", ids)
	cardMap, err := GameCardMap(ids)
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return list
	}
	storeMap, err := RevertStoreMap(revertStoreIds)
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return list
	}

	//fmt.Println("cardMap:", cardMap)
	//fmt.Println("cardMap:", storeMap)
	for i, _ := range list {

		gameCard, ok1 := cardMap[list[i].GameCardId]
		store, ok2 := storeMap[uint32(list[i].RevertStoreId)]
		if ok1 {
			list[i].GameName = gameCard.Name
			list[i].GameCoverImg = gameCard.CoverImg
			list[i].GamePrice = gameCard.Price
			if ok2 {
				list[i].RevertStore = &store
			}
		}
	}
	return list
}

func GameCardMap(ids []uint32) (map[uint32]GameCard, error) {
	cardMap := make(map[uint32]GameCard, 0)
	if len(ids) == 0 {
		return cardMap, nil
	}
	var cards []GameCard
	err := orm.Eloquent.Table("game_card").Where("id in (?)", ids).Find(&cards).Error
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return cardMap, err
	}
	if len(cards) == 0 {
		return cardMap, nil
	}
	for i, _ := range cards {
		cardMap[cards[i].ID] = cards[i]
	}
	return cardMap, nil
}

func RevertStoreMap(ids []uint32) (map[uint32]Store, error) {
	storeMap := make(map[uint32]Store, 0)
	if len(ids) == 0 {
		return storeMap, nil
	}
	var stores []Store
	err := orm.Eloquent.Table("store").Where("id in (?)", ids).Find(&stores).Error
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return storeMap, err
	}
	if len(stores) == 0 {
		return storeMap, nil
	}
	for i, _ := range stores {
		storeMap[stores[i].ID] = stores[i]
	}
	return storeMap, nil
}

func (m *ExpressNoInfo) SetStore() {
	err := orm.Eloquent.Table("store").Where("id=?", m.StoreId).Find(m.Store).Error
	if err != nil {
		logger.Error("err:%s", logger.Field("err", err))
		return
	}
}

// FundRecordListReq 财务统计入参
type FundRecordListReq struct {
	Uid           uint64    `json:"uid" `
	FundType      string    `json:"fund_type"`
	TransactionId string    `json:"transaction_id"` // 支付单号
	OutTradeNo    string    `json:"out_trade_no"`
	RefundId      string    `json:"refund_id"`
	PaymentNo     string    `json:"payment_no"`
	StartTime     time.Time `json:"start_time"` // 开始时间
	EndTime       time.Time `json:"end_time"`   // 结束时间
	Page          int       `json:"pageIndex"`
	PageSize      int       `json:"pageSize"`
	IsExport      uint32    `json:"is_export"` // 1-导出
}

type FundRecordListResp struct {
	List      []FundRecord `json:"list"`
	Total     int64        `json:"total"`     // 总条数
	PageIndex int          `json:"pageIndex"` // 页码
	PageSize  int          `json:"pageSize"`  // 每页展示条数
	ExportUrl string       `json:"export_url"`
}

func (m *FundRecordListReq) List() ([]FundRecord, int64, string, error) {
	var fundRecords []FundRecord
	qs := orm.Eloquent.Table("fund_record")

	// 默认剔除"尊享会员费"，只有传参有才展示
	if m.FundType != "" {
		qs = qs.Where("fund_type=?", m.FundType)
	} else {
		qs = qs.Where("fund_type != ?", "privilege_member_fee")
	}
	if m.TransactionId != "" {
		qs = qs.Where("transaction_id=?", m.TransactionId)
	}
	if m.OutTradeNo != "" {
		qs = qs.Where("out_trade_no=?", m.OutTradeNo)
	}
	if m.RefundId != "" {
		qs = qs.Where("refund_id=?", m.RefundId)
	}
	if m.PaymentNo != "" {
		qs = qs.Where("payment_no=?", m.PaymentNo)
	}
	if m.Uid != 0 {
		qs = qs.Where("uid=?", m.Uid)
	}

	if !m.StartTime.IsZero() {
		//fmt.Println("起始时间:", m.StartTime.Unix())
		qs = qs.Where("created_at > ?", m.StartTime)
	}
	if !m.EndTime.IsZero() {
		//fmt.Println("时间:", m.StartTime.Unix())
		qs = qs.Where("created_at < ?", m.EndTime)
	}

	var count int64
	err := qs.Count(&count).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return fundRecords, 0, "", err
	}
	if m.PageSize == 0 {
		m.PageSize = 10
	}
	page := m.Page
	pageSize := m.PageSize
	page -= 1
	if page < 0 {
		page = 0
	}

	if m.IsExport == 1 { // 导出excel
		err = qs.Order("created_at DESC").Find(&fundRecords).Error
		if err != nil {
			logger.Errorf("err:", logger.Field("err", err))
			return fundRecords, 0, "", err
		}

		exportUrl, err := fundRecordListExport(fundRecords)
		if err != nil {
			logger.Errorf("err:", logger.Field("err", err))
			return fundRecords, 0, "", err
		}

		return nil, 0, exportUrl, nil
	} else {
		err = qs.Order("created_at DESC").Offset(page * pageSize).Limit(pageSize).Find(&fundRecords).Error
		if err != nil {
			logger.Errorf("err:", logger.Field("err", err))
			return fundRecords, 0, "", err
		}
	}

	return fundRecords, count, "", nil
}

// TranslateFundType 将fund_type转换为对应的字符
func TranslateFundType(fundType string) string {
	fundTypeMap := map[string]string{
		"member_fee":           "会员费",
		"buy_goods_refund":     "商品退货",
		"buy_goods":            "商品购买",
		"buy_goods_cancel":     "商品取消",
		"recycle_card":         "回收卡带",
		"postage_package_fee":  "购买运费包",
		"member_deposit":       "押金",
		"upgrade_member":       "升级会员",
		"member_expire_delay":  "滞纳金",
		"express_fee":          "邮费",
		"deposit_refund":       "退押金",
		"express_fee_refund":   "退邮费",
		"downgrade_renewal":    "降级续费",
		"privilege_member_fee": "尊享会员费",
	}

	if val, ok := fundTypeMap[fundType]; ok {
		return val
	}
	return "未知类型"
}

// ConvertAmount 将Amount转换为格式化字符串
func ConvertAmount(amount int64) string {
	// 转换为以分为单位的小数，保留两位小数
	convertedAmount := float64(amount) / 100.0
	sign := "+"
	if convertedAmount < 0 {
		sign = "-"
		convertedAmount = -convertedAmount
	}
	return sign + strconv.FormatFloat(convertedAmount, 'f', 2, 64)
}

// fundRecordListExport 导出财务统计数据
func fundRecordListExport(list []FundRecord) (string, error) {
	file := excelize.NewFile()
	fSheet := "Sheet1"

	url := config.ExportConfig.Url
	fileName := time.Now().Format(TimeFormat) + "财务统计" + ".xlsx"
	fmt.Println("url fileName:", url+fileName)

	title := []interface{}{"用户ID", "类型", "金额", "商户单号", "交易单号", "退款单号", "付款单号", "创建时间", "备注"}

	for i, _ := range title {
		cell, _ := excelize.CoordinatesToCellName(1+i, 1)
		err := file.SetCellValue(fSheet, cell, title[i])
		if err != nil {
			logger.Errorf("file set value err:", err)
		}
	}

	var row []interface{}
	nExcelStartRow := 0
	for rowId := 0; rowId < len(list); rowId++ {
		formattedTime := list[rowId].CreatedAt.Format(QueryTimeFormat)
		row = []interface{}{
			list[rowId].Uid,
			TranslateFundType(list[rowId].FundType),
			ConvertAmount(list[rowId].Amount),
			list[rowId].OutTradeNo,
			list[rowId].TransactionId,
			list[rowId].RefundId,
			list[rowId].PaymentNo,
			formattedTime,
			list[rowId].Remark,
		}

		for j, _ := range row {
			cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2)
			err := file.SetCellValue(fSheet, cell, row[j])
			if err != nil {
				logger.Error("file set value err:", logger.Field("err", err))
			}
		}
		nExcelStartRow++
	}

	// 设置所有单元格的样式: 居中、加边框
	style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
	"border":[{"type":"left","color":"000000","style":1},
	{"type":"top","color":"000000","style":1},
	{"type":"right","color":"000000","style":1},
	{"type":"bottom","color":"000000","style":1}]}`)

	//设置单元格高度
	file.SetRowHeight("Sheet1", 1, 20)

	// 设置单元格大小
	file.SetColWidth("Sheet1", "A", "A", 10)
	file.SetColWidth("Sheet1", "B", "B", 13)
	file.SetColWidth("Sheet1", "C", "C", 10)
	file.SetColWidth("Sheet1", "D", "D", 16)
	file.SetColWidth("Sheet1", "E", "E", 30)
	file.SetColWidth("Sheet1", "F", "F", 30)
	file.SetColWidth("Sheet1", "G", "G", 30)
	file.SetColWidth("Sheet1", "H", "H", 25)
	file.SetColWidth("Sheet1", "I", "I", 13)

	var endRow string
	endRow = fmt.Sprintf("I"+"%d", nExcelStartRow+1)

	// 应用样式到整个表格
	_ = file.SetCellStyle("Sheet1", "A1", endRow, style)

	fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
	if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
		fmt.Println(err)
	}

	return url + fileName, nil
}

type CooperativeOrderReq struct {
	CooperativeBusinessId uint32    `json:"cooperative_business_id"`
	Uid                   uint64    `json:"uid" `
	OrderId               uint64    `json:"order_id"`
	GameCardId            uint64    `json:"game_card_id" `
	StoreId               uint64    `json:"store_id" `   // 门店id// 游戏id
	CardStatus            uint8     `json:"card_status"` // 1-待取货中 2-游玩中 3-归还中 4-已完成
	PayStatus             uint8     `json:"pay_status"`
	DeliveryType          uint8     `json:"delivery_type"`
	SerialNumber          string    `json:"serial_number" ` // 编号
	PickupCode            string    `json:"pickup_code"`    // 取货码
	StartTime             time.Time `json:"start_time"`     // 开始时间
	EndTime               time.Time `json:"end_time"`       // 结束时间
	Page                  int       `json:"pageIndex"`
	PageSize              int       `json:"pageSize"`
}

func (m *CooperativeOrderReq) List() ([]Order, int64, error) {
	var orderCards []OrderCard
	orders := make([]Order, 0)
	if m.PageSize == 0 {
		m.PageSize = 10
	}
	qs := orm.Eloquent.Table("order").Where("pay_status", 2).
		Where("cooperative_business_id=?", m.CooperativeBusinessId)

	isDeliver := true
	if m.SerialNumber != "" {
		isDeliver = false

		err := orm.Eloquent.Table("order_card").Where("serial_number=?", m.SerialNumber).
			Order("id DESC").Order("card_status ASC").Find(&orderCards).Error
		//Where("card_status in (?)", []uint32{2, 3}).Order("id DESC").Order("card_status DESC").Limit(30).Find(&orderCards).Error
		if err != nil {
			logger.Error("err:", logger.Field("err", err))
			return orders, 0, err
		}
		orderIds := make([]uint32, 0)
		for i, _ := range orderCards {
			orderIds = append(orderIds, orderCards[i].OrderId)
		}

		qs = qs.Where("id in (?)", orderIds)
	}
	if m.PickupCode != "" {
		isDeliver = false
		qs = qs.Where("pickup_code", m.PickupCode)
	}
	if m.PayStatus != 0 {
		qs = qs.Where("pay_status", m.PayStatus)
	}
	if m.DeliveryType != 0 {
		qs = qs.Where("delivery_type", m.DeliveryType)
	}
	if m.OrderId != 0 {
		isDeliver = false
		qs = qs.Where("id", m.OrderId)
	}
	if isDeliver {
		if m.Uid != 0 {
			qs = qs.Where("uid", m.Uid)
		}
		if m.GameCardId != 0 {
			qs = qs.Where("game_card_id", m.GameCardId)
		}
		if m.CardStatus != 0 {
			qs = qs.Where("card_status", m.CardStatus)
		}
		if m.StoreId != 0 {
			qs = qs.Where("store_id", m.StoreId)
		}
		if !m.StartTime.IsZero() {
			fmt.Println("起始时间:", m.StartTime.Unix())
			qs = qs.Where("created_at > ?", m.StartTime)
		}
		if !m.EndTime.IsZero() {
			fmt.Println("时间:", m.StartTime.Unix())
			qs = qs.Where("created_at < ?", m.EndTime)
		}
	}

	var count int64
	err := qs.Count(&count).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return orders, 0, err
	}
	page := m.Page
	pageSize := m.PageSize
	page -= 1
	if page < 0 {
		page = 0
	}
	err = qs.Order("created_at DESC").Offset(page * pageSize).Limit(pageSize).Find(&orders).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		return orders, 0, err
	}

	ids := make([]uint32, 0, len(orders))
	for i, _ := range orders {
		ids = append(ids, uint32(orders[i].ID))
	}
	if len(ids) == 0 {
		logger.Error("gameIds is nil")
		return orders, 0, err
	}

	//var orderCards []OrderCard
	err = orm.Eloquent.Table("order_card").Where("order_id in (?)", ids).Find(&orderCards).Error
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		return orders, 0, err
	}
	orderCards = OrderCardListSetGameInfo(orderCards)
	orderCardsMap := make(map[uint32][]OrderCard, 0)
	for i, _ := range orderCards {
		orderCardsMap[orderCards[i].OrderId] = append(orderCardsMap[orderCards[i].OrderId], orderCards[i])
	}
	for i, _ := range orders {
		if orders[i].CardStatus == 2 || orders[i].CardStatus == 3 {
			orders[i].CardStatus = 4
		}
		v, ok := orderCardsMap[orders[i].ID]
		if ok {
			orders[i].OrderCards = v
		}
	}

	return orders, count, nil
}

func GetUserExpiredCards(userId []uint32) (map[uint32][]OrderCard, error) {

	var m = make(map[uint32][]OrderCard)

	var oc []OrderCard
	err := orm.Eloquent.Table("order_card").
		Preload("GameCard").
		Where("uid in (?)", userId).
		Where("pay_status = ?", HavePaid).Where("card_status in ?", []int{1, 2, 3}).
		Find(&oc).Error
	if err != nil {
		return m, err
	}

	for _, card := range oc {
		l, ok := m[card.Uid]
		if ok {
			m[card.Uid] = append(l, card)
		} else {
			m[card.Uid] = []OrderCard{card}
		}
	}
	return m, nil
}
