package model import ( "encoding/json" "errors" "fmt" "github.com/codinl/go-logger" "github.com/jinzhu/gorm" "golang.org/x/sync/errgroup" "math/rand" "mh-server/kuaidi" "time" ) const ( OrderCardStatusUnPick = 1 // 待取货中 OrderCardStatusPlaying = 2 // 游玩中 OrderCardStatusReturning = 3 // 归还中 OrderCardStatusCompleted = 4 // 已完成 OrderCardStatusCancel = 5 // 已取消 OrderCardStatusRefund = 6 // 已退款 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"` // 邮费 PostageType uint32 `json:"postage_type"` // 邮费类型:1-法币 2-包邮券 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"` // 归还物流时长 OutTradeNo string `json:"out_trade_no"` // 支付订单 Mchid string `json:"mchid"` // 商户 CooperativeBusinessId uint32 `json:"cooperative_business_id" gorm:"index"` // 合作商id CooperativeName string `json:"cooperative_name"` // 合作商名称 OrderCardId uint32 `json:"order_card_id" gorm:"-"` // OrderCards []OrderCard `json:"order_cards" gorm:"-"` Store *Store `json:"store" gorm:"-"` UserAddress *UserAddress `json:"user_address" gorm:"-"` } // 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 uint32 `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-正常 CooperativeBusinessId uint32 `json:"cooperative_business_id" gorm:"index"` // 合作商id CooperativeName string `json:"cooperative_name"` // 合作商名称 Postage uint32 `json:"postage" gorm:"-"` // 邮费 PostageType uint32 `json:"postage_type"` // 邮费类型 ExpressCompany string `json:"express_company" gorm:"-"` // 物流公司 ExpressCompanyNo string `json:"express_company_no" gorm:"-"` // 物流公司编号 ExpressNo string `json:"express_no" gorm:"-"` // 物流单号 GameName string `json:"name" gorm:"-"` // 名称 GamePrice uint32 `json:"price" gorm:"-"` // 价格 GameCoverImg string `json:"cover_img" gorm:"-"` // 封面 IssueFeedbackStoreId uint32 `json:"issue_feedback_store_id" gorm:"-"` // 问题反馈门店 Order *Order `json:"order" gorm:"-"` // 订单 GameCard *GameCard `json:"game_card" gorm:"-"` // 游戏 Store *Store `json:"store" gorm:"-"` // 游戏 RevertStore *Store `json:"revert_store" gorm:"-"` // 游戏 //Status uint8 `json:"status" gorm:"index"` // 1-待领取 2-游玩中 3-已归还 4-未领取 //PickupCode string `json:"pickup_code"` // 取货码 } func (*Order) TableName() string { return "order" } func (m *Order) ToInfo(card *GameCard) OrderInfo { return OrderInfo{ Order: *m, } } type OrderInfo struct { Order Cards []OrderCard } func OrderCardListSetGameInfo(list []OrderCard) []OrderCard { ids := make([]uint32, 0, len(list)) orderIds := make([]uint32, 0, len(list)) for i, _ := range list { ids = append(ids, list[i].GameCardId) orderIds = append(orderIds, list[i].OrderId) } if len(ids) == 0 || len(orderIds) == 0 { return list } orderMap, err := OrderMap(orderIds) if err != nil { logger.Error("err:", err) return list } cardMap, err := GameCardMap(ids) if err != nil { logger.Error("err:", err) return list } for i, _ := range list { gameCard, ok1 := cardMap[list[i].GameCardId] order, ok2 := orderMap[list[i].OrderId] if ok1 && ok2 { if order.CardStatus == 2 || order.CardStatus == 3 { order.CardStatus = 4 } list[i].GameName = gameCard.Name list[i].GameCoverImg = gameCard.CoverImg list[i].GamePrice = gameCard.Price list[i].Order = &order } } 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 := NewGameCardQuerySet(DB).IDIn(ids...).All(&cards) if err != nil { logger.Error("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 OrderMap(ids []uint32) (map[uint32]Order, error) { cardMap := make(map[uint32]Order, 0) if len(ids) == 0 { return cardMap, nil } var cards []Order err := NewOrderQuerySet(DB).IDIn(ids...).All(&cards) if err != nil { logger.Error("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 } type OrderListReq struct { Page int `json:"page"` PageSize int `json:"page_size"` OrderType uint32 `json:"order_type"` // 1-全部 2-进行中 3-已完成 Uid uint32 `json:"uid"` } func (m *OrderListReq) GetOrderCardList() ([]OrderCard, uint32, error) { var ( orderCards []OrderCard totalPage uint32 //orderInfos = make([]OrderInfo, 0, pageSize) ) m.Page -= 1 if m.Page < 0 { m.Page = 0 } if m.PageSize == 0 { m.PageSize = 10 } oq := NewOrderCardQuerySet(DB).PayStatusEq(PayStatusPaid).UidEq(m.Uid) if m.OrderType == 2 { oq = oq.CardStatusIn([]uint32{1, 2, 3}...) } if m.OrderType == 3 { oq = oq.CardStatusEq(4) } count, err := oq.Count() if err != nil { logger.Error("NewGameCardQuerySet err:", err) return orderCards, 0, err } err = oq.OrderDescByCreatedAt().Offset(m.Page * m.PageSize).Limit(m.PageSize).All(&orderCards) if err != nil && err != RecordNotFound { logger.Error("err:", err) return orderCards, 0, err } totalPage = uint32(count/m.PageSize + 1) fmt.Println("orderCards:", orderCards) orderCards = OrderCardListSetGameInfo(orderCards) return orderCards, totalPage, nil } func (m *Order) Info(orderCardId uint32) ([]OrderCard, error) { //err := NewOrderQuerySet(DB).IDEq(m.ID).One(&order) //if err != nil { // logger.Error("err:", err) // return nil, err //} // //err = NewGameCardQuerySet(DB).IDEq(uint32(order.GameCardId)).One(&card) //if err != nil && err != RecordNotFound { // logger.Error("err:", err) // return nil, err //} qs := NewOrderCardQuerySet(DB).IDEq(orderCardId) //qs := NewOrderCardQuerySet(DB).OrderIdEq(m.ID).GameCardIdEq(uint32(m.GameCardId)) //if m.GameCardGoodsId != 0 { // qs = qs.GameCardGoodsIdEq(uint32(m.GameCardGoodsId)) //} var orderCards []OrderCard err := qs.All(&orderCards) if err != nil { logger.Error("err:", err) return nil, err } orderCards = OrderCardListSetGameInfo(orderCards) //info := order.ToInfo(&card) return orderCards, nil } func (m *Order) Revert() error { var ( orderCard OrderCard //card GameCard ) //qs := NewOrderQuerySet(DB).IDEq(m.ID) //err := qs.One(&order) //if err != nil { // logger.Error("err:%#v", err) // return err //} //if order.CardStatus == OrderCardStatusCompleted { // logger.Error("order card status completed") // return errors.New("order card status completed") //} //fmt.Println("GameCardGoodsId------:", m.GameCardGoodsId) //fmt.Println("ID------:", m.ID) //fmt.Println("OrderCardId------:", m.OrderCardId) err := NewOrderCardQuerySet(DB).IDEq(m.OrderCardId).One(&orderCard) //err := NewOrderCardQuerySet(DB).OrderIdEq(m.ID).GameCardGoodsIdEq(uint32(m.GameCardGoodsId)).One(&orderCard) if err != nil { logger.Errorf("err:%#v", err) return err } if orderCard.CardStatus == OrderCardStatusCompleted { logger.Error("order card status completed") return errors.New("order card status completed") } //err = qs.GetUpdater(). // SetCardStatus(OrderCardStatusReturning). // SetRevertTime(time.Now()). // SetRevertStoreId(m.RevertStoreId). // SetRevertExpressCompany(m.RevertExpressCompany). // SetRevertExpressCompanyNo(m.RevertExpressCompanyNo). // SetRevertExpressNo(m.RevertExpressNo).Update() //if err != nil { // logger.Error("err:", err) // return nil, err //} //order.CardStatus = OrderCardStatusReturning ////order.RevertTime = time.Now() //order.RevertStoreId = m.RevertStoreId //order.RevertExpressCompany = m.RevertExpressCompany //order.RevertExpressCompanyNo = m.RevertExpressCompanyNo //order.RevertExpressNo = m.RevertExpressNo _, err = NewOrderCardQuerySet(DB).IDEq(m.OrderCardId).GetUpdater(). //_, err = NewOrderCardQuerySet(DB).OrderIdEq(m.ID).GameCardGoodsIdEq(uint32(m.GameCardGoodsId)).GetUpdater(). SetCardStatus(OrderCardStatusReturning). SetRevertTime(time.Now()). SetRevertStoreId(m.RevertStoreId). SetRevertExpressCompany(m.RevertExpressCompany). SetRevertExpressCompanyNo(m.RevertExpressCompanyNo). SetRevertExpressNo(m.RevertExpressNo).UpdateNum() if err != nil { logger.Error("err:", err) return err } //err = NewGameCardQuerySet(DB).IDEq(uint32(order.GameCardId)).One(&card) //if err != nil && err != RecordNotFound { // logger.Error("err:", err) // return nil, err //} //info := order.ToInfo(&card) return nil } func (m *Order) RevertCancel() (bool, error) { var ( orderCard OrderCard //card GameCard ) //qs := NewOrderQuerySet(DB).IDEq(m.ID) //err := qs.One(&order) //if err != nil { // logger.Error("err:%#v", err) // return false, err //} //if order.CardStatus != OrderCardStatusReturning { // logger.Error("order card status completed") // return false, errors.New("order card status completed") //} err := NewOrderCardQuerySet(DB).IDEq(m.OrderCardId).One(&orderCard) //err := NewOrderCardQuerySet(DB).OrderIdEq(m.ID).GameCardGoodsIdEq(uint32(m.GameCardGoodsId)).One(&orderCard) if err != nil { logger.Errorf("err:%#v", err) return false, err } if orderCard.CardStatus != OrderCardStatusReturning { logger.Error("order card status returning") return false, errors.New("order card status returning") } //err = qs.GetUpdater(). // SetCardStatus(OrderCardStatusPlaying). // SetRevertStoreId(0). // SetRevertExpressCompany(""). // SetRevertExpressCompanyNo(""). // SetRevertExpressNo("").Update() //if err != nil { // logger.Error("err:", err) // return nil, err //} //order.CardStatus = OrderCardStatusCancel ////order.RevertTime = time.Now() //order.RevertStoreId = m.RevertStoreId //order.RevertExpressCompany = m.RevertExpressCompany //order.RevertExpressCompanyNo = m.RevertExpressCompanyNo //order.RevertExpressNo = m.RevertExpressNo _, err = NewOrderCardQuerySet(DB).IDEq(m.OrderCardId).GetUpdater(). //_, err = NewOrderCardQuerySet(DB).OrderIdEq(m.ID).GameCardGoodsIdEq(uint32(m.GameCardGoodsId)).GetUpdater(). SetCardStatus(OrderCardStatusPlaying). //SetRevertTime(time.Time{}). SetRevertStoreId(0). SetRevertExpressCompany(""). SetRevertExpressCompanyNo(""). SetRevertExpressNo("").UpdateNum() if err != nil { logger.Error("err:", err) return false, err } isRecede := false //if order.DeliveryType == 2 && order.Postage > 0 { // isHaveOnDeliver, err := IsHaveOnDeliverOrderCards(m.ID) // if err != nil { // logger.Error("err:", err) // return false, err // } // if !isHaveOnDeliver { // isRecede = true // } //} //info := order.ToInfo(&card) return isRecede, nil } func (m *Order) OrderCreate(gdb *gorm.DB) error { err := m.Create(gdb) if err != nil { logger.Error("err:", err) return err } return nil } func (m *Order) Modify() (*OrderInfo, error) { if m.ID == 0 { return nil, errors.New("orderId is null") } fields := make([]OrderDBSchemaField, 0) if m.CardStatus != 0 { fields = append(fields, OrderDBSchema.CardStatus) } if len(fields) > 0 { err := m.Update(DB.Where(&Order{Model: Model{ID: m.ID}, Uid: m.Uid}), fields...) if err != nil { logger.Error("err:", err) return nil, err } } var card GameCard err := NewGameCardQuerySet(DB).IDEq(uint32(m.GameCardId)).One(&card) if err != nil && err != RecordNotFound { logger.Error("err:", err) return nil, err } info := m.ToInfo(&card) return &info, nil } func (m *UserRentCard) IsHaveUnreturnedOrders(RentCount uint32) (bool, error) { fmt.Println("uid", m.Uid) sql := fmt.Sprintf("SELECT COUNT(order_card.id) FROM `order` RIGHT JOIN order_card ON `order`.id = order_card.order_id WHERE `order`.uid=%d AND `order`.pay_status=2 AND order_card.card_status IN (1,2,3) ;", m.Uid) //sql := fmt.Sprintf("SELECT COUNT(*) AS count FROM `order` WHERE uid = %d AND pay_status=2 AND card_status IN (1,2,3) ;", m.Uid) //sql := fmt.Sprintf("SELECT COUNT(*) AS count FROM `order` WHERE uid = %d AND pay_status=2 AND card_status IN (1,2,3) ;", uid) //count, err := NewOrderQuerySet(DB).UidEq(uint64(uid)).PayStatusEq(PayStatusPaid).CardStatusIn(1, 2, 3).Count() //if err != nil { // logger.Error("err:", err) // return false, err //} unreturned := &struct { Count int `json:"count"` }{} err := DB.Raw(sql).Scan(unreturned).Error if err != nil { logger.Error("err:", err) return false, err } fmt.Println("订单数量count:", unreturned.Count) return uint32(unreturned.Count)+RentCount > m.LevelRentCount, nil } func IsHaveOnDeliverOrderCards(orderId uint32) (bool, error) { count, err := NewOrderCardQuerySet(DB).OrderIdEq(orderId).CardStatusEq(OrderCardStatusUnPick).Count() if err != nil { logger.Error("err:", err) return false, err } return count > 0, nil } func IsUserHaveUnreturnedOrder(uid uint32) (bool, error) { fmt.Println("uid", uid) //sql := fmt.Sprintf("SELECT COUNT(*) AS count FROM `order` WHERE uid = %d AND pay_status IN (1,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 (2) AND card_status IN (1,2,3) ;", uid) //count, err := NewOrderQuerySet(DB).UidEq(uint64(uid)).PayStatusEq(PayStatusPaid).CardStatusIn(1, 2, 3).Count() //if err != nil { // logger.Error("err:", err) // return false, err //} unreturned := &struct { Count int `json:"count"` }{} DB.Raw(sql).Scan(unreturned) fmt.Println("订单数量count:", unreturned.Count) return unreturned.Count != 0, nil } // gen:qs type ExpressCompany struct { Model CompanyName string `json:"company_name"` CompanyCode string `json:"company_code"` } func (*ExpressCompany) TableName() string { return "express_company" } func (*ExpressCompany) List() ([]ExpressCompany, error) { companys := make([]ExpressCompany, 0) err := NewExpressCompanyQuerySet(DB).OrderAscByID().All(&companys) if err != nil && err != RecordNotFound { logger.Error("err:", err) return companys, err } return companys, nil } func GetPickupCode() string { for { rand.Seed(time.Now().UnixNano()) code := fmt.Sprintf("%d", rand.Intn(1000000)+100000) count, err := NewOrderQuerySet(DB).PickupCodeEq(code).Count() if err != nil { logger.Error("err:", err) } if count == 0 { return code } } //将时间戳设置成种子数 } func GetShareCardRetrievePickupCode() string { for { rand.Seed(time.Now().UnixNano()) code := fmt.Sprintf("%d", rand.Intn(1000000)+100000) //count, err := NewOrderQuerySet(DB).PickupCodeEq(code).Count() count, err := NewShareCardRetrieveQuerySet(DB).PickupCodeEq(code).Count() if err != nil { logger.Error("err:", err) } if count == 0 { return code } } //将时间戳设置成种子数 } func (m *Order) Cancel() (bool, Order, error) { var ( order Order orderCard OrderCard ) err := NewOrderQuerySet(DB).IDEq(m.ID).One(&order) if err != nil { logger.Error("err:", err) return false, order, err } orderJson, _ := json.Marshal(m) fmt.Println("orderJson:", string(orderJson)) err = NewOrderCardQuerySet(DB).IDEq(m.OrderCardId).One(&orderCard) //err = NewOrderCardQuerySet(DB).OrderIdEq(m.ID).GameCardIdEq(uint32(m.GameCardId)).CardStatusEq(OrderCardStatusUnPick).Limit(1).One(&orderCard) if err != nil && err != RecordNotFound { logger.Errorf("err:%#v", err) return false, order, err } if err == RecordNotFound { logger.Error("order card status not unpick") return false, order, errors.New("order card status not unpick") } if orderCard.CardStatus != OrderCardStatusUnPick { logger.Error("order card status not unpick") return false, order, errors.New("order card status not unpick") } //if userOrder.CardStatus != OrderCardStatusUnPick { // logger.Error("card status not unpick err: ") // return false,errors.New("card status not unpick") //} //if userOrder.PayStatus == PayStatusUnPay && userOrder.CreatedAt.Add(30*time.Minute).Before(time.Now()) { // //if userOrder.PayStatus == PayStatusUnPay && userOrder.CreatedAt.Add(3*time.Minute).Before(time.Now()) { // logger.Error("card status expire err: ") // return errors.New("card status expire") //} //fmt.Println("PayStatus",userOrder.PayStatus) //fmt.Println("DeliveryType",userOrder.DeliveryType) //fmt.Println("CreatedAt",userOrder.CreatedAt.Add(4*time.Minute)) //fmt.Println("Now",time.Now()) //if userOrder.PayStatus == PayStatusPaid && userOrder.DeliveryType == DeliveryTypeStorePick && userOrder.CreatedAt.Add(24*time.Hour).Before(time.Now()) { // //if userOrder.PayStatus == PayStatusPaid && userOrder.DeliveryType == DeliveryTypeStorePick && userOrder.CreatedAt.Add(4*time.Minute).Before(time.Now()) { // logger.Error("card status expire err: ") // return errors.New("card status expire") //} begin := DB.Begin() //err = NewOrderQuerySet(begin).IDEq(orderCard.OrderId).GetUpdater().SetCardStatus(OrderCardStatusCancel).Update() //if err != nil { // begin.Rollback() // logger.Error("err:", err) // return false,err //} _, err = NewOrderCardQuerySet(DB).IDEq(orderCard.ID).GetUpdater().SetCardStatus(OrderCardStatusCancel).UpdateNum() if err != nil { begin.Rollback() logger.Error("err:", err) return false, order, err } sql := fmt.Sprintf("UPDATE game_card_goods_stock SET rent_stock= rent_stock+1 WHERE store_id=%d AND game_card_id=%d;", orderCard.StoreId, orderCard.GameCardId) fmt.Println("sql:", sql) err = begin.Exec(sql).Error if err != nil { begin.Rollback() logger.Errorf("err:%#v", err) return false, order, err } //UserRentCard{} sqlRent := fmt.Sprintf("UPDATE user_rent_card SET have_rent_count = have_rent_count-1,can_rent_count=can_rent_count+1 WHERE uid =%d;", order.Uid) fmt.Println("sqlRent:", sqlRent) err = begin.Exec(sqlRent).Error if err != nil { begin.Rollback() logger.Errorf("err:%#v", err) return false, order, err } err = begin.Commit().Error if err != nil { begin.Rollback() logger.Errorf("err:%#v", err) return false, order, err } isHaveOnDeliver, err := IsHaveOnDeliverOrderCards(m.ID) if err != nil { logger.Error("err:", err) return false, order, err } if !isHaveOnDeliver { err = NewOrderQuerySet(DB).IDEq(order.ID).GetUpdater().SetCardStatus(OrderCardStatusCancel).Update() if err != nil { logger.Error("err:", err) return false, order, err } } isRecede := false if order.DeliveryType == 2 && order.Postage > 0 { if !isHaveOnDeliver { isRecede = true } } if order.DeliveryType == 2 { UpdateDeliverTaskSubStateCancel(order.ID) } //m.ID = order.ID //m.Uid = order.Uid //m.PayPrice = order.PayPrice return isRecede, order, nil } func UnPayOrderSetCancel(uid uint32) { fmt.Println("uid:", uid) var order Order err := NewOrderQuerySet(DB.Debug()).UidEq(uint64(uid)).PayStatusEq(PayStatusUnPay).CardStatusEq(OrderCardStatusUnPick).One(&order) if err != nil { logger.Error("err:", err) return } fmt.Println("Order:", order) begin := DB.Begin() _, err = NewOrderQuerySet(begin).IDEq(order.ID).GetUpdater(). SetCardStatus(OrderCardStatusCancel).UpdateNum() if err != nil { begin.Rollback() logger.Error("err:", err) return } sql := fmt.Sprintf("UPDATE game_card_goods_stock SET rent_stock= rent_stock+1 WHERE store_id=%d AND game_card_id=%d;", order.StoreId, order.GameCardId) fmt.Println("sql:", sql) err = begin.Exec(sql).Error if err != nil { begin.Rollback() logger.Error("err:", err) return } err = begin.Commit().Error if err != nil { begin.Rollback() logger.Error("err:", err) } } //func (m *Order) CreateByCardInfoList(cardInfos []CardInfo, gdb *gorm.DB) error { // err := gdb.Create(m).Error // if err != nil { // logger.Error("err:", err) // return err // } // if m.ID == 0 { // return errors.New("order id is 0") // } // for _, v := range cardInfos { // for i := 0; i < int(v.Count); i++ { // //OrderCard{ // // OrderId: m.ID, // // Uid: uint32(m.Uid), // // GameCardId: v.GameCardId, // // GameCardGoodsId: 0, // // StoreId: uint32(m.StoreId), // // Status: 0, // //} // } // // } // // return nil //} func IsCardGoodsStockEnough(cards []CardInfo, storeId uint32) (bool, error) { for i, _ := range cards { var gameCardGoodsStock GameCardGoodsStock err := NewGameCardGoodsStockQuerySet(DB).StoreIdEq(uint64(storeId)).GameCardIdEq(uint64(cards[i].GameCardId)). One(&gameCardGoodsStock) if err != nil && err != RecordNotFound { logger.Error("err:", err) return false, err } if err == RecordNotFound { logger.Error("order stock out:") return false, err } if gameCardGoodsStock.RentStock < cards[i].Count { logger.Error("order stock out ") return false, errors.New("order stock out") } } return false, nil } func GameCardGoodsInventoryReduction(cards []CardInfo, storeId uint32, gdb *gorm.DB) error { for i, _ := range cards { sql := fmt.Sprintf( "UPDATE game_card_goods_stock SET rent_stock= rent_stock-%d WHERE store_id=%d AND game_card_id=%d;", cards[i].Count, storeId, cards[i].GameCardId) fmt.Println("sql:", sql) err := gdb.Exec(sql).Error if err != nil { logger.Error("err:", err) return err } } return nil } func (m *Order) InventoryReduction(gdb *gorm.DB) error { var cards []OrderCard err := NewOrderCardQuerySet(DB).UidEq(uint32(m.Uid)).OrderIdEq(m.ID).All(&cards) if err != nil { logger.Error("err:", err) return err } //fmt.Println("cards:", cards) for i, _ := range cards { var gameCardGoodsStock GameCardGoodsStock err := NewGameCardGoodsStockQuerySet(DB).GameCardIdEq(uint64(cards[i].GameCardId)).StoreIdEq(m.StoreId).One(&gameCardGoodsStock) if err != nil { logger.Error("err:", err) return err } //fmt.Println("cards:", cards[i].GameCardId, cards[i].StoreId, cards[i].Uid) if gameCardGoodsStock.RentStock < 1 { logger.Error("rent stock not enough:") return errors.New("rent stock not enough") } sql := fmt.Sprintf("UPDATE game_card_goods_stock SET rent_stock= rent_stock-1 WHERE store_id=%d AND game_card_id=%d;", m.StoreId, cards[i].GameCardId) fmt.Println("sql:", sql) err = gdb.Exec(sql).Error if err != nil { logger.Error("err:", err) return err } } err = OrderCardUserRentCard(uint32(m.Uid), uint32(len(cards)), nil, gdb) if err != nil { logger.Error("err:", err) } return nil } func (m *Order) CreatOrderCard(cards []CardInfo, storeId uint32, gdb *gorm.DB) error { for _, v := range cards { for i := 0; i < int(v.Count); i++ { orderCard := &OrderCard{ OrderId: m.ID, Uid: uint32(m.Uid), GameCardId: v.GameCardId, GameCardGoodsId: 0, StoreId: storeId, CardStatus: OrderCardStatusUnPick, DeliveryTime: time.Time{}, ReceiptTime: time.Time{}, DeliveryType: m.DeliveryType, SerialNumber: "", PayStatus: m.PayStatus, IssueType: 2, CooperativeBusinessId: m.CooperativeBusinessId, CooperativeName: m.CooperativeName, } err := gdb.Create(orderCard).Error if err != nil { logger.Error("err:", err) return err } } } return nil } type RecordExist struct { RecordExist int64 `json:"record_exist"` } func QueryRecordExist(sql string) (bool, error) { var recordExist RecordExist existSql := fmt.Sprintf("SELECT EXISTS (%s) AS record_exist;", sql) err := DB.Raw(existSql).Scan(&recordExist).Error if err != nil { logger.Error("err:", err) return false, err } return recordExist.RecordExist == 1, nil } type CooperativeRentCardOrderReq struct { SerialNumber string `json:"serial_number" ` // 编号 PickupCode string `json:"pickup_code"` // 取货码 OrderId uint32 `json:"order_id"` // 取货码 } func (m *CooperativeRentCardOrderReq) Info() (Order, error) { var order Order if m.PickupCode != "" { err := NewOrderQuerySet(DB).PickupCodeEq(m.PickupCode).PayStatusEq(PayStatusPaid). CardStatusEq(OrderCardStatusUnPick).One(&order) if err != nil { logger.Error("order err:", err) return order, err } } else if m.SerialNumber != "" { var orderCard OrderCard err := NewOrderCardQuerySet(DB).SerialNumberEq(m.SerialNumber).CardStatusIn(OrderCardStatusPlaying, OrderCardStatusReturning).One(&orderCard) if err != nil { logger.Error("order card err:", err) return order, err } err = NewOrderQuerySet(DB).IDEq(orderCard.OrderId).One(&order) if err != nil { logger.Error("order err:", err) return order, err } } else if m.OrderId != 0 { err := NewOrderQuerySet(DB).IDEq(m.OrderId).One(&order) if err != nil { logger.Error("order err:", err) return order, err } } else { return order, errors.New("parameter_err") } var orderCards []OrderCard err := NewOrderCardQuerySet(DB).OrderIdEq(order.ID).All(&orderCards) if err != nil { logger.Error("order card err:", err) return order, err } var store Store err = NewStoreQuerySet(DB).IDEq(uint32(order.StoreId)).One(&store) if err != nil { logger.Error("store err:", err) return order, err } if order.UserAddressId != 0 { var address UserAddress err = NewUserAddressQuerySet(DB).IDEq(uint32(order.UserAddressId)).One(&address) if err != nil { logger.Error("address err:", err) return order, err } order.UserAddress = &address } order.Store = &store order.OrderCards = CooperativeOrderCardListSetInfo(orderCards) return order, nil } func CooperativeOrderCardListSetInfo(list []OrderCard) []OrderCard { ids := make([]uint32, 0, len(list)) storeIds := make([]uint32, 0, len(list)) for i, _ := range list { ids = append(ids, list[i].GameCardId) storeIds = append(storeIds, uint32(list[i].RevertStoreId)) } if len(ids) == 0 { return list } cardMap, err := GameCardMap(ids) if err != nil { logger.Error("game card map err:", err) return list } storeMap, err := GetStoreMap(storeIds) if err != nil { logger.Error("store map err:", err) return list } for i, _ := range list { gameCard, ok1 := cardMap[list[i].GameCardId] if ok1 { list[i].GameName = gameCard.Name list[i].GameCoverImg = gameCard.CoverImg list[i].GamePrice = gameCard.Price } revertStore, ok2 := storeMap[uint32(list[i].RevertStoreId)] if ok2 { list[i].RevertStore = &revertStore } } return list } func GetStoreMap(ids []uint32) (map[uint32]Store, error) { storeMap := make(map[uint32]Store, 0) if len(ids) == 0 { return storeMap, nil } var stores []Store err := NewStoreQuerySet(DB).IDIn(ids...).All(&stores) if err != nil { logger.Error("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 *Order) GetById() error { err := NewOrderQuerySet(DB).IDEq(m.ID).One(m) if err != nil { logger.Error("get order err") return err } return nil } func (m *Order) SetUnPickOrderCards() error { var cards []OrderCard err := NewOrderCardQuerySet(DB).OrderIdEq(m.ID).CardStatusEq(OrderCardStatusUnPick).All(&cards) if err != nil { logger.Error("get order err") return err } m.OrderCards = cards return nil } func (m *Order) SetOrderCards() error { var cards []OrderCard err := NewOrderCardQuerySet(DB).OrderIdEq(m.ID).All(&cards) if err != nil { logger.Error("get order err") return err } m.OrderCards = cards return nil } func (m *Order) GetOrderCardMap() (map[string]OrderCard, error) { cardMap := make(map[string]OrderCard, 0) err := m.SetOrderCards() if err != nil { logger.Error("order card err:", err) return cardMap, err } for i, _ := range m.OrderCards { cardMap[m.OrderCards[i].SerialNumber] = m.OrderCards[i] } return cardMap, nil } type CooperativeRentCardOrderDeliverReq struct { OrderId uint32 `json:"order_id"` SerialNumbers []string `json:"serial_numbers"` StoreId uint32 `json:"store_id"` ExpressCompany string `json:"express_company"` ExpressCompanyNo string `json:"express_company_no"` ExpressNo string `json:"express_no"` OperationUid uint32 `json:"operation_uid"` } func (m *CooperativeRentCardOrderDeliverReq) Deliver() (error, string) { order := new(Order) order.ID = m.OrderId err := order.GetById() if err != nil && err != RecordNotFound { logger.Error("err:", err) return err, "" } err = order.SetUnPickOrderCards() if err != nil { logger.Error("err:", err) return err, "" } if len(m.SerialNumbers) != len(order.OrderCards) || len(m.SerialNumbers) == 0 { logger.Error("发货卡的数量与订单游戏卡数量不一致") return errors.New("发货卡的数量与订单游戏卡数量不一致"), "发货卡的数量与订单游戏卡数量不一致" } user := GetUserByUid(uint32(order.Uid)) if user.MemberExpire.Before(time.Now()) { logger.Error("会员已过期,不能发货") return errors.New("会员已过期,不能发货"), "会员已过期,不能发货" } orderCardMaps := make(map[uint32]OrderCard, 0) for i, _ := range order.OrderCards { orderCardMaps[order.OrderCards[i].ID] = order.OrderCards[i] } receiptTime := time.Time{} if order.DeliveryType == 1 { receiptTime = time.Now() } serialNumberMap := make(map[string]GameCardGoods, 0) var serialGoods []GameCardGoods err = NewGameCardGoodsQuerySet(DB).SerialNumberIn(m.SerialNumbers...).All(&serialGoods) if err != nil { logger.Error("serial goods err:", err) return err, "" } for i, _ := range serialGoods { serialNumberMap[serialGoods[i].SerialNumber] = serialGoods[i] } isUpdateOrder := false begin := DB.Begin() for _, serialNumber := range m.SerialNumbers { if serialNumber == "" { continue } gameCardGoods, ok := serialNumberMap[serialNumber] if !ok { 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"), "该卡状态,不能发货" } if order.CardStatus != OrderCardStatusUnPick { begin.Rollback() logger.Error("order not unpick") return errors.New("order not unpick"), "订单不是待取货状态" } if order.PayStatus != PayStatusPaid { begin.Rollback() logger.Error("order not pay") return errors.New("order not pay"), "订单未支付" } orderCard := GetOrderCardMapSerialNumberUnset(orderCardMaps, uint32(gameCardGoods.GameCardId)) if orderCard == nil { begin.Rollback() logger.Error("发货游戏卡错误") return errors.New("发货游戏卡错误"), "发货游戏卡错误" } if m.StoreId != uint32(gameCardGoods.StoreId) { begin.Rollback() logger.Error("游戏编号卡不是该门店") return errors.New("游戏编号卡不是该门店"), "该门店没有改游戏卡" } if (m.StoreId) != orderCard.StoreId { begin.Rollback() // 订单锁库存 logger.Error("订单门店与发货门店不一致") return errors.New("订单门店与发货门店不一致"), "订单门店与发货门店不一致,请取消订单后重新下单" } paraMap := make(map[string]interface{}, 0) //paraMap["game_card_serial_number"] = serialNumber 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.OrderId).Updates(paraMap).Error if err != nil { begin.Rollback() logger.Error("err:", err) return err, "" } isUpdateOrder = true } var eg errgroup.Group eg.Go(func() error { err := begin.Table("game_card_goods").Where("serial_number=?", serialNumber). Update("status", GameCardGoodsStatusCustomerHold).Error if err != nil { begin.Rollback() logger.Error("err:", err) return err } return nil }) eg.Go(func() error { goodsStock := &GameCardGoodsStock{ StoreId: uint64(m.StoreId), GameCardId: gameCardGoods.GameCardId, } err = goodsStock.AddUserHoldStock(begin) if err != nil { begin.Rollback() logger.Error("err:", err) return err } return nil }) eg.Go(func() error { user := GetUserByUid(uint32(order.Uid)) if user.StoreId == 0 { sql := fmt.Sprintf("UPDATE `user` SET store_id = %d WHERE uid =%d", order.StoreId, order.Uid) err := DB.Exec(sql).Error if err != nil { logger.Error("err:", err) return err } } return nil }) eg.Go(func() 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, }).Error if err != nil { begin.Rollback() logger.Error("err:", err) return err } delete(orderCardMaps, orderCard.ID) return nil }) err = eg.Wait() if err != nil { begin.Rollback() logger.Error("err:", err) return err, "" } } err = begin.Commit().Error if err != nil { begin.Rollback() logger.Error("err:", err) return err, "" } err = DB.Table("order_card").Where("order_id=?", m.OrderId).Where("uid=?", order.Uid). Where("serial_number=''").Updates(&map[string]interface{}{ "card_status": 5, }).Error if err != nil { logger.Error("err:", err) return err, "" } go func() { if m.ExpressCompanyNo != "" && m.ExpressNo != "" { _, err = kuaidi.SubscribeExpressState(m.ExpressCompanyNo, m.ExpressNo) if err != nil { logger.Error("subscribe express state err:", err) } } operationLog := &OperationLog{ Uid: m.OperationUid, Description: "借卡发货", OperationType: OperationTypeRentCardDeliver, CorrelationId: order.ID, CorrelationName: LogCorrelationOrderId, StoreId: m.StoreId, StoreName: "", CooperativeName: "", //SerialNumber: m.SerialNumber, } operationLog.AddLog() }() return nil, "" } type CooperativeRentCardOrderRevertReq struct { OrderId uint32 `json:"order_id"` SerialNumber string `json:"serial_number"` RevertStoreId uint32 `json:"revert_store_id"` OperationUid uint32 `json:"operation_uid"` } func (m *CooperativeRentCardOrderRevertReq) Revert() error { order := new(Order) order.ID = m.OrderId err := order.GetById() if err != nil { logger.Error("get order err:", err) return err } cardMap, err := order.GetOrderCardMap() if err != nil { logger.Error("err:", err) return err } orderCardIds := make([]uint32, 0, len(cardMap)) orderCardIdString := "" for _, card := range cardMap { orderCardIds = append(orderCardIds, card.ID) orderCardIdString += fmt.Sprintf("%d,", card.ID) } recordExist, err := QueryRecordExist(fmt.Sprintf( "SELECT * FROM card_issue_feedback WHERE state='%s' AND relevance_id in (%s)", CardIssueStateFollowing, orderCardIdString[:len(orderCardIdString)-1])) if err != nil { logger.Errorf("err:%#v", err) return err } if recordExist { logger.Error("untreated_issue_feedback") return errors.New("untreated_issue_feedback") } serialNumber := m.SerialNumber 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 ") } gameCardGoods, err := GetGameCardGoodsBySerialNumber(serialNumber) if err != nil { logger.Errorf("err:%#v", 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") } begin := DB.Begin() var eg errgroup.Group eg.Go(func() error { goodsStatus := GameCardGoodsStatusStock if gameCardGoods.Status == 7 { goodsStatus = GameCardGoodsStatusUnusual } err := begin.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 { begin.Rollback() logger.Error("err:", err) return err } return nil }) eg.Go(func() error { if uint32(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 = begin.Exec(sqlStore).Error if err != nil { begin.Rollback() logger.Error("err:", err) return err } var count int64 err := DB.Table("game_card_goods_stock").Where("store_id=?", m.RevertStoreId). Where("game_card_id=?", gameCardGoods.GameCardId).Count(&count).Error if err != nil { begin.Rollback() logger.Error("err:", err) return err } if count == 0 && (gameCardGoods.Status != 7 || gameCardGoods.FunctionState != 1) { goodsStock := &GameCardGoodsStock{ StoreId: uint64(m.RevertStoreId), GameCardId: gameCardGoods.GameCardId, StoreStock: 0, RentStock: 1, UserHoldStock: 0, OrderCount: 0, TotalStock: 1, } err := begin.Create(goodsStock).Error if err != nil { begin.Rollback() logger.Error("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 = begin.Exec(sql).Error if err != nil { begin.Rollback() logger.Error("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 = begin.Exec(sqlStore).Error if err != nil { begin.Rollback() logger.Error("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 = begin.Exec(sql).Error if err != nil { begin.Rollback() logger.Error("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 := begin.Exec(sql).Error if err != nil { begin.Rollback() logger.Error("err:", err) return err } } return nil }) eg.Go(func() error { err := begin.Table("order_card").Where("id=?", orderCard.ID).Updates(map[string]interface{}{ "card_status": OrderCardStatusCompleted, "revert_store_id": m.RevertStoreId, "revert_time": time.Now(), }).Error if err != nil { begin.Rollback() logger.Error("err:", err) return err } var count int64 err = DB.Table("order_card").Where("order_id=?", orderCard.OrderId). Where("card_status in (?)", []uint32{1, 2, 3}).Count(&count).Error if err != nil { begin.Rollback() logger.Error("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 { begin.Rollback() logger.Error("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 { begin.Rollback() logger.Error("err:", err) return err } return nil }) err = eg.Wait() if err != nil { begin.Rollback() logger.Error("err:", err) return err } err = begin.Commit().Error if err != nil { begin.Rollback() logger.Error("err:", err) return err } operationLog := &OperationLog{ Uid: m.OperationUid, Description: "借卡归还入库", OperationType: OperationTypeRentCardRevert, CorrelationId: orderCard.ID, CorrelationName: LogCorrelationOrderCard, StoreId: m.RevertStoreId, StoreName: "", CooperativeName: "", SerialNumber: m.SerialNumber, } operationLog.AddLog() return nil }