You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
7.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)
}