package mtwm import ( "errors" "git.rosy.net.cn/baseapi/platformapi/mtwmapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/business/partner/putils" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" ) func jxActType2Mtwm(actType int) int { if actType == model.ActSkuDirectDown { actType = mtwmapi.RetailActTypeDirectDown } else if actType == model.ActSkuSecKill { actType = mtwmapi.RetailActTypeSecKill } else { actType = 0 } return actType } func actOrderRules2Mtwm(actOrderRules []*model.ActOrderRule) (actDetails []*mtwmapi.FullDiscountActDetail) { for _, v := range actOrderRules { actDetails = append(actDetails, &mtwmapi.FullDiscountActDetail{ OriginalPrice: jxutils.IntPrice2Standard(v.SalePrice), ActPrice: jxutils.IntPrice2Standard(v.DeductPrice), }) } return actDetails } func storeSku2ActData(act *model.Act2, actStoreSku []*model.ActStoreSku2, handler func(int8) bool) (actData []*mtwmapi.RetailDiscountActData) { orderLimit := 1 if act.LimitCount > 0 { orderLimit = act.LimitCount } for _, v := range actStoreSku { if handler == nil || handler(v.SyncStatus) { dayLimit := -1 if v.Stock > 0 { dayLimit = v.Stock } actData = append(actData, &mtwmapi.RetailDiscountActData{ AppFoodCode: utils.Int2Str(v.SkuID), // UserType: 0, StartTime: act.BeginAt.Unix(), EndTime: act.EndAt.Unix(), OrderLimit: orderLimit, DayLimit: dayLimit, // Period: "", // WeeksTime: "", SettingType: mtwmapi.SettingTypeAsPrice, ActPrice: jxutils.IntPrice2Standard(v.ActualActPrice), // DiscountCoefficient: 0, // Sequence: int(v.ActPrice), // 此字段不允许重复 // ItemID: utils.Str2Int64WithDefault(v.VendorActID, 0), }) } } return actData } func storeSku2ActData4Delete(actStoreSku []*model.ActStoreSku2, handler func(int8) bool) (actIDList []string) { for _, v := range actStoreSku { if handler == nil || handler(v.SyncStatus) { if v.VendorActID != "" { actIDList = append(actIDList, v.VendorActID) } } } return actIDList } func isCreateOrUpdate(syncStatus int8) bool { return model.IsSyncStatusNeedCreate(syncStatus) || model.IsSyncStatusNeedUpdate(syncStatus) } func createOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) { actData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate) if len(actData) > 0 { if globals.EnableMtwmStoreWrite { actResult, faileInfoList, err2 := api.MtwmAPI.RetailDiscountBatchSave2(vendorStoreID, jxActType2Mtwm(act.Type), actData) err = err2 // 忽略错误,都放在failedList里 // if err != nil { // return nil, err // } actStoreSkuMap := make(map[int]*model.ActStoreSku2) for _, v := range actStoreSku { actStoreSkuMap[v.SkuID] = v } for _, v := range actResult { if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil { v2.VendorActID = utils.Int64ToStr(v.ActID) } } for _, v := range faileInfoList { if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil { failedList = append(failedList, &partner.StoreSkuInfoWithErr{ StoreSkuInfo: &partner.StoreSkuInfo{ SkuID: v2.SkuID, }, VendoreID: model.VendorIDMTWM, StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)), ErrMsg: v.ErrorMsg, }) } } } else { for _, v := range actStoreSku { v.VendorActID = utils.Int64ToStr(jxutils.GenFakeID()) } } } return failedList, err } func cancelOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) { if list := storeSku2ActData4Delete(actStoreSku, nil /*model.IsSyncStatusNeedDelete*/); len(list) > 0 { if globals.EnableMtwmStoreWrite { failedList2, err2 := api.MtwmAPI.RetailDiscountDelete2(vendorStoreID, jxActType2Mtwm(act.Type), list) actStoreSkuMap := make(map[string]*model.ActStoreSku2) for _, v := range actStoreSku { actStoreSkuMap[v.VendorActID] = v } for _, v := range failedList2 { if !mtwmapi.CanDeleteActErrMsgIgnore(v.ErrorMsg) { failedList = append(failedList, &partner.StoreSkuInfoWithErr{ StoreSkuInfo: &partner.StoreSkuInfo{ SkuID: actStoreSkuMap[utils.Int64ToStr(v.ActID)].SkuID, }, StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)), ErrMsg: v.ErrorMsg, VendoreID: model.VendorIDMTWM, }) } } err = err2 err = nil // 强制不返回错误,使用部分错误 } } return failedList, err } func getActStoreSkuFromTaskResult(taskReslt []interface{}) (list []*model.ActStoreSku2) { for _, v := range taskReslt { actStoreSkuList := v.([]*model.ActStoreSku2) list = append(list, actStoreSkuList...) } return list } func createSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (createdList []*model.ActStoreSku2, err error) { actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku) task := tasksch.NewParallelTask("mtwm createSkuAct", nil, ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { list := batchItemList[0].([]*model.ActStoreSku2) failedList, err2 := createOneShopAct(act, list[0].VendorStoreID, list) if err = err2; err2 == nil { if len(failedList) > 0 { failedMap := putils.StoreSkuInfoWithErrList2MapBySku(failedList) list = []*model.ActStoreSku2{} for _, v := range actStoreSku { if failedMap[v.SkuID] == nil { list = append(list, v) } } list = []*model.ActStoreSku2{} } retVal = []interface{}{list} } return retVal, err }, actStoreSkuListList) tasksch.HandleTask(task, parentTask, true).Run() result, err := task.GetResult(0) return getActStoreSkuFromTaskResult(result), err } func cancelSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (canceledList []*model.ActStoreSku2, err error) { actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku) task := tasksch.NewParallelTask("mtwm cancelSkuAct", nil, ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { actStoreSkuList := batchItemList[0].([]*model.ActStoreSku2) if _, err = cancelOneShopAct(act, actStoreSkuList[0].VendorStoreID, actStoreSkuList); err == nil { retVal = []interface{}{actStoreSkuList} } return retVal, err }, actStoreSkuListList) tasksch.HandleTask(task, parentTask, true).Run() result, err := task.GetResult(0) return getActStoreSkuFromTaskResult(result), err } func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { var actStoreSkuList4Create, actStoreSkuList4Delete []*model.ActStoreSku2 var updateItems []*dao.KVUpdateItem actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuList) for storeID := range actStoreSkuMap { for _, actStoreSku := range actStoreSkuMap[storeID] { if model.IsSyncStatusDelete(actStoreSku.SyncStatus) { actStoreSkuList4Delete = append(actStoreSkuList4Delete, actStoreSku) } else if model.IsSyncStatusNew(actStoreSku.SyncStatus) { actStoreSkuList4Create = append(actStoreSkuList4Create, actStoreSku) } } } err = func() (err error) { if model.IsSyncStatusDelete(act.SyncStatus) { canceledList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList) updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, canceledList, model.SyncFlagModifiedMask)...) if err = err2; err == nil { updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask)) } } else if model.IsSyncStatusNew(act.SyncStatus) { createdList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create) updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, createdList, model.SyncFlagNewMask)...) if err = err2; err == nil { updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagNewMask)) } } else if model.IsSyncStatusUpdate(act.SyncStatus) { if len(actStoreSkuList4Create) > 0 { addedList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create) updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, addedList, model.SyncFlagNewMask)...) if err = err2; err != nil { return err } } if len(actStoreSkuList4Delete) > 0 { deletedList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList4Delete) updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, deletedList, model.SyncFlagDeletedMask)...) if err = err2; err != nil { return err } } if err == nil { updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask)) } } return err }() db := dao.GetDB() _, err2 := dao.BatchUpdateActEntity(db, model.IsSyncStatusDelete(act.SyncStatus), updateItems) if err == nil { err = err2 } return err } func (c *PurchaseHandler) GetActAmple(ctx *jxcontext.Context, vendorStoreID, vendorOrgCode string) (ample int, err error) { for _, v := range mtwmapi.ActTypeList { //1表示进行中 if actList, err := getAPI(vendorOrgCode, 0, vendorStoreID).GetByAppPoiCodeAndType(vendorOrgCode, 1, v); err == nil { ample += len(actList) } } return ample, err } const ( ActTypeBuy = 1 //买赠活动 ActTypeDeduction = 2 //商品满减 ActTypeDirectDown = 3 //折扣(爆品) ActTypeXM = 4 //X元M件 ActTypeN = 5 //第N件优惠 ActTypeDeductionAll = 0 //全店满减 ActTypeDeductionOne = 1 //指定商品满减 ) func GetActByAppPoiCode(vendorStoreID, vendorOrgCode string, sTime, eTime int64, actType int) (map[int]interface{}, error) { if len(vendorStoreID) == 0 || len(vendorOrgCode) == 0 || sTime == 0 || eTime == 0 { return nil, errors.New("未选中门店或时间,请检查") } var ( temp []interface{} resp = make(map[int]interface{}) a = getAPI(vendorOrgCode, 0, vendorStoreID) ) switch actType { case ActTypeDeduction: actInfo, err := a.FullDiscountList(vendorStoreID, ActTypeDeductionAll) if err != nil { return nil, err } //获取活动商品 for _, v := range actInfo { sku, err := a.FullDiscountFoodsList(vendorStoreID, v.ActInfo.ActIDs) //actID := utils.Str2Int(v.ActInfo.ActIDs) if err != nil || sku == nil { temp = append(temp, actInfo) } if CheckActTime(sTime, eTime, v.ActInfo.StartTime, v.ActInfo.EndTime) { temp = append(temp, sku) //temp[actID] = sku } } resp[ActTypeDeduction] = temp return resp, nil case ActTypeDirectDown: killInfo, err := a.RetailDiscountList(vendorStoreID, mtwmapi.RetailActTypeSecKill) if err != nil || killInfo == nil { resp[mtwmapi.RetailActTypeSecKill] = "" } else { for _, v := range killInfo { if CheckActTime(sTime, eTime, v.StartTime, v.EndTime) { temp = append(temp, v) } } resp[mtwmapi.RetailActTypeSecKill] = temp } downInfo, err1 := a.RetailDiscountList(vendorStoreID, mtwmapi.RetailActTypeDirectDown) if err1 != nil || downInfo == nil { resp[mtwmapi.RetailActTypeDirectDown] = "" } else { for _, k := range downInfo { if CheckActTime(sTime, eTime, k.StartTime, k.EndTime) { temp = append(temp, k) } } resp[mtwmapi.RetailActTypeDirectDown] = temp } return resp, nil } return nil, nil } func CheckActTime(startTime, endTime, sTime, eTime int64) bool { if sTime > endTime || eTime < startTime { return false } return true }