package tao_vegetable import ( "fmt" "math/rand" "time" "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability2770/domain" "git.rosy.net.cn/baseapi/platformapi/mtwmapi" "git.rosy.net.cn/baseapi/platformapi/tao_vegetable" "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" ) func actType2Txd(actType int) int64 { if actType == model.ActSkuDirectDown { actType = tao_vegetable.DiscountTypeDeductMoney } else if actType == model.ActSkuSecKill { actType = tao_vegetable.DiscountTypeOnePrice } else if actType == model.ActSkuDiscount { actType = tao_vegetable.DiscountTypeDiscounts } return int64(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 act2TxdActivity(act *model.Act2) (activity *domain.AlibabaRetailMarketingItemdiscountActivityCreateItemDiscountActivityOperateRequest) { actName := act.GetRealActName() activity = &domain.AlibabaRetailMarketingItemdiscountActivityCreateItemDiscountActivityOperateRequest{ ActivityName: &actName, CreatorId: utils.String2Pointer(utils.Int2Str(rand.Int())), CreatorName: &act.LastOperator, Description: &act.Advertising, Terminals: &[]int32{tao_vegetable.TerminalsAPP}, //StoreIds: &[]string{act.s}, DiscountType: utils.Int64ToPointer(actType2Txd(act.Type)), StartTime: utils.Int64ToPointer(act.BeginAt.UnixNano() / int64(time.Millisecond)), EndTime: utils.Int64ToPointer(act.EndAt.UnixNano() / int64(time.Millisecond)), } return activity } func storeSku2ActData(act *model.Act2, actStoreSku []*model.ActStoreSku2, handler func(int8) bool) (actData *domain.AlibabaRetailMarketingItemdiscountActivitySkuAddItemDiscountActivityElementOperateRequest) { var ( //limitCount = int64(1) //userLimitCount = int64(1) fixPriceMoney = int64(0) discountRate = int64(0) decreaseMoney = int64(0) //limitDaily = int64(1) skuElements []domain.AlibabaRetailMarketingItemdiscountActivitySkuAddSkuActivityElementDto skuElement domain.AlibabaRetailMarketingItemdiscountActivitySkuAddSkuActivityElementDto ) //if act.LimitCount > 0 { // limitCount = int64(act.LimitCount) // if act.LimitUser > 0 { // userLimitCount = int64(act.LimitCount) // } //} else if act.LimitDaily > 0 { // limitDaily = int64(act.LimitDaily) //} actData = &domain.AlibabaRetailMarketingItemdiscountActivitySkuAddItemDiscountActivityElementOperateRequest{ CreatorId: utils.String2Pointer(utils.Int2Str(rand.Int())), CreatorName: &act.LastOperator, OutActId: utils.String2Pointer(utils.Int2Str(act.Act.ID)), } for _, v := range actStoreSku { if handler == nil || handler(v.SyncStatus) { //stock := int64(0) //if v.Stock > 0 { // stock = int64(v.Stock) //} sType := actType2Txd(act.Type) switch sType { case tao_vegetable.DiscountTypeDeductMoney: decreaseMoney = v.VendorPrice - v.ActualActPrice skuElement = domain.AlibabaRetailMarketingItemdiscountActivitySkuAddSkuActivityElementDto{ SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), DecreaseMoney: &decreaseMoney, //Limit: &domain.AlibabaRetailMarketingItemdiscountActivitySkuAddLimitDto{ // OrderLimitCnt: &limitCount, //}, } case tao_vegetable.DiscountTypeOnePrice: fixPriceMoney = v.ActualActPrice skuElement = domain.AlibabaRetailMarketingItemdiscountActivitySkuAddSkuActivityElementDto{ SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), FixPriceMoney: &fixPriceMoney, //Limit: &domain.AlibabaRetailMarketingItemdiscountActivitySkuAddLimitDto{ // OrderLimitCnt: &limitCount, //}, } case tao_vegetable.DiscountTypeDiscounts: discountRate = int64(v.PricePercentage * 10) skuElement = domain.AlibabaRetailMarketingItemdiscountActivitySkuAddSkuActivityElementDto{ SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), DiscountRate: &discountRate, //Limit: &domain.AlibabaRetailMarketingItemdiscountActivitySkuAddLimitDto{ // OrderLimitCnt: &limitCount, //}, } } skuElements = append(skuElements, skuElement) actData.SkuElements = &skuElements } } 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 actSku2Delete(actIDs []string, vendorOrgCode, vendorStoreID string) (map[string]domain.AlibabaRetailMarketingItemdiscountActivitySkuDeleteItemDiscountActivityElementOperateRequest, error) { var ( SkuElement []domain.AlibabaRetailMarketingItemdiscountActivitySkuDeleteSkuActivityElementDto deData = make(map[string]domain.AlibabaRetailMarketingItemdiscountActivitySkuDeleteItemDiscountActivityElementOperateRequest, 0) ) for _, v := range actIDs { i := utils.Str2Int64(v) if skus, err := getAPI(vendorOrgCode, 0, vendorStoreID).ActivitySkuQuery(i); err == nil { //查询商品 for _, sku := range skus { SkuElement = append(SkuElement, domain.AlibabaRetailMarketingItemdiscountActivitySkuDeleteSkuActivityElementDto{ SkuCode: sku.SkuCode, }) } //查询活动详情 act, err := getAPI(vendorOrgCode, 0, vendorStoreID).ActivityQuery(i, "") if err != nil { return nil, err } deData[v] = domain.AlibabaRetailMarketingItemdiscountActivitySkuDeleteItemDiscountActivityElementOperateRequest{ SkuElements: &SkuElement, ActId: &i, CreatorId: act.CreatorId, CreatorName: act.CreatorName, } } } return deData, nil } 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) { //1 活动详情 actData := act2TxdActivity(act) //2 活动商品详情 actSkuData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate) globals.SugarLogger.Debugf("createOneShopAct actData=%s,actSkuData=%s", utils.Format4Output(actData, false), utils.Format4Output(actSkuData, false)) if actData != nil && actSkuData != nil { if globals.EnableMtwmStoreWrite { //创建活动 actData.StoreIds = &[]string{vendorStoreID} actID, err1 := getAPI(act.VendorOrgCode, 0, vendorStoreID).ActivityCreate(*actData) if err1 != nil || actID == 0 { failedList = append(failedList, &partner.StoreSkuInfoWithErr{ VendoreID: model.VendorIDTaoVegetable, ErrMsg: fmt.Sprintf("%v", err1), StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)), }) return failedList, err1 } //活动增加商品 actSkuData.ActId = &actID err3, successSkuCode, failSkuCode := getAPI(act.VendorOrgCode, 0, vendorStoreID).ActivitySkuCreate(*actSkuData) err = err3 if err != nil { //商品新增失败,回滚删除创建的活动 if err4 := getAPI(act.VendorOrgCode, 0, vendorStoreID).ActivityDelete(*actData.CreatorId, *actData.CreatorName, actID); err != nil { return nil, fmt.Errorf("活动创建但新增商品失败,删除活动错误:%v,请在淘鲜达平台删除此活动", err4) } } actStoreSkuMap := make(map[int]*model.ActStoreSku2) for _, v := range actStoreSku { actStoreSkuMap[v.SkuID] = v } for _, v := range successSkuCode.SkuID { if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v, 0))]; v2 != nil { v2.VendorActID = utils.Int64ToStr(successSkuCode.ActID) } } for _, v := range failSkuCode { if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v, 0))]; v2 != nil { failedList = append(failedList, &partner.StoreSkuInfoWithErr{ StoreSkuInfo: &partner.StoreSkuInfo{ SkuID: v2.SkuID, }, VendoreID: model.VendorIDTaoVegetable, StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)), ErrMsg: fmt.Sprint(err3), }) } } } } 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 { actStoreSkuMap := make(map[string]*model.ActStoreSku2) for _, v := range actStoreSku { actStoreSkuMap[v.VendorActID] = v } //查找删除的活动商品 sku2Delete, err := actSku2Delete(list, act.VendorOrgCode, vendorStoreID) if err != nil { return nil, err } //删除活动以及商品 for k, v := range sku2Delete { if err = getAPI(act.VendorOrgCode, 0, vendorStoreID).ActivitySkuDelete(v); err == nil { err = getAPI(act.VendorOrgCode, 0, vendorStoreID).ActivityDelete(*v.CreatorId, *v.CreatorName, utils.Str2Int64(k)) } if err != nil { failedList = append(failedList, &partner.StoreSkuInfoWithErr{ StoreSkuInfo: &partner.StoreSkuInfo{ SkuID: actStoreSkuMap[k].SkuID, }, StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)), ErrMsg: fmt.Sprint(err), VendoreID: model.VendorIDTaoVegetable, }) } } 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("txd 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("txd 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 }