package jyy import ( "errors" "fmt" "recook/internal/model/order_preview" user2 "recook/internal/model/user" "recook/internal/v2/model/jyy" goods2 "recook/internal/v2/model/recook/goods" "recook/internal/v2/model/recook/user" "time" "github.com/golangkit/formatime" "github.com/shopspring/decimal" "gorm.io/gorm" "git.oa00.com/go/mysql" ) type logic struct { } var Logic = logic{} func (o logic) Banners() (res []jyy.Banner, err error) { now := time.Now() mysql.Db.Where("start < ?", now).Where("end > ?", now).Order("order_sort asc").Order("id desc").Find(&res) return } func (o logic) Activities() (res []jyy.Activity, err error) { mysql.Db.Where("status = 1").Order("order_sort asc").Order("id desc").Find(&res) return } type ArgsEntryReq struct { UserID uint `json:"user_id"` } type ShopCartSku struct { ID uint `json:"id"` SkuID uint `json:"sku_id"` DiscountPrice decimal.Decimal `json:"discount_price"` SalePrice decimal.Decimal `json:"sale_price"` Quantity uint `json:"quantity"` Limit int `json:"limit"` Min int `json:"min"` SkuName string `json:"sku_name"` GoodsName string `json:"goods_name,omitempty"` SalePublish uint `json:"sale_publish"` PicUrl string `json:"pic_url"` GoodsID uint `json:"goods_id"` } type ShopCartEntry struct { GoodsID uint `json:"goods_id"` GoodsName string `json:"goods_name"` MainPhoto string `json:"main_photo"` SkuList []ShopCartSku `json:"sku_list"` SalePublish uint `json:"sale_publish"` } func (o logic) ShopCartEntries(args ArgsEntryReq) (res []ShopCartSku) { sc := make([]jyy.ShopCartEntry, 0) mysql.Db.Model(&jyy.ShopCartEntry{}).Where("user_id = ?", args.UserID).Find(&sc) ids := make([]uint, 0) idsMap := make(map[uint]uint) skuMap := make(map[uint]uint) for _, v := range sc { ids = append(ids, v.SkuID) idsMap[v.SkuID] = v.Quantity skuMap[v.SkuID] = v.ID } var u1 user.RecookUserInfoModel mysql.Db.First(&u1, "id = ?", args.UserID) skuList := make([]goods2.RecookGoodsSkuModel, 0) mysql.Db.Preload("GoodsInfo").Where("id in (?)", ids).Find(&skuList) for _, v := range skuList { res = append(res, ShopCartSku{ ID: skuMap[v.Id], SkuID: v.Id, DiscountPrice: v.DiscountPrice, SalePrice: v.GetSalePrice(u1.Level), Quantity: idsMap[v.Id], Limit: v.Limit, Min: v.Min, SkuName: v.Name, PicUrl: v.PicURL, SalePublish: v.GoodsInfo.SalePublish, GoodsName: v.GoodsInfo.GoodsName, GoodsID: v.GoodsId, }) } // goodsMap := make(map[uint][]ShopCartSku) // for _, v := range skuList { // goodsMap[v.GoodsId] = append(goodsMap[v.GoodsId], ShopCartSku{ // ID: skuMap[v.Id], // SkuID: v.Id, // DiscountPrice: v.DiscountPrice, // SalePrice: v.GetSalePrice(u1.Level), // Quantity: idsMap[v.Id], // Limit: v.Limit, // Min: v.Min, // SkuName: v.Name, // }) // } // inRes := make(map[uint]bool) // for _, v := range skuList { // if inRes[v.GoodsId] { // continue // } // inRes[v.GoodsId] = true // res = append(res, ShopCartEntry{ // GoodsID: v.GoodsId, // GoodsName: v.GoodsInfo.GoodsName, // MainPhoto: v.GoodsInfo.MainPhoto.Url, // SkuList: goodsMap[v.GoodsId], // SalePublish: v.GoodsInfo.SalePublish, // }) // } return } type skuEntry struct { SkuID uint `json:"sku_id"` Quantity int `json:"quantity"` } type ArgsAddSku struct { UserID uint `json:"user_id"` IsUpdate bool SkuList []skuEntry `json:"sku_list" validate:"required,gte=1"` } func (o logic) ShopCartAddSku(args ArgsAddSku) (err error) { var skuList []goods2.RecookGoodsSkuModel ids := make([]uint, 0) idMap := make(map[uint]int) for _, v := range args.SkuList { ids = append(ids, v.SkuID) idMap[v.SkuID] = v.Quantity } mysql.Db.Preload("GoodsInfo").Find(&skuList, "id in (?)", ids) if len(skuList) != len(ids) { return errors.New("商品选择错误") } for _, v := range skuList { if v.GoodsInfo.SalePublish != 1 { return fmt.Errorf("%d商品下架", v.GoodsId) } if !v.GoodsInfo.IsSale { return fmt.Errorf("%d商品不可批发", v.GoodsId) } if idMap[v.Id] < v.Min { return fmt.Errorf("%s商品最低%d", v.Name, v.Min) } if idMap[v.Id]%v.Limit != 0 { return fmt.Errorf("%s商品每手至少%d", v.Name, v.Min) } } data := make([]jyy.ShopCartEntry, 0) mysql.Db.Find(&data, "user_id = ?", args.UserID) isUsed := make(map[uint]bool) for _, v := range data { if idMap[v.SkuID] != 0 { if args.IsUpdate { v.Quantity = uint(idMap[v.SkuID]) } else { v.Quantity += uint(idMap[v.SkuID]) } mysql.Db.Save(v) isUsed[v.SkuID] = true } } res := make([]jyy.ShopCartEntry, 0) for _, v := range skuList { if isUsed[v.Id] { continue } res = append(res, jyy.ShopCartEntry{ SkuID: v.Id, GoodsID: v.GoodsId, UserID: args.UserID, Quantity: uint(idMap[v.Id]), }) } if len(res) == 0 { return nil } if err = mysql.Db.Create(&res).Error; err != nil { return err } return } func (o logic) ShopCartDeleteSku(args ArgsAddSku) (err error) { ids := make([]uint, 0) for _, v := range args.SkuList { ids = append(ids, v.SkuID) } err = mysql.Db.Delete(&jyy.ShopCartEntry{}, "sku_id in (?)", ids).Error return } type OrderPreview struct { UserID uint `json:"user_id" validate:"required"` SkuList []skuEntry `json:"sku_list" validate:"required"` Channel uint `json:"channel" validate:"oneof=0 1"` } type OrderPreviewInfo struct { PreviewID uint `json:"preview_id"` Addr user2.Addr `json:"Addr"` SkuList []ShopCartSku `json:"sku_list"` Total decimal.Decimal `json:"total"` } func (o logic) OrderPreview(args OrderPreview) (err error, res OrderPreviewInfo) { var u1 user.RecookUserInfoModel if err = mysql.Db.First(&u1, "id = ?", args.UserID).Error; err != nil { return } if u1.Level < 2 || (u1.Level == 2 && !u1.IsOffline) { err = errors.New("用户权限不足") return } var skuList []goods2.RecookGoodsSkuModel ids := make([]uint, 0) idMap := make(map[uint]int) for _, v := range args.SkuList { ids = append(ids, v.SkuID) idMap[v.SkuID] = v.Quantity } mysql.Db.Preload("GoodsInfo.MainPhoto"). Preload("GoodsInfo.Brand"). Preload("GoodsInfo.FirstCategory"). Preload("GoodsInfo.SecondCategory"). Find(&skuList, "id in (?)", ids) if len(skuList) != len(ids) { err = errors.New("商品选择错误") return } for _, v := range skuList { if v.GoodsInfo.SalePublish != 1 { err = fmt.Errorf("%d商品下架", v.GoodsId) return } if !v.GoodsInfo.IsSale { err = fmt.Errorf("%d商品不可批发", v.GoodsId) return } if idMap[v.Id] < v.Min { err = fmt.Errorf("%s商品最低%d", v.Name, v.Min) return } if idMap[v.Id]%v.Limit != 0 { err = fmt.Errorf("%s商品每手至少%d", v.Name, v.Min) return } } goodsTotalAmount := decimal.Zero cost := decimal.Zero preOrderGoodsList := make([]order_preview.GoodsDetail, 0, 0) sl := make([]ShopCartSku, 0) for _, v := range skuList { if v.SalePurchasePrice.IsZero() { err = errors.New("价格异常") return } qu := decimal.NewFromInt(int64(idMap[v.Id])) goodsInfo := v.GoodsInfo one := order_preview.GoodsDetail{ VendorID: goodsInfo.VendorID, VendorName: "", BrandID: goodsInfo.BrandID, BrandName: goodsInfo.Brand.Name, CategoryName: goodsInfo.FirstCategory.Name + "/" + goodsInfo.SecondCategory.Name, GoodsID: goodsInfo.Id, GoodsName: goodsInfo.GoodsName, IsJoinTeamPerformance: goodsInfo.IsJoinTeamPerformance, Hash: goodsInfo.Hash, SkuID: v.Id, SkuName: v.Name, SkuCode: v.Code, MainPhotoURL: goodsInfo.MainPhoto.Url, Quantity: uint(idMap[v.Id]), FreightID: goodsInfo.FreightID, Weight: goodsInfo.Weight, PromotionSkuId: 0, PromotionGoodsId: 0, PromotionName: "", UnitPrice: v.GetSalePrice(u1.Level), PurchasePrice: v.SalePurchasePrice, TotalCommission: decimal.Zero, GoodsAmount: v.GetSalePrice(u1.Level).Mul(qu), IsImport: goodsInfo.IsImport, Storehouse: goodsInfo.Storehouse, IsFerme: goodsInfo.IsFerme, ActualAmount: v.GetSalePrice(u1.Level).Mul(qu), } sl = append(sl, ShopCartSku{ SkuID: v.Id, DiscountPrice: v.DiscountPrice, SalePrice: v.GetSalePrice(u1.Level), Quantity: uint(idMap[v.Id]), Limit: v.Limit, Min: v.Min, SkuName: v.Name, GoodsName: v.GoodsInfo.GoodsName, PicUrl: v.PicURL, }) preOrderGoodsList = append(preOrderGoodsList, one) goodsTotalAmount = goodsTotalAmount.Add(v.GetSalePrice(u1.Level).Mul(qu)) cost = cost.Add(v.PurchasePrice.Mul(qu)) } if goodsTotalAmount.LessThanOrEqual(decimal.Zero) { err = fmt.Errorf("订单价格异常") return } var defaultAddr user2.Addr { err = mysql.Db.First(&defaultAddr, "user_id = ? AND is_default = 1", args.UserID).Error if err != nil && err != gorm.ErrRecordNotFound { return } } if err = mysql.Db.Transaction(func(tx *gorm.DB) error { preOrderInfo := order_preview.Information{ AncestorID: 0, ParentID: 0, UserID: args.UserID, SharerID: 0, Title: skuList[0].GoodsInfo.GoodsName + "等多件", BrandCouponTotalAmount: decimal.Zero, UniverseCouponTotalAmount: decimal.Zero, CoinTotalAmount: decimal.Zero, ExpressTotalFee: decimal.Zero, GoodsTotalAmount: goodsTotalAmount, GoodsTotalCommission: decimal.Zero, ActualTotalAmount: goodsTotalAmount, Channel: args.Channel, Cost: cost, CreatedAt: formatime.NewSecondNow(), OrderType: 2, } if e := tx.Create(&preOrderInfo).Error; e != nil { return e } for i := range preOrderGoodsList { preOrderGoodsList[i].OrderID = preOrderInfo.ID } if e := tx.Create(&preOrderGoodsList).Error; e != nil { return e } preOrderAddr := order_preview.Addr{ OrderID: preOrderInfo.ID, AddressID: defaultAddr.ID, Province: defaultAddr.Province, City: defaultAddr.City, District: defaultAddr.District, Address: defaultAddr.Address, ReceiverName: defaultAddr.Name, Mobile: defaultAddr.Mobile, IsDeliveryArea: 1, } if e := tx.Create(&preOrderAddr).Error; e != nil { return e } res.PreviewID = preOrderInfo.ID res.Addr = defaultAddr res.SkuList = sl res.Total = goodsTotalAmount return nil }); err != nil { return } return } type OrderAddrUpdate struct { PreviewID uint `json:"preview_id"` AddressID uint `json:"address_id"` BuyerMessage string `json:"buyer_message"` } func (o logic) OrderUpdate(args OrderAddrUpdate) (err error) { var addr user2.Addr err = mysql.Db.First(&addr, "id = ?", args.AddressID).Error if err != nil { return } var previewOrderAddr order_preview.Addr err = mysql.Db.First(&previewOrderAddr, "order_id = ?", args.PreviewID).Error if err != nil { return } if err = mysql.Db.Transaction(func(tx *gorm.DB) error { if addr.ID > 0 { if e := tx.Model(&previewOrderAddr).Updates(map[string]interface{}{ "address_id": addr.ID, "province": addr.Province, "city": addr.City, "district": addr.District, "address": addr.Address, "receiver_name": addr.Name, "mobile": addr.Mobile, "is_delivery_area": 1, }).Error; e != nil { return e } } if e := tx.Table((&order_preview.Information{}).TableName()). Where("id = ?", args.PreviewID). Updates(map[string]interface{}{"buyer_message": args.BuyerMessage}).Error; e != nil { return e } return nil }); err != nil { return } return } func (o logic) Contact() (res jyy.Contact) { mysql.Db.First(&res) return }