package act import ( "time" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" ) const ( ActionTypeNA = 0 ) type ActOrderRuleParam struct { SalePrice int64 `orm:"" json:"salePrice"` // 满的价格 DeductPrice int64 `orm:"" json:"deductPrice"` // 减的价格 } type ActStoreSkuParam struct { model.ActStoreSku Action int // -1删除,1修改,2新增 } type ActDetail struct { model.Act2 } func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Act, vendorIDs []int, actStoreSku []*ActStoreSkuParam) (validVendorIDs []int, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, err error) { wholeValidVendorMap := make(map[int]int) if len(actStoreSku) > 0 { storeIDMap := make(map[int]int) skuIDMap := make(map[int]int) storeSkuParamMap := make(map[int][]*ActStoreSkuParam) for _, v := range actStoreSku { storeIDMap[v.StoreID] = 1 skuIDMap[v.SkuID] = 1 storeSkuParamMap[v.StoreID] = append(storeSkuParamMap[v.StoreID], v) } storeSkuList, err2 := dao.GetStoresSkusInfo(db, jxutils.IntMap2List(storeIDMap), jxutils.IntMap2List(skuIDMap)) if err = err2; err != nil { return nil, nil, nil, err } storeSkuMap := make(map[int64]*model.StoreSkuBind) for _, v := range storeSkuList { storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v } for storeID, oneStoreSkuParam := range storeSkuParamMap { validVendorMap := make(map[int]int) validSkuMap := make(map[int]int) for _, vendorID := range vendorIDs { storeDetail, err2 := dao.GetStoreDetail(db, storeID, vendorID) if err = err2; err == nil { for _, v := range oneStoreSkuParam { if storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]; storeSkuInfo != nil { validVendorMap[vendorID] = 1 validSkuMap[v.SkuID] = 1 actSkuMap := &model.ActStoreSkuMap{ ActID: act.ID, StoreID: storeID, SkuID: v.SkuID, VendorID: vendorID, SyncStatus: model.SyncFlagNewMask, } if v.ActPrice != 0 { actSkuMap.ActualActPrice = v.ActPrice } else { percentage := act.PricePercentage if v.PricePercentage != 0 { percentage = v.PricePercentage } percentage = percentage * int(storeDetail.PricePercentage) / 100 actSkuMap.ActualActPrice = int64(jxutils.CaculateSkuVendorPrice(storeSkuInfo.Price, percentage, 0)) } dao.WrapAddIDCULDEntity(actSkuMap, ctx.GetUserName()) actStoreSkuMapList = append(actStoreSkuMapList, actSkuMap) } } wholeValidVendorMap[vendorID] = 1 } else if !dao.IsNoRowsError(err) { return nil, nil, nil, err } else { err = nil } } for _, v := range oneStoreSkuParam { if validSkuMap[v.SkuID] == 1 { // todo 这里是否需要判断 if storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]; storeSkuInfo != nil { storeSku := &v.ActStoreSku storeSku.ActID = act.ID storeSku.OriginalPrice = int64(storeSkuInfo.Price) dao.WrapAddIDCULDEntity(storeSku, ctx.GetUserName()) actStoreSkuList = append(actStoreSkuList, storeSku) } } } } } return jxutils.IntMap2List(wholeValidVendorMap), actStoreSkuList, actStoreSkuMapList, err } func addActStoreBind(ctx *jxcontext.Context, db *dao.DaoDB, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap) (err error) { dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() storeSkuMap := make(map[int64]int) for _, v := range actStoreSkuList { err = dao.CreateEntity(db, v) if err != nil { dao.Rollback(db) return err } storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v.ID } for _, v := range actStoreSkuMapList { v.BindID = storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] } if len(actStoreSkuMapList) > 0 { err = dao.CreateMultiEntities(db, actStoreSkuMapList) if err != nil { dao.Rollback(db) return err } } dao.Commit(db) return err } func AddActStoreBind(ctx *jxcontext.Context, actID int, actStoreSku []*ActStoreSkuParam) (err error) { db := dao.GetDB() var vendorIDs []int actMap, err := dao.GetActVendorInfo(db, actID, nil) if err != nil { return err } for vendorID := range actMap { vendorIDs = append(vendorIDs, vendorID) } var act *model.Act if len(vendorIDs) > 0 { act = &actMap[vendorIDs[0]].Act } else { act = &model.Act{} act.ID = actID if err = dao.GetEntity(db, act); err != nil { return err } } _, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku) if err != nil { return err } err = addActStoreBind(ctx, db, actStoreSkuList, actStoreSkuMapList) return err } func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (actID int, err error) { db := dao.GetDB() dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() dao.WrapAddIDCULDEntity(act, ctx.GetUserName()) err = dao.CreateEntity(db, act) if err != nil { dao.Rollback(db) return 0, err } validVendorIDs, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku) if err != nil { return 0, err } var actMapList []*model.ActMap for vendorID := range validVendorIDs { actMap := &model.ActMap{ ActID: act.ID, VendorID: vendorID, SyncStatus: model.SyncFlagNewMask, } dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName()) actMapList = append(actMapList, actMap) } if len(actMapList) > 0 { err = dao.CreateMultiEntities(db, actMapList) if err != nil { dao.Rollback(db) return 0, err } } if err = addActStoreBind(ctx, db, actStoreSkuList, actStoreSkuMapList); err != nil { dao.Rollback(db) return 0, err } dao.Commit(db) actID = act.ID err = SyncAct(ctx, actID, nil, nil, nil) return actID, err } func QueryActs(ctx *jxcontext.Context, actID int, keyword string, statusList []int, actTypeList []int, storeID, skuID int, beginAt, endAt time.Time) (actList []*model.Act, err error) { return actList, err } func GetActDetail(ctx *jxcontext.Context, actID int) (actDetail *ActDetail, err error) { return actDetail, err } func UpdateAct(ctx *jxcontext.Context, act *model.Act, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (err error) { return err } func CancelAct(ctx *jxcontext.Context, actID int) (err error) { db := dao.GetDB() if err = deleteActStoreBind(ctx, db, actID, nil); err != nil { return err } err = SyncAct(ctx, actID, nil, nil, nil) return err } func DeleteActStoreBind(ctx *jxcontext.Context, actID int, actStoreSku []*ActStoreSkuParam) (err error) { return deleteActStoreBind(ctx, dao.GetDB(), actID, actStoreSku) } func deleteActStoreBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actStoreSkuParam []*ActStoreSkuParam) (err error) { actMap, err := dao.GetActVendorInfo(db, actID, nil) if err != nil { return err } actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, nil, nil) if err != nil { return err } dao.Begin(db) defer func() { if r := recover(); r != nil || err != nil { dao.Rollback(db) if r != nil { panic(r) } } }() actStoreSkuParamMap := make(map[int64]*ActStoreSkuParam) for _, v := range actStoreSkuParam { actStoreSkuParamMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v if _, err = dao.DeleteEntityLogically(db, &model.ActStoreSku{}, nil, ctx.GetUserName(), map[string]interface{}{ model.FieldActID: actID, model.FieldStoreID: v.StoreID, model.FieldSkuID: v.SkuID, }); err != nil { return err } } isNeedCancelAct := true for vendorID, act := range actMap { isDeleteAll := true isDeleteAtLeastOne := false actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuMap[vendorID]) for storeID := range actStoreSkuMap { for _, actStoreSku := range actStoreSkuMap[storeID] { if actStoreSkuParam == nil || actStoreSkuParamMap[jxutils.Combine2Int(actStoreSku.StoreID, actStoreSku.SkuID)] != nil { if _, err = dao.UpdateEntityLogically(db, partner.ActStoreSku2ActStoreSkuMap(actStoreSku), map[string]interface{}{ model.FieldSyncStatus: actStoreSku.SyncStatus | model.SyncFlagDeletedMask, }, ctx.GetUserName(), nil); err != nil { return err } isDeleteAtLeastOne = true } else { isNeedCancelAct = false isDeleteAll = false } } } if isDeleteAll || isDeleteAtLeastOne { // globals.SugarLogger.Debugf("isDeleteAll:%t", isDeleteAll) syncStatus := model.SyncFlagModifiedMask if isDeleteAll { syncStatus = model.SyncFlagDeletedMask } syncStatus |= act.SyncStatus if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act), map[string]interface{}{ model.FieldSyncStatus: syncStatus, }, ctx.GetUserName(), nil); err != nil { return err } } if isDeleteAll != isNeedCancelAct { globals.SugarLogger.Warnf("deleteActStoreBind, actID:%d isDeleteAll:%t != isNeedCancelAct:%t", act.ID, isDeleteAll, isNeedCancelAct) } } if isNeedCancelAct { act := &model.Act{} act.ID = actID if _, err = dao.UpdateEntityLogically(db, act, map[string]interface{}{ model.FieldStatus: model.ActStatusCanceled, }, ctx.GetUserName(), nil); err != nil { return err } } dao.Commit(db) return err } func SyncAct(ctx *jxcontext.Context, actID int, vendorIDs, storeIDs, skuIDs []int) (err error) { db := dao.GetDB() actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs) if err != nil { return err } actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, storeIDs, skuIDs) if err != nil { return err } for vendorID := range actMap { if handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformActHandler); handler != nil { if err = handler.SyncAct(ctx, nil, actMap[vendorID], nil, actStoreSkuMap[vendorID]); err != nil { return err } } } return err // var actOrderRules []*model.ActOrderRule // db := dao.GetDB() // actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs) // if err != nil { // return err // } // actStoreMap, err := dao.GetActStoreVendorInfo(db, actID, vendorIDs, storeIDs) // if err != nil { // return err // } // actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, vendorIDs, storeIDs, skuIDs) // if err != nil { // return err // } // var realVendorIDs []int // for vendorID := range actMap { // realVendorIDs = append(realVendorIDs, vendorID) // } // task := tasksch.NewParallelTask("SyncAct", nil, ctx, // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { // vendorID := batchItemList[0].(int) // handler := partner.GetPurchasePlatformFromVendorID(vendorID) // if handler == nil { // err = fmt.Errorf("不被支持的vendorID:%d", vendorID) // } else { // act := actMap[vendorID] // actStore := actStoreMap[vendorID] // actStoreSku := actStoreSkuMap[vendorID] // // globals.SugarLogger.Debugf("%s", utils.Format4Output(act, false)) // // globals.SugarLogger.Debugf("%s", utils.Format4Output(actStore, false)) // // globals.SugarLogger.Debugf("%s", utils.Format4Output(actStoreSku, false)) // if act != nil && actStore != nil && actStoreSku != nil { // if model.IsSyncStatusNeedCreate(act.SyncStatus) { // err = handler.CreateAct(ctx, task, act, actOrderRules, actStore, actStoreSku) // } else if model.IsSyncStatusNeedUpdate(act.SyncStatus) { // if act.Status == model.ActStatusCanceled { // err = handler.CancelAct(ctx, task, act, actStore, actStoreSku) // } else { // // actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update := splitActStore(actStore) // // err = handler.UpdateAct(ctx, task, act, actOrderRules, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update, actStoreSku) // } // } // if err == nil { // actMap := &model.ActMap{} // actMap.ID = act.MapID // dao.UpdateEntityLogically(db, actMap, map[string]interface{}{ // model.FieldSyncStatus: 0, // model.FieldVendorActID: act.VendorActID, // }, ctx.GetUserName(), nil) // for _, v := range actStore { // storeMap := model.ActStoreMap{} // storeMap.ID = v.MapID // dao.UpdateEntityLogically(db, storeMap, map[string]interface{}{ // model.FieldSyncStatus: 0, // model.FieldVendorActID: v.VendorActID, // }, ctx.GetUserName(), nil) // } // for _, v := range actStoreSku { // storeSkuMap := model.ActStoreSkuMap{} // storeSkuMap.ID = v.MapID // dao.UpdateEntityLogically(db, storeSkuMap, map[string]interface{}{ // model.FieldSyncStatus: 0, // model.FieldVendorActID: v.VendorActID, // }, ctx.GetUserName(), nil) // } // } // } // } // return nil, err // }, realVendorIDs) // tasksch.ManageTask(task).Run() // _, err = task.GetResult(0) return err } // func splitActStore(actStore []*model.ActStore2) (actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2) { // for _, v := range actStore { // if model.IsSyncStatusNeedDelete(v.SyncStatus) { // if !dao.IsVendorThingIDEmpty(v.VendorActID) { // actStoreMap2Remove = append(actStoreMap2Remove, v) // } // } else if model.IsSyncStatusNeedCreate(v.SyncStatus) { // actStoreMap2Add = append(actStoreMap2Add, v) // } else if model.IsSyncStatusNeedUpdate(v.SyncStatus) { // actStoreMap2Update = append(actStoreMap2Update, v) // } // } // return actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update // }