package promotion import ( "fmt" "recook/internal/back" "recook/internal/dbc" "recook/internal/model/goods" "recook/internal/model/promotion" "recook/tools" "strconv" "time" "github.com/gin-gonic/gin" "github.com/golangkit/formatime" "github.com/shopspring/decimal" ) type createPromotionParam struct { Name string `json:"name" validate:"required"` StartDate string `json:"startDate" validate:"required" time_format:"2006-01-02"` EndDate string `json:"endDate" validate:"required" time_format:"2006-01-02"` TimeItems []timeItem `json:"timeItems" validate:"required"` IsSale bool `json:"is_sale"` } type timeItem struct { StartPoint int `json:"startPoint" validate:"required"` GoodsList []promotionGoods `json:"goodsList" validate:"required"` ActivitiesList []promotionActivites `json:"activitiesList"` } type promotionActivites struct { ActivityID uint `json:"activityId" validate:"numeric"` ActivitySortId uint `json:"activity_sort_id"` } type promotionGoods struct { GoodsID uint `json:"goodsId" validate:"required"` Subtitle string `json:"subtitle"` Order string `json:"order"` SkuList []promotionSku `json:"skuList" validate:"required"` } type promotionSku struct { SkuID uint `json:"skuId" validate:"required"` DiscountPrice float64 `json:"discountPrice" validate:"required"` Inventory uint `json:"inventory" validate:"required"` } func CreatePromotion(c *gin.Context) { var p createPromotionParam if err := tools.Params(&p, c); err != nil { back.Fail(c, err.Error()) return } if len(p.TimeItems) == 0 { back.Fail(c, "参数不完整") return } startDate, err := time.Parse("2006-01-02", p.StartDate) if err != nil { back.Fail(c, "日期无法解析") return } endDate, err := time.Parse("2006-01-02", p.EndDate) if err != nil { back.Fail(c, "日期无法解析") return } if startDate.Unix() > endDate.Unix() { back.Fail(c, "开始时间不能大于结束时间") return } // 判断日期提前 var count uint dbc.DB.Table((&promotion.Information{}).TableName()). Where("is_sale=?", p.IsSale).Where("start_date = ?", startDate.Format("2006-01-02")).Count(&count) if count > 0 { back.Fail(c, "该日期已创建过活动,请更改日期") return } endTime := time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 23, 59, 59, 0, time.Local) // // 先检测 // { // var promotionGoodsList []promotion.Goods // dbc.DB.Select("id, goods_id").Find(&promotionGoodsList, "start_time < ? AND end_time > ?", endTime, startTime) // ids := map[uint]uint{} // for _, v := range promotionGoodsList { // ids[v.GoodsID] = 1 // } // for _, v := range p.TimeItems { // for _, v2 := range v.GoodsList { // if _, ok := ids[v2.GoodsID]; ok { // back.Fail(c, "商品活动冲突") // return // } // } // if len(v.ActivitiesList) < 1 { // continue // } // } // } //for _, v := range p.TimeItems { // for _, g := range v.GoodsList { // var goodsSkuList []goods.Sku // dbc.DB.Select("id").Find(&goodsSkuList, "goods_id = ?", g.GoodsID) // for _, origin := range goodsSkuList { // 要看看每个sku都有填充数据 // aBool := false // for _, sku := range g.SkuList { // if origin.ID == sku.SkuID { // aBool = true // break // } // } // if aBool == false { // back.Fail(c, "sku不完整,商品ID为:"+fmt.Sprintf("%d", g.GoodsID)) // return // } // } // } //} formatEndTime := formatime.NewSecondFrom(endTime) tx := dbc.DB.Begin() { info := promotion.Information{ Name: p.Name, StartDate: formatime.NewDateFrom(startDate), EndDate: formatime.NewDateFrom(endDate), IsSale: p.IsSale, } if err := tx.Create(&info).Error; err != nil { back.Err(c, err.Error()) tx.Rollback() return } for _, v := range p.TimeItems { if v.StartPoint < 0 || v.StartPoint > 23 { back.Fail(c, "参数时间错误") tx.Rollback() return } startTime := formatime.NewSecondFrom(time.Date(startDate.Year(), startDate.Month(), startDate.Day(), v.StartPoint, 0, 0, 0, time.Local)) timeItem := promotion.TimeItem{ PromotionID: info.ID, PromotionName: info.Name, StartTime: startTime, EndTime: formatEndTime, } if err = tx.Create(&timeItem).Error; err != nil { back.Err(c, err.Error()) tx.Rollback() return } if len(v.GoodsList) > 0 && v.GoodsList[0].GoodsID > 0 { for _, g := range v.GoodsList { totalInventory := 0 for _, sku := range g.SkuList { inventory := sku.Inventory if p.IsSale { inventory = 9999 } totalInventory += int(inventory) } order, _ := strconv.Atoi(g.Order) promotionGoods := promotion.Goods{ PromotionTimeItemID: timeItem.ID, PromotionID: info.ID, PromotionStartDate: formatime.NewDateFrom(startDate), PromotionName: info.Name, StartTime: startTime, EndTime: formatEndTime, GoodsID: g.GoodsID, Subtitle: g.Subtitle, TotalInventory: uint(totalInventory), Order: order, } if err = tx.Create(&promotionGoods).Error; err != nil { back.Err(c, "Goods数据错误:"+err.Error()) tx.Rollback() return } for _, sku := range g.SkuList { var goodsSku goods.Sku dbc.DB.First(&goodsSku, sku.SkuID) if goodsSku.GoodsID != promotionGoods.GoodsID { es := fmt.Sprintf("%s-%d-%d", "sku没有匹配到商品", goodsSku.GoodsID, promotionGoods.GoodsID) back.Fail(c, es) tx.Rollback() return } discount := decimal.NewFromFloat(sku.DiscountPrice).Truncate(2) commission := decimal.NewFromFloat(sku.DiscountPrice).Mul(goodsSku.CommissionRate).Truncate(2) i1 := sku.Inventory if p.IsSale { discount = goodsSku.SalePurchasePrice commission = decimal.Zero i1 = 9999 } s := promotion.Sku{ PromotionGoodsID: promotionGoods.ID, GoodsID: promotionGoods.GoodsID, SkuID: sku.SkuID, DiscountPrice: discount, Commission: commission, SkuName: goodsSku.Name, SkuCode: goodsSku.Code, Inventory: i1, } if err = tx.Create(&s).Error; err != nil { back.Err(c, "数据错误:"+err.Error()) tx.Rollback() return } } } } if len(v.ActivitiesList) > 0 && v.ActivitiesList[0].ActivityID > 0 { for _, act := range v.ActivitiesList { // 放入活动前要检查, 本次时间只有一个活动在 var testGoods promotion.Goods dbc.DB.Select("start_time=?", startTime).First(&testGoods) if testGoods.ID > 0 { back.Err(c, "每个时间段只允许有一个活动") tx.Rollback() return } promotionGoods := promotion.Goods{ PromotionTimeItemID: timeItem.ID, PromotionID: info.ID, PromotionStartDate: formatime.NewDateFrom(startDate), PromotionName: info.Name, StartTime: startTime, EndTime: formatEndTime, GoodsID: 0, ActivityID: act.ActivityID, // 保存活动ID Subtitle: "", // 子标题咱不保存 TotalInventory: 0, // 活动默认库存为0 ActivitySortId: act.ActivitySortId, //新增多品排序位置 } if err = tx.Create(&promotionGoods).Error; err != nil { back.Err(c, err.Error()) tx.Rollback() return } } } } } tx.Commit() back.Suc(c, "操作成功", nil) }