From 045d54844fd024e010431cb5268ada29a96f3606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E5=B0=B9=E5=B2=9A?= <770236076@qq.com> Date: Sat, 10 Oct 2020 11:45:23 +0800 Subject: [PATCH] shan --- business/jxcallback/orderman/fake_jd_order.go | 74 - .../jxcallback/orderman/fake_jd_order_test.go | 14 - business/jxstore/act/act.go | 1686 ---------------- business/jxstore/act/act_test.go | 209 -- business/jxstore/misc/misc.go | 504 ----- business/jxstore/misc/misc2.go | 396 ---- business/jxstore/misc/misc2_test.go | 11 - business/jxstore/misc/store_alert_inform.go | 509 ----- business/jxstore/misc/store_score.go | 882 --------- business/jxstore/misc/store_score_test.go | 24 - business/jxstore/misc/store_sku_sales.go | 176 -- business/jxstore/report/report.go | 285 --- business/jxstore/tempop/tempop.go | 1690 ----------------- business/jxstore/tempop/tempop_test.go | 44 - business/jxstore/yonghui/yonghui.go | 1104 ----------- main.go | 2 - 16 files changed, 7610 deletions(-) delete mode 100644 business/jxcallback/orderman/fake_jd_order.go delete mode 100644 business/jxcallback/orderman/fake_jd_order_test.go delete mode 100644 business/jxstore/act/act.go delete mode 100644 business/jxstore/act/act_test.go delete mode 100644 business/jxstore/misc/misc2.go delete mode 100644 business/jxstore/misc/misc2_test.go delete mode 100644 business/jxstore/misc/store_alert_inform.go delete mode 100644 business/jxstore/misc/store_score.go delete mode 100644 business/jxstore/misc/store_score_test.go delete mode 100644 business/jxstore/misc/store_sku_sales.go delete mode 100644 business/jxstore/report/report.go delete mode 100644 business/jxstore/tempop/tempop.go delete mode 100644 business/jxstore/tempop/tempop_test.go delete mode 100644 business/jxstore/yonghui/yonghui.go diff --git a/business/jxcallback/orderman/fake_jd_order.go b/business/jxcallback/orderman/fake_jd_order.go deleted file mode 100644 index f9923f511..000000000 --- a/business/jxcallback/orderman/fake_jd_order.go +++ /dev/null @@ -1,74 +0,0 @@ -package orderman - -import ( - "fmt" - "strings" - - "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/netprinter" - "git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg" - "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/purchase/jd" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func (c *OrderManager) OnNewFakeJdOrder(vendorOrderID string) (err error) { - utils.CallFuncAsync(func() { - orderInfo, err := api.FakeJdAPI.FakeQuerySingleOrderRaw(vendorOrderID) - if err == nil { - order := jd.Map2Order(orderInfo) - jxutils.RefreshOrderSkuRelated(order) - err = c.notifyNewFakeJdOrder(order) - } - if err != nil { - globals.SugarLogger.Warnf("OnNewFakeJdOrder failed with err:%v", err) - } - }) - return err -} - -func (c *OrderManager) notifyNewFakeJdOrder(order *model.GoodsOrder) (err error) { - db := dao.GetDB() - storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, model.VendorIDJD) - if err != nil { - return err - } - realStoreID := storeDetail.ID - if storeDetail.LinkStoreID != 0 { - realStoreID = storeDetail.LinkStoreID - } - notifyWxNewFakeJdOrder(order, realStoreID) - netprinter.PrintOrderByOrder4Store(jxcontext.AdminCtx, order, realStoreID) - return err -} - -func notifyWxNewFakeJdOrder(order *model.GoodsOrder, storeID int) (err error) { - globals.SugarLogger.Debugf("notifyWxNewFakeJdOrder orderID:%s", order.VendorOrderID) - - sb := new(strings.Builder) - sb.WriteString("老板,你有新订单了\n") - sb.WriteString(fmt.Sprintf("订单号:%s\n", order.VendorOrderID)) - sb.WriteString("送达时间:") - if order.BusinessType == model.BusinessTypeDingshida { - sb.WriteString(utils.Time2Str(order.ExpectedDeliveredTime)) - } else { - sb.WriteString("立即达") - } - sb.WriteString("\n") - sb.WriteString(fmt.Sprintf("买家:%s\n", order.ConsigneeName)) - sb.WriteString(fmt.Sprintf("电话:%s\n", order.ConsigneeMobile)) - sb.WriteString(fmt.Sprintf("收货地址:%s\n", order.ConsigneeAddress)) - sb.WriteString("商品详情:\n") - for _, sku := range order.Skus { - sb.WriteString(fmt.Sprintf("\t%s*%d\n", sku.SkuName, sku.Count)) - } - title := fmt.Sprintf("你有到家菜市新订单%d", order.OrderSeq) - content := sb.String() - // globals.SugarLogger.Debugf("notifyWxNewFakeJdOrder, orderID:%s, content:%s", order.VendorOrderID, content) - _, err = weixinmsg.SendStoreMessage(jxcontext.AdminCtx, title, content, []int{storeID}, true, true) - return err -} diff --git a/business/jxcallback/orderman/fake_jd_order_test.go b/business/jxcallback/orderman/fake_jd_order_test.go deleted file mode 100644 index 2ac47e54a..000000000 --- a/business/jxcallback/orderman/fake_jd_order_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package orderman - -import ( - "testing" - "time" -) - -func TestOnNewFakeJdOrder(t *testing.T) { - err := FixedOrderManager.OnNewFakeJdOrder("2002984074001021") - if err != nil { - t.Fatal(err) - } - time.Sleep(3 * time.Second) -} diff --git a/business/jxstore/act/act.go b/business/jxstore/act/act.go deleted file mode 100644 index f28c60e9f..000000000 --- a/business/jxstore/act/act.go +++ /dev/null @@ -1,1686 +0,0 @@ -package act - -import ( - "fmt" - "math" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/jxstore/cms" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "github.com/360EntSecGroup-Skylar/excelize" - - "git.rosy.net.cn/jx-callback/business/jxutils/jsonerr" - "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" -) - -const ( - DefActSkuStock = 200 // 缺省活动库存 -) - -type ActOrderRuleParam struct { - SalePrice int64 `orm:"" json:"salePrice"` // 满的价格 - DeductPrice int64 `orm:"" json:"deductPrice"` // 减的价格 -} - -type ActStoreSkuParam struct { - model.ActStoreSku - - ActualActPrice int64 `json:"actualActPrice,omitempty"` // 单品级活动用,创建活动时商品的活动价格 - VendorPrice int64 `json:"vendorPrice,omitempty"` // 创建活动时的平台价格 - ErrMsg string `json:"errMsg,omitempty"` -} - -type ActDetail struct { - model.Act2 -} - -type tPreCreateActVendorInfo struct { - VendorID int - - VendorPrice int64 `orm:"" json:"vendorPrice"` // 单品级活动用,创建活动时商品的原始平台价 - ActualActPrice int64 `orm:"" json:"actualActPrice"` // 单品级活动用,创建活动时商品的活动价格 -} - -type tPreCreateActStoreSku struct { - model.ActStoreSku - VendorInfoList []*tPreCreateActVendorInfo `json:"vendorInfoList"` -} - -type tPreCreateActInfo struct { - model.Act - - ValidVendorIDs []int - ActStoreSku []*tPreCreateActStoreSku `json:"actStoreSku"` -} - -type tActRuleInfo struct { - MinDiscount int - MaxDiscount int -} - -type ActManager struct { -} - -type SheetParamAct struct { - StoreIDCol int - SkuIDCol int - SkuPricePercentageCol int - ActPriceCol int - EarningPriceCol int - StockCol int - ActTypeCol int - ActPricePercentageCol int - ActNameCol int - BeginTimeCol int - EndTimeCol int -} - -var ( - FixedActManager *ActManager - - actRuleMap = map[int]map[int]*tActRuleInfo{ - model.VendorIDJD: map[int]*tActRuleInfo{ - model.ActSkuFake: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 500, - }, - model.ActSkuDirectDown: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 99, - }, - model.ActSkuSecKill: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 80, - }, - }, - model.VendorIDMTWM: map[int]*tActRuleInfo{ - model.ActSkuFake: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 500, - }, - model.ActSkuDirectDown: &tActRuleInfo{ - MinDiscount: 30, - MaxDiscount: 99, - }, - model.ActSkuSecKill: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 30, - }, - }, - model.VendorIDEBAI: map[int]*tActRuleInfo{ - model.ActSkuFake: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 500, - }, - model.ActSkuDirectDown: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 99, - }, - }, - model.VendorIDJX: map[int]*tActRuleInfo{ - model.ActSkuFake: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 500, - }, - model.ActSkuDirectDown: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 99, - }, - model.ActSkuSecKill: &tActRuleInfo{ - MinDiscount: 0, - MaxDiscount: 80, - }, - model.ActSkuDiscount: &tActRuleInfo{ - MinDiscount: 100, - MaxDiscount: 100, - }, - }, - } -) - -func init() { - FixedActManager = &ActManager{} - partner.InitActManager(FixedActManager) -} - -func getVendorPriceFromStoreSkuBind(bind *model.StoreSkuBind, vendorID int) (vendorPrice int) { - switch vendorID { - case model.VendorIDJD: - vendorPrice = bind.JdPrice - case model.VendorIDMTWM: - vendorPrice = bind.MtwmPrice - case model.VendorIDEBAI: - vendorPrice = bind.EbaiPrice - case model.VendorIDJX: - vendorPrice = bind.JxPrice - } - return vendorPrice -} - -func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Act, vendorIDs []int, actStoreSku []*ActStoreSkuParam) ( - validVendorIDs []int, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, conflictActStoreSku []*model.ActStoreSku2, 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) - - actStoreSkuMap := make(map[int64]bool) - var wrongSkuList []*ActStoreSkuParam - for _, v := range actStoreSku { - if act.Type == model.ActSkuFake && v.EarningPrice == 0 { - wrongSkuList = append(wrongSkuList, v) - } else { - storeIDMap[v.StoreID] = 1 - skuIDMap[v.SkuID] = 1 - storeSkuParamMap[v.StoreID] = append(storeSkuParamMap[v.StoreID], v) - - actStoreSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = true - } - } - if len(wrongSkuList) > 0 { - return nil, nil, nil, nil, jsonerr.New(wrongSkuList, model.ErrCodeJsonActEarningPriceIsZero) - } - storeIDs := jxutils.IntMap2List(storeIDMap) - skuIDs := jxutils.IntMap2List(skuIDMap) - // 判断活动是否重叠的检查,当前忽略京东平台及所有结算信息 - if act.Type != model.ActSkuFake { - effectActStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, act.Type, storeIDs, skuIDs, act.BeginAt, act.EndAt) - if err != nil { - globals.SugarLogger.Errorf("GetEffectiveActStoreSkuInfo can not get sku promotion info for error:%v", err) - return nil, nil, nil, nil, err - } - if len(effectActStoreSkuList) > 0 { - for _, v := range effectActStoreSkuList { - if actStoreSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] { - conflictActStoreSku = append(conflictActStoreSku, v) - } - } - } - } - - storeSkuList, err2 := dao.GetStoresSkusInfo(db, storeIDs, skuIDs) - if err = err2; err != nil { - return nil, 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 { - if storeDetail.IsSync != 0 { - if act.Type == model.ActSkuFake || - storeDetail.Status != model.StoreStatusDisabled && storeDetail.VendorStatus != model.StoreStatusDisabled { - for _, v := range oneStoreSkuParam { - validVendorMap[vendorID] = 1 - validSkuMap[v.SkuID] = 1 - v.ActID = act.ID - actSkuMap := &model.ActStoreSkuMap{ - ActID: act.ID, - StoreID: storeID, - SkuID: v.SkuID, - VendorID: vendorID, - } - storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] - if storeSkuInfo != nil { - jxPrice := storeSkuInfo.Price - actSkuMap.VendorPrice = int64(getVendorPriceFromStoreSkuBind(storeSkuInfo, vendorID)) - v.OriginalPrice = int64(jxPrice) - } - var err2 error - if act.Type != model.ActSkuFake { // 非结算,要计算实际活动价格 - if storeSkuInfo == nil { - v.ErrMsg = fmt.Sprintf("门店:%d没有关注商品:%d", v.StoreID, v.SkuID) - wrongSkuList = append(wrongSkuList, v) - continue - } - if !(vendorID == model.VendorIDJX || act.Type == model.ActSkuFake) { - actSkuMap.SyncStatus = model.SyncFlagNewMask - } - if v.ActPrice != 0 { - actSkuMap.ActualActPrice = v.ActPrice - } else { - percentage := act.PricePercentage - if v.PricePercentage != 0 { - percentage = v.PricePercentage - } - actSkuMap.ActualActPrice = int64(jxutils.CaculateSkuActVendorPrice(int(actSkuMap.VendorPrice), percentage, 0)) - if actSkuMap.ActualActPrice > 10 { - actSkuMap.ActualActPrice = int64(math.Floor(float64(actSkuMap.ActualActPrice)/10) * 10) - } - } - if actSkuMap.ActualActPrice <= 0 { - actSkuMap.ActualActPrice = 1 - } - if err2 = checkDiscountValidation(vendorIDs, act.Type, float64(actSkuMap.ActualActPrice)*100/float64(actSkuMap.VendorPrice)); err2 != nil { - v.ErrMsg = err2.Error() - v.ActualActPrice = actSkuMap.ActualActPrice - v.VendorPrice = actSkuMap.VendorPrice - wrongSkuList = append(wrongSkuList, v) - } - } - if err2 == nil { - actSkuMap.EarningPrice = v.EarningPrice - dao.WrapAddIDCULDEntity(actSkuMap, ctx.GetUserName()) - actStoreSkuMapList = append(actStoreSkuMapList, actSkuMap) - } - } - wholeValidVendorMap[vendorID] = 1 - } - } - } else if !dao.IsNoRowsError(err) { - return nil, nil, nil, nil, err - } else { - err = nil - } - } - if len(wrongSkuList) == 0 { - for _, v := range oneStoreSkuParam { - if validSkuMap[v.SkuID] == 1 { // todo 这里是否需要判断 - storeSku := &v.ActStoreSku - dao.WrapAddIDCULDEntity(storeSku, ctx.GetUserName()) - actStoreSkuList = append(actStoreSkuList, storeSku) - } - } - } - } - if len(wrongSkuList) > 0 { - return nil, nil, nil, nil, jsonerr.New(wrongSkuList, model.ErrCodeJsonActPriceTooLarger) - } - } - return jxutils.IntMap2List(wholeValidVendorMap), actStoreSkuList, actStoreSkuMapList, conflictActStoreSku, err -} - -func addActStoreSkuBind(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 { - if v.Stock == 0 { - v.Stock = DefActSkuStock - } - 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 checkActUpdate(actID int, actMap map[int]*model.Act2) (err error) { - if len(actMap) == 0 { - return fmt.Errorf("活动%d不存在或已被取消", actID) - } - errList := errlist.New() - for vendorID, act := range actMap { - if vendorID == model.VendorIDEBAI && act.CreateType != model.ActCreateTypeAPI { - errList.AddErr(fmt.Errorf("饿百平台不支持修改或取消网页活动")) - } - } - return errList.GetErrListAsOne() -} - -func AddActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actStoreSku []*ActStoreSkuParam) (err error) { - actMap, err := dao.GetActVendorInfo(db, actID, nil) - if err != nil { - return err - } - if err = checkActUpdate(actID, actMap); err != nil { - return err - } - - vendorIDs := partner.GetVendorIDsFromActMap(actMap) - - 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 - } - } - if act.Status != model.ActStatusCreated || time.Now().Sub(act.EndAt) > 0 { - return fmt.Errorf("当前活动状态:%s不能进行此操作,或已过期", model.ActStatusName[act.Status]) - } - - // TODO conflictActStoreSku的处理 - _, actStoreSkuList, actStoreSkuMapList, _, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku) - 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) - } - } - }() - if err = addActStoreSkuBind(ctx, db, actStoreSkuList, actStoreSkuMapList); err != nil { - return err - } - if act.Type != model.ActSkuFake { - for _, act := range actMap { - if act.VendorID != model.VendorIDJX { - if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act), - map[string]interface{}{ - model.FieldSyncStatus: act.SyncStatus | model.SyncFlagModifiedMask, - }, ctx.GetUserName(), nil); err != nil { - return err - } - } - } - } - dao.Commit(db) - return err -} - -func getActRule(vendorID, actType int) (actRule *tActRuleInfo, err error) { - if actRuleMap[vendorID] != nil { - actRule = actRuleMap[vendorID][actType] - } - if actRule == nil { - err = fmt.Errorf("%s不支持%s活动", model.VendorChineseNames[vendorID], model.ActTypeName[actType]) - } - return actRule, err -} - -func checkDiscountValidation(vendorIDs []int, actType int, pricePercentage float64) (err error) { - pricePercentageMin := int(math.Floor(pricePercentage)) - pricePercentageMax := int(math.Ceil(pricePercentage)) - errList := errlist.New() - for _, vendorID := range vendorIDs { - actRule, err2 := getActRule(vendorID, actType) - if err2 == nil { - if pricePercentageMin < actRule.MinDiscount { - errList.AddErr(fmt.Errorf("%s%s活动折扣必须大于:%d", model.VendorChineseNames[vendorID], model.ActTypeName[actType], actRule.MinDiscount)) - } else if pricePercentageMax > actRule.MaxDiscount { - errList.AddErr(fmt.Errorf("%s%s活动折扣必须小于:%d", model.VendorChineseNames[vendorID], model.ActTypeName[actType], actRule.MaxDiscount)) - } - } else { - errList.AddErr(err2) - } - } - return errList.GetErrListAsOne() -} - -func checkActValidation(act *model.Act, vendorIDs []int) (err error) { - errList := errlist.New() - if utils.IsTimeZero(act.BeginAt) || utils.IsTimeZero(act.EndAt) { - errList.AddErr(fmt.Errorf("活动开始与结束时间必须指定")) - } else if act.EndAt.Sub(act.BeginAt) < 0 { - errList.AddErr(fmt.Errorf("活动开始时间必须小于活动结束时间")) - } - vendorIDMap := make(map[int]int) - for _, vendorID := range vendorIDs { - vendorIDMap[vendorID] = 1 - } - - if act.Type == model.ActSkuDirectDown || act.Type == model.ActSkuSecKill { - if act.PricePercentage == 0 { - errList.AddErr(fmt.Errorf("必须指定缺省活动折扣")) - } else if err = checkDiscountValidation(vendorIDs, act.Type, float64(act.PricePercentage)); err != nil { - errList.AddErr(err) - } - } else if act.Type == model.ActSkuFake { - - } else if act.Type == model.ActSkuDiscount { - if act.DiscountType == 0 { - errList.AddErr(fmt.Errorf("折扣活动必须选择折扣类型")) - } - if act.DiscountValue1 == 0 || act.DiscountValue2 == 0 { - errList.AddErr(fmt.Errorf("折扣活动必须填入两档")) - } - } else { - errList.AddErr(fmt.Errorf("当前只支持%s与%s活动", model.ActTypeName[model.ActSkuDirectDown], model.ActTypeName[model.ActSkuSecKill])) - } - err = errList.GetErrListAsOne() - return err -} - -func setActDefault(act *model.Act) { - if act.LimitCount == 0 { - act.LimitCount = 1 // 缺省限购一份,如果确定不限,明确给一个很大的值 - } - if act.LimitUser == 0 { - act.LimitUser = 1 - } - act.Status = model.ActStatusCreated -} - -func PreCreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (preCreateActInfo *tPreCreateActInfo, err error) { - if err = checkActValidation(act, vendorIDs); err != nil { - return nil, err - } - setActDefault(act) - - db := dao.GetDB() - validVendorIDs, actStoreSkuList, actStoreSkuMapList, conflictActStoreSku, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku) - if err != nil { - return nil, err - } - if len(validVendorIDs) == 0 { - return nil, fmt.Errorf("没有一个合法平台可以创建活动") - } - if act.OverlapRule == model.OverlapRuleNormal && len(conflictActStoreSku) > 0 { - return nil, jsonerr.New(conflictActStoreSku, model.ErrCodeJsonActSkuConflict) - } - - preCreateActInfo = &tPreCreateActInfo{ - ValidVendorIDs: validVendorIDs, - } - storeSkuMap := make(map[int64]*tPreCreateActStoreSku) - for _, v := range actStoreSkuList { - tmp := &tPreCreateActStoreSku{ - ActStoreSku: *v, - } - storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = tmp - preCreateActInfo.ActStoreSku = append(preCreateActInfo.ActStoreSku, tmp) - } - - for _, v := range actStoreSkuMapList { - index := jxutils.Combine2Int(v.StoreID, v.SkuID) - storeSkuMap[index].VendorInfoList = append(storeSkuMap[index].VendorInfoList, &tPreCreateActVendorInfo{ - VendorID: v.VendorID, - VendorPrice: v.VendorPrice, - ActualActPrice: v.ActualActPrice, - }) - } - return preCreateActInfo, nil -} - -func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, vendorOrgCode string, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam, isAsync bool) (hint string, err error) { - if err = checkActValidation(act, vendorIDs); err != nil { - return "", err - } - act.VendorMask = model.GetVendorMask(vendorIDs...) - if act.VendorMask&(^model.GetVendorMask(model.VendorIDJX)) != 0 && - vendorOrgCode == "" { - return "", fmt.Errorf("必须指定平台分账号信息") - } - setActDefault(act) - - db := dao.GetDB() - // TODO - // 事务应该从ActStoreSkuParam2Model之后开始 - // 创建Act也应该往后放 - 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 "", err - } - - validVendorIDs, actStoreSkuList, actStoreSkuMapList, conflictActStoreSku, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku) - if err != nil { - dao.Rollback(db) - return "", err - } - if len(validVendorIDs) == 0 { - dao.Rollback(db) - return "", fmt.Errorf("没有一个合法平台可以创建活动") - } - var neeSyncActIDs []int - if len(conflictActStoreSku) > 0 { - if act.OverlapRule == model.OverlapRuleNormal { - dao.Rollback(db) - return "", jsonerr.New(conflictActStoreSku, model.ErrCodeJsonActSkuConflict) - } - if neeSyncActIDs, err = DeleteActStoreSkuList(ctx, db, conflictActStoreSku); err != nil { - dao.Rollback(db) - return "", err - } - } - - var actMapList []*model.ActMap - for _, vendorID := range validVendorIDs { - actMap := &model.ActMap{ - ActID: act.ID, - VendorID: vendorID, - VendorOrgCode: vendorOrgCode, - } - if !(vendorID == model.VendorIDJX || act.Type == model.ActSkuFake) { - actMap.SyncStatus = model.SyncFlagNewMask - } - dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName()) - actMapList = append(actMapList, actMap) - } - err = dao.CreateMultiEntities(db, actMapList) - if err != nil { - dao.Rollback(db) - return "", err - } - - if err = addActStoreSkuBind(ctx, db, actStoreSkuList, actStoreSkuMapList); err != nil { - dao.Rollback(db) - return "", err - } - dao.Commit(db) - - neeSyncActIDs = append(neeSyncActIDs, act.ID) - task := tasksch.NewParallelTask(fmt.Sprintf("处理活动创建%d", act.ID), tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - actID := batchItemList[0].(int) - _, err = SyncAct(ctx, task, actID, nil, false) - return retVal, err - }, neeSyncActIDs) - - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - hint = utils.Int2Str(act.ID) - } else { - _, err = task.GetResult(0) - hint = utils.Int2Str(len(neeSyncActIDs)) - } - return hint, err -} - -func vendorActInfo2Model(ctx *jxcontext.Context, db *dao.DaoDB, act2 *model.Act2, actStoreSku []*model.ActStoreSku2) (actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, err error) { - vendorStoreIDMap := make(map[string]int) - vendorSkuIDMap := make(map[string]int) - for _, v := range actStoreSku { - vendorStoreIDMap[v.VendorStoreID] = 1 - vendorSkuIDMap[v.VendorSkuID] = 1 - } - // globals.SugarLogger.Debug(utils.Format4Output(vendorStoreIDMap, false)) - // globals.SugarLogger.Debug(utils.Format4Output(vendorSkuIDMap, false)) - - vendorID := act2.VendorID - storeSkuList, err2 := dao.GetStoresSkusInfoByVendorInfo(db, vendorID, jxutils.StringMap2List(vendorStoreIDMap), jxutils.StringMap2List(vendorSkuIDMap)) - if err = err2; err != nil { - return nil, nil, err - } - storeSkuMap := make(map[string]*dao.StoreSkuBindWithVendorInfo) - for _, v := range storeSkuList { - storeSkuMap[v.VendorStoreID+"/"+v.VendorSkuID] = v - } - storeSkuMap2 := make(map[int64]int) - for _, v := range actStoreSku { - if storeSkuInfo := storeSkuMap[v.VendorStoreID+"/"+v.VendorSkuID]; storeSkuInfo != nil { - index := jxutils.Combine2Int(storeSkuInfo.StoreID, storeSkuInfo.SkuID) - if storeSkuMap2[index] == 0 { - storeSkuMap2[index] = 1 - actSku := &model.ActStoreSku{ - ActID: act2.ID, - StoreID: storeSkuInfo.StoreID, - SkuID: storeSkuInfo.SkuID, - - Stock: v.Stock, - ActPrice: v.ActualActPrice, - OriginalPrice: int64(storeSkuInfo.Price), - } - dao.WrapAddIDCULDEntity(actSku, ctx.GetUserName()) - actStoreSkuList = append(actStoreSkuList, actSku) - - actSkuMap := &model.ActStoreSkuMap{ - ActID: act2.ID, - VendorActID: act2.VendorActID, - StoreID: storeSkuInfo.StoreID, - SkuID: storeSkuInfo.SkuID, - VendorID: vendorID, - - SyncStatus: 0, - VendorPrice: 0, - ActualActPrice: v.ActualActPrice, - } - dao.WrapAddIDCULDEntity(actSkuMap, ctx.GetUserName()) - actStoreSkuMapList = append(actStoreSkuMapList, actSkuMap) - } - } - } - return actStoreSkuList, actStoreSkuMapList, err -} - -func (a *ActManager) CreateActFromVendor(ctx *jxcontext.Context, act2 *model.Act2, actStoreSku []*model.ActStoreSku2) (actID int, err error) { - globals.SugarLogger.Debugf("CreateActFromVendor vendorID:%d, vendorActID:%s", act2.VendorID, act2.VendorActID) - db := dao.GetDB() - return createActFromVendor(ctx, db, act2, actStoreSku) -} - -func createActFromVendor(ctx *jxcontext.Context, db *dao.DaoDB, act2 *model.Act2, actStoreSku []*model.ActStoreSku2) (actID int, err error) { - actMap := &model.ActMap{ - VendorID: act2.VendorID, - VendorOrgCode: act2.VendorOrgCode, - VendorActID: act2.VendorActID, - SyncStatus: 0, - } - dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName()) - if actMap.VendorActID != "" { - if err = dao.GetEntity(db, actMap, model.FieldVendorActID, model.FieldVendorID, model.FieldDeletedAt); err == nil { - return actMap.ActID, nil - } else if !dao.IsNoRowsError(err) { - return 0, err - } - err = nil - } - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - act := &act2.Act - act.VendorMask = model.GetVendorMask(act2.VendorID) - dao.WrapAddIDCULDEntity(act, ctx.GetUserName()) - err = dao.CreateEntity(db, act) - if err != nil { - dao.Rollback(db) - return 0, err - } - - actMap.ActID = act.ID - err = dao.CreateEntity(db, actMap) - if err != nil { - dao.Rollback(db) - return 0, err - } - actStoreSkuList, actStoreSkuMapList, err := vendorActInfo2Model(ctx, db, act2, actStoreSku) - if err != nil { - dao.Rollback(db) - return 0, err - } - if err = addActStoreSkuBind(ctx, db, actStoreSkuList, actStoreSkuMapList); err != nil { - dao.Rollback(db) - return 0, err - } - dao.Commit(db) - - return act.ID, nil -} - -func (a *ActManager) IsVendorActExist(ctx *jxcontext.Context, vendorActID string, vendorID int) (isExist bool) { - db := dao.GetDB() - actMap := &model.ActMap{ - VendorActID: vendorActID, - VendorID: vendorID, - } - actMap.DeletedAt = utils.DefaultTimeValue - if err := dao.GetEntity(db, actMap, "VendorActID", "VendorID", "DeletedAt"); err == nil { - isExist = true - } - return isExist -} - -func QueryActs(ctx *jxcontext.Context, actID int, offset, pageSize int, syncStatus int, keyword string, vendorID int, statusList, actTypeList, createTypeList []int, storeID, skuID, cityCode int, beginAt, endAt, createdAtFrom, createdAtTo time.Time) (pagedInfo *dao.PagedActListInfo, err error) { - var skuIDs []int - if skuID > 0 { - skuIDs = []int{skuID} - } - return dao.QueryActs(dao.GetDB(), actID, offset, pageSize, syncStatus, keyword, vendorID, statusList, actTypeList, createTypeList, storeID, skuIDs, cityCode, beginAt, endAt, createdAtFrom, createdAtTo) -} - -func GetActStoreSkuInfo(ctx *jxcontext.Context, actID int, vendorIDs []int, keyword string, offset, pageSize int) (retVal interface{}, err error) { - db := dao.GetDB() - totalCount, actStoreSkuList, err := dao.GetActStoreSkuVendorList(db, actID, vendorIDs, nil, nil, keyword, offset, pageSize) - if err != nil { - return nil, err - } - for _, v := range actStoreSkuList { - v.SkuName = jxutils.ComposeSkuName(v.Prefix, v.SkuNameName, v.Comment, v.Unit, v.SpecQuality, v.SpecUnit, 0, v.ExPrefix, v.ExPrefixBegin, v.ExPrefixEnd) - } - if pageSize > 0 && pageSize != model.UnlimitedPageSize { - pagedInfo := &model.PagedInfo{ - TotalCount: totalCount, - Data: actStoreSkuList, - } - retVal = pagedInfo - } else { - retVal = actStoreSkuList - } - return retVal, err -} - -func CancelAct(ctx *jxcontext.Context, actID int) (err error) { - db := dao.GetDB() - if _, err = DeleteActStoreSkuBind(ctx, db, actID, nil); err != nil { - return err - } - _, err = SyncAct(ctx, nil, actID, nil, false) - return err -} - -// actStoreSkuParam为空,不会删除act_store_sku,但会删除act_store_sku_map -func DeleteActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actStoreSkuParam []*ActStoreSkuParam) (originSyncStatus int8, err error) { - actMap, err := dao.GetActVendorInfo(db, actID, nil) - if err != nil { - return 0, err - } - if err = checkActUpdate(actID, actMap); err != nil { - return 0, err - } - - actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, nil, nil) - if err != nil { - return 0, err - } - act := actMap[partner.GetVendorIDsFromActMap(actMap)[0]] - if act.Status != model.ActStatusCreated || time.Now().Sub(act.EndAt) > 0 { - return 0, fmt.Errorf("当前活动状态:%s,不能进行此操作,或已过期", model.ActStatusName[act.Status]) - } - - 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 0, err - } - } - - isNeedCancelAct := true - for vendorID, act := range actMap { - originSyncStatus |= act.SyncStatus - isDeleteAll := true - isDeleteAtLeastOne := false - if true { //actStoreSkuParam != nil { - 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 act.Type == model.ActSkuFake { - _, err = dao.DeleteEntityLogically(db, &model.ActStoreSkuMap{}, nil, ctx.GetUserName(), - map[string]interface{}{ - model.FieldActID: actID, - model.FieldStoreID: actStoreSku.StoreID, - model.FieldSkuID: actStoreSku.SkuID, - }) - } else { - _, err = dao.UpdateEntityLogically(db, partner.ActStoreSku2ActStoreSkuMap(actStoreSku), - map[string]interface{}{ - model.FieldSyncStatus: actStoreSku.SyncStatus | model.SyncFlagDeletedMask, - }, ctx.GetUserName(), nil) - } - if err != nil { - return 0, err - } - isDeleteAtLeastOne = true - } else { - isNeedCancelAct = false - isDeleteAll = false - } - } - } - } else { - isDeleteAll = true - isDeleteAtLeastOne = true - } - if isDeleteAll || isDeleteAtLeastOne { - syncStatus := int8(model.SyncFlagModifiedMask) - if isDeleteAll { - syncStatus = model.SyncFlagDeletedMask - } - syncStatus |= act.SyncStatus - if act.Type != model.ActSkuFake && vendorID != model.VendorIDJX { - if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act), - map[string]interface{}{ - model.FieldSyncStatus: syncStatus, - }, ctx.GetUserName(), nil); err != nil { - return 0, 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 0, err - } - } - dao.Commit(db) - return originSyncStatus, err -} - -func DeleteActStoreSkuList(ctx *jxcontext.Context, db *dao.DaoDB, actStoreSkuList []*model.ActStoreSku2) (actIDs []int, err error) { - if globals.IsStoreSkuAct { - actStoreSkuParamMap := make(map[int][]*ActStoreSkuParam) - for _, v := range actStoreSkuList { - param := &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - ActID: v.ActID, - StoreID: v.StoreID, - SkuID: v.SkuID, - }, - } - actStoreSkuParamMap[v.ActID] = append(actStoreSkuParamMap[v.ActID], param) - } - for actID := range actStoreSkuParamMap { - if _, err = DeleteActStoreSkuBind(ctx, db, actID, actStoreSkuParamMap[actID]); err != nil { - return nil, err - } - } - - for actID := range actStoreSkuParamMap { - actIDs = append(actIDs, actID) - } - } - return actIDs, nil -} - -// todo 当前逻辑要求传入活动的全部SKU信息(以便低层做一些判断,比如全部删除时要取消,所以暂时删除storeIDs与skuIDs这两个参数 -func SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, actID int, vendorIDs /*, storeIDs, skuIDs */ []int, isAsync bool) (hint string, err error) { - db := dao.GetDB() - actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs) - if err != nil { - return "", err - } - actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, nil, nil) - if err != nil { - return "", err - } - if vendorIDs == nil { - vendorIDs = partner.GetVendorIDsFromActMap(actMap) - } - if len(vendorIDs) == 0 || vendorIDs[0] == model.VendorIDJX || actMap[vendorIDs[0]].Type == model.ActSkuFake { - return "", nil - } - task := tasksch.NewParallelTask("SyncAct", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorID := batchItemList[0].(int) - if handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformActHandler); handler != nil { - tmpActMap := &model.ActMap{} - tmpActMap.ID = actMap[vendorID].MapID - if !globals.IsStoreSkuAct || actMap[vendorID].IsSpecial == 0 { - if err = handler.SyncAct(ctx, task, actMap[vendorID], nil, actStoreSkuMap[vendorID]); err == nil { - retVal = []int{1} - } else { - tmpActMap.Remark = utils.LimitUTF8StringLen(err.Error(), 1024) - } - // 保存最后一次同步错误信息 - dao.UpdateEntity(db, tmpActMap, "Remark") - } else { - err = SyncSpecialAct(ctx, task, actMap[vendorID], nil, actStoreSkuMap[vendorID]) - } - } else { - globals.SugarLogger.Warnf("SyncAct strange actID:%d, vendorID:%d", actID, vendorID) - } - return retVal, err - }, vendorIDs) - tasksch.HandleTask(task, parentTask, true).Run() - if !isAsync { - result, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(result)) - } - } else { - hint = task.GetID() - } - return hint, err -} - -func RefreshPageActs(ctx *jxcontext.Context, vendorIDs []int, createdFrom time.Time, isAsync bool) (hint string, err error) { - task := tasksch.NewParallelTask("RefreshPageActs", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorID := batchItemList[0].(int) - if handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformPageActHandler); handler != nil { - db := dao.GetDB() - actList, err2 := handler.GetPageActList(ctx, createdFrom) - globals.SugarLogger.Debug(utils.Format4Output(actList, false)) - if err = err2; err != nil { - return nil, err - } - // actInfo, err2 := dao.QueryActs(db, 0, 0, -1, -1, "", vendorID, nil, []int{model.ActCreateTypeSpider}, - // nil, 0, nil, 0, utils.DefaultTimeValue, utils.DefaultTimeValue, createdFrom, utils.DefaultTimeValue) - vendorActIDs, err2 := dao.GetExistVendorActIDs(db, vendorID) - if err = err2; err != nil { - return nil, err - } - localActMap := jxutils.StringList2Map(vendorActIDs) - // localActMap := make(map[string]*dao.ActVendorInfo) - // for _, v := range vendorActIDs { - // if v.VendorList[0].VendorActID != "" { - // localActMap[v.VendorList[0].VendorActID] = v - // } - // } - var needAddActList []*model.Act2 - // var needUpdateActList []*model.Act - for _, v := range actList { - localAct := localActMap[v.VendorActID] - if localAct == 0 { - if v.Status == model.ActStatusCreated { - needAddActList = append(needAddActList, v) - } - } - // else if v.Status != localAct.Status { - // localAct.Status = v.Status - // needUpdateActList = append(needUpdateActList, &localAct.Act) - // } - } - subTask := tasksch.NewParallelTask("RefreshPageAct Sub", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - act2 := batchItemList[0].(*model.Act2) - actStoreSkuList, err := handler.GetPageActSkuList(ctx, act2.VendorActID) - if err == nil { - retVal = actStoreSkuList - } - return retVal, err - }, needAddActList) - tasksch.AddChild(task, subTask).Run() - - skuList, err2 := subTask.GetResult(0) - if err = err2; err != nil { - return nil, err - } - needAddActSkuMap := make(map[string][]*model.ActStoreSku2) - for _, v := range skuList { - actStoreSku := v.(*model.ActStoreSku2) - needAddActSkuMap[actStoreSku.VendorActID] = append(needAddActSkuMap[actStoreSku.VendorActID], actStoreSku) - } - - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - - for _, v := range needAddActList { - if len(needAddActSkuMap[v.VendorActID]) > 0 { - if _, err = createActFromVendor(ctx, db, v, needAddActSkuMap[v.VendorActID]); err != nil { - return nil, err - } - } - } - // for _, v := range needUpdateActList { - // if _, err = dao.UpdateEntity(db, v, model.FieldStatus); err != nil { - // return nil, err - // } - // } - dao.Commit(db) - } - return retVal, err - }, vendorIDs) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - hint = "1" - _, err = task.GetResult(0) - } else { - hint = task.GetID() - } - return hint, err -} - -func DeleteStoresFromAct(ctx *jxcontext.Context, vendorID int, actTypes, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - task := tasksch.NewParallelTask("将门店从所有活动中删除", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeID := batchItemList[0].(int) - acts, _ := dao.QueryActs(db, 0, 0, 50, -1, "", vendorID, []int{1}, actTypes, nil, storeID, nil, 0, utils.ZeroTimeValue, utils.ZeroTimeValue, time.Now().AddDate(0, -3, 0), time.Now()) - for _, v := range acts.Data { - var actStoreSkuParam []*ActStoreSkuParam - _, actStoreSkus, _ := dao.GetActStoreSkuVendorList(db, v.ID, []int{vendorID}, nil, nil, "", 0, 99999) - for _, actStoreSku := range actStoreSkus { - if actStoreSku.StoreID == storeID { - aa := &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: storeID, - SkuID: actStoreSku.SkuID, - ActID: v.ID, - }, - } - actStoreSkuParam = append(actStoreSkuParam, aa) - } - } - _, err = DeleteActStoreSkuBind(ctx, db, v.ID, actStoreSkuParam) - if err == nil { - _, err = SyncAct(ctx, nil, v.ID, nil, true) - } - } - return retVal, err - }, storeIDs) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - resultList, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(resultList)) - } - } - return hint, err -} - -func DeleteSkusFromAct(ctx *jxcontext.Context, vendorID int, actTypes, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - actMap := make(map[int]*model.Act) - pagedInfo, err2 := dao.QueryActs(db, 0, 0, -1, -1, "", vendorID, []int{model.ActStatusCreated}, actTypes, nil, 0, skuIDs, 0, - utils.DefaultTimeValue, utils.DefaultTimeValue, time.Now().Add(-24*30*3*time.Hour), utils.DefaultTimeValue) - if err = err2; err != nil { - return "", err - } - for _, v := range pagedInfo.Data { - actMap[v.Act.ID] = &v.Act - } - - if len(actMap) == 0 { - return "", nil - } - skuIDMap := jxutils.IntList2Map(skuIDs) - var actIDList []int - for k := range actMap { - actIDList = append(actIDList, k) - } - task := tasksch.NewParallelTask("将SKU从所有活动中删除", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - actID := batchItemList[0].(int) - _, actStoreSkuList, err := dao.GetActStoreSkuVendorList(db, actID, []int{-1}, nil, skuIDs, "", 0, -1) - if err == nil { - // db := dao.GetDB() - var deleteList []*ActStoreSkuParam - for _, v := range actStoreSkuList { - if skuIDMap[v.SkuID] == 1 { - deleteList = append(deleteList, &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: v.StoreID, - SkuID: v.SkuID, - }, - }) - } - } - if len(deleteList) > 0 { - // globals.SugarLogger.Debug(utils.Format4Output(deleteList, false)) - originSyncStatus, err2 := DeleteActStoreSkuBind(ctx, db, actID, deleteList) - if err = err2; err == nil && originSyncStatus == 0 { - if _, err = SyncAct(ctx, task, actID, nil, false); err == nil { - retVal = deleteList - } - } - } - } - return retVal, err - }, actIDList) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - resultList, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(resultList)) - } - } - return hint, err -} - -func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, storeSkuList []*ActStoreSkuParam, lockTime time.Time, isAsync bool) (hint string, err error) { - var wrongSkuList []*ActStoreSkuParam - var storeSkuBindList []*model.StoreSkuBind - - actRule, _ := getActRule(vendorID, actType) - db := dao.GetDB() - errList := errlist.New() - for _, v := range storeSkuList { - storeSkuBind := &model.StoreSkuBind{ - StoreID: v.StoreID, - SkuID: v.SkuID, - } - storeSkuBind.DeletedAt = utils.DefaultTimeValue - if err = dao.GetEntity(db, storeSkuBind, model.FieldStoreID, model.FieldSkuID, model.FieldDeletedAt); err == nil { - vendorPrice := int(v.VendorPrice) - if vendorPrice != 0 { - if err2 := checkDiscountValidation([]int{vendorID}, actType, float64(v.ActPrice)*100/float64(v.VendorPrice)); err2 != nil { - v.ErrMsg = err2.Error() - v.ActualActPrice = v.ActPrice - wrongSkuList = append(wrongSkuList, v) - storeSkuBind = nil - } - } else { - vendorPrice = dao.GetStoreSkuBindVendorPrice(storeSkuBind, vendorID) - if checkDiscountValidation([]int{vendorID}, actType, float64(v.ActPrice)*100/float64(vendorPrice)) != nil { - vendorPrice = int(v.ActPrice)*100/actRule.MaxDiscount + 10 - } else { - storeSkuBind = nil - } - } - if storeSkuBind != nil { - dao.SetStoreSkuBindVendorPrice(storeSkuBind, vendorID, vendorPrice, lockTime) - if vendorID != model.VendorIDJX { - dao.SetStoreSkuBindSyncStatus(storeSkuBind, vendorID, dao.GetStoreSkuBindSyncStatus(storeSkuBind, vendorID)|model.SyncFlagPriceMask) - } - storeSkuBind.LastOperator = ctx.GetUserName() - storeSkuBindList = append(storeSkuBindList, storeSkuBind) - } - } else if dao.IsNoRowsError(err) { // 忽略不存在错 - err = nil - } else { - errList.AddErr(fmt.Errorf("获取门店:%d商品:%d出错:%s", v.StoreID, v.SkuID, err)) - } - } - if err = errList.GetErrListAsOne(); err != nil { - return "", err - } - if len(wrongSkuList) > 0 { - return "", jsonerr.New(wrongSkuList, model.ErrCodeJsonActPriceTooLarger) - } - - storeVendorIDMap := make(map[int]string) - storeSkuIDMap := make(map[int][]int) - - task := tasksch.NewSeqTask2(fmt.Sprintf("强制刷新门店商品%s平台价", model.VendorChineseNames[vendorID]), ctx, false, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - errList := errlist.New() - for _, storeSkuBind := range storeSkuBindList { - if _, err2 := dao.UpdateEntity(db, storeSkuBind); err2 == nil { - if storeVendorIDMap[storeSkuBind.StoreID] == "" { - if storeDetail, err2 := dao.GetStoreDetail(db, storeSkuBind.StoreID, vendorID); err2 == nil { - storeVendorIDMap[storeSkuBind.StoreID] = storeDetail.VendorStoreID - } - } - storeSkuIDMap[storeSkuBind.StoreID] = append(storeSkuIDMap[storeSkuBind.StoreID], storeSkuBind.SkuID) - errList.AddErr(err2) - } - } - err = errList.GetErrListAsOne() - case 1: - if vendorID != model.VendorIDJX && len(storeVendorIDMap) > 0 { - var storeIDs []int - for storeID := range storeVendorIDMap { - storeIDs = append(storeIDs, storeID) - } - subTask := tasksch.NewParallelTask("同步平台价格", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeID := batchItemList[0].(int) - _, err = cms.SyncStoreSkuNew2(ctx, task, 0 /*model.SyncFlagPriceMask*/, vendorID, storeID, storeVendorIDMap[storeID], nil, storeSkuIDMap[storeID], nil, true, false, true) - return retVal, err - }, storeIDs) - tasksch.HandleTask(subTask, task, true).Run() - _, err = subTask.GetResult(0) - } - } - return result, err - }, 2) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - _, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(1) - } - } - return hint, err -} - -func SyncActStoreSku2StoreSkuAct(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, act *model.Act2) (err error) { - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - - // 创建时,会直接覆盖,后续修改时,会判断是否是相同的act_id - // MySql的SET语句,顺序是有关系的,如果当前SET语句中有判断,且依赖于前一条SET过的字段,是用的是SET后的值的 - sql := ` - UPDATE store_sku_act t1 - JOIN act_store_sku_map t2 ON t2.store_id = t1.store_id AND t2.sku_id = t1.sku_id AND t2.vendor_id = t1.vendor_id AND t2.act_id = ? AND t2.sync_status <> 0 - JOIN act_store_sku t3 ON t3.store_id = t1.store_id AND t3.sku_id = t1.sku_id AND t3.act_id = t2.act_id - JOIN act_map t4 ON t4.act_id = t2.act_id AND t4.vendor_id = t2.vendor_id - SET - t1.sync_status = IF(t1.act_percentage = IF(t2.sync_status & ? = 0 AND t3.deleted_at = ?, t3.price_percentage, 0), 0, ?), - t1.act_percentage = IF(t2.sync_status & ? = 0 AND t3.deleted_at = ?, t3.price_percentage, 0), - t1.updated_at = NOW(), - t1.last_operator = ?, - t1.hint_act_id = t2.act_id - WHERE t1.vendor_id = ? AND (t4.sync_status & ? <> 0 OR t1.hint_act_id = t2.act_id) - ` - sqlParams := []interface{}{ - act.ID, - model.SyncFlagDeletedMask, utils.DefaultTimeValue, model.SyncFlagModifiedMask, - model.SyncFlagDeletedMask, utils.DefaultTimeValue, - ctx.GetUserName(), - act.VendorID, model.SyncFlagNewMask, - } - _, err = dao.ExecuteSQL(dao.GetDB(), sql, sqlParams...) - if err != nil { - return err - } - - sql = ` - INSERT INTO store_sku_act(id, created_at, updated_at, last_operator, store_id, sku_id, vendor_id, act_percentage, sync_status, hint_act_id) - SELECT 0, NOW(), NOW(), ?, t2.store_id, t2.sku_id, t2.vendor_id, t3.price_percentage, ?, t2.act_id - FROM act_store_sku_map t2 - JOIN act_store_sku t3 ON t3.store_id = t2.store_id AND t3.sku_id = t2.sku_id AND t3.act_id = t2.act_id - LEFT JOIN store_sku_act t1 ON t2.store_id = t1.store_id AND t2.sku_id = t1.sku_id AND t2.vendor_id = t1.vendor_id - WHERE t2.vendor_id = ? AND t2.act_id = ? AND t2.sync_status <> 0 AND t1.id IS NULL - ` - sqlParams = []interface{}{ - ctx.GetUserName(), model.SyncFlagModifiedMask, - act.VendorID, act.ID, - } - _, err = dao.ExecuteSQL(dao.GetDB(), sql, sqlParams...) - if err != nil { - return err - } - - sql = ` - UPDATE act_store_sku_map t2 - SET - t2.deleted_at = IF(t2.sync_status & ? = 0, t2.deleted_at, NOW()), - t2.sync_status = 0 - WHERE t2.vendor_id = ? AND t2.act_id = ? - ` - sqlParams = []interface{}{ - model.SyncFlagDeletedMask, - act.VendorID, act.ID, - } - _, err = dao.ExecuteSQL(dao.GetDB(), sql, sqlParams...) - if err != nil { - return err - } - - sql = ` - UPDATE act_map t4 - SET - t4.sync_status = 0 - WHERE t4.vendor_id = ? AND t4.act_id = ? - ` - sqlParams = []interface{}{ - act.VendorID, act.ID, - } - _, err = dao.ExecuteSQL(dao.GetDB(), sql, sqlParams...) - if err != nil { - return err - } - - dao.Commit(db) - return err -} - -func SyncSpecialAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { - db := dao.GetDB() - if err = SyncActStoreSku2StoreSkuAct(ctx, db, parentTask, act); err == nil { - err = cms.FullSyncStoreSkuBindAct(ctx, parentTask, act.ID, nil, nil) - } - return err -} - -func CreateActByExcel(ctx *jxcontext.Context, files string, vendorID int, vendorOrgCode string, mixType int, isFocus, isSync, isAsync, isContinueWhenError bool) (hint string, err error) { - // if len(files) == 0 { - // return "", errors.New("没有文件上传!") - // } - // fileHeader := files[0] - // file, err := fileHeader.Open() - hint, err = CreateActByExcelBin(ctx, files, vendorID, vendorOrgCode, mixType, isFocus, isSync, isAsync, isContinueWhenError) - // file.Close() - return hint, err -} - -func CreateActByExcelBin(ctx *jxcontext.Context, reader string, vendorID int, vendorOrgCode string, mixType int, isFocus, isSync, isAsync, isContinueWhenError bool) (hint string, err error) { - sheetParam := &SheetParamAct{ - StoreIDCol: 0, - SkuIDCol: 2, - SkuPricePercentageCol: 4, - ActPriceCol: 5, - EarningPriceCol: 6, - StockCol: 7, - ActTypeCol: 8, - ActPricePercentageCol: 9, - ActNameCol: 10, - BeginTimeCol: 11, - EndTimeCol: 12, - } - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - var ( - actObj = &model.Act{} - actStoreSkuList []*ActStoreSkuParam - actStoreSkusResult []*ActStoreSkuParam - storeIDs []int - ) - switch step { - case 0: - //读取excel文件 - xlsx, err := excelize.OpenFile("111.xlsx") - // xlsx, err := excelize.OpenReader(reader) - if err != nil { - return result, err - } - rows, _ := xlsx.GetRows(xlsx.GetSheetName(1)) - for rowNum, row := range rows { - if rowNum < 1 { - continue - } - loadExcelForCreateAct(rowNum, mixType, row, sheetParam, actObj, actStoreSkuList, storeIDs) - } - case 1: - //叉乘 - if mixType == 2 { - for _, v := range storeIDs { - for _, vv := range actStoreSkuList { - actStoreSkus := &ActStoreSkuParam{} - actStoreSkus = vv - actStoreSkus.StoreID = v - actStoreSkusResult = append(actStoreSkusResult, actStoreSkus) - } - } - _, err = CreateAct(ctx, actObj, []int{vendorID}, vendorOrgCode, nil, actStoreSkusResult, isAsync) - } else if mixType == 1 { - _, err = CreateAct(ctx, actObj, []int{vendorID}, vendorOrgCode, nil, actStoreSkuList, isAsync) - } - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("根据Excel创建活动-序列任务", ctx, isContinueWhenError, taskSeqFunc, 5) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func loadExcelForCreateAct(rowNum, mixType int, row []string, sheetParam *SheetParamAct, actObj *model.Act, actStoreSkuList []*ActStoreSkuParam, storeIDs []int) { - actStoreSku := &ActStoreSkuParam{} - for k, cell := range row { - if rowNum == 1 { - if k == sheetParam.ActTypeCol { - var actType int - for k, v := range model.ActTypeName { - if cell == v { - actType = k - break - } - } - actObj.Type = actType - } - if k == sheetParam.ActPricePercentageCol { - actObj.PricePercentage = int(utils.Str2Float64(cell) * 10) - } - if k == sheetParam.ActNameCol { - actObj.Name = cell - } - if k == sheetParam.BeginTimeCol { - begin, err := time.Parse("2006年1月2日 15:04:05", cell) - if err != nil { - begin = utils.ZeroTimeValue - } - actObj.BeginAt = begin - } - if k == sheetParam.EndTimeCol { - end, err := time.Parse("2006年1月2日 15:04:05", cell) - if err != nil { - end = utils.ZeroTimeValue - } - actObj.EndAt = end - } - } - if k == sheetParam.StoreIDCol { - //一行一行 - if mixType == 1 { - actStoreSku.StoreID = int(utils.Str2Int64(cell)) - } else if mixType == 2 { - storeIDs = append(storeIDs, int(utils.Str2Int64(cell))) - } - } - if k == sheetParam.SkuIDCol { - actStoreSku.SkuID = int(utils.Str2Int64(cell)) - } - if k == sheetParam.SkuPricePercentageCol { - actStoreSku.PricePercentage = int(utils.Str2Float64WithDefault(cell, 0) * 10) - } - if k == sheetParam.ActPriceCol { - actStoreSku.ActPrice = int64(utils.Str2Float64(cell) * 100) - } - if k == sheetParam.EarningPriceCol { - actStoreSku.EarningPrice = int64(utils.Str2Float64(cell) * 100) - } - if k == sheetParam.StockCol { - actStoreSku.Stock = int(utils.Str2Int64(cell)) - } - } - actStoreSkuList = append(actStoreSkuList, actStoreSku) -} - -func ChangeJxPriceByDiscountAct(ctx *jxcontext.Context) { - var ( - db = dao.GetDB() - pageSize = 9999 - ) - globals.SugarLogger.Debug("ChangeJxPriceByDiscountAct begin:") - page, err := dao.QueryActs(db, 0, 0, pageSize, -1, "", model.VendorIDJX, []int{model.YES}, []int{model.ActSkuDiscount}, nil, 0, nil, 0, utils.ZeroTimeValue, utils.ZeroTimeValue, time.Now().AddDate(0, -3, 0), time.Now()) - if err != nil { - return - } - if len(page.Data) == 0 { - return - } - for _, act := range page.Data { - _, actStoreSkus, _ := dao.GetActStoreSkuVendorList(db, act.ID, nil, nil, nil, "", 0, pageSize) - if len(actStoreSkus) == 0 { - continue - } - for _, actStoreSku2 := range actStoreSkus { - actStoreSkuMap := &model.ActStoreSkuMap{ - ModelIDCULD: model.ModelIDCULD{ - ID: actStoreSku2.MapID, - }, - ActID: actStoreSku2.ActID, - StoreID: actStoreSku2.StoreID, - SkuID: actStoreSku2.SkuID, - TrendPrice: actStoreSku2.TrendPrice, - TrendType: actStoreSku2.TrendType, - ActualActPrice: actStoreSku2.ActualActPrice, - VendorPrice: actStoreSku2.VendorPrice, - } - storeSkus, _ := dao.GetStoresSkusInfo(db, []int{actStoreSkuMap.StoreID}, []int{actStoreSkuMap.SkuID}) - if len(storeSkus) == 0 { - continue - } - var ( - storeSku = storeSkus[0] - shouldStockOut = utils.Float64TwoInt64(math.Ceil(float64(storeSku.Stock) / float64(60))) //每个时间点应出货 = 总库存/60 = N - actualStockOut int64 //每个时间点实际出货 = C - pricePercentage float64 //每次涨跌值为 原价的 2%,即原价100,每个时间点降价为2,涨价也为2 - actualPrice int64 - minJxPrice int64 - ) - if storeSku.Stock == 0 { - continue - } - actualStockOut, err = dao.GetOrderStoreSkusCount(db, actStoreSkuMap.StoreID, actStoreSkuMap.SkuID, time.Now().Add(-time.Minute*10), time.Now()) - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - //第一档时间内 - if (time.Now().Hour() >= 10 && time.Now().Hour() < 20) || (time.Now().Hour() == 20 && time.Now().Minute() < 1) { - pricePercentage = 0.02 - actualPrice = utils.Float64TwoInt64(float64(actStoreSkuMap.VendorPrice) * pricePercentage) - if actStoreSkuMap.TrendType == model.TrendTypeUp { - actStoreSkuMap.ActualActPrice = actStoreSkuMap.ActualActPrice + actualPrice - // storeSku.JxPrice = storeSku.JxPrice + int(actualPrice) - } else if actStoreSkuMap.TrendType == model.TrendTypeDown { - actStoreSkuMap.ActualActPrice = actStoreSkuMap.ActualActPrice - actualPrice - //判断活动的折扣类型是最低价还是最低折扣(第一档) - if act.DiscountType == model.ActDiscountTypePrice { - minJxPrice = int64(act.DiscountValue1) - } else if act.DiscountType == model.ActDiscountTypePercentage { - minJxPrice = actStoreSkuMap.VendorPrice * int64(act.DiscountValue1) / 100 - } - if actStoreSkuMap.ActualActPrice <= minJxPrice { - actStoreSkuMap.ActualActPrice = minJxPrice - } - // storeSku.JxPrice = storeSku.JxPrice - int(actualPrice) - stock := checkPriceDefendOrderByPrice(db, storeSku.StoreID, storeSku.SkuID, storeSku.Stock, int(actStoreSkuMap.ActualActPrice)) - if stock != -1 { - storeSku.Stock = stock - if _, err = dao.UpdateEntity(db, storeSku, "Stock"); err != nil { - dao.Rollback(db) - } - } - } - if actStoreSkuMap.ActualActPrice >= actStoreSkuMap.VendorPrice { - actStoreSkuMap.ActualActPrice = actStoreSkuMap.VendorPrice - } - // if _, err = dao.UpdateEntity(db, actStoreSkuMap, "ActualActPrice"); err != nil { - // dao.Rollback(db) - // } - //C >= 2N 涨价趋势,最高涨价到无折扣 - if actualStockOut >= 2*shouldStockOut { - actStoreSkuMap.TrendType = model.TrendTypeUp - if actStoreSkuMap.ActualActPrice == actStoreSkuMap.VendorPrice { - actStoreSkuMap.TrendType = model.TrendTypeNothing - } - } else if actualStockOut < utils.Float64TwoInt64(math.Ceil(float64(shouldStockOut)/float64(2))) { //C <= N/2 降价趋势,最低降价到设置到最低折扣 - actStoreSkuMap.TrendType = model.TrendTypeDown - if actStoreSkuMap.ActualActPrice == minJxPrice { - actStoreSkuMap.TrendType = model.TrendTypeNothing - } - } else { - actStoreSkuMap.TrendType = model.TrendTypeNothing - } - actStoreSkuMap.TrendPrice = int(actualPrice) - if _, err = dao.UpdateEntity(db, actStoreSkuMap, "ActualActPrice", "TrendType", "TrendPrice"); err != nil { - dao.Rollback(db) - } - } else { //第二档时间内 - pricePercentage = 0.1 - actualPrice = utils.Float64TwoInt64(float64(actStoreSkuMap.VendorPrice) * pricePercentage) - //判断活动的折扣类型是最低价还是最低折扣(第二档) - if act.DiscountType == model.ActDiscountTypePrice { - minJxPrice = int64(act.DiscountValue2) - } else if act.DiscountType == model.ActDiscountTypePercentage { - minJxPrice = actStoreSkuMap.VendorPrice * int64(act.DiscountValue2) / 100 - } - if actStoreSkuMap.ActualActPrice == minJxPrice { - actStoreSkuMap.TrendType = model.TrendTypeNothing - } else { - actStoreSkuMap.TrendType = model.TrendTypeDown - } - actStoreSkuMap.TrendPrice = int(actualPrice) - // if _, err = dao.UpdateEntity(db, actStoreSkuMap, "TrendType", "TrendPrcie"); err != nil { - // dao.Rollback(db) - // } - actStoreSkuMap.ActualActPrice = actStoreSkuMap.ActualActPrice - actualPrice - if actStoreSkuMap.ActualActPrice <= minJxPrice { - actStoreSkuMap.ActualActPrice = minJxPrice - } - stock := checkPriceDefendOrderByPrice(db, storeSku.StoreID, storeSku.SkuID, storeSku.Stock, int(actStoreSkuMap.ActualActPrice)) - if stock != -1 { - storeSku.Stock = stock - if _, err = dao.UpdateEntity(db, storeSku, "Stock"); err != nil { - dao.Rollback(db) - } - } - //22:00 恢复库存为100,价格恢复原价 - if time.Now().Hour() == 22 && time.Now().Minute() < 1 { - storeSku.Stock = 100 - if _, err = dao.UpdateEntity(db, storeSku, "Stock"); err != nil { - dao.Rollback(db) - } - actStoreSkuMap.ActualActPrice = actStoreSkuMap.VendorPrice - actStoreSkuMap.TrendType = model.TrendTypeNothing - actStoreSkuMap.TrendPrice = 0 - } - if _, err = dao.UpdateEntity(db, actStoreSkuMap, "ActualActPrice", "TrendType", "TrendPrice"); err != nil { - dao.Rollback(db) - } - } - dao.Commit(db) - } - } -} - -func checkPriceDefendOrderByPrice(db *dao.DaoDB, storeID, skuID, stock, jxPrice int) (realStock int) { - priceDefends, _ := dao.GetPriceDefendOrder(db, "", []int{storeID}, []int{skuID}, []int{jxutils.GetDefendPriceIssue()}, 0, 0, 0, 1, "", utils.ZeroTimeValue, utils.ZeroTimeValue, false) - if len(priceDefends) == 0 { - return -1 - } - for _, v := range priceDefends { - //如果刚好守的价和降的价一样,再判断库存够不够 - if v.DefendPrice > int64(jxPrice) { - if v.Count <= stock { - stock -= v.Count - v.IsSuccess = model.YES - v.RealPrice = int64(jxPrice) - dao.UpdateEntity(db, v, "IsSuccess", "RealPrice") - } else { - continue - } - } else { - continue - } - } - return stock -} - - diff --git a/business/jxstore/act/act_test.go b/business/jxstore/act/act_test.go deleted file mode 100644 index dd76e8cf3..000000000 --- a/business/jxstore/act/act_test.go +++ /dev/null @@ -1,209 +0,0 @@ -package act - -import ( - "testing" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/testinit" - - "git.rosy.net.cn/jx-callback/business/model" - - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm" -) - -func init() { - testinit.Init() -} - -func TestInitDb(t *testing.T) { - dao.ExecuteSQL(dao.GetDB(), ` - DROP TABLE IF EXISTS act, act_map, act_order_rule, act_store_sku, act_store_sku_map; - `) -} - -func TestCreateActOnAlpha(t *testing.T) { - actStoreSkuList := []*ActStoreSkuParam{ - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 2, - SkuID: 2142, - }, - }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 2, - SkuID: 1162, - }, - }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 2, - SkuID: 1167, - }, - }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 2, - SkuID: 1172, - }, - }, - } - t.Log(utils.Format4Output(actStoreSkuList, true)) - // actID, err := CreateAct(jxcontext.AdminCtx, &model.Act{ - // Name: "测试活动", - // PricePercentage: 80, - // Type: model.ActSkuDirectDown, - // }, []int{model.VendorIDJD, model.VendorIDMTWM, model.VendorIDEBAI}, nil, actStoreSkuList, false) - // if err != nil { - // t.Fatal(err) - // } - // globals.SugarLogger.Debug(actID) -} - -func TestCreateActOnDev(t *testing.T) { - actStoreSkuList := []*ActStoreSkuParam{ - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 100884, - SkuID: 22716, - }, - }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 100884, - SkuID: 22717, - }, - }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 100920, - SkuID: 22714, - }, - }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 100920, - SkuID: 22715, - }, - }, - // &ActStoreSkuParam{ - // ActStoreSku: model.ActStoreSku{ - // StoreID: 100119, - // SkuID: 26595, - // }, - // }, - } - // t.Log(utils.Format4Output(actStoreSkuList, true)) - actID, err := CreateAct(jxcontext.AdminCtx, &model.Act{ - Name: "测试活动", - PricePercentage: 80, - Type: model.ActSkuDirectDown, - BeginAt: time.Now().Add(-24 * time.Hour), - EndAt: time.Now().Add(10 * 24 * time.Hour), - }, []int{model.VendorIDJD, model.VendorIDMTWM /*, model.VendorIDEBAI*/}, nil, actStoreSkuList, false) - if err != nil { - t.Fatal(err) - } - globals.SugarLogger.Debug(actID) -} - -func TestCancelAct(t *testing.T) { - err := CancelAct(jxcontext.AdminCtx, 1) - if err != nil { - t.Fatal(err) - } -} - -func TestDeleteActStoreBind(t *testing.T) { - _, err := DeleteActStoreSkuBind(jxcontext.AdminCtx, dao.GetDB(), 1, []*ActStoreSkuParam{ - // &ActStoreSkuParam{ - // ActStoreSku: model.ActStoreSku{ - // StoreID: 100119, - // SkuID: 30828, - // }, - // }, - // &ActStoreSkuParam{ - // ActStoreSku: model.ActStoreSku{ - // StoreID: 100119, - // SkuID: 30827, - // }, - // }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 100884, - SkuID: 22716, - }, - }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 100884, - SkuID: 22717, - }, - }, - }) - if err != nil { - t.Fatal(err) - } -} - -func TestAddActStoreBind(t *testing.T) { - err := AddActStoreSkuBind(jxcontext.AdminCtx, dao.GetDB(), 1, []*ActStoreSkuParam{ - // &ActStoreSkuParam{ - // ActStoreSku: model.ActStoreSku{ - // StoreID: 100119, - // SkuID: 30828, - // }, - // }, - // &ActStoreSkuParam{ - // ActStoreSku: model.ActStoreSku{ - // StoreID: 100119, - // SkuID: 30827, - // }, - // }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 100884, - SkuID: 22716, - }, - }, - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 100884, - SkuID: 22717, - }, - }, - }) - if err != nil { - t.Fatal(err) - } -} - -func TestSyncAct(t *testing.T) { - _, err := SyncAct(jxcontext.AdminCtx, nil, 1, nil, false) - if err != nil { - t.Fatal(err) - } -} - -func TestForceUpdateVendorPrice(t *testing.T) { - hint, err := ForceUpdateVendorPrice(jxcontext.AdminCtx, model.VendorIDJD, model.ActSkuDirectDown, []*ActStoreSkuParam{ - &ActStoreSkuParam{ - ActStoreSku: model.ActStoreSku{ - StoreID: 100118, - SkuID: 22509, - ActPrice: 9900, - }, - VendorPrice: 19900, - }, - }, false) - if err != nil { - t.Fatal(err) - } - t.Log(hint) -} diff --git a/business/jxstore/misc/misc.go b/business/jxstore/misc/misc.go index 9c2cb8b85..a8d89d3ad 100644 --- a/business/jxstore/misc/misc.go +++ b/business/jxstore/misc/misc.go @@ -1,531 +1,27 @@ package misc import ( - "fmt" - "strings" - "sync" "time" - "git.rosy.net.cn/jx-callback/business/partner/purchase/jdshop" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" - - "git.rosy.net.cn/jx-callback/business/partner/purchase/jx/localjx" - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/jx-callback/business/jxstore/event" - - "git.rosy.net.cn/jx-callback/business/jxstore/report" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" - "git.rosy.net.cn/jx-callback/business/jxstore/act" - "git.rosy.net.cn/jx-callback/business/jxstore/cms" "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/netprinter" - "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/netspider" - "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" - "github.com/astaxie/beego" -) - -const ( - SpecialTaskID = "Running" - TaskNameSyncStoreSku = "SyncStoreSku" ) var ( - dailyHeartbeat = []string{ - "09:00:00", - } dailyWorkTimeList = []string{ "20:30:00", } - dailyWorkTimeList2 = []string{ - "02:00:00", - } - priceReferTimeList = []string{ - "03:00:00", - } - checkCookieList = []string{ - "08:00:00", - "12:00:00", - "18:00:00", - } - createStorePriceTimeList = []string{ - "04:00:00", - } - refreshPageActTimeList = []string{ - "7:00:00", - "8:00:00", - "9:00:00", - "10:00:00", - "11:00:00", - "12:00:00", - "13:00:00", - "14:00:00", - "15:00:00", - "16:00:00", - "17:00:00", - "18:00:00", - "19:00:00", - "22:00:00", - } - ChangeStoreSkuSaleStatusList = []string{ - "7:00:00", - "8:00:00", - "9:00:00", - "10:00:00", - "11:00:00", - "12:00:00", - "13:00:00", - "14:00:00", - "15:00:00", - "16:00:00", - "17:00:00", - "18:00:00", - "19:00:00", - "20:00:00", - } - openRemoteStoreTimeList = []string{ - "04:30:00", - "23:30:00", - } - updateActStatusTimeList = []string{ - "00:01:00", - } - sendSecKillWarnList = []string{ - "9:00:00", - } - autoPayForPopluarManList = []string{ - "10:30:00", - } - - autoSaleStoreSkuTimeList = []string{ - cms.AutoSaleAtStr, - } - - backUpStoreSkuBindList = []string{ - "23:30:00", - } - - exSyncList = []string{ - "11:30:00", - } - - importantTaskMap = &sync.Map{} - - cancelPayTimeOutOrderList = localjx.GetHalfHoursList() - discountActJxList = localjx.GetDiscountActHoursList() - - ebaiStorePageCookieExdTOKEN string - ebaiStorePageCookieWMUSS2 string - ebaiStorePageCookieWMSTOKEN2 string - ebaiStorePageCookieWMUSS string - ebaiStorePageCookieWMSTOKEN string - mtwmCookieStr string - mtpsStoreToken string - jd2StorePageCookie string - JdStorePageCookie string - yinbaoCookie string - feiePageCookie string - jdStorePageEarning string - jdsCookie string ) -func GetImportantTaskID(taskName string) string { - if value, ok := importantTaskMap.Load(taskName); ok { - return value.(string) - } - return "" -} - -func SaveImportantTaskID(taskName, taskID string) { - importantTaskMap.Store(taskName, taskID) -} - -func IsImportantTaskRunning(taskName string) bool { - taskID := GetImportantTaskID(taskName) - if taskID == "" { - return false - } else if taskID == SpecialTaskID { - return true - } - return tasksch.IsTaskRunning(taskID) -} - func Init() { if globals.IsProductEnv() { ScheduleTimerFunc("doDailyWork", doDailyWork, dailyWorkTimeList) - - ScheduleTimerFunc("doDailyWork2", doDailyWork2, dailyWorkTimeList2) - - // ScheduleTimerFuncByInterval(func() { - // orderman.SaveJdsOrders(jxcontext.AdminCtx, time.Now().Add(-20*time.Minute), time.Now()) - // }, 10*time.Second, 10*time.Minute) - - //京东的订单信息解密密钥获取 - ScheduleTimerFuncByInterval(func() { - jdshop.InitKey() - }, 10*time.Second, 8*time.Hour) - - ScheduleTimerFuncByInterval(func() { - RefreshRealMobile(jxcontext.AdminCtx, model.VendorIDEBAI, time.Now().Add(-24*time.Hour), utils.DefaultTimeValue, false, true) - }, 5*time.Second, 1*time.Hour) - - ScheduleTimerFuncByInterval(func() { - defsch.FixedScheduler.ConfirmSelfTakeOrders(jxcontext.AdminCtx, []int{model.VendorIDJD}, time.Now().Add(-48*time.Hour), time.Now().Add(-30*time.Minute), true, true) - }, 5*time.Second, 10*time.Minute) - - ScheduleTimerFunc("auto enable remote store", func() { - cms.EnableHaveRestStores(jxcontext.AdminCtx, false, true) - cms.OpenRemoteStoreByJxStatus(jxcontext.AdminCtx, nil, nil, false, false, true) - }, openRemoteStoreTimeList) - - ScheduleTimerFunc("SaveAndSendAlarmVendorSnapshot", func() { - cms.SaveAndSendAlarmVendorSnapshot(jxcontext.AdminCtx, nil, nil, false) - }, cms.WatchVendorStoreTimeList) - - ScheduleTimerFunc("RefreshPageActs", func() { - act.RefreshPageActs(jxcontext.AdminCtx, []int{model.VendorIDEBAI}, time.Now().Add(-30*24*time.Hour), false) - }, refreshPageActTimeList) - ScheduleTimerFunc("UpdateActStatusByTime", func() { - dao.UpdateActStatusByTime(dao.GetDB(), time.Now()) - }, updateActStatusTimeList) - ScheduleScoreStore() - ScheduleCheckStoreAlert() - ScheduleTimerFunc("ChangeStoreSkuSaleStatus", func() { - cms.CurVendorSync.ChangeStoreSkuSaleStatus(jxcontext.AdminCtx, 0, true, true) - }, ChangeStoreSkuSaleStatusList) - ScheduleTimerFunc("BeginSavePriceRefer", func() { - report.BeginSavePriceRefer(jxcontext.AdminCtx, nil, nil, true, true) - }, priceReferTimeList) - ScheduleTimerFunc("CreateStorePriceScore", func() { - cms.CreateStorePriceScore(jxcontext.AdminCtx) - }, createStorePriceTimeList) - ScheduleTimerFunc("AutoFocusStoreSkusForTopSkus", func() { - cms.AutoFocusStoreSkusForTopSkus(jxcontext.AdminCtx, true, true) - }, createStorePriceTimeList) - ScheduleTimerFunc("GetCheckVendorCookie", func() { - event.GetCheckVendorCookie(jxcontext.AdminCtx, []int{model.VendorIDEBAI, model.VendorIDJD, model.VendorIDMTWM, model.VendorIDMTPS, model.VendorIDJDShop}, true) - }, checkCookieList) - ScheduleTimerFunc("SendSeckillSkusCountMsg", func() { - cms.SendSeckillSkusCountMsg(jxcontext.AdminCtx, []int{model.VendorIDEBAI, model.VendorIDJD, model.VendorIDMTWM}, false, true) - }, sendSecKillWarnList) - ScheduleTimerFunc("每日报警心跳", func() { - globals.SugarLogger.Warnf("每日报警心跳,这不是报警。启动时间:%s", cms.GetServiceInfo(jxcontext.AdminCtx)["startupTime"]) - }, dailyHeartbeat) - ScheduleTimerFunc("AutoPayForPopluarMan", func() { - localjx.AutoPayForPopluarMan(jxcontext.AdminCtx) - }, autoPayForPopluarManList) - ScheduleTimerFunc("CancelPayTimeOutOrder", func() { - localjx.CancelPayTimeOutOrder(jxcontext.AdminCtx) - }, cancelPayTimeOutOrderList) - ScheduleTimerFunc("BackUpStoreSkuBind", func() { - cms.BackUpStoreSkuBind(jxcontext.AdminCtx, true, true) - }, backUpStoreSkuBindList) - ScheduleTimerFunc("SendNoCatSkusToOperater", func() { - cms.SendNoCatSkusToOperater(jxcontext.AdminCtx) - }, autoPayForPopluarManList) - ScheduleTimerFunc("CleanStoreIsBoughtMatter", func() { - cms.CleanStoreIsBoughtMatter(jxcontext.AdminCtx) - }, priceReferTimeList) - ScheduleTimerFunc("CleanUserOrderSMSMark", func() { - cms.CleanUserOrderSMSMark(jxcontext.AdminCtx) - }, priceReferTimeList) - ScheduleTimerFunc("exSync", func() { - var ( - db = dao.GetDB() - storeList []int - exSyncStoreIDList string - syncFlag = 0 - ) - syncFlag = model.SyncFlagPriceMask - if (time.Now().Unix()/24*3600)%10 == 0 { - syncFlag |= model.SyncFlagSaleMask - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "exSyncStoreIDList", model.ConfigTypeSys, ""); err == nil { - exSyncStoreIDList = configs[0].Value - } - storeIDList := strings.Split(exSyncStoreIDList, ",") - for _, v := range storeIDList { - storeList = append(storeList, int(utils.Str2Int64(v))) - } - cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, partner.GetMultiStoreVendorIDs(), storeList, false, nil, []int{27379}, syncFlag, true, true) - }, exSyncList) - ScheduleTimerFunc("CreateOrderByPriceDefend", func() { - localjx.CreateOrderByPriceDefend(jxcontext.AdminCtx) - }, []string{ - "22:00:00", - }) - ScheduleTimerFunc("ChangeJxPriceByDiscountAct", func() { - act.ChangeJxPriceByDiscountAct(jxcontext.AdminCtx) - }, discountActJxList) - ScheduleTimerFunc("RefreshUserMemberStatus", func() { - cms.RefreshUserMemberStatus(jxcontext.AdminCtx) - }, updateActStatusTimeList) } - ScheduleTimerFunc("AutoSaleStoreSku", func() { - cms.AutoSaleStoreSku(jxcontext.AdminCtx, nil, false) - }, autoSaleStoreSkuTimeList) - - if beego.BConfig.RunMode == "jxgy" { - ScheduleTimerFunc("SyncMatterC4ToGy", func() { - cms.SyncMatterC4ToGy(jxcontext.AdminCtx, true, true) - }, dailyWorkTimeList) - } - if beego.BConfig.RunMode == "beta" { - ScheduleTimerFunc("CancelPayTimeOutOrder", func() { - localjx.CancelPayTimeOutOrder(jxcontext.AdminCtx) - }, cancelPayTimeOutOrderList) - ScheduleTimerFunc("GetAndStoreCitiesShops", func() { - netspider.GetAndStoreCitiesShops(jxcontext.AdminCtx, nil, nil, 0, 0, false, false) - }, []string{ - "04:05:06", - }) - //京东的订单信息解密密钥获取 - ScheduleTimerFuncByInterval(func() { - jdshop.InitKey() - }, 10*time.Second, 8*time.Hour) - ScheduleTimerFunc("ChangeJxPriceByDiscountAct", func() { - act.ChangeJxPriceByDiscountAct(jxcontext.AdminCtx) - }, discountActJxList) - ScheduleTimerFunc("CreateOrderByPriceDefend", func() { - localjx.CreateOrderByPriceDefend(jxcontext.AdminCtx) - }, []string{ - "22:00:00", - }) - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "ebaiStorePageCookieExdTOKEN", model.ConfigTypeCookie, ""); err == nil { - ebaiStorePageCookieExdTOKEN = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "ebaiStorePageCookieWMUSS2", model.ConfigTypeCookie, ""); err == nil { - ebaiStorePageCookieWMUSS2 = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "ebaiStorePageCookieWMSTOKEN2", model.ConfigTypeCookie, ""); err == nil { - ebaiStorePageCookieWMSTOKEN2 = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "ebaiStorePageCookieWMUSS", model.ConfigTypeCookie, ""); err == nil { - ebaiStorePageCookieWMUSS = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "ebaiStorePageCookieWMSTOKEN", model.ConfigTypeCookie, ""); err == nil { - ebaiStorePageCookieWMSTOKEN = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "mtwmCookieStr", model.ConfigTypeCookie, ""); err == nil { - mtwmCookieStr = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "mtpsStoreToken", model.ConfigTypeCookie, ""); err == nil { - mtpsStoreToken = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "jdStorePageCookie", model.ConfigTypeCookie, ""); err == nil { - JdStorePageCookie = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "jdStorePageEarning", model.ConfigTypeCookie, ""); err == nil { - jdStorePageEarning = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "jd2StorePageCookie", model.ConfigTypeCookie, ""); err == nil { - jd2StorePageCookie = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "feiePageCookie", model.ConfigTypeCookie, ""); err == nil { - feiePageCookie = configs[0].Value - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "jdsCookie", model.ConfigTypeCookie, ""); err == nil { - jdsCookie = configs[0].Value - api.JdShopAPI.SetCookieWithStr(jdsCookie) - } - if configs, err := dao.QueryConfigs(dao.GetDB(), "yinbaoCookie", model.ConfigTypeCookie, ""); err == nil { - yinbaoCookie := configs[0].Value - api.YinBaoAPI.SetCookie(".POSPALAUTH30220", yinbaoCookie) - } - if globals.Jd2OrgCode != "" { - api.Jd2API.SetJdCookie(jd2StorePageCookie) - } - api.EbaiAPI.SetCookie("PASSPORT_DELIMONT_TOKEN", ebaiStorePageCookieExdTOKEN) - api.EbaiAPI.SetCookie("WMUSS", ebaiStorePageCookieWMUSS) - api.EbaiAPI.SetCookie("WMSTOKEN", ebaiStorePageCookieWMSTOKEN) - api.Ebai2API.SetCookie("PASSPORT_DELIMONT_TOKEN", ebaiStorePageCookieExdTOKEN) - api.Ebai2API.SetCookie("WMUSS", ebaiStorePageCookieWMUSS2) - api.Ebai2API.SetCookie("WMSTOKEN", ebaiStorePageCookieWMSTOKEN2) - api.MtwmAPI.SetCookieWithStr(mtwmCookieStr) - api.MtpsAPI.SetCookie("token", mtpsStoreToken) - api.JdAPI.SetJdCookie(JdStorePageCookie) - api.JdAPI.SetCookie("user", jdStorePageEarning) - api.JdPageAPI.SetCookie(jdapi.AccessStorePageCookieName, JdStorePageCookie) - api.JdPageAPI.SetCookie(jdapi.AccessStorePageCookieName2, JdStorePageCookie) - api.FeieAPI.SetCookieWithStr(feiePageCookie) -} - -func syncStoreSku() { - syncFlag := 0 - // syncFlag := model.SyncFlagPriceMask - // if (time.Now().Unix()/24*3600)%10 == 0 { - // syncFlag |= model.SyncFlagSaleMask - // } - task := tasksch.NewParallelTask("同步京西与平台数据", nil, jxcontext.AdminCtx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - errList := errlist.New() - db := dao.GetDB() - switch step { - case 0: - errList.AddErr(cms.DeleteSkuNameExPrefixOverdue(db)) - errList.AddErr(cms.SetMultiStoreSkuSyncModifyStatus(db, partner.GetMultiStoreVendorIDs())) - - _, err = cms.CurVendorSync.LoopMultiStoresVendors(jxcontext.AdminCtx, db, "同步多门店平台商品库", false, true, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorInfo := batchItemList[0].(*cms.MultiStoreVendorInfo) - _, err = cms.FullSyncVendorStuff(jxcontext.AdminCtx, task, vendorInfo.VendorID, vendorInfo.OrgCode, false, true) - return retVal, err - }) - errList.AddErr(err) - - _, err = cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{0}, nil, false, nil, []int{27379}, syncFlag, true, true) - // _, err = cms.CurVendorSync.FullSyncStoresSkus(jxcontext.AdminCtx, db, partner.GetMultiStoreVendorIDs(), nil, false, []int{27379}, true, true) - errList.AddErr(err) - case 1: - //TODO 暂时不同步银豹(可能要从银豹到京西),2020-04-27 - errList.AddErr(cms.SetSingleStoreSkuSyncModifyStatus(db, []int{1, 3})) - - // errList.AddErr(cms.SetSingleStoreSkuSyncModifyStatus(db, partner.GetSingleStoreVendorIDs())) - // _, err = cms.CurVendorSync.AmendAndPruneStoreStuff(jxcontext.AdminCtx, []int{1, 3}, nil, false, true, cms.AmendPruneAll, false) - - // _, err = cms.CurVendorSync.AmendAndPruneStoreStuff(jxcontext.AdminCtx, partner.GetSingleStoreVendorIDs(), nil, false, true, cms.AmendPruneAll, false) - errList.AddErr(err) - - SaveImportantTaskID(TaskNameSyncStoreSku, SpecialTaskID) - taskID, err2 := cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{1, 3, 5}, nil, false, nil, nil, syncFlag, true, true) - // taskID, err2 := cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, partner.GetSingleStoreVendorIDs(), nil, false, nil, nil, syncFlag, true, true) - - errList.AddErr(err2) - SaveImportantTaskID(TaskNameSyncStoreSku, taskID) - } - err = errList.GetErrListAsOne() - return retVal, err - }, []int{0, 1}) - tasksch.HandleTask(task, nil, true).Run() -} - -func doDailyWork2() { - globals.SugarLogger.Debug("doDailyWork2") - - //同步京东商城门店的商品 - cms.CurVendorSync.SyncJdsStoresSkus(jxcontext.AdminCtx, nil, true, true) - //刷新京东商城的门店库存 - cms.SyncJdsStoreStock(jxcontext.AdminCtx, true, true) } func doDailyWork() { globals.SugarLogger.Debug("doDailyWork") - - //同步商品额外前缀和水印图(打标记) - cms.SyncSkuExperfixAndWatermark(jxcontext.AdminCtx) - - dao.SetStoresMapSyncStatus(dao.GetDB(), nil, nil, model.SyncFlagStoreStatus) - cms.CurVendorSync.SyncStore2(jxcontext.AdminCtx, dao.GetDB(), nil, nil, true, true) - - syncStoreSku() - InitEx() - cms.SyncStoresCourierInfo(jxcontext.AdminCtx, nil, false, true) - netprinter.RebindAllPrinters(jxcontext.AdminCtx, false, true) - - // 每天补全前一天与当天的订单 - curDate := utils.Time2Date(time.Now()) - orderman.FixedOrderManager.AmendMissingOrders(jxcontext.AdminCtx, nil, 0, curDate.Add(-72*time.Hour), curDate, true, true) - //订单门店归属补漏 - //fromDate, toDate都不传默认刷新当前天5天以前的订单,只传fromDate默认刷新fromDate到当天的订单 - //只传toDate默认刷新toDate到5天以前的订单 - orderman.RefreshOrdersWithoutJxStoreID(jxcontext.AdminCtx, "", "", true, true) - //刷新京东门店的等级 - cms.RefreshJdLevel(jxcontext.AdminCtx) - //删除操作日志 - // event.DeleteOperateEventAndDetail(jxcontext.AdminCtx, time.Now().AddDate(0, -3, 0)) - //禁用没有绑定的门店 - cms.DisabledStoreWithoutVendor(jxcontext.AdminCtx, true, true) - //刷新物料订单状态 - localjx.RefreshAllMatterOrderStatus(jxcontext.AdminCtx) - //同步银豹到京西 - // cms.CurVendorSync.SyncStoreSkusFromYb(jxcontext.AdminCtx, nil, true, true) - //刷新京东商城订单结算价 - orderman.RefreshJdShopOrdersEarningPrice(jxcontext.AdminCtx, time.Now().AddDate(0, 0, -2).Format("20060102"), time.Now().Format("20060102")) - //同步上架京东商城待售商品 - cms.RefreshJdsSkusStatus(jxcontext.AdminCtx) - //同步美团配送与否状态及美团门店是否存在 - cms.SetMTPSStatus(jxcontext.AdminCtx, 0, 0) - //售后单如果超过12小时没有审核,就自动通过 - RefreshAfsOrderStatusAccess(jxcontext.AdminCtx) -} - -func RefreshAfsOrderStatusAccess(ctx *jxcontext.Context) { - var ( - offset = 0 - pageSize = 9999 - db = dao.GetDB() - ) - afsOrderList, _, err := dao.GetAfsOrdersByPage(db, "", "", "", time.Now().AddDate(0, 0, -7), time.Now(), offset, pageSize) - if err != nil { - return - } - for _, v := range afsOrderList { - if v.Status == model.AfsOrderStatusWait4Approve && time.Now().Sub(v.AfsCreatedAt).Hours() > 12 { - defsch.FixedScheduler.AgreeOrRefuseRefund(ctx, v.AfsOrderID, v.VendorID, model.AfsTypePartRefund, "超时系统同意") - } - } -} - -func RefreshRealMobile(ctx *jxcontext.Context, vendorID int, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debug("RefreshRealMobile") - - handler := partner.GetPurchasePlatformFromVendorID(vendorID) - if handler == nil { - return "", fmt.Errorf("不合法的vendorID:%d", vendorID) - } - sql := ` - SELECT * - FROM goods_order - WHERE vendor_id = ? AND consignee_mobile2 = '' - ` - sqlParams := []interface{}{ - vendorID, - } - if !utils.IsTimeZero(fromTime) { - sql += " AND order_created_at >= ?" - sqlParams = append(sqlParams, fromTime) - } - if !utils.IsTimeZero(toTime) { - sql += " AND order_created_at <= ?" - sqlParams = append(sqlParams, toTime) - } - var orderList []*model.GoodsOrder - db := dao.GetDB() - if err = dao.GetRows(db, &orderList, sql, sqlParams...); err == nil && len(orderList) > 0 { - task := tasksch.NewParallelTask("misc RefreshRealMobile", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - order := batchItemList[0].(*model.GoodsOrder) - mobile, err2 := handler.GetOrderRealMobile(ctx, order) - if err = err2; err == nil { - mobile = jxutils.FormalizeMobile(mobile) - if jxutils.IsStringLikeMobile(mobile) && strings.Index(order.ConsigneeMobile, mobile) == -1 { - order.ConsigneeMobile2 = mobile - _, err = dao.UpdateEntity(db, order, "ConsigneeMobile2") - } - } else { - globals.SugarLogger.Infof("RefreshRealMobile orderID:%s failed with error:%v", order.VendorOrderID, err) - } - return nil, err - }, orderList) - tasksch.HandleTask(task, nil, true).Run() - hint = task.ID - if !isAsync { - _, err = task.GetResult(0) - } - } - return hint, err } // 按时间序列循环 diff --git a/business/jxstore/misc/misc2.go b/business/jxstore/misc/misc2.go deleted file mode 100644 index c39f735d3..000000000 --- a/business/jxstore/misc/misc2.go +++ /dev/null @@ -1,396 +0,0 @@ -package misc - -import ( - "strings" - "sync" - "time" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxstore/cms" - "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/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - enableScheduleRefreshStore = true - taskParallelCount = 4 - specialSkuNameKeyWord = "温馨提示" - startOpStoreStockNumber = 0 - endOpStoreStockNumber = model.MaxStoreSkuStockQty -) - -var ( - isDaemonRunning = false - vendorList = map[int]bool{ - model.VendorIDMTWM: true, - model.VendorIDEBAI: true, - } - storeListQueueData = map[bool]*StoreListQueueData{ - true: &StoreListQueueData{}, - false: &StoreListQueueData{}, - } - // vendorStoreRefreshTimeList = map[int][]string { - // model.VendorIDMTWM: []string { - // //start and end time for JXGY - // "22:00:00", - // "00:00:00", - // //start and end time for JXCS - // "22:10:00", - // "00:10:00", - // }, - // model.VendorIDEBAI: []string { - // "22:20:00", - // "06:00:00", - - // "22:30:00", - // "06:10:00", - // }, - // } - - // vendorStartEndStoreTime = map[int][]int16 { - // model.VendorIDMTWM: []int16 { - // int16(2200),//start time - // int16(2355),//end time - // }, - // model.VendorIDEBAI: []int16 { - // int16(5), - // int16(2355), - // }, - // } -) - -type StoreListQueueData struct { - waitQueue []*cms.StoreExt - processQueue []*cms.StoreExt - locker sync.RWMutex -} - -func (s *StoreListQueueData) GetProcessQueue() (outQueue []*cms.StoreExt) { - s.locker.RLock() - defer s.locker.RUnlock() - outQueue = append(outQueue, s.processQueue...) - return outQueue -} - -func (s *StoreListQueueData) InsertToWaitQueue(storeInfo *cms.StoreExt) { - s.locker.Lock() - defer s.locker.Unlock() - s.waitQueue = append(s.waitQueue, storeInfo) -} - -func (s *StoreListQueueData) ClearProcessQueue() { - s.locker.Lock() - defer s.locker.Unlock() - if len(s.processQueue) > 0 { - s.processQueue = []*cms.StoreExt{} - } -} - -func (s *StoreListQueueData) TransferWaitQueueToProcessQueue() { - s.locker.Lock() - defer s.locker.Unlock() - if len(s.processQueue) == 0 && len(s.waitQueue) > 0 { - for _, value := range s.waitQueue { - s.processQueue = append(s.processQueue, value) - } - s.waitQueue = []*cms.StoreExt{} - } -} - -func AddOrDelExtraStoreOptime(ctx *jxcontext.Context, vendorID int, vendorOrgCode string, storeID int, vendorStoreID string, storeInfo *model.Store, startOpStoreTime, endOpStoreTime int16, needAddTime bool) bool { - opTimeList := storeInfo.GetOpTimeList() - if needAddTime { - opTimeList = []int16{startOpStoreTime, endOpStoreTime} - } - handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IStoreHandler) - return handler.UpdateStoreOpTime(ctx, vendorOrgCode, storeID, vendorStoreID, opTimeList) == nil -} - -func GetStockValue(isStart bool) int { - if isStart { - return startOpStoreStockNumber - } else { - return endOpStoreStockNumber - } -} - -// func GetOpStoreTime(vendorID int) (startTime, endTime int16) { -// startTime = vendorStartEndStoreTime[vendorID][0] -// endTime = vendorStartEndStoreTime[vendorID][1] -// return startTime, endTime -// } - -func IsSpecialSku(name string) bool { - return strings.Contains(name, specialSkuNameKeyWord) -} - -func SetSkuStock(isStart bool, storeSkuNameList []*partner.SkuNameInfo) { - for _, skuNameInfo := range storeSkuNameList { - for _, skuInfo := range skuNameInfo.SkuList { - if IsSpecialSku(skuNameInfo.Name) || IsSpecialSku(skuInfo.SkuName) { - skuInfo.Stock = endOpStoreStockNumber - } else { - skuInfo.Stock = GetStockValue(isStart) - } - } - } -} - -func SetSpecialSkuStatus(ctx *jxcontext.Context, vendorID int, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuNameList []*partner.SkuNameInfo) { - singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - for _, skuNameInfo := range storeSkuNameList { - for _, skuInfo := range skuNameInfo.SkuList { - if IsSpecialSku(skuNameInfo.Name) || IsSpecialSku(skuInfo.SkuName) { - storeSkuList := []*partner.StoreSkuInfo{&skuInfo.StoreSkuInfo} - singleStoreHandler.UpdateStoreSkusStatus(ctx, vendorOrgCode, storeID, vendorStoreID, storeSkuList, model.SkuStatusNormal) - } - } - } -} - -func GetFilterStoreSkuList(storeSkuList []*partner.StoreSkuInfo) (storeSkuListOut []*partner.StoreSkuInfo) { - for _, value := range storeSkuList { - if value.SkuID != 0 { - storeSkuListOut = append(storeSkuListOut, value) - } - } - - return storeSkuListOut -} - -func GetStoreList(ctx *jxcontext.Context) (storeList []*cms.StoreExt, err error) { - storeInfo, err := cms.GetStores(ctx, "", map[string]interface{}{}, 0, -1, utils.DefaultTimeValue, utils.DefaultTimeValue, 0, 0) - storeList = storeInfo.Stores - return storeList, err -} - -func GetFilterStoreList(storeList []*cms.StoreExt, vendorMap, storeIDMap map[int]bool) (outStoreList []*cms.StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - //filter for storeID - if len(storeIDMap) > 0 { - if _, ok := storeIDMap[storeID]; !ok { - continue - } - } - for _, vendorStoreInfo := range storeInfo.StoreMaps { - vendorID := vendorStoreInfo.VendorID - //filter for vendorID - if len(vendorMap) > 0 { - if _, ok := vendorMap[vendorID]; !ok { - continue - } - } - if _, ok := vendorList[vendorID]; !ok { - continue - } - temp := *storeInfo - newStoreInfo := &temp - newStoreInfo.StoreMaps = []*model.StoreMap{vendorStoreInfo} - outStoreList = append(outStoreList, newStoreInfo) - } - } - - return outStoreList -} - -func StartOrEndOpStore(ctx *jxcontext.Context, isStart bool, vendorIDList []int, storeIDList []int, startTime, endTime int16, isAsync, isContinueWhenError bool) (retVal interface{}, err error) { - storeList, err := GetStoreList(ctx) - vendorMap := make(map[int]bool) - for _, vendorID := range vendorIDList { - vendorMap[vendorID] = true - } - storeIDMap := make(map[int]bool) - for _, storeID := range storeIDList { - storeIDMap[storeID] = true - } - storeList = GetFilterStoreList(storeList, vendorMap, storeIDMap) - return StartOrEndOpStoreEx(ctx, isStart, startTime, endTime, isAsync, isContinueWhenError, storeList) -} - -func StartOrEndOpStoreEx(ctx *jxcontext.Context, isStart bool, startTime, endTime int16, isAsync, isContinueWhenError bool, storeList []*cms.StoreExt) (retVal interface{}, err error) { - startProcessTime := time.Now().Unix() - baseapi.SugarLogger.Debugf("StartOrEndOpStore start time: %v", time.Now()) - - if len(storeList) > 0 { - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeListValue := batchItemList[0].(*cms.StoreExt) - storeID := storeListValue.ID - for _, vendorListValue := range storeListValue.StoreMaps { - vendorID := vendorListValue.VendorID - startOpStoreTime := vendorListValue.FakeOpenStart - endOpStoreTime := vendorListValue.FakeOpenStop - //startOpStoreTime, endOpStoreTime := GetOpStoreTime(vendorID) - if startTime != 0 && endTime != 0 { - startOpStoreTime = startTime - endOpStoreTime = endTime - baseapi.SugarLogger.Debugf("StartOrEndOpStore SetStoreOptime:%d do:%d", startTime, endTime) - } - if isStart && (startOpStoreTime == 0 || endOpStoreTime == 0) { - continue - } - vendorStoreID := vendorListValue.VendorStoreID - baseapi.SugarLogger.Debugf("StartOrEndOpStore storeID:%d vendorID:%d vendorStoreID:%s", storeID, vendorID, vendorStoreID) - singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - storeSkuNameList, err := singleStoreHandler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, nil) - if err != nil { - baseapi.SugarLogger.Errorf("StartOrEndOpStore GetStoreSkusFullInfo error:%v storeID:%d vendorID:%d vendorStoreID:%s", err, storeID, vendorID, vendorStoreID) - } else { - SetSkuStock(isStart, storeSkuNameList) - SetSpecialSkuStatus(ctx, vendorID, vendorListValue.VendorOrgCode, storeID, vendorStoreID, storeSkuNameList) - storeSkuList := putils.StoreSkuFullList2Bare(storeSkuNameList) - if vendorID == model.VendorIDMTWM { - storeSkuList = GetFilterStoreSkuList(storeSkuList) - } - if len(storeSkuList) > 0 { - if !isStart { - AddOrDelExtraStoreOptime(ctx, vendorID, vendorListValue.VendorOrgCode, storeID, vendorStoreID, &storeListValue.Store, startOpStoreTime, endOpStoreTime, false) - } - - _, err = putils.FreeBatchStoreSkuInfo("更新门店商品库存", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - _, err = singleStoreHandler.UpdateStoreSkusStock(ctx, vendorListValue.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList) - return nil, 0, err - }, ctx, task, storeSkuList, singleStoreHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStock), true) - - if isStart { - AddOrDelExtraStoreOptime(ctx, vendorID, vendorListValue.VendorOrgCode, storeID, vendorStoreID, &storeListValue.Store, startOpStoreTime, endOpStoreTime, true) - } - } - } - } - return retVal, err - } - taskName := "" - if isStart { - taskName = "开启平台商店的额外营业时间" - } else { - taskName = "结束平台商店的额外营业时间" - } - task := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetParallelCount(taskParallelCount), ctx, taskFunc, storeList) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - retVal = task.ID - } else { - _, err = task.GetResult(0) - if err != nil { - baseapi.SugarLogger.Debugf("StartOrEndOpStore tasksch error:%v", err) - } - retVal = "1" - } - } - endProcessTime := time.Now().Unix() - diff := endProcessTime - startProcessTime - baseapi.SugarLogger.Debugf("StartOrEndOpStore end time: %v", time.Now()) - baseapi.SugarLogger.Debugf("StartOrEndOpStore cost time: %d sec", diff) - - return retVal, err -} - -func IsJXCS() bool { - return globals.IsMainProductEnv() -} - -// func GetVendorStoreRefreshTime(vendorID int) (startTimeList, stopTimeList []string) { -// isJXCS := globals.IsMainProductEnv() -// refreshTimeList := vendorStoreRefreshTimeList[vendorID] -// if isJXCS { -// startTimeList = []string{refreshTimeList[2]} -// stopTimeList = []string{refreshTimeList[3]} -// } else { -// startTimeList = []string{refreshTimeList[0]} -// stopTimeList = []string{refreshTimeList[1]} -// } -// return startTimeList, stopTimeList -// } - -// func RefreshStore(vendorID int) { -// ctx := jxcontext.AdminCtx -// startTimeList, stopTimeList := GetVendorStoreRefreshTime(vendorID) -// vendorIDList := []int{vendorID} -// storeIDList := []int{} -// ScheduleTimerFunc("StartOpStore", func() { -// if !IsImportantTaskRunning(TaskNameSyncStoreSku) { -// StartOrEndOpStore(ctx, true, vendorIDList, storeIDList, 0, 0, false, true) -// } -// }, startTimeList) -// ScheduleTimerFunc("EndOpStore", func() { -// if !IsImportantTaskRunning(TaskNameSyncStoreSku) { -// StartOrEndOpStore(ctx, false, vendorIDList, storeIDList, 0, 0, false, true) -// } -// }, stopTimeList) -// } - -func InitEx() { - // for index, value := range vendorList { - // if value { - // RefreshStore(index) - // } - // } - if enableScheduleRefreshStore && IsJXCS() { - ctx := jxcontext.AdminCtx - storeList, err := GetStoreList(ctx) - storeList = GetFilterStoreList(storeList, map[int]bool{}, map[int]bool{}) - if err == nil { - for _, storeInfo := range storeList { - for _, vendorStoreInfo := range storeInfo.StoreMaps { - startOpStoreTime := vendorStoreInfo.FakeOpenStart - endOpStoreTime := vendorStoreInfo.FakeOpenStop - if startOpStoreTime == 0 || endOpStoreTime == 0 { - continue - } - - startTime := jxutils.OperationTime2StrWithSecond(startOpStoreTime) - ScheduleTimerFuncOnce("StartOpStore", func(param interface{}) { - if !IsImportantTaskRunning(TaskNameSyncStoreSku) { - storeInfo := param.(*cms.StoreExt) - storeListQueueData[true].InsertToWaitQueue(storeInfo) - } - }, startTime, storeInfo) - - stopTime := jxutils.OperationTime2StrWithSecond(endOpStoreTime) - ScheduleTimerFuncOnce("EndOpStore", func(param interface{}) { - storeInfo := param.(*cms.StoreExt) - storeListQueueData[false].InsertToWaitQueue(storeInfo) - }, stopTime, storeInfo) - } - } - if !isDaemonRunning { - isDaemonRunning = true - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - periodlyFunc := func() { - for isStart, value := range storeListQueueData { - storeList := value.GetProcessQueue() - if len(storeList) > 0 { - StartOrEndOpStoreEx(ctx, isStart, 0, 0, false, true, storeList) - } - } - for _, value := range storeListQueueData { - value.ClearProcessQueue() - value.TransferWaitQueueToProcessQueue() - } - } - PeriodlyCall(60*time.Second, periodlyFunc) - } - return result, err - } - taskSeq := tasksch.NewSeqTask("启动监听-定时刷新平台商店的额外营业时间", ctx, taskSeqFunc, 1) - tasksch.HandleTask(taskSeq, nil, true).Run() - } - } - } -} - -func PeriodlyCall(d time.Duration, handler func()) { - ticker := time.NewTicker(d) - for _ = range ticker.C { - handler() - } -} diff --git a/business/jxstore/misc/misc2_test.go b/business/jxstore/misc/misc2_test.go deleted file mode 100644 index e6627a75a..000000000 --- a/business/jxstore/misc/misc2_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package misc - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" -) - -func TestStartOrEndOpStore(t *testing.T) { - StartOrEndOpStore(jxcontext.AdminCtx, true, nil, nil, 0, 0, false, true) -} diff --git a/business/jxstore/misc/store_alert_inform.go b/business/jxstore/misc/store_alert_inform.go deleted file mode 100644 index 25b7bfd02..000000000 --- a/business/jxstore/misc/store_alert_inform.go +++ /dev/null @@ -1,509 +0,0 @@ -package misc - -import ( - "fmt" - "math" - "time" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxstore/cms" - "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/weixinmsg" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals/refutil" -) - -const ( - EnableCheckStoreAlert = true - EnableSendStoreAlert = true - - IncludeToday = true - CheckStoreAlertOneMonthDayNum = 30 - CheckStoreAlertOneDayNum = 1 - CheckStoreAlertOneWeekDayNum = 7 - MonthCheckOnWeekDay = 1 - - AlertTypePickTimeOrderDaDa = 0 - AlertTypeBadCommentOrder = 1 - AlertTypeAbsentGoodsOrder = 2 - AlertTypeStandardFinishTimeOrderSelfDelivery = 3 - AlertTypeStandardPickUpTimeOrderDaDa = 4 - - ColorRed = "red" - ColorYellow = "yellow" - ColorUnknown = "unknown" - - AlertLevelExtraRed = 1 - AlertLevelRed = 2 - AlertLevelYellow = 3 - - OneDayName = "单日" - OneWeekDayName = "七日" - OneMonthDayName = "三十日" - YellowAlertInfo = "您的店铺-%s,由于%s%s%s%d%%,可能会被系统下线,请及时补救。" - RedAlertInfo = "您的店铺-%s,由于%s%s%s%d%%,会被系统下线,需要马上补救。" - ExtraRedAlertInfo = "您的店铺-%s,由于%s%s%s%d%%,会被系统下线,需要马上补救。" - NoOrderAlertInfo = "您的店铺-%s,由于近%s无订单,会被系统下线,需要马上补救。" - RiskOrderAlertInfo = "您的店铺-%s,可能有虚假定单,定单号为:%s,可能会被罚款,请及时与运营联系!" -) - -var ( - checkStoreAlertTimeList = []string{ - "18:30:00", - } - - AlertTypeNameMap = map[int]string{ - AlertTypePickTimeOrderDaDa: "拣货履约率(达达)", - AlertTypeBadCommentOrder: "差评率", - AlertTypeAbsentGoodsOrder: "缺货率", - AlertTypeStandardFinishTimeOrderSelfDelivery: "按时履约率(商家自送)", - AlertTypeStandardPickUpTimeOrderDaDa: "10分钟取货完成率(达达)", - } - - AlertTypeExtraNameMap = map[int]string{ - AlertTypePickTimeOrderDaDa: "拣货超时订单(达达)", - AlertTypeBadCommentOrder: "差评订单", - AlertTypeAbsentGoodsOrder: "缺货订单", - } - - storeAlertDataWrapper StoreAlertDataWrapper -) - -type StoreAlertDataWrapper struct { - storeAlertList map[int]*model.StoreAlert -} - -func (s *StoreAlertDataWrapper) InitData() { - s.storeAlertList = make(map[int]*model.StoreAlert) -} - -func (s *StoreAlertDataWrapper) ClearData() { - s.storeAlertList = nil -} - -func (s *StoreAlertDataWrapper) IsStatusField(valueName string) bool { - return valueName == model.FieldYellowStatus || valueName == model.FieldRedStatus || valueName == model.FieldExtraRedStatus -} - -func (s *StoreAlertDataWrapper) SetData(storeID int, valueName string, value int) { - data := s.storeAlertList[storeID] - if data == nil { - data = &model.StoreAlert{} - data.StoreID = storeID - data.AlertDate = utils.GetCurDate() - s.storeAlertList[storeID] = data - } - if s.IsStatusField(valueName) { - srcFieldValue := refutil.GetObjFieldByName(data, valueName).(int) - value |= srcFieldValue - } - refutil.SetObjFieldByName(data, valueName, value) -} - -func (s StoreAlertDataWrapper) InsertStoreAlertList() { - for _, value := range s.storeAlertList { - dao.InsertStoreAlert(value) - } -} - -func ConvertListToMap(listData []*model.StoreCount) (mapData map[int]int) { - mapData = make(map[int]int) - for _, value := range listData { - mapData[value.StoreID] = value.Count - } - - return mapData -} - -func ConvertListToMapEx(listData []*model.StoreOrder) (mapData map[int][]string) { - mapData = make(map[int][]string) - for _, value := range listData { - if mapData[value.StoreID] == nil { - mapData[value.StoreID] = []string{} - } - mapData[value.StoreID] = append(mapData[value.StoreID], value.VendorOrderID) - } - - return mapData -} - -func GetAlertInfo(dayNum, alertLevel int, storeName string, alertType int, logicCondition string, value int) (info string) { - if dayNum == CheckStoreAlertOneDayNum { - if alertLevel == AlertLevelExtraRed { - info = fmt.Sprintf(ExtraRedAlertInfo, storeName, OneDayName, AlertTypeExtraNameMap[alertType], logicCondition, value) - } else if alertLevel == AlertLevelRed { - info = fmt.Sprintf(RedAlertInfo, storeName, OneDayName, AlertTypeNameMap[alertType], logicCondition, value) - } else if alertLevel == AlertLevelYellow { - info = fmt.Sprintf(YellowAlertInfo, storeName, OneDayName, AlertTypeNameMap[alertType], logicCondition, value) - } - } else if dayNum == CheckStoreAlertOneWeekDayNum { - if alertLevel == AlertLevelExtraRed { - info = fmt.Sprintf(ExtraRedAlertInfo, storeName, OneWeekDayName, AlertTypeExtraNameMap[alertType], logicCondition, value) - } else if alertLevel == AlertLevelRed { - info = fmt.Sprintf(RedAlertInfo, storeName, OneWeekDayName, AlertTypeNameMap[alertType], logicCondition, value) - } else if alertLevel == AlertLevelYellow { - info = fmt.Sprintf(YellowAlertInfo, storeName, OneWeekDayName, AlertTypeNameMap[alertType], logicCondition, value) - } - } else if dayNum == CheckStoreAlertOneMonthDayNum { - info = fmt.Sprintf(NoOrderAlertInfo, storeName, OneMonthDayName) - } - - return info -} - -func CheckAlert(alertType int, dayNum int, ratio int, count int) (alertLevel int, logicCondtion string, outValue int) { - yellowRatio := -1 - redRatio := -1 - extraCount := -1 - conditionLessEqual := false - - switch alertType { - case AlertTypePickTimeOrderDaDa: - if dayNum == CheckStoreAlertOneDayNum { - redRatio = 0 - } else if dayNum == CheckStoreAlertOneWeekDayNum { - yellowRatio = 70 - redRatio = 50 - extraCount = 5 - } - conditionLessEqual = true - case AlertTypeBadCommentOrder: - if dayNum == CheckStoreAlertOneDayNum { - redRatio = 100 - } else if dayNum == CheckStoreAlertOneWeekDayNum { - yellowRatio = 1 - redRatio = 3 - extraCount = 5 - } - conditionLessEqual = false - case AlertTypeAbsentGoodsOrder: - if dayNum == CheckStoreAlertOneDayNum { - redRatio = 100 - } else if dayNum == CheckStoreAlertOneWeekDayNum { - yellowRatio = 3 - redRatio = 5 - extraCount = 5 - } - conditionLessEqual = false - case AlertTypeStandardFinishTimeOrderSelfDelivery: - yellowRatio = 85 - redRatio = 70 - conditionLessEqual = true - case AlertTypeStandardPickUpTimeOrderDaDa: - yellowRatio = 85 - redRatio = 70 - conditionLessEqual = true - } - - if conditionLessEqual { - logicCondtion = "<=" - if extraCount != -1 && count >= extraCount { - alertLevel = AlertLevelExtraRed - outValue = extraCount - } else if redRatio != -1 && ratio <= redRatio { - alertLevel = AlertLevelRed - outValue = redRatio - } else if yellowRatio != -1 && ratio <= yellowRatio { - alertLevel = AlertLevelYellow - outValue = yellowRatio - } - } else { - logicCondtion = ">=" - if extraCount != -1 && count >= extraCount { - alertLevel = AlertLevelExtraRed - outValue = extraCount - } else if redRatio != -1 && ratio >= redRatio { - alertLevel = AlertLevelRed - outValue = redRatio - } else if yellowRatio != -1 && ratio >= yellowRatio { - alertLevel = AlertLevelYellow - outValue = yellowRatio - } - } - - return alertLevel, logicCondtion, outValue -} - -func SendAlertInfo(storeID int, storeName, alertInfo string) { - if EnableSendStoreAlert { - baseapi.SugarLogger.Debugf("SendAlertInfo: %d, %s", storeID, alertInfo) - weixinmsg.NotifyStoreAlertMessage(storeID, storeName, "门店警告", alertInfo) - } -} - -func GetFieldNameByAlertType(alertType, dayNum int) (fieldName string, fieldFlag int) { - switch alertType { - case AlertTypePickTimeOrderDaDa: - if dayNum == CheckStoreAlertOneDayNum { - fieldName = model.FieldPickTimeDaDa - fieldFlag = model.FlagPickTimeDaDa - } else if dayNum == CheckStoreAlertOneWeekDayNum { - fieldName = model.FieldPickTimeDaDaOneWeek - fieldFlag = model.FlagPickTimeDaDaOneWeek - } - case AlertTypeBadCommentOrder: - if dayNum == CheckStoreAlertOneDayNum { - fieldName = model.FieldBadComment - fieldFlag = model.FlagBadComment - } else if dayNum == CheckStoreAlertOneWeekDayNum { - fieldName = model.FieldBadCommentOneWeek - fieldFlag = model.FlagBadCommentOneWeek - } - case AlertTypeAbsentGoodsOrder: - if dayNum == CheckStoreAlertOneDayNum { - fieldName = model.FieldAbsentGoods - fieldFlag = model.FlagAbsentGoods - } else if dayNum == CheckStoreAlertOneWeekDayNum { - fieldName = model.FieldAbsentGoodsOneWeek - fieldFlag = model.FlagAbsentGoodsOneWeek - } - case AlertTypeStandardFinishTimeOrderSelfDelivery: - fieldName = model.FieldStandardFinishTimeSelfDelivery - fieldFlag = model.FlagStandardFinishTimeSelfDelivery - case AlertTypeStandardPickUpTimeOrderDaDa: - fieldName = model.FieldStandardPickUpTimeDaDa - fieldFlag = model.FlagStandardPickUpTimeDaDa - } - - return fieldName, fieldFlag -} - -func SendAlertInfoWrapper(storeID int, storeName string, dayNum, alertType, count, totalCount int) { - if totalCount > 0 { - ratio := int(math.Round(float64(count) * 100 / float64(totalCount))) - alertLevel, logicCondtion, outValue := CheckAlert(alertType, dayNum, ratio, count) - if alertLevel != 0 { - alertInfo := GetAlertInfo(dayNum, alertLevel, storeName, alertType, logicCondtion, outValue) - SendAlertInfo(storeID, storeName, alertInfo) - fieldName, fieldFlag := GetFieldNameByAlertType(alertType, dayNum) - storeAlertDataWrapper.SetData(storeID, fieldName, ratio) - - if alertLevel == AlertLevelExtraRed { - storeAlertDataWrapper.SetData(storeID, model.FieldExtraRedStatus, fieldFlag) - } else if alertLevel == AlertLevelRed { - storeAlertDataWrapper.SetData(storeID, model.FieldRedStatus, fieldFlag) - } else if alertLevel == AlertLevelYellow { - storeAlertDataWrapper.SetData(storeID, model.FieldYellowStatus, fieldFlag) - } - } - } -} - -func CheckStoreDayAlert(storeList []*cms.StoreExt, dayNum int) { - db := dao.GetDB() - //拣货履约订单(达达) - pickTimeOrderCountDaDaList, _ := dao.GetStandardPickTimeOrderCountByDaDa(db, dayNum, IncludeToday) - pickTimeOrderCountDaDaMapData := ConvertListToMap(pickTimeOrderCountDaDaList) - - //完成订单(达达) - finishOrderCountDaDaList, _ := dao.GetFinishOrderCountByDaDa(db, dayNum, IncludeToday) - finishOrderCountDaDaMapData := ConvertListToMap(finishOrderCountDaDaList) - - //差评订单 - badCommentOrderCountList, _ := dao.GetBadCommentOrderCountByDayNum(db, dayNum, IncludeToday) - badCommentOrderCountMapData := ConvertListToMap(badCommentOrderCountList) - - //缺货订单 - absentGoodsOrderCountList, _ := dao.GetAbsentGoodsOrderCountByDayNum(db, dayNum, IncludeToday) - absentGoodsOrderCountMapData := ConvertListToMap(absentGoodsOrderCountList) - - //完成订单 - finishOrderCountList, _ := dao.GetFinishOrderCountByDayNum(db, dayNum, IncludeToday) - finishOrderCountMapData := ConvertListToMap(finishOrderCountList) - - var standardFinishTimeOrderCountSelfDeliveryList []*model.StoreCount - var standardFinishTimeOrderCountSelfDeliveryMapData map[int]int - var finishOrderCountSelfDeliveryList []*model.StoreCount - var finishOrderCountSelfDeliveryMapData map[int]int - var standardPickUpTimeOrderCountDaDaList []*model.StoreCount - var standardPickUpTimeOrderCountDaDaMapData map[int]int - isOneWeekDay := dayNum == CheckStoreAlertOneWeekDayNum - if isOneWeekDay { - //按时履约订单(商家自送) - standardFinishTimeOrderCountSelfDeliveryList, _ = dao.GetStandardFinishTimeOrderCountBySelfDelivery(db, dayNum, IncludeToday) - standardFinishTimeOrderCountSelfDeliveryMapData = ConvertListToMap(standardFinishTimeOrderCountSelfDeliveryList) - - //完成订单(商家自送) - finishOrderCountSelfDeliveryList, _ = dao.GetFinishOrderCountBySelfDelivery(db, dayNum, IncludeToday) - finishOrderCountSelfDeliveryMapData = ConvertListToMap(finishOrderCountSelfDeliveryList) - - //10分钟取货完成订单(达达) - standardPickUpTimeOrderCountDaDaList, _ = dao.GetStandardPickUpTimeOrderCountByDaDa(db, dayNum, IncludeToday) - standardPickUpTimeOrderCountDaDaMapData = ConvertListToMap(standardPickUpTimeOrderCountDaDaList) - } - - for _, storeInfo := range storeList { - storeID := storeInfo.ID - storeName := storeInfo.Name - count := pickTimeOrderCountDaDaMapData[storeID] - totalCount := finishOrderCountDaDaMapData[storeID] - SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypePickTimeOrderDaDa, count, totalCount) - - count = badCommentOrderCountMapData[storeID] - totalCount = finishOrderCountMapData[storeID] - SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypeBadCommentOrder, count, totalCount) - count = absentGoodsOrderCountMapData[storeID] - SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypeAbsentGoodsOrder, count, totalCount) - - if isOneWeekDay { - count = standardFinishTimeOrderCountSelfDeliveryMapData[storeID] - totalCount = finishOrderCountSelfDeliveryMapData[storeID] - SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypeStandardFinishTimeOrderSelfDelivery, count, totalCount) - - count = standardPickUpTimeOrderCountDaDaMapData[storeID] - totalCount = finishOrderCountDaDaMapData[storeID] - SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypeStandardPickUpTimeOrderDaDa, count, totalCount) - } - } -} - -func CheckStoreMonthAlert(storeList []*cms.StoreExt) { - db := dao.GetDB() - storeCountList, _ := dao.GetFinishOrderCountByDayNum(db, CheckStoreAlertOneMonthDayNum, IncludeToday) - storeCountMapData := make(map[int]int) - for _, value := range storeCountList { - storeCountMapData[value.StoreID] = value.Count - } - - for _, storeInfo := range storeList { - storeID := storeInfo.ID - storeName := storeInfo.Name - if _, ok := storeCountMapData[storeID]; !ok { - alertInfo := GetAlertInfo(CheckStoreAlertOneMonthDayNum, AlertLevelRed, storeName, -1, "", -1) - SendAlertInfo(storeID, storeName, alertInfo) - storeAlertDataWrapper.SetData(storeID, model.FieldNoOrderInMonth, 1) - storeAlertDataWrapper.SetData(storeID, model.FieldRedStatus, model.FlagNoOrderInMonth) - } - } -} - -func CheckStoreRiskOrderAlert(storeList []*cms.StoreExt, dayNum int) { - db := dao.GetDB() - storeOrderList, _ := dao.GetRiskOrderCount(db, dayNum, IncludeToday) - storeOrderMapData := ConvertListToMapEx(storeOrderList) - for _, storeInfo := range storeList { - storeID := storeInfo.ID - storeName := storeInfo.Name - vendorOrderIDList := storeOrderMapData[storeID] - if vendorOrderIDList != nil { - vendorOrderIDStr := "" - for index, vendorOrderID := range vendorOrderIDList { - if index == 0 { - vendorOrderIDStr += vendorOrderID - } else { - vendorOrderIDStr += "," + vendorOrderID - } - } - alertInfo := fmt.Sprintf(RiskOrderAlertInfo, storeName, vendorOrderIDStr) - SendAlertInfo(storeID, storeName, alertInfo) - storeAlertDataWrapper.SetData(storeID, model.FieldRiskOrderCount, len(vendorOrderIDList)) - storeAlertDataWrapper.SetData(storeID, model.FieldRedStatus, model.FlagRiskOrderCount) - } - } -} - -func GetWeekDay() int { - return int(time.Now().Weekday()) -} - -func CheckStoreAlert(ctx *jxcontext.Context, storeIDList []int) { - storeAlertDataWrapper.InitData() - storeList, _ := GetStoreList(ctx) - storeIDMap := jxutils.IntList2Map(storeIDList) - storeList = GetFilterStoreListEx(storeList, storeIDMap) - if GetWeekDay() == MonthCheckOnWeekDay { - CheckStoreMonthAlert(storeList) - } - CheckStoreDayAlert(storeList, CheckStoreAlertOneDayNum) - CheckStoreDayAlert(storeList, CheckStoreAlertOneWeekDayNum) - CheckStoreRiskOrderAlert(storeList, CheckStoreAlertOneDayNum) - storeAlertDataWrapper.InsertStoreAlertList() - storeAlertDataWrapper.ClearData() -} - -func ScheduleCheckStoreAlert() { - if EnableCheckStoreAlert { - ScheduleTimerFunc("ScheduleCheckStoreAlert", func() { - CheckStoreAlert(jxcontext.AdminCtx, nil) - }, checkStoreAlertTimeList) - } -} - -func GetValueColorByStatus(extraRedStatus, redStatus, yellowStatus, flag int) (color string) { - if (extraRedStatus&flag != 0) || (redStatus&flag != 0) { - color = ColorRed - } else if yellowStatus&flag != 0 { - color = ColorYellow - } else { - color = ColorUnknown - } - - return color -} - -func GetStoreAlertList(storeIDList []int, cityCode int, keyWord string, dateTime time.Time, offset, pageSize int) (storeAlertData model.StoreAlertData, err error) { - db := dao.GetDB() - storeAlertList, err := dao.GetStoreAlertList(db, storeIDList, cityCode, keyWord, dateTime) - if err == nil && len(storeAlertList) > 0 { - offset = jxutils.FormalizePageOffset(offset) - pageSize = jxutils.FormalizePageSize(pageSize) - var pagedStoreAlertList []*model.StoreAlertEx - for i := offset; i < offset+pageSize && i < len(storeAlertList); i++ { - pagedStoreAlertList = append(pagedStoreAlertList, storeAlertList[i]) - } - - var storeAlertAdvancedList []*model.StoreAlertAdvanced - for _, value := range pagedStoreAlertList { - storeAlertAdvanced := &model.StoreAlertAdvanced{} - storeAlertAdvanced.ID = value.ID - storeAlertAdvanced.CreatedTime = value.CreatedTime - storeAlertAdvanced.AlertDate = value.AlertDate - storeAlertAdvanced.StoreID = value.StoreID - storeAlertAdvanced.StoreName = value.StoreName - storeAlertAdvanced.CityName = value.CityName - - storeAlertAdvanced.PickTimeDaDa.Value = fmt.Sprintf("%d%%", value.PickTimeDaDa) - storeAlertAdvanced.PickTimeDaDa.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagPickTimeDaDa) - - storeAlertAdvanced.BadComment.Value = fmt.Sprintf("%d%%", value.BadComment) - storeAlertAdvanced.BadComment.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagBadComment) - - storeAlertAdvanced.AbsentGoods.Value = fmt.Sprintf("%d%%", value.AbsentGoods) - storeAlertAdvanced.AbsentGoods.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagAbsentGoods) - - storeAlertAdvanced.PickTimeDaDaOneWeek.Value = fmt.Sprintf("%d%%", value.PickTimeDaDaOneWeek) - storeAlertAdvanced.PickTimeDaDaOneWeek.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagPickTimeDaDaOneWeek) - - storeAlertAdvanced.BadCommentOneWeek.Value = fmt.Sprintf("%d%%", value.BadCommentOneWeek) - storeAlertAdvanced.BadCommentOneWeek.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagBadCommentOneWeek) - - storeAlertAdvanced.AbsentGoodsOneWeek.Value = fmt.Sprintf("%d%%", value.AbsentGoodsOneWeek) - storeAlertAdvanced.AbsentGoodsOneWeek.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagAbsentGoodsOneWeek) - - storeAlertAdvanced.StandardFinishTimeSelfDelivery.Value = fmt.Sprintf("%d%%", value.StandardFinishTimeSelfDelivery) - storeAlertAdvanced.StandardFinishTimeSelfDelivery.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagStandardFinishTimeSelfDelivery) - - storeAlertAdvanced.StandardPickUpTimeDaDa.Value = fmt.Sprintf("%d%%", value.StandardPickUpTimeDaDa) - storeAlertAdvanced.StandardPickUpTimeDaDa.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagStandardPickUpTimeDaDa) - - if value.NoOrderInMonth == 1 { - storeAlertAdvanced.NoOrderInMonth.Value = "是" - } else { - storeAlertAdvanced.NoOrderInMonth.Value = "否" - } - storeAlertAdvanced.NoOrderInMonth.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagNoOrderInMonth) - - storeAlertAdvanced.RiskOrderCount.Value = utils.Int2Str(value.RiskOrderCount) - storeAlertAdvanced.RiskOrderCount.Color = GetValueColorByStatus(value.ExtraRedStatus, value.RedStatus, value.YellowStatus, model.FlagRiskOrderCount) - - storeAlertAdvancedList = append(storeAlertAdvancedList, storeAlertAdvanced) - } - storeAlertData.TotalCount = len(storeAlertList) - storeAlertData.StoreAlertList = storeAlertAdvancedList - } - - return storeAlertData, err -} diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go deleted file mode 100644 index 90e3a24ce..000000000 --- a/business/jxstore/misc/store_score.go +++ /dev/null @@ -1,882 +0,0 @@ -package misc - -import ( - "fmt" - "math" - "reflect" - "sort" - "sync" - "time" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxstore/cms" - "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/globals" - "git.rosy.net.cn/jx-callback/globals/refutil" -) - -const ( - EnableScheduleScoreStore = true - ParallelCount = 1 - - GoldMedalScore = 90 - SilverMedalScore = 80 - BronzeMedalScore = 70 - GoldMedalLevel = 1 - SilverMedalLevel = 2 - BronzeMedalLevel = 3 - - ItemTotalScore = 10 - - StoreOpenTimeNormalTime = 12.0 //小时 - SaleSkuNormalCount = 1000 //数量 - SaleSkuScorePerUnit = float64(ItemTotalScore) / SaleSkuNormalCount //分数 - PromotionSkuNormalCount = 20 //数量 - AveragePickupTimeNormalTime = 10.0 //分钟 - BadCommentOrderNormalRatio = 0.2 //百分比 - UnfinishOrderNormalRatio = 1.0 //百分比 - AbsentGoodsOrderNormalRatio = 1.0 //百分比 - StoreRangeGoodRadius = 2.0 //千米 - StoreRangeBadRadius = 1.0 //千米 - SaleSkuPriceRatio = 90 //千米 - SaleSkuCheckRange = 5.0 //千米 - - WeekNum = 5 //得到门店近期周的数量 -) - -var ( - scoreStoreTimeList = []string{ - "23:00:00", - } - scoreStoreCheckTimeEnd = "23:30:00" - fullVendorList = map[int]bool{ - model.VendorIDJD: true, - model.VendorIDMTWM: true, - model.VendorIDEBAI: true, - } - storeScoreFieldName = []string{ - model.FieldStoreOpenTime, - model.FieldSaleSkuCount, - model.FieldAveragePickupTime, - model.FieldBadCommentOrder, - model.FieldUnfinishOrder, - model.FieldAbsentGoodsOrder, - model.FieldPromotionSku, - model.FieldFullVendor, - model.FieldStoreRange, - model.FieldSaleSkuPrice, - } - - storeScoreDataWrapper StoreScoreDataWrapper - allStoreSkusWrapper AllStoreSkusWrapper - scoreDate time.Time - isScoring bool -) - -type AllStoreSkusWrapper struct { - allStoreSkus map[int]map[int]int - locker sync.RWMutex -} - -func (a *AllStoreSkusWrapper) InitData() { - a.allStoreSkus = make(map[int]map[int]int) -} - -func (a *AllStoreSkusWrapper) ClearData() { - a.allStoreSkus = nil -} - -func (a *AllStoreSkusWrapper) SetData(storeID int, skuMapData map[int]int) { - a.locker.Lock() - defer a.locker.Unlock() - a.allStoreSkus[storeID] = skuMapData -} - -func (a *AllStoreSkusWrapper) GetData(storeID int) map[int]int { - a.locker.RLock() - defer a.locker.RUnlock() - return a.allStoreSkus[storeID] -} - -type StoreScoreDataWrapper struct { - storeScoreData map[int]*model.StoreScore - dailyBadCommentOrderCount map[int]int - dailyUnFinishOrderCount map[int]int - dailyFinishOrderCount map[int]int - dailyAbsentGoodsOrderCount map[int]int - locker sync.RWMutex -} - -func (s *StoreScoreDataWrapper) InitData() { - s.storeScoreData = make(map[int]*model.StoreScore) - s.dailyBadCommentOrderCount = make(map[int]int) - s.dailyUnFinishOrderCount = make(map[int]int) - s.dailyFinishOrderCount = make(map[int]int) - s.dailyAbsentGoodsOrderCount = make(map[int]int) -} - -func (s *StoreScoreDataWrapper) ClearData() { - s.storeScoreData = nil - s.dailyBadCommentOrderCount = nil - s.dailyUnFinishOrderCount = nil - s.dailyFinishOrderCount = nil - s.dailyAbsentGoodsOrderCount = nil -} - -func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int) { - s.locker.Lock() - defer s.locker.Unlock() - data := s.storeScoreData[storeID] - if data == nil { - data = &model.StoreScore{} - data.StoreID = storeID - data.ScoreDate = scoreDate - s.storeScoreData[storeID] = data - } - valueInfo := reflect.ValueOf(data).Elem() - valueInfo.FieldByName(valueName).SetInt(int64(value)) -} - -func (s *StoreScoreDataWrapper) SetDailyBadCommentOrderCount(storeCountList []*model.StoreCount) { - s.locker.Lock() - defer s.locker.Unlock() - for _, value := range storeCountList { - s.dailyBadCommentOrderCount[value.StoreID] = value.Count - } -} - -func (s *StoreScoreDataWrapper) GetDailyBadCommentOrderCount(storeID int) int { - s.locker.RLock() - defer s.locker.RUnlock() - if count, ok := s.dailyBadCommentOrderCount[storeID]; ok { - return count - } - - return 0 -} - -func (s *StoreScoreDataWrapper) SetDailyUnFinishOrderCount(storeCountList []*model.StoreCount) { - for _, value := range storeCountList { - s.dailyUnFinishOrderCount[value.StoreID] = value.Count - } -} - -func (s *StoreScoreDataWrapper) GetDailyUnFinishOrderCount(storeID int) int { - s.locker.RLock() - defer s.locker.RUnlock() - if count, ok := s.dailyUnFinishOrderCount[storeID]; ok { - return count - } - - return 0 -} - -func (s *StoreScoreDataWrapper) SetDailyFinishOrderCount(storeCountList []*model.StoreCount) { - for _, value := range storeCountList { - s.dailyFinishOrderCount[value.StoreID] = value.Count - } -} - -func (s *StoreScoreDataWrapper) GetDailyFinishOrderCount(storeID int) int { - s.locker.RLock() - defer s.locker.RUnlock() - if count, ok := s.dailyFinishOrderCount[storeID]; ok { - return count - } - - return 0 -} - -func (s *StoreScoreDataWrapper) SetDailyAbsentGoodsOrderCount(storeCountList []*model.StoreCount) { - for _, value := range storeCountList { - s.dailyAbsentGoodsOrderCount[value.StoreID] = value.Count - } -} - -func (s *StoreScoreDataWrapper) GetDailyAbsentGoodsOrderCount(storeID int) int { - s.locker.RLock() - defer s.locker.RUnlock() - if count, ok := s.dailyAbsentGoodsOrderCount[storeID]; ok { - return count - } - - return 0 -} - -func (s *StoreScoreDataWrapper) InsertStoreScore() { - for _, value := range s.storeScoreData { - dao.InsertStoreScore(value) - } -} - -//得到所有门店的可售商品(优化内存,只存商品的价格) -func GetAllStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeList []*cms.StoreExt) { - allStoreSkusWrapper.InitData() - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeInfo := batchItemList[0].(*cms.StoreExt) - storeID := storeInfo.ID - if jxSkuInfoData, err2 := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, false, map[string]interface{}{}, 0, -1); jxSkuInfoData != nil { - jxSkuPriceMapData := make(map[int]int) - for _, value := range jxSkuInfoData.SkuNames { - for _, skuInfo := range value.Skus { - saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) - if saleStatus == model.SkuStatusNormal { - jxSkuPriceMapData[skuInfo.SkuID] = skuInfo.BindPrice - } - } - } - allStoreSkusWrapper.SetData(storeID, jxSkuPriceMapData) - } else { - globals.SugarLogger.Warnf("store_score.GetAllStoreSkus %d return empty, err:%v", storeID, err2) - } - return retVal, err - } - taskParallel := tasksch.NewParallelTask("得到所有门店商品", tasksch.NewParallelConfig().SetParallelCount(ParallelCount), ctx, taskFunc, storeList) - tasksch.HandleTask(taskParallel, parentTask, true).Run() - taskParallel.GetResult(0) -} - -func GetOpenTime(opTimeList []int16) (opTime float64) { - opTime = 0 - for index, _ := range opTimeList { - if index%2 == 1 { - endTime := opTimeList[index] - startTime := opTimeList[index-1] - diffHour := float64(endTime/100 - startTime/100) - diffMin := float64(endTime%100-startTime%100) / 60 - opTime += diffHour + diffMin - } - } - return opTime -} - -//营业时间12小时及以上满分,总分10分,每少一个小时扣1分 -func ScoreStoreOpenTime(storeInfo *cms.StoreExt) { - storeID := storeInfo.ID - storeStatus := storeInfo.Status - isStoreOpen := storeStatus == model.StoreStatusOpened - finalScore := 0 - if isStoreOpen { - for _, storeMap := range storeInfo.StoreMaps { - isSyncStoreSku := storeMap.IsSync - vendorStoreStatus := storeMap.Status - isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened - opTimeList := storeInfo.GetOpTimeList() - if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen && isSyncStoreSku != 0 { - opTime := GetOpenTime(opTimeList) - if opTime >= StoreOpenTimeNormalTime { - finalScore = ItemTotalScore - } else { - decScore := int(math.Round(StoreOpenTimeNormalTime - opTime)) - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } - } - } - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldStoreOpenTime, finalScore) -} - -//可售商品数量大于1000,总分10分,按比例扣 -func ScoreSaleSkuCount(storeInfo *cms.StoreExt) { - storeID := storeInfo.ID - skusMapData := allStoreSkusWrapper.GetData(storeID) - finalScore := 0 - if len(skusMapData) > 0 { - saleSkuCount := len(skusMapData) - finalScore = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) - if finalScore > ItemTotalScore { - finalScore = ItemTotalScore - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuCount, finalScore) -} - -//平均捡货时间小于等于拣货截止时间为10分满分,每超出1分钟,减1分 -func ScoreAveragePickupTime(storeInfo *cms.StoreExt) { - storeID := storeInfo.ID - db := dao.GetDB() - orderList, err := dao.GetDailyFinishOrderList(db, storeID, scoreDate) - orderListCount := len(orderList) - finalScore := 0 - if err == nil && orderListCount > 0 { - totalScore := 0 - for _, value := range orderList { - statusTime := value.StatusTime.Unix() - pickDeadline := value.PickDeadline.Unix() - if statusTime <= pickDeadline { - totalScore += ItemTotalScore - } else { - decScore := int(math.Round(float64(statusTime-pickDeadline) / 60)) - tempScore := ItemTotalScore - decScore - if tempScore < 0 { - tempScore = 0 - } - totalScore += tempScore - } - } - finalScore = totalScore / orderListCount - } - storeScoreDataWrapper.SetData(storeID, model.FieldAveragePickupTime, finalScore) -} - -//差评订单和完成订单比例小于0.2%,得满分10分,每增加0.1%减1分 -func ScoreBadCommentOrder(storeInfo *cms.StoreExt) { - storeID := storeInfo.ID - badCommentOrderCount := storeScoreDataWrapper.GetDailyBadCommentOrderCount(storeID) - finishOrderCount := storeScoreDataWrapper.GetDailyFinishOrderCount(storeID) - finalScore := 0 - if finishOrderCount > 0 { - badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) - if badCommentOrderRatio <= BadCommentOrderNormalRatio { - finalScore = ItemTotalScore - } else { - decScore := int(math.Round((badCommentOrderRatio - BadCommentOrderNormalRatio) / 0.1)) - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldBadCommentOrder, finalScore) -} - -//未完成订单和完成订单比小于1%,得满分10分,比例每增加5%,分数减1 -func ScoreUnfinishOrder(storeInfo *cms.StoreExt) { - storeID := storeInfo.ID - unFinishOrderCount := storeScoreDataWrapper.GetDailyUnFinishOrderCount(storeID) - finishOrderCount := storeScoreDataWrapper.GetDailyFinishOrderCount(storeID) - finalScore := 0 - if finishOrderCount > 0 { - unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) - if unfinishOrderRatio <= UnfinishOrderNormalRatio { - finalScore = ItemTotalScore - } else { - decScore := int(math.Round((unfinishOrderRatio - UnfinishOrderNormalRatio) / 5)) - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldUnfinishOrder, finalScore) -} - -//缺货订单和完成订单比小于1%得10分,比例每增加0.1%减1分 -func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt) { - storeID := storeInfo.ID - absentGoodsOrderCount := storeScoreDataWrapper.GetDailyAbsentGoodsOrderCount(storeID) - finishOrderCount := storeScoreDataWrapper.GetDailyFinishOrderCount(storeID) - finalScore := 0 - if finishOrderCount > 0 { - absentGoodsOrderRatio := float64(absentGoodsOrderCount) * 100 / float64(finishOrderCount) - if absentGoodsOrderRatio <= AbsentGoodsOrderNormalRatio { - finalScore = ItemTotalScore - } else { - decScore := int(math.Round((absentGoodsOrderRatio - AbsentGoodsOrderNormalRatio) / 0.1)) - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldAbsentGoodsOrder, finalScore) -} - -//促销品数量20个以上为满分10分,每少2个扣1分 -func ScorePromotionSku(storeInfo *cms.StoreExt) { - storeID := storeInfo.ID - db := dao.GetDB() - beginTime := time.Now() - endTime := time.Now() - actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, nil, model.ActTypeAll, []int{storeID}, nil, beginTime, endTime) - finalScore := 0 - if err == nil && len(actStoreSkuList) > 0 { - actStoreSkuMap := make(map[int]int) - for _, value := range actStoreSkuList { - if value.Type != model.ActSkuFake { - actStoreSkuMap[value.SkuID] = 1 - } - } - promotionSkuCount := len(actStoreSkuMap) - if promotionSkuCount >= PromotionSkuNormalCount { - finalScore = ItemTotalScore - } else { - decScore := (PromotionSkuNormalCount - promotionSkuCount) / 2 - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldPromotionSku, finalScore) -} - -//经营全平台满分10分,每少一个平台扣2分(一个平台没有得0分) -func ScoreFullVendor(storeInfo *cms.StoreExt) { - fullVendorCount := len(fullVendorList) - finalScore := 0 - storeID := storeInfo.ID - storeStatus := storeInfo.Status - isStoreOpen := storeStatus == model.StoreStatusOpened - count := 0 - for _, storeMap := range storeInfo.StoreMaps { - isSyncStoreSku := storeMap.IsSync - vendorStoreStatus := storeMap.Status - isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened - opTimeList := storeInfo.GetOpTimeList() - if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen && isSyncStoreSku != 0 { - count++ - } - } - if count > 0 { - if count == fullVendorCount { - finalScore = ItemTotalScore - } else { - decScore := (fullVendorCount - count) * 2 - finalScore = ItemTotalScore - decScore - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldFullVendor, finalScore) -} - -//经营范围面积大于半径2km的圆得满分10分,低于1km得分0 -func ScoreStoreRange(storeInfo *cms.StoreExt) { - finalScore := 0 - storeID := storeInfo.ID - if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { - if storeInfo.DeliveryRange != "" { - points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) - area := jxutils.CalcPolygonAreaAutonavi(points) - goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius - badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius - if area >= goodArea { - finalScore = ItemTotalScore - } else if area <= badArea { - finalScore = 0 - } else { - diff := goodArea - area - ratio := float64(ItemTotalScore) / (goodArea - badArea) - finalScore = ItemTotalScore - int(math.Round(diff*ratio)) - } - } - } else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius { - deliveryRadius := utils.Str2Float64WithDefault(storeInfo.DeliveryRange, 0) / 1000 - if deliveryRadius >= StoreRangeGoodRadius { - finalScore = ItemTotalScore - } else if deliveryRadius <= StoreRangeBadRadius { - finalScore = 0 - } else { - diff := StoreRangeGoodRadius - deliveryRadius - ratio := float64(ItemTotalScore) / (StoreRangeGoodRadius - StoreRangeBadRadius) - finalScore = ItemTotalScore - int(math.Round(diff*ratio)) - } - } - if finalScore < 0 { - globals.SugarLogger.Infof("ScoreStoreRange abnormal finalScore:%d, storeInfo:%s", finalScore, utils.Format4Output(storeInfo, true)) - finalScore = 0 - } else if finalScore > ItemTotalScore { - globals.SugarLogger.Infof("ScoreStoreRange abnormal finalScore:%d, storeInfo:%s", finalScore, utils.Format4Output(storeInfo, true)) - finalScore = ItemTotalScore - } - storeScoreDataWrapper.SetData(storeID, model.FieldStoreRange, finalScore) -} - -//得到距离某个门店多少KM内的所有门店信息 -func GetRangeStoreList(storeID int, lng, lat, checkRange float64, storeList []*cms.StoreExt) (outStoreList []*cms.StoreExt) { - for _, storeInfo := range storeList { - if storeInfo.ID == storeID { - outStoreList = append(outStoreList, storeInfo) - } else { - distance := jxutils.EarthDistance(lng, lat, storeInfo.FloatLng, storeInfo.FloatLat) - if distance <= checkRange { - outStoreList = append(outStoreList, storeInfo) - } - } - } - - return outStoreList -} - -//得到给定门店列表里的同一SkuID商品的平均价格 -func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int { - skusTotalPrice := make(map[int]int) - skusCount := make(map[int]int) - skusAveragePrice := make(map[int]int) - for _, storeInfo := range storeList { - storeID := storeInfo.ID - storeSkuMapData := allStoreSkusWrapper.GetData(storeID) - for skuID, skuPrice := range storeSkuMapData { - skusTotalPrice[skuID] += skuPrice - skusCount[skuID]++ - } - } - for id, totalPrice := range skusTotalPrice { - skusAveragePrice[id] = int(math.Round(float64(totalPrice) / float64(skusCount[id]))) - } - return skusAveragePrice -} - -func GetSkusCountLessEqualAvgPrice(storeID int, skusAveragePrice map[int]int) (count int) { - storeSkuMapData := allStoreSkusWrapper.GetData(storeID) - for skuID, skuPrice := range storeSkuMapData { - skuAvgPrice := skusAveragePrice[skuID] - if skuPrice <= skuAvgPrice { - count++ - } - } - - return count -} - -//可售商品价格在附近5km内门店比较,价格低于等于平均值的商品数占90%以上满分10分,比例每降低10%减1分,100%超标得0分 -func ScoreSaleSkuPrice(storeInfo *cms.StoreExt, storeList []*cms.StoreExt) { - finalScore := 0 - storeID := storeInfo.ID - totalCount := len(allStoreSkusWrapper.GetData(storeID)) - if totalCount > 0 { - rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, SaleSkuCheckRange, storeList) - skusAveragePrice := GetStoreSkusAveragePrice(rangeStoreList) - count := GetSkusCountLessEqualAvgPrice(storeID, skusAveragePrice) - if count > 0 { - ratio := int(math.Round(float64(count) * 100 / float64(totalCount))) - if ratio >= SaleSkuPriceRatio { - finalScore = ItemTotalScore - } else { - decScore := (SaleSkuPriceRatio - ratio) / 10 - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } - } - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuPrice, finalScore) -} - -func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (outStoreList []*cms.StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - if len(storeIDMap) > 0 { - if _, ok := storeIDMap[storeID]; !ok { - continue - } - } - var tempStoreMaps []*model.StoreMap - for _, vendorStoreInfo := range storeInfo.StoreMaps { - vendorID := vendorStoreInfo.VendorID - if _, ok := fullVendorList[vendorID]; !ok { - continue - } - tempStoreMaps = append(tempStoreMaps, vendorStoreInfo) - } - if len(tempStoreMaps) > 0 { - storeInfo.StoreMaps = tempStoreMaps - outStoreList = append(outStoreList, storeInfo) - } - } - - return outStoreList -} - -func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, err error) { - isScoring = true - scoreDate = utils.GetCurDate() - var storeList []*cms.StoreExt - taskCount := 5 - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - baseapi.SugarLogger.Debugf("ScoreStore step0 begin") - storeScoreDataWrapper.InitData() - storeList, err = GetStoreList(ctx) - storeIDMap := jxutils.IntList2Map(storeIDList) - storeList = GetFilterStoreListEx(storeList, storeIDMap) - baseapi.SugarLogger.Debugf("ScoreStore step0 end") - case 1: - baseapi.SugarLogger.Debugf("ScoreStore step1 begin") - GetAllStoreSkus(ctx, task, storeList) - baseapi.SugarLogger.Debugf("ScoreStore step1 end") - case 2: - baseapi.SugarLogger.Debugf("ScoreStore step2 begin") - db := dao.GetDB() - storeCountList, err := dao.GetDailyBadCommentOrderCount(db, scoreDate) - if err == nil { - storeScoreDataWrapper.SetDailyBadCommentOrderCount(storeCountList) - } else { - baseapi.SugarLogger.Debugf("ScoreStore GetDailyBadCommentOrderCount %v", err) - } - storeCountList, err = dao.GetDailyUnFinishOrderCount(db, scoreDate) - if err == nil { - storeScoreDataWrapper.SetDailyUnFinishOrderCount(storeCountList) - } else { - baseapi.SugarLogger.Debugf("ScoreStore GetDailyUnFinishOrderCount %v", err) - } - storeCountList, err = dao.GetDailyFinishOrderCount(db, scoreDate) - if err == nil { - storeScoreDataWrapper.SetDailyFinishOrderCount(storeCountList) - } else { - baseapi.SugarLogger.Debugf("ScoreStore GetDailyFinishOrderCount %v", err) - } - storeCountList, err = dao.GetDailyAbsentGoodsOrderCount(db, scoreDate) - if err == nil { - storeScoreDataWrapper.SetDailyAbsentGoodsOrderCount(storeCountList) - } else { - baseapi.SugarLogger.Debugf("ScoreStore GetDailyAbsentGoodsOrderCount %v", err) - } - baseapi.SugarLogger.Debugf("ScoreStore step2 end") - case 3: - baseapi.SugarLogger.Debugf("ScoreStore step3 begin") - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeInfo := batchItemList[0].(*cms.StoreExt) - storeID := storeInfo.ID - baseapi.SugarLogger.Debugf("Begin store id:%d", storeID) - ScoreStoreOpenTime(storeInfo) - ScoreSaleSkuCount(storeInfo) - ScoreAveragePickupTime(storeInfo) - ScoreBadCommentOrder(storeInfo) - ScoreUnfinishOrder(storeInfo) - ScoreAbsentGoodsOrder(storeInfo) - ScorePromotionSku(storeInfo) - ScoreFullVendor(storeInfo) - ScoreStoreRange(storeInfo) - ScoreSaleSkuPrice(storeInfo, storeList) - baseapi.SugarLogger.Debugf("End store id:%d", storeID) - return retVal, err - } - taskParallel := tasksch.NewParallelTask("计算门店得分", tasksch.NewParallelConfig().SetParallelCount(ParallelCount), ctx, taskFunc, storeList) - tasksch.HandleTask(taskParallel, task, true).Run() - taskParallel.GetResult(0) - _, err = taskParallel.GetResult(0) - if err != nil { - baseapi.SugarLogger.Debugf("ScoreStore taskParallel error:%v", err) - } - baseapi.SugarLogger.Debugf("ScoreStore step3 end") - case 4: - baseapi.SugarLogger.Debugf("ScoreStore step4 begin") - storeScoreDataWrapper.InsertStoreScore() - storeScoreDataWrapper.ClearData() - allStoreSkusWrapper.ClearData() - baseapi.SugarLogger.Debugf("ScoreStore step4 end") - isScoring = false - } - return result, err - } - taskSeq := tasksch.NewSeqTask("门店评分-序列任务", ctx, taskSeqFunc, taskCount) - tasksch.HandleTask(taskSeq, nil, true).Run() - - return retVal, err -} - -func ScheduleScoreStore() { - if EnableScheduleScoreStore { - ScheduleTimerFunc("ScheduleScoreStore", func() { - if !isScoring { - ScoreStore(jxcontext.AdminCtx, nil) - } - }, scoreStoreTimeList) - CheckScoreStore() - } -} - -func CheckScoreStore() { - if !isScoring { - curTime := time.Now() - checkTimeStr1 := fmt.Sprintf("%s %s", utils.Time2DateStr(curTime), scoreStoreTimeList[0]) - checkTime1 := utils.Str2Time(checkTimeStr1) - checkTimeStr2 := fmt.Sprintf("%s %s", utils.Time2DateStr(curTime), scoreStoreCheckTimeEnd) - checkTime2 := utils.Str2Time(checkTimeStr2) - if curTime.Unix() >= checkTime1.Unix() && curTime.Unix() <= checkTime2.Unix() { - db := dao.GetDB() - hasStoreScoreData, err := dao.CheckHasStoreScoreData(db, curTime) - if err == nil && !hasStoreScoreData { - ScoreStore(jxcontext.AdminCtx, nil) - } - } - } -} - -func Time2Week(t time.Time) int { - yearDay := t.YearDay() - yearFirstDay := t.AddDate(0, 0, -yearDay+1) - firstDayInWeek := int(yearFirstDay.Weekday()) - - firstWeekDays := 1 - if firstDayInWeek != 0 { - firstWeekDays = 7 - firstDayInWeek + 1 - } - var week int - if yearDay <= firstWeekDays { - week = 1 - } else { - tempWeek := (float64(yearDay) - float64(firstWeekDays)) / float64(7) - week = int(math.Ceil(tempWeek)) + 1 - } - - return week -} - -func SplitToSingleWeekDataList(storeScoreList []*model.StoreScoreEx) (weekDataList [][]*model.StoreScoreEx) { - singleWeekData := []*model.StoreScoreEx{} - weekIndex := 0 - for _, value := range storeScoreList { - if weekIndex == 0 { - weekIndex = Time2Week(value.ScoreDate) - } - if weekIndex == Time2Week(value.ScoreDate) { - singleWeekData = append(singleWeekData, value) - } else { - weekDataList = append(weekDataList, singleWeekData) - singleWeekData = []*model.StoreScoreEx{} - weekIndex = 0 - singleWeekData = append(singleWeekData, value) - } - } - if len(singleWeekData) > 0 { - weekDataList = append(weekDataList, singleWeekData) - } - - return weekDataList -} - -func GetStoreScoreLevel(score int) int { - level := 0 - if score >= GoldMedalScore { - level = GoldMedalLevel - } else if score >= SilverMedalScore { - level = SilverMedalLevel - } else if score >= BronzeMedalScore { - level = BronzeMedalLevel - } - - return level -} - -func GetWeeklyStoreScore(storeID, weekIndexParam int) (outWeeklyStoreScoreDataList []*model.WeeklyStoreScore, err error) { - db := dao.GetDB() - storeScoreList, err := dao.GetWeeklyStoreScoreList(db, storeID, WeekNum) - if err == nil && len(storeScoreList) > 0 { - weeklyStoreScoreDataList := []*model.WeeklyStoreScore{} - weekDataList := SplitToSingleWeekDataList(storeScoreList) - for weekIndex, weekData := range weekDataList { - weeklyData := &model.WeeklyStoreScore{} - weeklyData.ID = weekIndex - weeklyData.ItemTotalScore = ItemTotalScore - weeklyData.StoreID = storeID - weeklyStoreScoreDataList = append(weeklyStoreScoreDataList, weeklyData) - weekDataCount := len(weekData) - for dayIndex, dayData := range weekData { - for _, fieldName := range storeScoreFieldName { - srcFieldValue := refutil.GetObjFieldByName(dayData, fieldName).(int) - destFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int) - refutil.SetObjFieldByName(weeklyData, fieldName, destFieldValue+srcFieldValue) - } - if weekDataCount == 1 { - weeklyData.BeginTime = dayData.ScoreDate - weeklyData.EndTime = dayData.ScoreDate - } else { - if dayIndex == 0 { - weeklyData.EndTime = dayData.ScoreDate - } else if dayIndex == weekDataCount-1 { - weeklyData.BeginTime = dayData.ScoreDate - } - } - weeklyData.StoreName = dayData.StoreName - } - for _, fieldName := range storeScoreFieldName { - destFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int) - refutil.SetObjFieldByName(weeklyData, fieldName, int(math.Round(float64(destFieldValue)/float64(weekDataCount)))) - } - for _, fieldName := range storeScoreFieldName { - srcFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int) - destFieldValue := refutil.GetObjFieldByName(weeklyData, model.FieldTotalScore).(int) - refutil.SetObjFieldByName(weeklyData, model.FieldTotalScore, destFieldValue+srcFieldValue) - } - weeklyData.Level = GetStoreScoreLevel(weeklyData.TotalScore) - } - if weekIndexParam == -1 { - outWeeklyStoreScoreDataList = weeklyStoreScoreDataList - } else { - fmt.Println("testss", utils.Format4Output(weeklyStoreScoreDataList, false)) - outWeeklyStoreScoreDataList = []*model.WeeklyStoreScore{weeklyStoreScoreDataList[weekIndexParam]} - } - } - - return outWeeklyStoreScoreDataList, err -} - -func GetStoreTotalScoreList(storeIDList []int, cityCode int, keyWord string, beginTime, endTime time.Time, isDesc bool, checkScoreLow, checkScoreHigh, offset, pageSize int) (storeTotalScoreEx model.StoreTotalScoreEx, err error) { - db := dao.GetDB() - storeTotalScoreMapData := make(map[int]*model.StoreTotalScore) - storeTotalScoreList, err := dao.GetStoreTotalScoreList(db, storeIDList, cityCode, keyWord, beginTime, endTime) - var filterStoreTotalScoreList []*model.StoreTotalScore - if err == nil && len(storeTotalScoreList) > 0 { - countDayNum := make(map[int]int) - for _, value := range storeTotalScoreList { - storeID := value.StoreID - if storeTotalScoreMapData[storeID] == nil { - storeTotalScore := &model.StoreTotalScore{} - storeTotalScore.StoreID = value.StoreID - storeTotalScore.StoreName = value.StoreName - storeTotalScore.CityName = value.CityName - storeTotalScoreMapData[storeID] = storeTotalScore - } - storeTotalScore := storeTotalScoreMapData[storeID] - storeTotalScore.StoreScore += value.StoreScore - countDayNum[storeID]++ - } - for storeID, value := range storeTotalScoreMapData { - value.StoreScore = int(math.Round(float64(value.StoreScore) / float64(countDayNum[storeID]))) - needAdd := true - if checkScoreLow > 0 && value.StoreScore < checkScoreLow { - needAdd = false - } - if checkScoreHigh > 0 && value.StoreScore > checkScoreHigh { - needAdd = false - } - if needAdd { - filterStoreTotalScoreList = append(filterStoreTotalScoreList, value) - } - } - if isDesc { - sort.Slice(filterStoreTotalScoreList, func(i, j int) bool { - data1 := filterStoreTotalScoreList[i] - data2 := filterStoreTotalScoreList[j] - if data1.StoreScore == data2.StoreScore { - return data1.StoreID < data2.StoreID - } else { - return data1.StoreScore > data2.StoreScore - } - }) - } else { - sort.Slice(filterStoreTotalScoreList, func(i, j int) bool { - data1 := filterStoreTotalScoreList[i] - data2 := filterStoreTotalScoreList[j] - if data1.StoreScore == data2.StoreScore { - return data1.StoreID < data2.StoreID - } else { - return data1.StoreScore < data2.StoreScore - } - }) - } - } - - offset = jxutils.FormalizePageOffset(offset) - pageSize = jxutils.FormalizePageSize(pageSize) - var pagedStoreTotalScoreList []*model.StoreTotalScore - for i := offset; i < offset+pageSize && i < len(filterStoreTotalScoreList); i++ { - pagedStoreTotalScoreList = append(pagedStoreTotalScoreList, filterStoreTotalScoreList[i]) - } - - storeTotalScoreEx.TotalCount = len(filterStoreTotalScoreList) - storeTotalScoreEx.StoreTotalScoreList = pagedStoreTotalScoreList - - return storeTotalScoreEx, err -} diff --git a/business/jxstore/misc/store_score_test.go b/business/jxstore/misc/store_score_test.go deleted file mode 100644 index 01e0a42bb..000000000 --- a/business/jxstore/misc/store_score_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package misc - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/globals/api2" - "git.rosy.net.cn/jx-callback/globals/testinit" - - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc" -) - -func init() { - testinit.Init() - api2.Init() -} - -func TestScoreStore(t *testing.T) { - ScoreStore(jxcontext.AdminCtx, []int{}) -} diff --git a/business/jxstore/misc/store_sku_sales.go b/business/jxstore/misc/store_sku_sales.go deleted file mode 100644 index e7f0e6f7f..000000000 --- a/business/jxstore/misc/store_sku_sales.go +++ /dev/null @@ -1,176 +0,0 @@ -package misc - -import ( - "errors" - "fmt" - "math" - "sync" - - "git.rosy.net.cn/jx-callback/business/jxstore/cms" - "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" -) - -const ( - DayNum = 30 //请求天数 - LimitNum = 100 //最大数据限制 -) - -func GetStoreSkuSalesInfo(ctx *jxcontext.Context, storeID int) (outStoreSkuSales []*model.StoreSkuSales, err error) { - db := dao.GetDB() - //得到所有门店 - storeList, err := GetStoreList(ctx) - if err == nil { - storeList = GetFilterStoreListEx(storeList, nil) - } else { - return nil, err - } - storeMapData := make(map[int]*cms.StoreExt) - for _, value := range storeList { - storeMapData[value.ID] = value - } - curStoreInfo := storeMapData[storeID] - if curStoreInfo == nil { - return nil, errors.New(fmt.Sprintf("未找到商店:[%d]", storeID)) - } - cityCode := curStoreInfo.CityCode - - //获取本市商品总销量 - citySkuSalesCntMap := make(map[int]int) - citySkuSalesCntList, err := dao.GetSkuSalesCntList(db, -1, cityCode, DayNum, LimitNum, nil) - citySkuIDs := []int{} - if err == nil { - for _, value := range citySkuSalesCntList { - citySkuSalesCntMap[value.SkuID] = value.Count - citySkuIDs = append(citySkuIDs, value.SkuID) - } - } else { - return nil, err - } - - //获取本店商品总销量 - storeSkuSalesCntMap := make(map[int]int) - storeSkuSalesCntList, err := dao.GetSkuSalesCntList(db, storeID, cityCode, DayNum, -1, citySkuIDs) - if err == nil { - for _, value := range storeSkuSalesCntList { - storeSkuSalesCntMap[value.SkuID] = value.Count - } - } else { - return nil, err - } - - //获取本店商品差评数量 - storeSkuBadCommentCntMap := make(map[int]int) - storeSkuBadCommentCntList, err := dao.GetSkuBadCommentCntList(db, storeID, DayNum) - if err == nil { - for _, value := range storeSkuBadCommentCntList { - storeSkuBadCommentCntMap[value.SkuID] = value.Count - } - } else { - return nil, err - } - - //得到当前门店商品数据 - storeSkuMapData := make(map[int]*dao.StoreSkuNameExt) - storeSkuData, err := cms.GetStoreSkus(ctx, storeID, citySkuIDs, true, "", true, false, map[string]interface{}{}, 0, -1) - if err == nil { - for _, value := range storeSkuData.SkuNames { - for _, skuInfo := range value.Skus { - storeSkuMapData[skuInfo.SkuID] = value - } - } - } else { - return nil, err - } - - //得到5KM内的所有门店 - rangeStoreList := GetRangeStoreList(storeID, curStoreInfo.FloatLng, curStoreInfo.FloatLat, SaleSkuCheckRange, storeList) - - //得到5KM内的所有门店的商品的价格 - allStoreSkus := make(map[int]map[int]int) - var locker sync.RWMutex - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeInfo := batchItemList[0].(*cms.StoreExt) - storeID := storeInfo.ID - jxSkuInfoData, err := cms.GetStoreSkus(ctx, storeID, citySkuIDs, true, "", true, false, map[string]interface{}{}, 0, -1) - jxSkuPriceMapData := make(map[int]int) - for _, value := range jxSkuInfoData.SkuNames { - for _, skuInfo := range value.Skus { - jxSkuPriceMapData[skuInfo.SkuID] = skuInfo.BindPrice - } - } - locker.Lock() - defer locker.Unlock() - allStoreSkus[storeID] = jxSkuPriceMapData - return retVal, err - } - taskParallel := tasksch.NewParallelTask("得到所有门店商品", nil, ctx, taskFunc, rangeStoreList) - taskParallel.Run() - _, err = taskParallel.GetResult(0) - if err != nil { - return nil, err - } - - //计算商品的平均价格 - skusTotalPrice := make(map[int]int) - skusCount := make(map[int]int) - skusAveragePrice := make(map[int]int) - for _, storeInfo := range rangeStoreList { - storeID := storeInfo.ID - storeSkuMapData := allStoreSkus[storeID] - for skuID, skuPrice := range storeSkuMapData { - skusTotalPrice[skuID] += skuPrice - skusCount[skuID]++ - } - } - for id, totalPrice := range skusTotalPrice { - skusAveragePrice[id] = int(math.Round(float64(totalPrice) / float64(skusCount[id]))) - } - - //输出商品销量统计结果 - skuAndNameMapData := make(map[int]*model.SkuAndName) - if len(storeSkuMapData) < len(citySkuIDs) { - skuAndNameList, err := dao.GetSkus(db, citySkuIDs, nil, nil, nil, nil) - if err == nil { - for _, value := range skuAndNameList { - skuAndNameMapData[value.ID] = value - } - } - } - for _, value := range citySkuSalesCntList { - skuID := value.SkuID - storeSkuSales := &model.StoreSkuSales{} - storeSkuSales.SkuID = skuID - storeSkuInfo := storeSkuMapData[skuID] - skuAndNameInfo := skuAndNameMapData[skuID] - if storeSkuInfo != nil { - skuName := storeSkuInfo.SkuName - skuInfo := storeSkuInfo.Skus[0] - storeSkuSales.SkuName = jxutils.ComposeSkuName(skuName.Prefix, skuName.Name, skuInfo.Comment, skuName.Unit, skuInfo.SkuSpecQuality, skuInfo.SkuSpecUnit, 0, skuName.ExPrefix, skuName.ExPrefixBegin, skuName.ExPrefixEnd) - storeSkuSales.SkuImage = storeSkuInfo.Img - storeSkuSales.SkuPrice = jxutils.IntPrice2StandardCurrencyString(int64(storeSkuInfo.Skus[0].BindPrice)) - } else if skuAndNameInfo != nil { - skuNameList, err := dao.GetSkuNames(db, []int{skuAndNameInfo.NameID}, nil, "", false) - prefix := "" - if err == nil && len(skuNameList) > 0 { - storeSkuSales.SkuImage = skuNameList[0].Img - prefix = skuNameList[0].Prefix - } - storeSkuSales.SkuName = jxutils.ComposeSkuName(prefix, skuAndNameInfo.Name, skuAndNameInfo.Comment, skuAndNameInfo.Unit, skuAndNameInfo.SpecQuality, skuAndNameInfo.SpecUnit, 0, skuAndNameInfo.ExPrefix, skuAndNameInfo.ExPrefixBegin, skuAndNameInfo.ExPrefixEnd) - storeSkuSales.SkuPrice = "N/A" - } else { - storeSkuSales.SkuName = "N/A" - storeSkuSales.SkuPrice = "N/A" - } - storeSkuSales.SkuAvgPrice = jxutils.IntPrice2StandardCurrencyString(int64(skusAveragePrice[skuID])) - storeSkuSales.BadCommentCnt = storeSkuBadCommentCntMap[skuID] - storeSkuSales.StoreSkuSalesCnt = storeSkuSalesCntMap[skuID] - storeSkuSales.CitySkuSalesCnt = citySkuSalesCntMap[skuID] - outStoreSkuSales = append(outStoreSkuSales, storeSkuSales) - } - - return outStoreSkuSales, err -} diff --git a/business/jxstore/report/report.go b/business/jxstore/report/report.go deleted file mode 100644 index 6fadcdcfe..000000000 --- a/business/jxstore/report/report.go +++ /dev/null @@ -1,285 +0,0 @@ -package report - -import ( - "errors" - "fmt" - "math" - "sort" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - - "git.rosy.net.cn/baseapi/utils" - "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" -) - -type tStoreSkuBindAndSkuName struct { - CityCode int - StoreID int `orm:"column(store_id)"` - NameID int `orm:"column(name_id)"` - UnitPrice int - UnitPriceList []int -} - -func GetStatisticsReportForOrders(ctx *jxcontext.Context, storeIDs []int, fromDate string, toDate string) (statisticsReportForOrdersList []*dao.StatisticsReportForOrdersList, err error) { - db := dao.GetDB() - fromDateParm := utils.Str2Time(fromDate) - toDateParm := utils.Str2Time(toDate) - //若时间间隔大于3个月则不允许查询 - if math.Ceil(toDateParm.Sub(fromDateParm).Hours()/24) > 92 { - return nil, errors.New(fmt.Sprintf("查询间隔时间不允许大于3个月!: 时间范围:[%v] 至 [%v]", fromDate, toDate)) - } - statisticsReportForOrdersList, err = dao.GetStatisticsReportForOrders(db, storeIDs, fromDateParm, toDateParm) - return statisticsReportForOrdersList, err -} - -func GetStatisticsReportForAfsOrders(ctx *jxcontext.Context, storeIDs []int, fromDate string, toDate string) (statisticsReportForOrdersList []*dao.StatisticsReportForOrdersList, err error) { - db := dao.GetDB() - fromDateParm := utils.Str2Time(fromDate) - toDateParm := utils.Str2Time(toDate) - //若时间间隔大于3个月则不允许查询 - if math.Ceil(toDateParm.Sub(fromDateParm).Hours()/24) > 92 { - return nil, errors.New(fmt.Sprintf("查询间隔时间不允许大于3个月!: 时间范围:[%v] 至 [%v]", fromDate, toDate)) - } - statisticsReportForOrdersList, err = dao.GetGetStatisticsReportForAfsOrders(db, storeIDs, fromDateParm, toDateParm) - return statisticsReportForOrdersList, err -} - -func StatisticsReportForStoreSkusPrice(ctx *jxcontext.Context, cityCodes, skuIDs []int, snapDate string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - var snapDateParam time.Time - db := dao.GetDB() - if snapDate != "" { - snapDateParam = utils.Str2Time(snapDate) - } - priceReferSnapshot, totalCount, err := dao.GetPriceReferSnapshot(db, cityCodes, skuIDs, 0, snapDateParam, offset, pageSize) - pagedInfo = &model.PagedInfo{ - Data: priceReferSnapshot, - TotalCount: totalCount, - } - return -} - -func BeginSavePriceRefer(ctx *jxcontext.Context, cityCodes, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - var priceReferSnapshotList []*model.PriceReferSnapshot - db := dao.GetDB() - snapshotAt := utils.Time2Date(time.Now().AddDate(0, 0, -1)) - dao.DeletePriceReferHistory(db, utils.Time2Date(snapshotAt.AddDate(0, 0, -7))) - priceReferSnapshotDelete := &model.PriceReferSnapshot{SnapshotAt: snapshotAt} - dao.DeleteEntity(db, priceReferSnapshotDelete, "SnapshotAt") - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - priceReferSnapshot, err := dao.GetStatisticsReportForStoreSkusPrice(db, cityCodes, skuIDs) - if len(priceReferSnapshot) > 0 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - for _, v := range priceReferSnapshot { - dao.WrapAddIDCULDEntity(v, ctx.GetUserName()) - v.SnapshotAt = snapshotAt - } - dao.CreateMultiEntities(db, priceReferSnapshot) - dao.Commit(db) - } - case 1: - priceReferSnapshotList, err = dao.GetPriceReferSnapshotNoPage(db, nil, nil, nil, snapshotAt) - var ( - citySkuMap = make(map[int]map[int][]int) - countryMap = make(map[int][]int) - resultMap = make(map[int]map[int]*model.PriceReferSnapshot) - resultCountryMap = make(map[int]*model.PriceReferSnapshot) - ) - storeList, err := dao.GetStoreList(db, nil, nil, nil, nil, "") - if err != nil { - return result, err - } - for _, v := range storeList { - if v.PayPercentage < 50 { - continue - } - var tList []*tStoreSkuBindAndSkuName - sql := ` - SELECT DISTINCT b.city_code, a.store_id, Round(a.unit_price * IF(b.pay_percentage < 50 , 70, b.pay_percentage) / 100) AS unit_price, c.name_id - FROM store_sku_bind a - JOIN store b ON b.id = a.store_id AND b.deleted_at = ? AND b.status != ? - JOIN sku c ON c.id = a.sku_id - WHERE a.store_id = ? - AND c.name_id NOT IN( - SELECT b.name_id - FROM store_sku_bind a - JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ? - WHERE a.deleted_at = ? - AND a.store_id = ? - AND b.name_id NOT IN(SELECT DISTINCT b.name_id - FROM store_sku_bind a - JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ? - WHERE a.deleted_at = ? - AND a.store_id = ? - AND a.status = ?) - ) - AND a.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - model.StoreStatusDisabled, - v.ID, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - v.ID, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - v.ID, - model.StoreSkuBindStatusNormal, - utils.DefaultTimeValue, - } - dao.GetRows(db, &tList, sql, sqlParams...) - skuNameMap := make(map[int][]int) - if len(tList) > 0 { - for _, vv := range tList { - skuNameMap[vv.NameID] = append(skuNameMap[vv.NameID], vv.UnitPrice) - countryMap[vv.NameID] = append(countryMap[vv.NameID], vv.UnitPrice) - } - if citySkuMap[v.CityCode] != nil { - for nameID, unitPriceList := range skuNameMap { - if citySkuMap[v.CityCode][nameID] != nil { - citySkuMap[v.CityCode][nameID] = append(citySkuMap[v.CityCode][nameID], unitPriceList...) - } else { - citySkuMap[v.CityCode][nameID] = unitPriceList - } - } - } else { - citySkuMap[v.CityCode] = skuNameMap - } - } - } - for k, v := range countryMap { - var midUnitPrice int - var avgUnitPrice int - sort.Ints(v) - if len(v)%2 == 0 { - midUnitPrice = v[len(v)/2-1] - } else { - midUnitPrice = v[len(v)/2] - } - for _, vv := range v { - avgUnitPrice += vv - } - priceRefer := &model.PriceReferSnapshot{ - MidUnitPrice: midUnitPrice, - MaxUnitPrice: v[len(v)-1], - MinUnitPrice: v[0], - AvgUnitPrice: avgUnitPrice / len(v), - } - resultCountryMap[k] = priceRefer - } - for k1, v := range citySkuMap { - skuNameMap := make(map[int]*model.PriceReferSnapshot) - for k2, _ := range v { - var midUnitPrice int - var avgUnitPrice int - sort.Ints(v[k2]) - if len(v[k2])%2 == 0 { - midUnitPrice = v[k2][len(v[k2])/2-1] - } else { - midUnitPrice = v[k2][len(v[k2])/2] - } - for _, vv := range v[k2] { - avgUnitPrice += vv - } - skuNameMap[k2] = &model.PriceReferSnapshot{ - MidUnitPrice: midUnitPrice, - MaxUnitPrice: v[k2][len(v[k2])-1], - MinUnitPrice: v[k2][0], - AvgUnitPrice: avgUnitPrice / len(v[k2]), - } - } - resultMap[k1] = skuNameMap - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - if len(priceReferSnapshotList) > 0 { - for _, v := range priceReferSnapshotList { - if v.CityCode == 0 { - if resultCountryMap[v.NameID] != nil { - v.MidUnitPrice = resultCountryMap[v.NameID].MidUnitPrice - v.MaxUnitPrice = resultCountryMap[v.NameID].MaxUnitPrice - v.AvgUnitPrice = resultCountryMap[v.NameID].AvgUnitPrice - v.MinUnitPrice = resultCountryMap[v.NameID].MinUnitPrice - dao.UpdateEntity(db, v, "MidUnitPrice", "MaxUnitPrice", "MinUnitPrice", "AvgUnitPrice") - } - continue - } - if resultMap[v.CityCode][v.NameID] != nil { - v.MidUnitPrice = resultMap[v.CityCode][v.NameID].MidUnitPrice - v.MaxUnitPrice = resultMap[v.CityCode][v.NameID].MaxUnitPrice - v.AvgUnitPrice = resultMap[v.CityCode][v.NameID].AvgUnitPrice - v.MinUnitPrice = resultMap[v.CityCode][v.NameID].MinUnitPrice - dao.UpdateEntity(db, v, "MidUnitPrice", "MaxUnitPrice", "MinUnitPrice", "AvgUnitPrice") - } - } - } - dao.Commit(db) - case 2: - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - if len(priceReferSnapshotList) > 0 { - for _, v := range priceReferSnapshotList { - result, _ := dao.GetPriceReferPrice(db, v.CityCode, v.SkuID, snapshotAt) - v.MaxPrice = result.MaxPrice - v.MinPrice = result.MinPrice - v.AvgPrice = result.AvgPrice - v.MidPrice = result.MidPrice - dao.UpdateEntity(db, v, "MidPrice", "MaxPrice", "MinPrice", "AvgPrice") - } - } - dao.Commit(db) - //TODO 京东查询接口报错,暂时屏蔽了 - // case 3: - // priceReferSnapshotList, err = dao.GetPriceReferSnapshotNoPage(db, []int{0}, nil, nil, snapshotAt) - // taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // v := batchItemList[0].(*model.PriceReferSnapshot) - // for _, appOrg := range apimanager.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD) { - // directPrice, _ := jd.GetAPI(appOrg).GetJdSkuDirectPrice(v.SkuID) - // v.JdDirectPrice = int(directPrice) - // dao.UpdateEntity(db, v, "JdDirectPrice") - // } - // return retVal, err - // } - // taskParallel := tasksch.NewParallelTask("获取并更新京东指导价格", tasksch.NewParallelConfig(), ctx, taskFunc, priceReferSnapshotList) - // tasksch.HandleTask(taskParallel, task, true).Run() - // _, err = taskParallel.GetResult(0) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("生成每日价格统计", ctx, isContinueWhenError, taskSeqFunc, 3) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} diff --git a/business/jxstore/tempop/tempop.go b/business/jxstore/tempop/tempop.go deleted file mode 100644 index 9a3c134c6..000000000 --- a/business/jxstore/tempop/tempop.go +++ /dev/null @@ -1,1690 +0,0 @@ -package tempop - -import ( - "bytes" - "context" - "fmt" - "regexp" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" - "git.rosy.net.cn/jx-callback/business/partner/delivery" - "github.com/360EntSecGroup-Skylar/excelize" - "github.com/qiniu/api.v7/storage" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/jxstore/cms" - "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/model/legacymodel" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" - "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" - "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var innerDataPat *regexp.Regexp - -func init() { - innerDataPat = regexp.MustCompile(`"result":(.*),"code":200`) -} - -func Convert2JDSPU(ctx *jxcontext.Context, count int, isAsync, isContinueWhenError bool) (hint string, err error) { - // sql := ` - // SELECT t1.* - // FROM sku_name t1 - // LEFT JOIN sku_name t2 ON t2.link_id = t1.id AND t2.deleted_at = ? - // WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.is_spu = 0/* AND t1.unit = '份'*/ - // AND t2.id IS NULL - // ORDER BY t1.id - // ` - // if count > 0 { - // sql += " LIMIT " + utils.Int2Str(count) - // } - // sqlParams := []interface{}{ - // utils.DefaultTimeValue, - // utils.DefaultTimeValue, - // model.SkuStatusDeleted, - // } - - // db := dao.GetDB() - // var skuNameList []*model.SkuName - // if err = dao.GetRows(db, &skuNameList, sql, sqlParams...); err != nil { - // return "", err - // } - // for _, skuName := range skuNameList { - // sql = ` - // SELECT * - // FROM sku - // WHERE name_id = ? AND deleted_at = ? AND status = ?; - // ` - // sqlParams := []interface{}{ - // skuName.ID, - // utils.DefaultTimeValue, - // model.SkuStatusNormal, - // } - // var skuList []*model.Sku - // if err = dao.GetRows(db, &skuList, sql, sqlParams...); err != nil { - // return "", err - // } - - // sql = ` - // SELECT t1.* - // FROM sku_name_place_bind t1 - // WHERE t1.name_id = ? - // ` - // sqlParams = []interface{}{ - // skuName.ID, - // } - // var skuNamePlaceBindList []*model.SkuNamePlaceBind - // if err = dao.GetRows(db, &skuNamePlaceBindList, sql, sqlParams...); err != nil { - // return "", err - // } - - // globals.SugarLogger.Debugf("Convert2JDSPU, skuName:%s, skuCount:%d", skuName.Name, len(skuList)) - // dao.Begin(db) - // skuNameNew2 := *skuName - // skuNameNew := &skuNameNew2 - // dao.WrapAddIDCULEntity(skuNameNew, ctx.GetUserName()) - // skuNameNew.JdID = 0 - // skuNameNew.LinkID = skuName.ID - // skuNameNew.IsSpu = 1 - // skuNameNew.JdSyncStatus = model.SyncFlagNewMask - // // skuNameNew.Status = model.SkuStatusDontSale - // if err = dao.CreateEntity(db, skuNameNew); err != nil { - // dao.Rollback(db) - // return "", err - // } - // if len(skuList) > 0 { - // for _, sku := range skuList { - // skuNew2 := *sku - // skuNew := &skuNew2 - // dao.WrapAddIDCULEntity(skuNew, ctx.GetUserName()) - // skuNew.JdID = 0 - // skuNew.LinkID = sku.ID - // skuNew.NameID = skuNameNew.ID - // skuNew.JdSyncStatus = model.SyncFlagNewMask - // if skuNameNew.Status == model.SkuStatusDontSale { - // skuNew.Status = model.SkuStatusDontSale - // } - // globals.SugarLogger.Debugf("Convert2JDSPU, sku:%s", utils.Format4Output(skuNew, false)) - // if err = dao.CreateEntity(db, skuNew); err != nil { - // dao.Rollback(db) - // return "", err - // } - // } - // for _, placeBind := range skuNamePlaceBindList { - // dao.WrapAddIDCULEntity(placeBind, ctx.GetUserName()) - // placeBind.NameID = skuNameNew.ID - // globals.SugarLogger.Debugf("Convert2JDSPU, placeBind:%s", utils.Format4Output(placeBind, false)) - // if err = dao.CreateEntity(db, placeBind); err != nil { - // dao.Rollback(db) - // return "", err - // } - // } - // } - // dao.Commit(db) - // } - // sql = ` - // SELECT DISTINCT t1.* - // FROM sku_name t1 - // JOIN sku t2 ON t1.id = t2.name_id AND t2.jd_sync_status <> 0 AND t2.deleted_at = ? - // WHERE t1.link_id > 0; - // ` - // skuNameList = []*model.SkuName{} - // if err = dao.GetRows(db, &skuNameList, sql, utils.DefaultTimeValue); err != nil { - // return "", err - // } - // rootTask := tasksch.NewParallelTask("Convert2JDSPU", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // skuName := batchItemList[0].(*model.SkuName) - // _, err = cms.CurVendorSync.SyncSku(ctx, db, skuName.ID, -1, false, isContinueWhenError, ctx.GetUserName()) - // return nil, err - // }, skuNameList) - // tasksch.ManageTask(rootTask).Run() - - // if !isAsync { - // _, err = rootTask.GetResult(0) - // } else { - // hint = rootTask.ID - // } - return hint, err -} - -func Change2JDSPU4Store(ctx *jxcontext.Context, storeIDs []int, step int, isAsync, isContinueWhenError bool) (hint string, err error) { - // db := dao.GetDB() - // if len(storeIDs) == 0 { - // if err = dao.GetRows(db, &storeIDs, ` - // SELECT t1.id - // FROM store t1 - // JOIN store_map t2 ON t2.store_id = t1.id AND t2.vendor_id = 0 AND t2.deleted_at = ? AND t2.status <> ? - // WHERE t1.deleted_at = ? AND t1.status <> ? /* AND t1.city_code IN (110100, 120100, 440100, 440300, 510100)*/ - // `, utils.DefaultTimeValue, model.StoreStatusDisabled, utils.DefaultTimeValue, model.StoreStatusDisabled); err != nil { - // return "", err - // } - // } - // var sql string - // var sqlParams []interface{} - - // dao.Begin(db) - // defer dao.Rollback(db) - - // if step == 1 { - // sql = ` - // DELETE t1 - // FROM store_sku_bind t1 - // JOIN sku t2 ON t2.id = t1.sku_id AND t2.link_id > 0 - // WHERE 1 = 1 - // ` - // sqlParams = []interface{}{} - // if len(storeIDs) > 0 { - // sql += " AND store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - // sqlParams = append(sqlParams, storeIDs) - // } - // if _, err = dao.ExecuteSQL(db, sql, sqlParams...); err != nil { - // return "", err - // } - - // sql = ` - // INSERT INTO store_sku_bind(created_at, updated_at, last_operator, deleted_at, store_id, sku_id, price, unit_price, status, ebai_id, mtwm_id, jd_sync_status, ebai_sync_status, mtwm_sync_status) - // SELECT NOW(), NOW(), ?, ?, t1.store_id, t2.id, t1.price, t1.unit_price, t1.status , 0, 0, ?, ?, ? - // FROM store_sku_bind t1 - // JOIN sku t2 ON t2.link_id = t1.sku_id AND t2.deleted_at = ? - // JOIN store t3 ON t3.id = t1.store_id - // JOIN sku_name t4 ON t4.id = t2.name_id - // LEFT JOIN sku_name_place_bind t5 ON t5.place_code = t3.city_code AND t5.name_id = t4.id - // WHERE t1.deleted_at = ? AND (t4.is_global = 1 OR t5.id IS NOT NULL) AND t1.price > 0 - // ` - // sqlParams = []interface{}{ - // ctx.GetUserName(), - // utils.DefaultTimeValue, - // // model.SkuStatusDontSale, - // model.SyncFlagNewMask, - // 0, //model.SyncFlagNewMask, - // 0, //model.SyncFlagNewMask, - // utils.DefaultTimeValue, - // utils.DefaultTimeValue, - // } - // } else if step == 2 { - // sql = ` - // SELECT COUNT(*) ct - // FROM store_sku_bind t1 - // JOIN sku t2 ON t2.id = t1.sku_id AND t2.link_id > 0 - // WHERE 1 = 1 - // ` - // sqlParams = []interface{}{} - // if len(storeIDs) > 0 { - // sql += " AND store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - // sqlParams = append(sqlParams, storeIDs) - // } - // ct := 0 - // if err = dao.GetRow(db, &ct, sql, sqlParams...); err != nil { - // return "", err - // } - // if ct == 0 { - // return "", fmt.Errorf("%s看起来还没有执行《将转化的SPU在门店上架》", utils.Format4Output(storeIDs, true)) - // } - - // sql = ` - // UPDATE store_sku_bind t1 - // JOIN sku t2 ON t2.link_id = t1.sku_id - // SET t1.status = 0, - // t1.jd_sync_status = ? - // WHERE t1.deleted_at = ? - // ` - // sqlParams = []interface{}{ - // model.SyncFlagSaleMask | model.SyncFlagModifiedMask, - // utils.DefaultTimeValue, - // } - // } else { - // return "", fmt.Errorf("非法的step") - // } - // if len(storeIDs) > 0 { - // sql += " AND t1.store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - // sqlParams = append(sqlParams, storeIDs) - // } - // globals.SugarLogger.Debug(sql) - // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) - // var num int64 - // if num, err = dao.ExecuteSQL(db, sql, sqlParams...); err != nil { - // return "", err - // } - // globals.SugarLogger.Debug(num) - // dao.Commit(db) - - // var skuIDs []int - // if step == 1 { - // sql = ` - // SELECT id - // FROM sku t1 - // WHERE t1.link_id > 0 AND t1.deleted_at = ? - // ` - // sqlParams = []interface{}{ - // utils.DefaultTimeValue, - // } - // } else if step == 2 { - // sql = ` - // SELECT t1.link_id - // FROM sku t1 - // WHERE t1.link_id > 0 AND t1.deleted_at = ? - // ` - // sqlParams = []interface{}{ - // utils.DefaultTimeValue, - // } - // } - // if err = dao.GetRows(db, &skuIDs, sql, sqlParams...); err != nil { - // return "", err - // } - // hint, err = cms.CurVendorSync.SyncStoresSkus(ctx, db, []int{model.VendorIDJD}, storeIDs, skuIDs, false, isAsync, isContinueWhenError) - return hint, err -} - -// func TransferLegacyJdOrder(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { -// sqlBatchCount := 1000 -// rootTask := tasksch.NewSeqTask("TransferLegacyJdOrder", ctx, -// func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { -// sql := ` -// SELECT t1.* -// FROM jdorder t1 -// LEFT JOIN goods_order_original t2 ON t2.vendor_order_id = t1.vendor_order_id -// WHERE t2.id IS NULL AND LENGTH(t1.data) > 10 AND t1.cityname = 'all' -// ORDER BY t1.orderstatustime -// LIMIT ? -// ` -// db := dao.GetDB() -// var jdOrderList []*legacymodel2.Jdorder -// if err = dao.GetRows(db, &jdOrderList, sql, sqlBatchCount); err != nil { -// return nil, err -// } -// if len(jdOrderList) > 0 { -// task := tasksch.NewParallelTask("TransferLegacyJdOrder2", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetBatchSize(40), ctx, -// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { -// var orderDetailList []*model.GoodsOrderOriginal -// for _, v := range batchItemList { -// jdOrder := v.(*legacymodel2.Jdorder) -// var detail map[string]interface{} -// if err = utils.UnmarshalUseNumber([]byte(strings.Replace(strings.Replace(jdOrder.Data, "\n", "", -1), "\r", "", -1)), &detail); err != nil { -// return nil, err -// } -// resultList := detail["result"].(map[string]interface{})["resultList"].([]interface{}) -// if len(resultList) > 0 { -// originalData := resultList[0].(map[string]interface{}) -// orgCode := originalData["orgCode"].(string) -// if orgCode == "320406" { -// orderPurchaseTime := utils.Interface2String(originalData["orderPurchaseTime"]) -// if orderPurchaseTime == "" { -// globals.SugarLogger.Debugf("TransferLegacyJdOrder abnormal order:%s", jdOrder.VendorOrderID) -// orderPurchaseTime = utils.Interface2String(originalData["orderStartTime"]) -// } -// if orderPurchaseTime != "" { -// orderDetail := &model.GoodsOrderOriginal{ -// VendorOrderID: jdOrder.VendorOrderID, -// VendorID: model.VendorIDJD, -// AccountNo: orgCode, -// OrderCreatedAt: utils.Str2Time(orderPurchaseTime), -// OriginalData: string(utils.MustMarshal(originalData)), -// } -// orderDetailList = append(orderDetailList, orderDetail) -// } else { -// globals.SugarLogger.Debugf("TransferLegacyJdOrder abnormal2 order:%s", jdOrder.VendorOrderID) -// } -// } -// } -// } -// if len(orderDetailList) > 0 { -// err = dao.CreateMultiEntities(db, orderDetailList) -// } -// return nil, err -// }, jdOrderList) -// // rootTask.AddChild(task).Run() -// task.Run() -// _, err = task.GetResult(0) -// } else { -// rootTask.Cancel() -// } -// return nil, err -// }, math.MaxInt32) -// tasksch.ManageTask(rootTask).Run() -// if !isAsync { -// _, err = rootTask.GetResult(0) -// } else { -// hint = rootTask.ID -// } -// return hint, err -// } - -func TransferLegacyElmOrder(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - // sqlBatchCount := 1000 - // rootTask := tasksch.NewSeqTask("TransferLegacyElmOrder", ctx.GetUserName(), func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - // sql := ` - // SELECT t1.* - // FROM elemeorder t1 - // LEFT JOIN goods_order_original t2 ON t2.vendor_order_id = t1.orderid - // WHERE t2.id IS NULL AND LENGTH(t1.data) > 10 - // ORDER BY t1.order_created_at - // LIMIT ? - // ` - // db := dao.GetDB() - // var elmOrderList []*legacymodel2.Elemeorder - // if err = dao.GetRows(db, &elmOrderList, sql, sqlBatchCount); err != nil { - // return "", err - // } - // if len(elmOrderList) > 0 { - // task := tasksch.NewParallelTask("TransferLegacyElmOrder2", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetBatchSize(40), ctx.GetUserName(), func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // var orderDetailList []*model.GoodsOrderOriginal - // for _, v := range batchItemList { - // elmOrder := v.(*legacymodel2.Elemeorder) - // if len(elmOrder.Data) > 10 { - // var detail map[string]interface{} - // if err = utils.UnmarshalUseNumber([]byte(strings.Replace(strings.Replace(elmOrder.Data, "\n", "", -1), "\r", "", -1)), &detail); err != nil { - // return nil, err - // } - // orderDetail := &model.GoodsOrderOriginal{ - // VendorOrderID: elmOrder.Orderid, - // VendorID: model.VendorIDELM, - // AccountNo: "fakeelm", - // OrderCreatedAt: utils.Str2Time(detail["activeAt"].(string)), - // OriginalData: elmOrder.Data, - // } - // orderDetailList = append(orderDetailList, orderDetail) - // } - // } - // if len(orderDetailList) > 0 { - // err = dao.CreateMultiEntities(db, orderDetailList) - // } - // return nil, err - // }, elmOrderList) - // // rootTask.AddChild(task).Run() - // task.Run() - // _, err = task.GetResult(0) - // } else { - // rootTask.Cancel() - // } - // return nil, err - // }, math.MaxInt32) - // tasksch.ManageTask(rootTask).Run() - // if !isAsync { - // _, err = rootTask.GetResult(0) - // } else { - // hint = rootTask.ID - // } - return hint, err -} - -func saveJdOrderList(existJdIDMap map[string]int, jdOrderList []interface{}, jdStoreOrderList []map[string]interface{}) (err error) { - var storeOrderList []*model.TempGoodsOrderMobile - for _, v := range jdStoreOrderList { - order := &model.TempGoodsOrderMobile{ - VendorOrderID: v["orderId"].(string), - VendorID: model.VendorIDJD, - AccountNo: v["venderId"].(string), - OrderCreatedAt: utils.Timestamp2Time(utils.MustInterface2Int64(v["orderPaidTime"]) / 1000), - Mobile: v["mobile"].(string), - } - storeOrderList = append(storeOrderList, order) - } - - var orderDetailList []*model.GoodsOrderOriginal - for _, v := range jdOrderList { - orderMap := v.(map[string]interface{}) - orderID := utils.Int64ToStr(utils.MustInterface2Int64(orderMap["orderId"])) - if existJdIDMap[orderID] == 0 { - orgCode := orderMap["orgCode"].(string) - orderDetail := &model.GoodsOrderOriginal{ - VendorOrderID: orderID, - VendorID: model.VendorIDJD, - AccountNo: orgCode, - OrderCreatedAt: utils.Str2Time(orderMap["orderPurchaseTime"].(string)), - OriginalData: string(utils.MustMarshal(orderMap)), - } - orderDetailList = append(orderDetailList, orderDetail) - } - } - - if len(orderDetailList) > 0 || len(storeOrderList) > 0 { - db := dao.GetDB() - if len(orderDetailList) > 0 { - // err = dao.CreateMultiEntities(db, orderDetailList) - for _, v := range orderDetailList { - dao.CreateEntity(db, v) - } - } - if len(storeOrderList) > 0 { - // err = dao.CreateMultiEntities(db, storeOrderList) - for _, v := range storeOrderList { - dao.CreateEntity(db, v) - } - } - } - return err -} - -func PullJdOrder(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { - var existJdIDs []string - db := dao.GetDB() - if err = dao.GetRows(db, &existJdIDs, ` - SELECT vendor_order_id - FROM goods_order_original - WHERE vendor_id = ?`, model.VendorIDJD); err != nil { - return "", err - } - existJdIDMap := make(map[string]int) - for _, v := range existJdIDs { - existJdIDMap[v] = 1 - } - - pageSize := 100 - hourGap := 1 - gapCount := int((toTime.Sub(fromTime)-time.Hour*time.Duration(hourGap))/(time.Hour*time.Duration(hourGap)) + 1) - if gapCount <= 0 { - gapCount = 1 - } - gapList := make([]int, gapCount) - for k := range gapList { - gapList[k] = k - - } - rootTask := tasksch.NewParallelTask("PullJdOrder", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(20), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - gapIndex := batchItemList[0].(int) - hourIndex := gapIndex * hourGap - subFromTime := fromTime.Add(time.Duration(hourIndex) * time.Hour) - subToTime := fromTime.Add(time.Duration(hourIndex+hourGap) * time.Hour) - if subToTime.Sub(toTime) > 0 { - subToTime = toTime - } - if true { //gapIndex < gapCount-1 { - subToTime = subToTime.Add(-1 * time.Second) // 减一秒 - } - commonParams := map[string]interface{}{ - jdapi.KeyPageSize: pageSize, - "orderPurchaseTime_begin": utils.Time2Str(subFromTime), - "orderPurchaseTime_end": utils.Time2Str(subToTime), - } - // globals.SugarLogger.Debugf("PullJdOrder, commonParams=%s", utils.Format4Output(commonParams, false)) - orderList, totalCount, err := api.JdAPI.OrderQuery(commonParams) - if err != nil { - return "", err - } - storeOrderList, err := api.JdAPI.GetStoreOrderInfoList(utils.Time2Str(subFromTime), utils.Time2Str(subToTime)) - if err != nil { - } - if err = saveJdOrderList(existJdIDMap, orderList, storeOrderList); err != nil { - return "", err - } - if false { - globals.SugarLogger.Debugf("subFromTime:%s, subToTime:%s, totalCount:%d, len(orderList):%d", utils.Time2Str(subFromTime), utils.Time2Str(subToTime), totalCount, len(orderList)) - } - return nil, err - }, gapList) - tasksch.ManageTask(rootTask).Run() - - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.ID - } - return hint, err -} - -func UpdateJdOrderRealMobile(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { - return hint, err -} - -func DeleteWrongSpu(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - // sql := ` - // SELECT t1.* - // FROM sku_name t1 - // JOIN sku_name t2 ON t2.link_id = t1.id AND t2.deleted_at = ? - // WHERE t1.deleted_at = ?; - // ` - // db := dao.GetDB() - // var skuNameList []*model.SkuName - // if err = dao.GetRows(db, &skuNameList, sql, utils.DefaultTimeValue, utils.DefaultTimeValue); err != nil { - // return "", err - // } - // rootTask := tasksch.NewSeqTask("DeleteWrongSpu", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - // _, err = cms.DeleteSkuName(ctx, skuNameList[step].ID, ctx.GetUserName()) - // if err != nil { - // globals.SugarLogger.Debugf("DeleteWrongSpu failed nameid:%d, name:%s, with error:%v", skuNameList[step].ID, skuNameList[step].Name, err) - // err = nil // 强制忽略错误 - // } - // return nil, err - // }, len(skuNameList)) - - sql := ` - SELECT t1.* - FROM sku_name t1 - WHERE t1.deleted_at = ? AND t1.is_spu = 1 AND t1.jd_id > 0 - ORDER BY t1.id - ` - db := dao.GetDB() - var skuNameList []*model.SkuName - if err = dao.GetRows(db, &skuNameList, sql, utils.DefaultTimeValue); err != nil { - return "", err - } - rootTask := tasksch.NewSeqTask2("DeleteWrongSpu", ctx, true, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - mapData := map[string]interface{}{ - "name": skuNameList[step].Name, - } - _, err = cms.UpdateSkuName(ctx, skuNameList[step].ID, mapData, false) - if err != nil { - globals.SugarLogger.Debugf("DeleteWrongSpu failed nameid:%d, name:%s, with error:%v", skuNameList[step].ID, skuNameList[step].Name, err) - } - return nil, err - }, len(skuNameList)) - - tasksch.ManageTask(rootTask).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.ID - } - return hint, err -} - -type GoodsOrderOriginalEx struct { - model.GoodsOrderOriginal - OrderStatus int -} - -func TransformJdSpu2Sku(ctx *jxcontext.Context, skuNameIDs []int, count int, isAsync, isContinueWhenError bool) (hint string, err error) { - // sql := ` - // SELECT t1.* - // FROM sku_name t1 - // WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.is_spu = 1 AND jd_id <> 0 - // ` - // sqlParams := []interface{}{ - // utils.DefaultTimeValue, - // model.SkuStatusDeleted, - // } - // if len(skuNameIDs) > 0 { - // sql += " AND t1.id IN (" + dao.GenQuestionMarks(len(skuNameIDs)) + ")" - // sqlParams = append(sqlParams, skuNameIDs) - // } - // sql += " ORDER BY t1.id" - // if count > 0 { - // sql += " LIMIT ?" - // sqlParams = append(sqlParams, count) - // } - // db := dao.GetDB() - // var skuNameList []*model.SkuName - // if err = dao.GetRows(db, &skuNameList, sql, sqlParams...); err != nil { - // return "", err - // } - // if len(skuNameList) == 0 { - // return "", fmt.Errorf("待转换的skuName为空") - // } - // batchSize := 40 - // rootTask := tasksch.NewSeqTask2("TransformJdSpu2Sku", ctx, isContinueWhenError, - // func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - // var ( - // locker sync.Mutex - // skuIDs []int - // ) - // lastIndex := (step + 1) * batchSize - // if lastIndex > len(skuNameList) { - // lastIndex = len(skuNameList) - // } - // batchSkNameList := skuNameList[step*batchSize : lastIndex] - // subTask := tasksch.NewParallelTask(fmt.Sprintf("TransformJdSpu2Sku:%d", step), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - // func(subTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // skuName := batchItemList[0].(*model.SkuName) - // if !jxutils.IsEmptyID(skuName.JdID) { - // sql = ` - // SELECT * - // FROM sku - // WHERE name_id = ? AND deleted_at = ? AND status <> ?; - // ` - // sqlParams := []interface{}{ - // skuName.ID, - // utils.DefaultTimeValue, - // model.SkuStatusDeleted, - // } - // var skuList []*model.Sku - // if err = dao.GetRows(db, &skuList, sql, sqlParams...); err != nil { - // return "", err - // } - // globals.SugarLogger.Debugf("TransformJdSpu2Sku skuList:%s", utils.Format4Output(skuList, false)) - // if len(skuList) > 0 { - // for _, sku := range skuList { - // locker.Lock() - // skuIDs = append(skuIDs, sku.ID) - // locker.Unlock() - // if !jxutils.IsEmptyID(sku.JdID) { - // if globals.EnableJdStoreWrite { - // if err = api.JdAPI.UpdateSkuBaseInfo(utils.Int2Str(skuName.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)); err != nil { - // if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 11004 { - // err = nil - // } else { - // break - // } - // } - // } - // } - // } - // } - // if err == nil && globals.EnableJdStoreWrite { - // if err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusOffline)); err == nil { - // err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)) - // } else if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 11035 { - // err = nil - // } - // } - // if err == nil { - // skuName.IsSpu = 0 - // skuName.JdID = 0 - // if _, err = dao.UpdateEntity(db, skuName, "IsSpu", "JdID"); err == nil { - // sql := ` - // UPDATE sku t1 - // SET - // t1.jd_sync_status = ?, - // t1.jd_id = 0 - // WHERE t1.name_id = ? AND t1.deleted_at = ? AND t1.status <> ? - // ` - // sqlParams := []interface{}{ - // model.SyncFlagNewMask, - // skuName.ID, - // utils.DefaultTimeValue, - // model.SkuStatusDeleted, - // } - // if _, err = dao.ExecuteSQL(db, sql, sqlParams...); err == nil { - // _, err = cms.CurVendorSync.SyncSku(ctx, db, skuName.ID, -1, false, isContinueWhenError, ctx.GetUserName()) - // } - // } - // } - // } else { - // globals.SugarLogger.Debugf("TransformJdSpu2Sku skuName:%d is fake", skuName.ID) - // } - // return nil, err - // }, batchSkNameList) - // rootTask.AddChild(subTask).Run() - // if _, err = subTask.GetResult(0); err == nil { - // if len(skuIDs) > 0 { - // if _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDJD, nil, skuIDs, model.SyncFlagStoreSkuModifiedMask); err == nil { - // // time.Sleep(20 * time.Second) - // // _, err = cms.CurVendorSync.SyncStoresSkus(ctx, db, []int{model.VendorIDJD}, nil, skuIDs, false, isContinueWhenError) - // } - // } - // } - // return nil, err - // }, (len(skuNameList)-1)/batchSize+1) - // tasksch.ManageTask(rootTask).Run() - // if !isAsync { - // _, err = rootTask.GetResult(0) - // } else { - // hint = rootTask.ID - // } - return hint, err -} - -func ReProcessJdBadComment(ctx *jxcontext.Context, isForce, isAsync, isContinueWhenError bool) (hint string, err error) { - sql := ` - SELECT * - FROM jx_bad_comments - ` - if !isForce { - sql += " WHERE (createtime IS NULL OR createtime = '') OR (updatetime IS NULL OR updatetime = '')" - } - // sql += " LIMIT 1" - db := dao.GetDB() - var commentList []*legacymodel.JxBadComments - if err = dao.GetRows(db, &commentList, sql); err == nil { - if len(commentList) > 0 { - rootTask := tasksch.NewParallelTask("ReProcessJdBadComment", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - badComment := batchItemList[0].(*legacymodel.JxBadComments) - comment1, _ := unmarshalCommentText(badComment.Msg) - comment2, _ := unmarshalCommentText(badComment.UpdatedMsg) - if len(comment1) > 0 { - badComment.Createtime = utils.Timestamp2Str(utils.MustInterface2Int64(comment1["createTime"].(map[string]interface{})["time"]) / 1000) - badComment.Msg = string(utils.MustMarshal(comment1)) - if len(comment2) > 0 { - badComment.Updatetime = utils.Timestamp2Str(utils.MustInterface2Int64(comment2["createTime"].(map[string]interface{})["time"]) / 1000) - badComment.UpdatedMsg = string(utils.MustMarshal(comment2)) - } - _, err = dao.UpdateEntity(db, badComment) - } - return nil, err - }, commentList) - tasksch.ManageTask(rootTask).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.ID - } - } - } - return hint, err -} - -func unmarshalCommentText(commentStr string) (retVal map[string]interface{}, isNeedUpdate bool) { - var err error - for { - var retVal map[string]interface{} // 必须要用局部变量 - if commentStr == "" { - return nil, false - } - if err = jxutils.Strings2Objs(commentStr, &retVal); err == nil { - if retVal["data"] != nil { - commentStr = retVal["data"].(string) - } else if retVal["result"] != nil { - return retVal["result"].(map[string]interface{}), true - } else { - return retVal, false - } - } else { - strList := innerDataPat.FindStringSubmatch(commentStr) - if strList[1] != "" { - commentStr = strList[1] - } else { - return nil, false - } - } - } -} - -func RefreshEbaiBadComment(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { - if utils.IsTimeZero(fromTime) { - fromTime = utils.Str2Time("2018-05-03 00:00:00") - } - if utils.IsTimeZero(toTime) { - toTime = time.Now().Add(-3 * time.Hour) - } - days := int(toTime.Sub(fromTime)/(24*time.Hour) + 1) - globals.SugarLogger.Debugf("RefreshEbaiBadComment fromTime:%s, toTime:%s, days:%d", utils.Time2Str(fromTime), utils.Time2Str(toTime), days) - rootTask := tasksch.NewSeqTask("RefreshEbaiBadComment", ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - batchFromTime := fromTime.Add(time.Duration(step) * 24 * time.Hour) - batchToTime := batchFromTime.Add(24*time.Hour - time.Second) - if batchToTime.Sub(toTime) > 0 { - batchToTime = toTime - } - err = ebai.CurPurchaseHandler.RefreshComment(batchFromTime, batchToTime) - return nil, err - }, days) - tasksch.ManageTask(rootTask).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.ID - } - return hint, err -} - -func PrintMsg(ctx *jxcontext.Context, vendorID int, id1, id2, msgTitle, msgContent string) (printerStatus *partner.PrinterStatus, err error) { - handler := partner.GetPrinterPlatformFromVendorID(vendorID) - if handler == nil { - return nil, fmt.Errorf("打印机厂商:%d当前不被支持,请检查vendorID", vendorID) - } - return handler.PrintMsg(ctx, id1, id2, msgTitle, msgContent) -} - -func UpdateAllWeiXinRemark(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - var mobileList []string - sql := ` - SELECT tel - FROM weixins - WHERE openid <> '' AND tel <> ''` - sqlParams := []interface{}{} - if globals.EnableWXAuth2 { - sql = ` - SELECT t1.mobile - FROM user t1 - JOIN auth_bind t2 ON t2.user_id = t1.user_id AND t2.deleted_at = ? and t2.type = ? - WHERE t1.deleted_at = ? AND t1.type & ? <> 0` - sqlParams = []interface{}{ - utils.DefaultTimeValue, - weixin.AuthTypeMP, - utils.DefaultTimeValue, - model.UserTypeStoreBoss, - } - } - if err = dao.GetRows(dao.GetDB(), &mobileList, sql, sqlParams...); err == nil { - rootTask := tasksch.NewParallelTask("刷新微信备注", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - tel := batchItemList[0].(string) - err = cms.HandleUserWXRemark(dao.GetDB(), tel, false) - return nil, err - }, mobileList) - tasksch.ManageTask(rootTask).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.ID - } - } - return hint, err -} - -// 从饿百得到执照信息 -func RetrieveEbaiShopLicence(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - var ebaiStoreList []*model.StoreMap - db := dao.GetDB() - if err = dao.GetRows(db, &ebaiStoreList, ` - SELECT * - FROM store_map - WHERE vendor_id = ? AND deleted_at = ? - `, model.VendorIDEBAI, utils.DefaultTimeValue); err == nil { - globals.SugarLogger.Debugf("RetrieveEbaiShopLicence, count:%d", len(ebaiStoreList)) - rootTask := tasksch.NewParallelTask("XXXX", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - ebaiStore := batchItemList[0].(*model.StoreMap) - xxList, err := api.EbaiAPI.ShopAptitudeGet("", utils.Str2Int64(ebaiStore.VendorStoreID)) - if err == nil && ebaiStore != nil { - if len(xxList) > 1 { - ebaiStore2, err2 := api.EbaiAPI.ShopGet("", utils.Str2Int64(ebaiStore.VendorStoreID)) - if err = err2; err == nil { - shop := &legacymodel.EbaiShopLicence{ - ShopName: utils.Interface2String(ebaiStore2["name"]), - Licence: utils.Interface2String(xxList[1]["license_number"]), - Address: utils.Interface2String(ebaiStore2["address"]), - Owner: utils.Interface2String(xxList[1]["legal_representative_name"]), - Tel: utils.Interface2String(ebaiStore2["service_phone"]), - LicenceName: utils.Interface2String(xxList[1]["license_name"]), - } - err = dao.CreateEntity(db, shop) - } - } - } - return nil, err - }, ebaiStoreList) - tasksch.ManageTask(rootTask).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.ID - } - } - return hint, err -} - -func RefreshMtpsWaybillFee(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - var waybillList []*model.Waybill - db := dao.GetDB() - if err = dao.GetRows(db, &waybillList, ` - SELECT * - FROM waybill - WHERE status_time > '2019-04-01' AND waybill_vendor_id = 102 AND desired_fee = 0 - `); err == nil { - globals.SugarLogger.Debugf("RefreshMtpsWaybillFee, count:%d", len(waybillList)) - rootTask := tasksch.NewParallelTask("RefreshMtpsWaybillFee", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - bill := batchItemList[0].(*model.Waybill) - bill.DesiredFee, _ = delivery.CalculateBillDeliveryFee(bill) - _, err = dao.UpdateEntity(db, bill, "DesiredFee") - return nil, err - }, waybillList) - tasksch.ManageTask(rootTask).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.ID - } - } - return hint, err -} - -func CreateConsumerFromOrders(ctx *jxcontext.Context, vendorIDs []int, fromDate, toDate time.Time, isForce, isAsync, isContinueWhenError bool) (hint string, err error) { - if utils.IsTimeZero(fromDate) { - return "", fmt.Errorf("fromDate必须指定") - } - if utils.IsTimeZero(toDate) { - toDate = time.Now() - } - fromDate = utils.Time2Date(fromDate) - toDate = utils.Time2Date(toDate) - if len(vendorIDs) == 0 { - vendorIDs = partner.GetPurchasePlatformVendorIDs() - } - var dateList []time.Time - curDate := fromDate - for { - if toDate.Sub(curDate) < 0 { - break - } - dateList = append(dateList, curDate) - curDate = curDate.Add(24 * time.Hour) - } - - type GoodsOrderWithOriginal struct { - model.GoodsOrder - OriginalData string `orm:"type(text)" json:"-"` - } - - db := dao.GetDB() - rootTask := tasksch.NewParallelTask("从订单中创建消费者账户", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - curDate := batchItemList[0].(time.Time) - sql := ` - SELECT t1.*, t2.original_data - FROM goods_order t1 - LEFT JOIN goods_order_original t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id - WHERE t1.order_created_at >= ? AND t1.order_created_at < ?` - sqlParams := []interface{}{ - curDate, - curDate.Add(24 * time.Hour), - } - if len(vendorIDs) > 0 { - sql += " AND t1.vendor_id IN (" + dao.GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if !isForce { - sql += " AND t1.user_id = ''" - } - var orderList []*GoodsOrderWithOriginal - if err = dao.GetRows(db, &orderList, sql, sqlParams...); err == nil { - if len(orderList) > 0 { - // 并发必须是1,否则在HandleOrder4Consignee中可能导致主键重,错误 - subTask := tasksch.NewParallelTask(fmt.Sprintf("处理日期:%s的订单", utils.Time2DateStr(curDate)), tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - order := batchItemList[0].(*GoodsOrderWithOriginal) - if isForce || order.UserID == "" { - if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil { - var updateFields []string - if isForce || order.VendorUserID == "" { - var order2 *model.GoodsOrder - if order.OriginalData != "" { - var orderData map[string]interface{} - if utils.UnmarshalUseNumber([]byte(order.OriginalData), &orderData) == nil { - order2 = handler.Map2Order(orderData) - if order2.VendorUserID == "" { - order2 = nil - } - } - } - if order2 == nil && order.VendorID == model.VendorIDMTWM && time.Now().Sub(curDate) < 60*24*time.Hour { - order2, err = handler.GetOrder(order.VendorOrgCode, order.VendorOrderID) - } - if order2 != nil { - if order2.VendorUserID != "" && order.VendorUserID != order2.VendorUserID { - updateFields = append(updateFields, "VendorUserID") - order.VendorUserID = order2.VendorUserID - } - } - } - /* - if err = cms.HandleOrder4Consignee(&order.GoodsOrder); err == nil { - updateFields = append(updateFields, "UserID") - } - */ - if len(updateFields) > 0 { - dao.UpdateEntity(db, &order.GoodsOrder, updateFields...) - } - } - } - return nil, err - }, orderList) - tasksch.HandleTask(subTask, task, true).Run() - _, err = subTask.GetResult(0) - } - } - return nil, err - }, dateList) - tasksch.HandleTask(rootTask, nil, true).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.ID - } - return hint, err -} - -func CheckImages(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - // db := dao.GetDB() - // rootTask := tasksch.NewSeqTask("检查图片的有效性", ctx, - // func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - // switch step { - // case 0: // 检查图片的格式与大小 - // var imgList []*model.DataResource - // if err = dao.GetRows(db, &imgList, ` - // SELECT t1.* - // FROM data_resource t1 - // WHERE t1.use_type = 1 - // `); err == nil && len(imgList) > 0 { - // calcTask := tasksch.NewParallelTask("检查京西图片的有效性", - // tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, - // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // dataRes := batchItemList[0].(*model.DataResource) - // binaryData, hashCode, err2 := jxutils.DownloadFileByURL(dataRes.MainURL) - // if err = err2; err == nil { - // errMsg := "" - // if hashCode != dataRes.HashCode { - // errMsg = fmt.Sprintf("hashcode:%s", hashCode) - // dataRes.HashCode = hashCode - // } - // resType := http.DetectContentType(binaryData) - // if resType != dataRes.ResourceType { - // errMsg += "," + resType - // dataRes.ResourceType = resType - // } - // var img image.Image - // if dataRes.ResourceType == "image/png" { - // img, err = png.Decode(bytes.NewReader(binaryData)) - // } else if dataRes.ResourceType == "image/jpeg" { - // img, err = jpeg.Decode(bytes.NewReader(binaryData)) - // } - // if err == nil { - // if img != nil { - // if img.Bounds().Dx() != 800 || img.Bounds().Dy() != 800 { - // errMsg += fmt.Sprintf(",size:%dx%d", img.Bounds().Dx(), img.Bounds().Dy()) - // } - // } - // } else { - // errMsg += "," + err.Error() - // } - // if errMsg != "" { - // dataRes.Remark = errMsg - // dao.UpdateEntity(dao.GetDB(), dataRes, "Remark", "ResourceType", "HashCode") - // } - // } - // return retVal, err - // }, imgList) - // tasksch.HandleTask(calcTask, task, false).Run() - // _, err = calcTask.GetResult(0) - // } - // case 1: // 检查京东商品图片 - // skuNameInfo, err2 := cms.GetSkuNames(ctx, "", false, map[string]interface{}{}, 0, -1) - // if err = err2; err == nil && len(skuNameInfo.SkuNames) > 0 { - // calcTask := tasksch.NewParallelTask("检查京东图片的有效性", - // tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, - // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // skuName := batchItemList[0].(*model.SkuNameExt) - // for _, sku := range skuName.Skus { - // if sku.JdID != 0 { - // skuPageInfo, err2 := api.JdAPI.GetSkuPageInfo(sku.JdID) - // if err = err2; err == nil && skuPageInfo.FixedStatus && len(skuPageInfo.Image) == 0 { - // err = fmt.Errorf("skuName:%d, sku:%d, jdid:%d, 没有图片", skuName.ID, sku.ID, sku.JdID) - // skuName.ImgHashCode = "np" - // dao.UpdateEntity(dao.GetDB(), &skuName.SkuName, "ImgHashCode") - // } - // break - // } - // } - // return retVal, err - // }, skuNameInfo.SkuNames) - // tasksch.HandleTask(calcTask, task, false).Run() - // _, err = calcTask.GetResult(0) - // } - // } - // return result, err - // }, 2) - // tasksch.HandleTask(rootTask, nil, true).Run() - // if !isAsync { - // if _, err = rootTask.GetResult(0); err == nil { - // hint = "1" - // } - // } else { - // hint = rootTask.ID - // } - return hint, err -} - -func fixMtwmCategoryList(cats []*partner.BareCategoryInfo, vendorStoreID string, name2CatMap map[string]*model.SkuCategory, id2CatMap map[int]*model.SkuCategory) (err error) { - errList := errlist.New() - for _, v := range cats { - // 深度优先,先处理底层次的分类 - errList.AddErr(fixMtwmCategoryList(v.Children, vendorStoreID, name2CatMap, id2CatMap)) - - var cat *model.SkuCategory - var catCodeStr string - rFilterCatName := utils.FilterEmoji(v.Name) - if rCatCode := int(utils.Str2Int64WithDefault(v.VendorCatID, 0)); rCatCode > 0 { - catCodeStr = utils.Int2Str(rCatCode) - if catCodeStr == v.VendorCatID { // 防止带有数字分类名误被认为是catCode - cat = id2CatMap[rCatCode] - } else { - catCodeStr = "" - } - } - if cat == nil { - cat = name2CatMap[rFilterCatName] - } - if cat != nil { - if v.Name != cat.Name || v.VendorCatID != utils.Int2Str(cat.ID) { - errList.AddErr(api.MtwmAPI.RetailCatUpdate(vendorStoreID, cat.Name, &mtwmapi.Param4UpdateCat{ - CategoryCodeOrigin: catCodeStr, - CategoryNameOrigin: v.Name, - CategoryCode: utils.Int2Str(cat.ID), - Sequence: v.Seq, - })) - } - } else if rFilterCatName != v.Name { - errList.AddErr(api.MtwmAPI.RetailCatUpdate(vendorStoreID, rFilterCatName[:len(rFilterCatName)-2], &mtwmapi.Param4UpdateCat{ - CategoryCodeOrigin: catCodeStr, - CategoryNameOrigin: v.Name, - Sequence: v.Seq, - })) - } - } - return errList.GetErrListAsOne() -} - -func FixMtwmCategory(ctx *jxcontext.Context, mtwmStoreIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - id2CatMap := make(map[int]*model.SkuCategory) - name2CatMap := make(map[string]*model.SkuCategory) - var mtwmIDMap map[string]int - if len(mtwmStoreIDs) > 0 { - mtwmIDMap = make(map[string]int) - for _, v := range mtwmStoreIDs { - mtwmIDMap[utils.Int2Str(v)] = 1 - } - } - task := tasksch.NewParallelTask("修复美团分类信息", tasksch.NewParallelConfig().SetParallelCount(1), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - var catList []*model.SkuCategory - sql := ` - SELECT * - FROM sku_category t1 - WHERE t1.deleted_at = ? - ` - db := dao.GetDB() - if err = dao.GetRows(db, &catList, sql, utils.DefaultTimeValue); err != nil { - return nil, err - } - for _, v := range catList { - v.Name = utils.FilterEmoji(v.Name) - id2CatMap[v.ID] = v - name2CatMap[v.Name] = v - } - case 1: - storeIDs, err := mtwm.CurPurchaseHandler.GetAllStoresVendorID(ctx, "") - if err != nil { - return nil, err - } - subTask := tasksch.NewParallelTask("修复美团分类信息2", tasksch.NewParallelConfig().SetParallelCount(5).SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeID := batchItemList[0].(string) - if mtwmIDMap == nil || mtwmIDMap[storeID] == 1 { - catList, err := mtwm.CurPurchaseHandler.GetStoreAllCategories(ctx, 0, storeID) - if err == nil { - err = fixMtwmCategoryList(catList, storeID, name2CatMap, id2CatMap) - } - } - return retVal, err - }, storeIDs) - tasksch.HandleTask(subTask, task, true).Run() - _, err = subTask.GetResult(0) - } - return retVal, err - }, []int{0, 1}) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - _, err = task.GetResult(0) - hint = "1" - } else { - hint = task.GetID() - } - return hint, err -} - -func JdStoreInfo1125() (hint string, err error) { - fileName := "老格恢复拓店进度.xlsx" - db := dao.GetDB() - storeList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") - if err == nil { - var validStoreList []*dao.StoreDetail - for _, v := range storeList { - if v.Status != model.StoreStatusDisabled && v.CreatedAt.Sub(utils.Str2Time("2019-10-01")) > 0 { - storeInfo, err := api.JdAPI.GetStoreInfoByStationNo2(v.VendorStoreID) - if err == nil && storeInfo.CreateTime.GoTime().Sub(utils.Str2Time("2019-10-25")) > 0 { - if storeDetail, err := dao.GetStoreDetail(db, v.StoreID, v.VendorID); err == nil { - validStoreList = append(validStoreList, storeDetail) - } - } - } - } - getStoreList := func(lng, lat, lng2, lat2 int) (vendorStoreIDs []string) { - for _, v := range validStoreList { - if v.Lng >= lng && v.Lng <= lng2 && v.Lat >= lat && v.Lat <= lat2 { - vendorStoreIDs = append(vendorStoreIDs, v.VendorStoreID) - } - } - return vendorStoreIDs - } - sheetName := "老格明细" - file, err2 := excelize.OpenFile(fileName) - if err = err2; err == nil { - // globals.SugarLogger.Debug(err, file) - rows, err2 := file.GetRows(sheetName) - if err = err2; err == nil { - str2Coords := func(str string) (lng, lat int) { - list := strings.Split(str, ",") - if len(list) >= 2 { - lng, lat = jxutils.StandardCoordinate2Int(utils.Str2Float64WithDefault(list[1], 0)), jxutils.StandardCoordinate2Int(utils.Str2Float64WithDefault(list[0], 0)) - } - return lng, lat - } - for i := 1; i < len(rows); i++ { - lng, lat := str2Coords(rows[i][8]) - lng2, lat2 := str2Coords(rows[i][7]) - vendorStoreIDs := getStoreList(lng, lat, lng2, lat2) - // fmt.Printf("%d,%v", i, vendorStoreIDs) - countInfo := fmt.Sprintf("京西已拓%d", len(vendorStoreIDs)) - axis, _ := excelize.CoordinatesToCellName(5, i+1) - file.SetCellStr(sheetName, axis, countInfo) - axis2, _ := excelize.CoordinatesToCellName(6, i+1) - file.SetCellStr(sheetName, axis2, strings.Join(vendorStoreIDs, ",")) - } - file.SaveAs("ffff.xlsx") - } - } - } - return hint, err -} - -func BuildSkuFromEbaiStore(ctx *jxcontext.Context, baiduShopID int64, isAsync, isContinueWhenError bool) (hint string, err error) { - ebaiCatIDKey := "ebaiCatID" - catList, err := api.EbaiAPI.PageGetCustomCatList(baiduShopID) - if err != nil { - return hint, err - } - catMap := make(map[string]map[string]interface{}) - - allSkuInfo := make(map[string]map[string]map[string]map[string]interface{}) - for _, cat := range catList { - catName := utils.Interface2String(cat["cat_name"]) - if catName == "限时特惠" || catName == "应季热销" { - catName = "应季水果" - } - skuNameMap := allSkuInfo[catName] - if skuNameMap == nil { - skuNameMap = make(map[string]map[string]map[string]interface{}) - allSkuInfo[catName] = skuNameMap - } - if catMap[catName] == nil { - catMap[catName] = cat - } - skuList, err2 := api.EbaiAPI.PageGetCustomSkuList(baiduShopID, utils.Str2Int64(utils.Interface2String(cat["cat_id"]))) - if err = err2; err != nil { - return hint, err - } - for _, sku := range skuList { - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(sku["upc_name"].(string)) - if specQuality > 0 { - if catMap[catName][ebaiCatIDKey] == nil { - catMap[catName][ebaiCatIDKey] = utils.Interface2String(sku["cat3_id"]) - } - skuNameKey := sku["photos"].([]interface{})[0].(map[string]interface{})["url"].(string) - if skuNameMap[skuNameKey] == nil { - skuNameMap[skuNameKey] = make(map[string]map[string]interface{}) - } - skuNameMap[skuNameKey][fmt.Sprintf("%f.%s", specQuality, specUnit)] = sku - } - } - } - allSkuInfo2 := make(map[*model.SkuCategory][]*model.SkuNameExt) - catSeq := 0 - for catName, catSkuNameMap := range allSkuInfo { - if len(catSkuNameMap) > 0 { - skuCat := &model.SkuCategory{ - Name: catName, - ParentID: 0, - Level: 1, - Type: model.SkuCategoryNormal, - Seq: catSeq, - EbaiCategoryID: utils.Str2Int64(utils.Interface2String(catMap[catName][ebaiCatIDKey])), - } - catSeq++ - for _, skuList := range catSkuNameMap { - var skuNameExt *model.SkuNameExt - for _, sku := range skuList { - prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(sku["upc_name"].(string)) - if skuNameExt == nil { - skuNameExt = &model.SkuNameExt{ - SkuName: model.SkuName{ - Prefix: prefix, - Name: name, - // CategoryID: - IsGlobal: 1, - Unit: unit, - SpecQuality: specQuality, - SpecUnit: specUnit, - Price: int(jxutils.StandardPrice2Int(utils.MustInterface2Float64(sku["sale_price"]))), - Img: sku["photos"].([]interface{})[0].(map[string]interface{})["url"].(string), - Status: model.SkuStatusNormal, - IsSpu: 0, - }, - } - if len(skuList) > 1 { - skuNameExt.Unit = "份" - skuNameExt.SpecQuality = 500 - skuNameExt.SpecUnit = "g" - } - if skuNameExt.Unit == "份" { - tmpSpecQuality := specQuality - if specUnit == "kg" || specUnit == "l" { - tmpSpecQuality *= 1000 - } - skuNameExt.Price = int(float32(skuNameExt.Price) * 500 / tmpSpecQuality) - } - } - mySku := &model.SkuWithVendor{ - Sku: &model.Sku{ - // CategoryID: - // NameID: - Comment: comment, - SpecQuality: specQuality, - SpecUnit: specUnit, - Weight: int(utils.Str2Int64(utils.Interface2String(sku["weight"]))), - Status: model.SkuStatusNormal, - - SkuIndex: int(jxutils.StandardPrice2Int(utils.MustInterface2Float64(sku["sale_price"]))), // 临时传递价格用 - }, - } - if sku["enabled"].(string) == "0" { - mySku.Status = model.SkuStatusDontSale - } - skuNameExt.Skus = append(skuNameExt.Skus, mySku) - } - allSkuInfo2[skuCat] = append(allSkuInfo2[skuCat], skuNameExt) - } - } - } - - startOutSkuID := 1000 - var skuCatList []*model.SkuCategory - for cat := range allSkuInfo2 { - skuCatList = append(skuCatList, cat) - } - putPolicy := storage.PutPolicy{ - Scope: globals.QiniuBucket, - // Expires: 10 * 60, - } - cfg := &storage.Config{} - upToken := putPolicy.UploadToken(api.QiniuAPI) - rootTask := tasksch.NewSeqTask("BuildSkuFromEbaiStore", ctx, - func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - var catID string - cat := skuCatList[step] - skuNameExtList := allSkuInfo2[cat] - catID, err = addShopCategory(0, cat.Name, int(cat.Level), cat.Seq, ctx.GetUserName()) - if err == nil { - shopCategories := []int64{utils.Str2Int64(catID)} - for _, skuNameExt := range skuNameExtList { - var imgContent []byte - skuNameExt.CategoryID = cat.ID - skuNameExt.Img = strings.Replace(skuNameExt.Img, "https://", "http://", 1) - if imgContent, _, err = jxutils.DownloadFileByURL(skuNameExt.Img); err != nil { - globals.SugarLogger.Infof("download pic %s failed with error:%v", skuNameExt.Img, err) - if !isContinueWhenError { - return nil, err - } - err = nil - continue - } - formUploader := storage.NewFormUploader(cfg) - ret := storage.PutRet{} - key := jxutils.GenPicFileName(".jpeg") - for i := 0; i < 3; i++ { - if err = formUploader.Put(context.Background(), &ret, upToken, key, bytes.NewReader(imgContent), int64(len(imgContent)), &storage.PutExtra{}); err == nil { - break - } - } - if err != nil { - globals.SugarLogger.Infof("upload pic %s failed with error:%v", skuNameExt.Img, err) - if !isContinueWhenError { - return nil, err - } - err = nil - continue - } - qiniuImgURL := jxutils.ComposeQiniuResURL(key) + "?imageMogr2/thumbnail/x800/gravity/Center/crop/800x800" - for _, sku := range skuNameExt.Skus { - jdCatID := 22410 // 其他国产水果 - if cat.Name == "进口水果" { - jdCatID = 20342 // 其他进口水果 - } - price := sku.SkuIndex - skuName := jxutils.ComposeSkuNameOriginal(skuNameExt.Prefix, skuNameExt.Name, sku.Comment, skuNameExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameCharCount) - fixedStatus := 1 - if sku.Status != model.SkuStatusNormal { - fixedStatus = 2 - } - var vendorSkuID string - vendorSkuID, err = addSku(utils.Int2Str(startOutSkuID), jdCatID, shopCategories, jd.DefBrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{qiniuImgURL}, fixedStatus, true, nil) - if err == nil { - globals.SugarLogger.Debugf("vendorSkuID=%s", vendorSkuID) - } else { - globals.SugarLogger.Infof("create %s failed with error:%v", skuName, err) - if !isContinueWhenError { - return nil, err - } - err = nil - } - // fmt.Printf("%s,[%s]%s-%f-%s, %s, %s\n", cat.Name, skuNameExt.Prefix, skuNameExt.Name, skuNameExt.SpecQuality, skuNameExt.SpecUnit, qiniuImgURL, skuName) - startOutSkuID++ - // rootTask.Cancel() - // return nil, nil - } - } - } else { - return nil, err - } - return nil, err - }, len(skuCatList)) - tasksch.ManageTask(rootTask).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.ID - } - return hint, err -} - -func addShopCategory(pid int64, shopCategoryName string, shopCategoryLevel, sort int, userName string) (catId string, err error) { - // globals.SugarLogger.Debug(pid, shopCategoryName, shopCategoryLevel, sort, userName) - // return "123", err - return api.JdAPI.AddShopCategory(pid, shopCategoryName, shopCategoryLevel, sort, userName) -} - -func addSku(outSkuId string, cagtegoryId int, shopCategories []int64, brandId int, skuName string, skuPrice int, weight float32, images []string, fixedStatus int, isSale bool, addParams map[string]interface{}) (skuId string, err error) { - // globals.SugarLogger.Debug(outSkuId, cagtegoryId, shopCategories, brandId, skuName, skuPrice, weight, images, fixedStatus, isSale, addParams) - // return "456", err - return api.JdAPI.AddSku(outSkuId, cagtegoryId, shopCategories, brandId, skuName, skuPrice, weight, images, fixedStatus, isSale, addParams) -} - -func UploadJdsImage(ctx *jxcontext.Context) (err error) { - // db := dao.GetDB() - // result1, _ := api.JdShopAPI.GetProvince() - // for _, v := range result1 { - // place1, _ := dao.GetPlaceByName(db, v.AreaName, 1, 0) - // place1.JdsCode = v.AreaID - // dao.UpdateEntity(db, place1, "JdsCode") - // result2, _ := api.JdShopAPI.GetCity(v.AreaID) - // for _, vv := range result2 { - // place2, _ := dao.GetPlaceByName(db, vv.AreaName, 2, 0) - // place2.JdsCode = vv.AreaID - // dao.UpdateEntity(db, place2, "JdsCode") - // place22, _ := dao.GetPlaceByName(db, vv.AreaName, 3, 0) - // if place22 != nil { - // place22.JdsCode = vv.AreaID - // dao.UpdateEntity(db, place22, "JdsCode") - // } - // result3, _ := api.JdShopAPI.GetCounty(vv.AreaID) - // for _, vvv := range result3 { - // place3, _ := dao.GetPlaceByName(db, vvv.AreaName, 3, 0) - // place3.JdsCode = vvv.AreaID - // dao.UpdateEntity(db, place3, "JdsCode") - // } - // } - // } - - //京东商城商品不同 - // type tTmp struct { - // SkuID int `json:"skuID"` - // Reason string `json:"reason"` - // } - // var vendorMap = make(map[int]*partner.SkuNameInfo) - // var localMap = make(map[int]*model.StoreSkuBind) - // var addList, deleteList []int - // var updateList []*tTmp - // vendorStock2JxStatus := func(stock int) (status int) { - // if stock > 0 { - // return model.StoreSkuBindStatusNormal - // } else { - // return model.StoreSkuBindStatusDontSale - // } - // } - // handler := partner.GetPurchasePlatformFromVendorID(model.VendorIDJDShop).(partner.ISingleStoreStoreSkuHandler) - // skuNameList, err := handler.GetStoreSkusFullInfo(ctx, nil, 0, "", nil) - // storeSkuList, err := dao.GetStoresSkusInfo(dao.GetDB(), []int{model.JdShopMainStoreID}, nil) - // for _, v := range skuNameList { - // vendorMap[v.SkuList[0].SkuID] = v - // } - // for _, v := range storeSkuList { - // if vendorMap[v.SkuID] == nil { - // if v.Status == model.StoreSkuBindStatusNormal { - // addList = append(addList, v.SkuID) - // } - // } else { - // if int64(v.JdsPrice) != vendorMap[v.SkuID].SkuList[0].VendorPrice { - // updateList = append(updateList, &tTmp{ - // SkuID: v.SkuID, - // Reason: "价格不同", - // }) - // } - // if v.Status != vendorStock2JxStatus(vendorMap[v.SkuID].SkuList[0].Stock) { - // updateList = append(updateList, &tTmp{ - // SkuID: v.SkuID, - // Reason: "库存可售不同", - // }) - // } - // skus, _ := dao.GetSkus(dao.GetDB(), []int{v.SkuID}, nil, nil, nil, nil) - // if skus[0].Comment != "" { - // if skus[0].Comment != vendorMap[v.SkuID].SkuList[0].Comment { - // updateList = append(updateList, &tTmp{ - // SkuID: v.SkuID, - // Reason: "备注与销售属性不同", - // }) - // } - // } - // } - // localMap[v.SkuID] = v - // } - // for k, _ := range vendorMap { - // if localMap[k] == nil { - // deleteList = append(deleteList, k) - // } - // } - // fmt.Println("addList2", addList) - // fmt.Println("updateList2", utils.Format4Output(updateList, false)) - // fmt.Println("deleteList2", deleteList) - // cms.DeletedDuplicateWaitAuditData(ctx, dao.GetDB()) - // orderman.RefreshJdShopOrdersEarningPrice(jxcontext.AdminCtx, time.Now().AddDate(0, 0, -2).Format("20060102"), time.Now().Format("20060102")) - var ( - db = dao.GetDB() - goods []*model.GoodsOrder - ) - sql := `SELECT * from goods_order where vendor_id = 0 and buyer_comment = '【JD】' and total_shop_money = 0 and status = 110 - AND order_created_at > '2020-09-01'` - dao.GetRows(db, &goods, sql, nil) - for _, order2 := range goods { - results, err := api.JdAPI.GetJdShopOrders(order2.OrderCreatedAt.AddDate(0, 0, -1).Format("20060102"), order2.OrderCreatedAt.Format("20060102"), globals.JdOrgCode, globals.JdLoginName) - if err != nil || results == nil { - return err - } - for _, v := range results.BillList.Result { - if v.DueAmount != 0 { - order, _ := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(v.OrderID), model.VendorIDJD) - stores, _ := dao.GetStoreList(db, []int{jxutils.GetSaleStoreIDFromOrder(order)}, nil, nil, nil, "") - if len(stores) > 0 { - store := stores[0] - if order.NewEarningPrice == 0 { - jxutils.RefreshOrderEarningPrice2(order, store.PayPercentage) - } - if order.TotalShopMoney == 0 { - order.TotalShopMoney = utils.Float64TwoInt64(v.DueAmount * 100) - } - dao.UpdateEntity(db, order, "TotalShopMoney", "NewEarningPrice") - } - } - } - } - return err -} - -func RefreshJXPriceChange(ctx *jxcontext.Context, storeID int) (hint string, err error) { - db := dao.GetDB() - var ( - stores []*model.Store - vendorIDs = []int{0, 1, 3, 5, 9} - isAsync = true - isContinueWhenError = true - ) - sql := ` - SELECT * - FROM store - WHERE deleted_at = ? AND pay_percentage > 50 - ` - sqlParams := []interface{}{utils.DefaultTimeValue} - if storeID != 0 { - sql += " AND id = ?" - sqlParams = append(sqlParams, storeID) - } - err = dao.GetRows(db, &stores, sql, sqlParams) - task := tasksch.NewParallelTask("刷新门店价格", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - store := batchItemList[0].(*model.Store) - var skuBindInfos []*cms.StoreSkuBindInfo - for _, v := range vendorIDs { - storeMaps, _ := dao.GetStoresMapList(db, []int{v}, []int{store.ID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if len(storeMaps) > 0 { - storeMap := storeMaps[0] - switch v { - case model.VendorIDJD: - storeMap.PricePercentagePack = "京东测试报价=结算价" - dao.UpdateEntity(db, storeMap, "PricePercentagePack") - case model.VendorIDEBAI: - storeMap.PricePercentagePack = "美团测试报价=结算价" - dao.UpdateEntity(db, storeMap, "PricePercentagePack") - case model.VendorIDMTWM: - storeMap.PricePercentagePack = "饿百测试报价=结算价" - dao.UpdateEntity(db, storeMap, "PricePercentagePack") - case model.VendorIDJDShop: - storeMap.PricePercentagePack = "京西100-100" - dao.UpdateEntity(db, storeMap, "PricePercentagePack") - case model.VendorIDJX: - storeMap.PricePercentagePack = "京西100-100" - dao.UpdateEntity(db, storeMap, "PricePercentagePack") - } - } - } - storeSkus, err := dao.GetStoresSkusInfo(db, []int{store.ID}, nil) - for _, v := range storeSkus { - skuAndName, _ := dao.GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil) - skuBindInfo := &cms.StoreSkuBindInfo{ - // StoreID: store.ID, - NameID: skuAndName[0].NameID, - UnitPrice: v.UnitPrice * store.PayPercentage / 100, - } - skuBindInfos = append(skuBindInfos, skuBindInfo) - } - // cms.UpdateStoresSkusByBind(ctx, task, skuBindInfos, isAsync, isContinueWhenError, false) - cms.UpdateStoresSkusWithoutSync(ctx, []int{store.ID}, skuBindInfos, false) - store.PayPercentage = 100 - dao.UpdateEntity(db, store, "PayPercentage") - return retVal, err - }, stores) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - _, err = task.GetResult(0) - hint = "1" - } - return hint, err -} diff --git a/business/jxstore/tempop/tempop_test.go b/business/jxstore/tempop/tempop_test.go deleted file mode 100644 index 06875b096..000000000 --- a/business/jxstore/tempop/tempop_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package tempop - -import ( - "fmt" - "io/ioutil" - "net/http" - "testing" - - "git.rosy.net.cn/jx-callback/globals/api2" - "git.rosy.net.cn/jx-callback/globals/testinit" - - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc" -) - -func init() { - testinit.Init() - api2.Init() -} - -func TestJdStoreInfo1125(t *testing.T) { - _, err := JdStoreInfo1125() - if err != nil { - t.Fatal(err) - } -} - -func Testaa(t *testing.T) { - request, _ := http.NewRequest(http.MethodGet, "https://stores.shop.jd.com/stores/updateStoreStatus?storeId=24332466&storeStatus=1", nil) - c := &http.Cookie{ - Name: "thor", - Value: "80FAF09E9A09B6E618A68057BDFCFCB8C86E8252DC9F7D3B34572625904FBA0AB6BF053A5325612EC0407791BB05F5301356E71E8B282C40C06D0B5DF3439DEECB102A78FAFF7AC0FC4E2D1FA8DD8BBAE1A011E50B5C74F1870AD982D7BF453F470F31F2241B73AC4C25485025C2ABEBC8A538AF7257824D2FAEE300A1435175B0B451FB5C19B78D729FC83152CA3BAF", - } - request.AddCookie(c) - client := &http.Client{} - fmt.Println("test1", request.URL) - response, _ := client.Do(request) - defer response.Body.Close() - bodyData, _ := ioutil.ReadAll(response.Body) - fmt.Println("test1", string(bodyData)) -} diff --git a/business/jxstore/yonghui/yonghui.go b/business/jxstore/yonghui/yonghui.go deleted file mode 100644 index 38cbb183d..000000000 --- a/business/jxstore/yonghui/yonghui.go +++ /dev/null @@ -1,1104 +0,0 @@ -package yonghui - -import ( - "errors" - "fmt" - "io" - "math" - "mime/multipart" - "strings" - "sync" - "time" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/utils" - "github.com/360EntSecGroup-Skylar/excelize" - - "git.rosy.net.cn/baseapi/platformapi/dingdingapi" - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/platformapi/weimobapi" - "git.rosy.net.cn/jx-callback/business/jxstore/cms" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" - "git.rosy.net.cn/jx-callback/business/jxutils/excel" - "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/globals" - - "git.rosy.net.cn/jx-callback/globals/api" -) - -type SheetParam struct { - SkuIDCol int - SkuPriceCol int - SkuNameCol int - OrgSkuIdCol int - OrgSkuPriceCol int - OrgSkuNameCol int - SkuRow int -} - -type DataStoreSkusSuccessLock struct { - dataStoreSkusSuccessList []DataStoreSkusSuccess - locker sync.RWMutex -} - -type DataSuccessLock struct { - dataSuccessList []DataSuccess - locker sync.RWMutex -} - -type DataFailedLock struct { - dataFailedList []DataFailed - locker sync.RWMutex -} - -type DataStoreSkusSuccess struct { - StoreID int `json:"门店ID"` - NameID int `json:"商品编码"` - Name string `json:"商品名称"` - Unit string `json:"单位"` - OrgPrice float64 `json:"原价"` - NowPrice float64 `json:"现价"` - MixPrice float64 `json:"涨跌"` -} - -type DataSuccess struct { - NameID string `json:"商品编码"` - Name string `json:"商品名称"` - Unit string `json:"单位"` - OrgPrice float64 `json:"原价"` - NowPrice float64 `json:"现价"` - MixPrice float64 `json:"涨跌"` -} - -type DataFailed struct { - GoodsID string `json:"商品ID"` - GoodsName string `json:"商品名称"` - Comment string `json:"备注"` -} - -type Data struct { - GoodsID string `json:"商品编码"` - GoodsName string `json:"商品名称"` - GoodsNum int `json:"订货数量"` -} - -type ExcelParam struct { - SpuCode string - Name string - Price float64 -} - -type OrderList struct { - Name string `json:"name"` - Phone string `json:"phone"` - OrderNo int64 `json:"orderNo"` -} - -type WeimobOrderSkusExcelResult struct { - DownloadUrlFine string `json:"downloadUrlFine,omitempty"` - DownloadUrlHairy string `json:"downloadUrlHairy,omitempty"` -} - -var ( - sheetMap = map[string]*SheetParam{ - "蔬菜": &SheetParam{ - SkuIDCol: 0, - SkuPriceCol: 14, - SkuNameCol: 1, - OrgSkuIdCol: 5, - OrgSkuPriceCol: 8, - OrgSkuNameCol: 6, - SkuRow: 2, - }, "水果": &SheetParam{ - SkuIDCol: 0, - SkuPriceCol: 14, - SkuNameCol: 1, - OrgSkuIdCol: 5, - OrgSkuPriceCol: 8, - OrgSkuNameCol: 6, - SkuRow: 2, - }, "肉禽": &SheetParam{ - SkuIDCol: 0, - SkuPriceCol: 12, - SkuNameCol: 1, - OrgSkuIdCol: 4, - OrgSkuPriceCol: 7, - OrgSkuNameCol: 5, - SkuRow: 1, - }, "净配": &SheetParam{ - SkuIDCol: 0, - SkuPriceCol: 14, - SkuNameCol: 1, - OrgSkuIdCol: 4, - OrgSkuPriceCol: 7, - OrgSkuNameCol: 5, - SkuRow: 1, - }, "水产": &SheetParam{ - SkuIDCol: 1, - SkuPriceCol: 15, - SkuNameCol: 2, - OrgSkuIdCol: 6, - OrgSkuPriceCol: 9, - OrgSkuNameCol: 7, - SkuRow: 1, - }, "干货": &SheetParam{ - SkuIDCol: 0, - SkuPriceCol: 13, - SkuNameCol: 1, - OrgSkuIdCol: 4, - OrgSkuPriceCol: 7, - OrgSkuNameCol: 5, - SkuRow: 2, - }, "MINI肉禽价格": &SheetParam{ - SkuIDCol: 1, - SkuPriceCol: 5, - SkuNameCol: 2, - OrgSkuIdCol: -1, - OrgSkuPriceCol: -1, - OrgSkuNameCol: -1, - SkuRow: 1, - }, - } - titleListStoreSkusSuccess = []string{ - "门店ID", - "商品编码", - "商品名称", - "单位", - "原价", - "现价", - "涨跌", - } - titleListSuccess = []string{ - "商品编码", - "商品名称", - "单位", - "原价", - "现价", - "涨跌", - } - titleListFailed = []string{ - "商品ID", - "商品名称", - "备注", - } - titleList = []string{ - "商品编码", - "商品名称", - "订货数量", - } - dataSuccess DataSuccessLock - dataFailed DataFailedLock - dataStoreSkusSuccess DataStoreSkusSuccessLock -) - -const ( - parallelCount = 5 - UpdateGoodsShelfStatusCount = 50 //微盟下架商品api限制一次50个 -) - -func (d *DataSuccessLock) AppendData(dataSuccess DataSuccess) { - d.locker.Lock() - defer d.locker.Unlock() - d.dataSuccessList = append(d.dataSuccessList, dataSuccess) -} - -func (d *DataFailedLock) AppendData2(dataFailed DataFailed) { - d.locker.Lock() - defer d.locker.Unlock() - d.dataFailedList = append(d.dataFailedList, dataFailed) -} - -func (d *DataStoreSkusSuccessLock) AppendData3(dataStoreSkusSuccess DataStoreSkusSuccess) { - d.locker.Lock() - defer d.locker.Unlock() - d.dataStoreSkusSuccessList = append(d.dataStoreSkusSuccessList, dataStoreSkusSuccess) -} - -func LoadExcelByYongHui(ctx *jxcontext.Context, files []*multipart.FileHeader, isAsync, isContinueWhenError bool) (hint string, err error) { - if len(files) == 0 { - return "", errors.New("没有文件上传!") - } - fileHeader := files[0] - file, err := fileHeader.Open() - hint, err = LoadExcelBinByYongHui(ctx, file, true, true) - file.Close() - return hint, err -} - -func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - skuMap = make(map[string]*ExcelParam) - costPrice float64 //成本价 - goodsList []*weimobapi.GoodsInfo - goodsIDListForPutAway []interface{} - isCompare bool - isExecute = false - ) - db := dao.GetDB() - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - var errMsg string - switch step { - case 0: - //读取excel文件 - xlsx, err := excelize.OpenReader(reader) - if err != nil { - return "", err - } - for k := range sheetMap { - sheetParam := sheetMap[k] - rows, _ := xlsx.GetRows(k) - for rowNum, row := range rows { - errMsg += GetCellIntoMap(sheetParam, skuMap, row, k, rowNum) - } - } - //修改分组名 - // 分类名格式为:可定XX日 - // XX为上传永辉 提供的 价格表时间 +2天 - if errMsg == "" { - isExecute = true - } else { - return "", fmt.Errorf(errMsg) - } - if isExecute { - isCompare, err = UpdateClassifyAndGetLastClassify() - } - case 1: - //获取微盟所有商品 - param := &weimobapi.QueryGoodsListParam{ - PageNum: 1, - PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds, - } - goodsList, err = GetWeiMobGoodsList(param) - if err != nil { - baseapi.SugarLogger.Errorf("GetWeiMobGoodsList error:%v", err) - } - taskFunc2 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - v := batchItemList[0].(*weimobapi.GoodsInfo) - goodsDetail, err := api.WeimobAPI.QueryGoodsDetail(v.GoodsID) - if err != nil { - baseapi.SugarLogger.Errorf("QueryGoodsDetail error:%v", err) - } - v.GoodsDetailInfo = goodsDetail - return retVal, err - } - taskParallel2 := tasksch.NewParallelTask("获取微盟商品", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc2, goodsList) - tasksch.HandleTask(taskParallel2, task, true).Run() - _, err = taskParallel2.GetResult(0) - //找出excel上有,微盟没有的,有就列出报错,不进行更新 - goodsInfoAndDetailMap := GetGoodsInfoAndDetailMap(goodsList) - for k, _ := range skuMap { - //表示excel上有,微盟上没有 - if goodsInfoAndDetailMap[k] == nil { - outPutData := DataFailed{ - GoodsID: k, - GoodsName: skuMap[k].Name, - Comment: "在微盟上未找到该商品", - } - dataFailed.AppendData2(outPutData) - } - } - case 2: - //找出微盟上有,excel上没有的,有就更新,没有就下架 - taskFunc3 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - goods := batchItemList[0].(*weimobapi.GoodsInfo) - goodsDetail := goods.GoodsDetailInfo - spuCode := goodsDetail.OuterGoodsCode - if spuCode != "" { - //如果微盟商品里找得到excel中的商品 - if skuMap[spuCode] != nil { - //获取京西库商品 - skuList, _ := dao.GetSkus(db, nil, []int{int(utils.Str2Int64(goodsDetail.SkuMap.SingleSku.OuterSkuCode))}, nil, nil, nil) - if len(skuList) == 0 { - outPutData := DataFailed{ - GoodsID: spuCode, - GoodsName: skuMap[spuCode].Name, - Comment: "在京西库中未找到该商品", - } - dataFailed.AppendData2(outPutData) - } else { - if skuList[0].Unit == "份" { - if goodsDetail.SkuMap.SingleSku.B2CSku.Weight == 0 { - costPrice = skuMap[spuCode].Price - } else { - costPrice = Float64Round(0.5 / goodsDetail.SkuMap.SingleSku.B2CSku.Weight * skuMap[spuCode].Price) - } - } else { - costPrice = skuMap[spuCode].Price - } - if isExecute { - _, _, _ = updateWeiMobGoods(costPrice, skuMap[spuCode].Price, skuList[0].Unit, isCompare, goodsDetail) - } - } - } else { - //下架微盟商品 - retVal = []int64{goodsDetail.GoodsID} - } - } - return retVal, err - } - taskParallel3 := tasksch.NewParallelTask("根据获取的微盟所有商品并更新", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc3, goodsList) - tasksch.HandleTask(taskParallel3, task, true).Run() - goodsIDListForPutAwayInterface, err2 := taskParallel3.GetResult(0) - if err = err2; err != nil { - return "", err - } - goodsIDListForPutAway = goodsIDListForPutAwayInterface - case 3: - // 批量下架微盟商品 - taskFunc4 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - int64Slice := []int64{} - for _, v := range batchItemList { - int64Slice = append(int64Slice, v.(int64)) - } - if isExecute { - PutAwayWeiMobSku(int64Slice) - } - return retVal, err - } - taskParallel4 := tasksch.NewParallelTask("下架微盟商品", tasksch.NewParallelConfig().SetParallelCount(parallelCount).SetBatchSize(UpdateGoodsShelfStatusCount), ctx, taskFunc4, goodsIDListForPutAway) - tasksch.HandleTask(taskParallel4, task, true).Run() - _, err = taskParallel4.GetResult(0) - case 4: - WriteToExcel(task, dataSuccess.dataSuccessList, dataFailed.dataFailedList) - } - - return result, err - } - taskSeq := tasksch.NewSeqTask2("读取永辉Excel文件修改微盟商品价格可售状态-序列任务", ctx, isContinueWhenError, taskSeqFunc, 5) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func PutAwayWeiMobSku(goodsIDListForPutAway []int64) (err error) { - if globals.EnableStoreWrite { - err = api.WeimobAPI.UpdateGoodsShelfStatus(goodsIDListForPutAway, false) - } - if err != nil { - baseapi.SugarLogger.Errorf("UpdateGoodsShelfStatus error:%v", err) - } - return err -} - -func GetGoodsInfoAndDetailMap(goodsList []*weimobapi.GoodsInfo) (goodsMap map[string]*weimobapi.GoodsInfo) { - goodsMap = make(map[string]*weimobapi.GoodsInfo) - for _, v := range goodsList { - goodsMap[v.GoodsDetailInfo.OuterGoodsCode] = v - } - return goodsMap -} - -func updateWeiMobGoods(costPrice, salePrice float64, unit string, isCompare bool, goodsDetail *weimobapi.GoodsDetailInfo) (goodsID int64, skuMap map[string]int64, err error) { - var ( - categoryList []*weimobapi.CategoryList - skuListInfo = goodsDetail.SkuList[0] - skuListParam []*weimobapi.SkuList - categoryID int - deliveryTypeListSlice []int64 - newSkuTitle string - ) - - //查询配送方式 - deliveryTypeList, err := api.WeimobAPI.FindDeliveryTypeList(goodsDetail.GoodsID) - if err != nil { - baseapi.SugarLogger.Errorf("FindDeliveryTypeList error:%v", err) - } - for _, deliveryType := range deliveryTypeList { - if deliveryType.Selected { - deliveryTypeListSlice = append(deliveryTypeListSlice, deliveryType.DeliveryID) - } - } - //查询运费模板 - freightTemplateListInfo, err := api.WeimobAPI.FindFreightTemplateList(goodsDetail.GoodsID) - if err != nil { - baseapi.SugarLogger.Errorf("FindFreightTemplateList error:%v", err) - } - - //寻找分类子ID - categoryList = goodsDetail.CategoryList - if len(categoryList) > 0 { - categoryID = categoryList[len(categoryList)-1].CategoryID - } else { - return 0, nil, errors.New(fmt.Sprintf("未查询到此商品的分类信息!goodsID : [%v] ,", goodsDetail.GoodsID)) - } - - //商品分组(原有的分组IDs) - selectedClassifyList := goodsDetail.SelectedClassifyList - selectedClassifyListIDMap := make(map[int64]int64) - if len(selectedClassifyList) > 0 { - for _, v := range selectedClassifyList { - for _, v := range v.ChildrenClassify { - selectedClassifyListIDMap[v.ClassifyID] = v.ClassifyID - } - } - } - - //上次上传价格和这次上传价格对比 - // 4、微盟商品。两个重要分组 - // 降价超0.2元,与前一日数据对比,需要将此类商品增加分类到这里,不改变原分类 - // 涨价超0.2元,与前一日数据对比,需要将此类商品增加分类到这里,不改变原分类 - // 其他商品,取消 这两个分类 - // 同一天第二次上传的处理,需要注意是与前一天价格的对比,不是当天的价格对比。 - - // 5. 涨价和跌价值保留2位小数 - // 需要在每个商品中增加↑0.01或↓0.02。 - // 显示在商品最前的括号里,如果没有括号,需要增加。都用小写的括号,大写括号需要删除。 - // 包装菜需要增加“精”,其他不需要加字,比如: - // (精↓2.11)新土豆1kg/袋 - // (↓2.11)新土豆1kg - //salePrice 这次上传的价格 goodsDetail.SkuMap.SingleSku.SalePrice 上次上传的价格 priceMix 两次上传价格差 priceMixRound 保留两位后的价格差 - if !isCompare { - priceMix := salePrice - goodsDetail.SkuMap.SingleSku.SalePrice - if priceMix > 0.2 { - delete(selectedClassifyListIDMap, 1064198248) - delete(selectedClassifyListIDMap, 1065246248) - selectedClassifyListIDMap[1064198248] = 1064198248 - } else if priceMix < -0.2 { - delete(selectedClassifyListIDMap, 1064198248) - delete(selectedClassifyListIDMap, 1065246248) - selectedClassifyListIDMap[1065246248] = 1065246248 - } else { - delete(selectedClassifyListIDMap, 1064198248) - delete(selectedClassifyListIDMap, 1065246248) - } - priceMixRound := Float64Round(priceMix) - newSkuTitle = GetNewSkuTitle(priceMixRound, goodsDetail.Title, goodsDetail.OuterGoodsCode) - } else { - newSkuTitle = goodsDetail.Title - } - - b2CSku := &weimobapi.B2CSku{ - Weight: skuListInfo.B2CSku.Weight, - Volume: skuListInfo.B2CSku.Volume, - } - b2CGoods := &weimobapi.B2CGoods{ - B2CGoodsType: goodsDetail.B2CGoods.B2CGoodsType, - DeliveryTypeIDList: deliveryTypeListSlice, - FreightTemplateID: freightTemplateListInfo.DefaultFreightTemplate.TemplateID, - } - skuList := &weimobapi.SkuList{ - SalePrice: salePrice, - CostPrice: costPrice, - SkuID: skuListInfo.SkuID, - EditStockNum: 9999 - skuListInfo.AvailableStockNum, - OuterSkuCode: skuListInfo.OuterSkuCode, - B2CSku: b2CSku, - } - skuListParam = append(skuListParam, skuList) - goods := &weimobapi.Goods{ - B2CGoods: b2CGoods, - SkuList: skuListParam, - Title: newSkuTitle, - IsMultiSku: goodsDetail.IsMultiSku, - IsPutAway: weimobapi.GoodsTypeNormal, - GoodsImageURL: goodsDetail.GoodsImageURL, - GoodsID: goodsDetail.GoodsID, - CategoryID: categoryID, - OuterGoodsCode: goodsDetail.OuterGoodsCode, - PointDeductRatio: goodsDetail.PointDeductRatio, - SelectedClassifyIDList: Map2Int64Slice(selectedClassifyListIDMap), - } - updateGoodsParam := &weimobapi.UpdateGoodsParam{ - Goods: goods, - } - if globals.EnableStoreWrite { - goodsID, skuMap, err = api.WeimobAPI.UpdateGoods3(updateGoodsParam) - if err != nil { - if errExt, ok := err.(*utils.ErrorWithCode); ok { - outPutData := DataFailed{ - GoodsID: goodsDetail.OuterGoodsCode, - GoodsName: goodsDetail.Title, - Comment: errExt.ErrMsg(), - } - dataFailed.AppendData2(outPutData) - } - } else { - outPutData := DataSuccess{ - NameID: goodsDetail.OuterGoodsCode, - Name: newSkuTitle, - Unit: unit, - OrgPrice: goodsDetail.SkuMap.SingleSku.SalePrice, - NowPrice: salePrice, - MixPrice: Float64Round(salePrice - goodsDetail.SkuMap.SingleSku.SalePrice), - } - dataSuccess.AppendData(outPutData) - } - } - return goodsID, skuMap, err -} - -func GetWeiMobGoodsList(param *weimobapi.QueryGoodsListParam) (goodsList []*weimobapi.GoodsInfo, err error) { - for { - goodsInfoList, _, err := api.WeimobAPI.QueryGoodsList(param) - if err != nil { - return nil, err - } - if len(goodsInfoList) > 0 { - goodsList = append(goodsList, goodsInfoList...) - } - if len(goodsInfoList) < param.PageSize { - break - } - param.PageNum++ - } - return goodsList, err -} - -func GetCellIntoMap(sheetParam *SheetParam, skuMap map[string]*ExcelParam, row []string, sheetName string, rowNum int) (errMsg string) { - var ( - skuID string - orgSkuID string - skuPrice float64 - orgSkuPrice float64 - skuName string - orgSkuName string - skuIDCol = sheetParam.SkuIDCol - skuPriceCol = sheetParam.SkuPriceCol - skuNameCol = sheetParam.SkuNameCol - orgSkuIDCol = sheetParam.OrgSkuIdCol - orgSkuPriceCol = sheetParam.OrgSkuPriceCol - orgSkuNameCol = sheetParam.OrgSkuNameCol - ) - for k, cell := range row { - if cell != "" { - if k == skuIDCol && skuIDCol >= 0 { - skuID = cell - } - if k == skuPriceCol && skuPriceCol >= 0 { - if rowNum == sheetParam.SkuRow-1 { - if !strings.Contains(cell, "今日供价") && !strings.Contains(cell, "单价") { - errMsg += fmt.Sprintf("sheet页:[%v],Excel排版发生变化!第[%v]列今日供价附近可能增加或减少了一列,请确认!", sheetName, k+1) - } - } - skuPrice = Float64Round(utils.Str2Float64WithDefault(cell, 0)) - } - if k == orgSkuIDCol && orgSkuIDCol >= 0 { - orgSkuID = "0" + cell - } - if k == orgSkuPriceCol && orgSkuPriceCol >= 0 { - if rowNum == sheetParam.SkuRow-1 { - if !strings.Contains(cell, "进价") { - errMsg += fmt.Sprintf("sheet页:[%v],Excel排版发生变化!第[%v]列进价附近可能增加或减少了一列,请确认!", sheetName, k+1) - } - } - orgSkuPrice = Float64Round(utils.Str2Float64WithDefault(cell, 0)) - } - if k == skuNameCol && skuNameCol >= 0 { - skuName = cell - } - if k == orgSkuNameCol && orgSkuNameCol >= 0 { - orgSkuName = cell - } - } - } - if rowNum >= sheetParam.SkuRow { - if rowNum == sheetParam.SkuRow { - if cms.IsChineseChar(skuID) { - errMsg += fmt.Sprintf("sheet页:[%v],Excel排版发生变化!第[%v]行附近可能增加了一行,请确认!", sheetName, rowNum) - } - } - if len(skuMap) > 0 { - if skuMap[skuID] != nil { - if skuMap[skuID].Price != 0 && skuMap[skuID].Price != skuPrice && skuPrice != 0 { - if skuPrice > skuMap[skuID].Price { - BuildSkuMap(skuID, skuName, skuPrice, skuMap) - } - } else { - BuildSkuMap(skuID, skuName, skuPrice, skuMap) - } - } else if skuPrice != 0 { - BuildSkuMap(skuID, skuName, skuPrice, skuMap) - } - if skuMap[orgSkuID] != nil { - if skuMap[orgSkuID].Price != 0 && skuMap[orgSkuID].Price != orgSkuPrice && orgSkuPrice != 0 { - if orgSkuPrice > skuMap[orgSkuID].Price { - BuildSkuMap(orgSkuID, orgSkuName, orgSkuPrice, skuMap) - } - } else if orgSkuPriceCol >= 0 && orgSkuIDCol >= 0 && orgSkuNameCol >= 0 { - BuildSkuMap(orgSkuID, orgSkuName, orgSkuPrice, skuMap) - } - } else if orgSkuPrice != 0 { - BuildSkuMap(orgSkuID, orgSkuName, orgSkuPrice, skuMap) - } - } else { - BuildSkuMap(skuID, skuName, skuPrice, skuMap) - BuildSkuMap(orgSkuID, orgSkuName, orgSkuPrice, skuMap) - } - delete(skuMap, "") - } else { - for i := rowNum; i < sheetParam.SkuRow; i++ { - if !cms.IsChineseChar(skuID) { - errMsg += fmt.Sprintf("sheet页:[%v],Excel排版发生变化!第[%v]行附近可能减少了一行,请确认!", sheetName, rowNum) - } - } - } - return errMsg -} -func BuildSkuMap(id, name string, price float64, skuMap map[string]*ExcelParam) { - excelParam := &ExcelParam{ - SpuCode: id, - Price: price, - Name: name, - } - skuMap[id] = excelParam -} - -func Float64Round(f float64) (flt float64) { - return math.Round(f*100) / 100 -} - -func Map2Int64Slice(m map[int64]int64) (result []int64) { - for _, v := range m { - result = append(result, v) - } - return result -} - -func UpdateClassifyAndGetLastClassify() (isCompare bool, err error) { - var lastTitle string - classfiyList, err := api.WeimobAPI.QueryClassifyInfoList() - if len(classfiyList) > 0 { - for _, v := range classfiyList { - if v.ClassifyID == 1065244148 { - lastTitle = v.Title - } - } - } - title := "可定" - now := time.Now() - afterDay := now.AddDate(0, 0, 2).Day() - title += utils.Int2Str(afterDay) + "日" - if lastTitle == title { - return true, err - } else { - err = api.WeimobAPI.UpdateClassify(1065244148, title, "") - return false, err - } -} - -func GetNewSkuTitle(priceMixRound float64, orgTitle, outerGoodsCode string) (name string) { - var prefix = "" - title1 := strings.ReplaceAll(orgTitle, "(", "(") - title := strings.ReplaceAll(title1, ")", ")") - if outerGoodsCode[0:1] != "0" { - prefix += "(精" - if priceMixRound > 0 { - prefix += "↑" - } else if priceMixRound < 0 { - prefix += "↓" - } else { - prefix += ")" - return GetReplaceNewTitle(title, prefix) - } - } else { - if priceMixRound > 0 { - prefix += "(↑" - } else if priceMixRound < 0 { - prefix += "(↓" - } else { - return GetReplaceNewTitle(title, prefix) - } - } - prefix += utils.Float64ToStr(math.Abs(priceMixRound)) + ")" - return GetReplaceNewTitle(title, prefix) -} - -func GetReplaceNewTitle(title, prefix string) (newTitle string) { - if title[0:1] == "(" { - return strings.Replace(title, title[0:strings.Index(title, ")")+1], prefix, 1) - } else { - return prefix + title - } -} - -func WriteToExcel(task *tasksch.SeqTask, dataSuccess []DataSuccess, dataFailed []DataFailed) (err error) { - var sheetList1 []*excel.Obj2ExcelSheetConfig - var sheetList2 []*excel.Obj2ExcelSheetConfig - var downloadURL1, downloadURL2, fileName1, fileName2 string - excelConf1 := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: dataSuccess, - CaptionList: titleListSuccess, - } - sheetList1 = append(sheetList1, excelConf1) - excelConf2 := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: dataFailed, - CaptionList: titleListFailed, - } - sheetList2 = append(sheetList2, excelConf2) - if excelConf1 != nil { - downloadURL1, fileName1, err = jxutils.UploadExeclAndPushMsg(sheetList1, "微盟已更新商品") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!") - } - if excelConf2 != nil { - downloadURL2, fileName2, err = jxutils.UploadExeclAndPushMsg(sheetList2, "缺少商品_微盟") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataFailed is nil!") - } - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName1, fileName2, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]path1=%s, path2=%s \n", downloadURL1, downloadURL2) - task.SetNoticeMsg(noticeMsg) - baseapi.SugarLogger.Debugf("WriteToExcel:upload %s ,%s success, downloadURL1:%s ,downloadURL2:%s", fileName1, fileName2, downloadURL1, downloadURL2) - } - return err -} - -func UpdateJxPriceByWeimob(ctx *jxcontext.Context, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - storeSkuBindInfoList []interface{} - skuBindInfos []*cms.StoreSkuBindInfo - nameID int - ) - db := dao.GetDB() - dataFailed.dataFailedList = dataFailed.dataFailedList[0:0] - dataStoreSkusSuccess.dataStoreSkusSuccessList = dataStoreSkusSuccess.dataStoreSkusSuccessList[0:0] - //获取微盟所有商品 - param := &weimobapi.QueryGoodsListParam{ - PageNum: 1, - PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds, - } - goodsList, err := GetWeiMobGoodsList(param) - if err != nil { - baseapi.SugarLogger.Errorf("GetWeiMobGoodsList error:%v", err) - } - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - v := batchItemList[0].(*weimobapi.GoodsInfo) - goodsDetail, err := api.WeimobAPI.QueryGoodsDetail(v.GoodsID) - if err != nil { - baseapi.SugarLogger.Errorf("QueryGoodsDetail error:%v", err) - } - goodsID := goodsDetail.OuterGoodsCode - unitPrice := int(utils.Float64TwoInt64(goodsDetail.SkuMap.SingleSku.CostPrice * 100)) - if goodsDetail.SkuMap.SingleSku.OuterSkuCode != "" { - nameID = int(utils.Str2Int64(goodsDetail.SkuMap.SingleSku.OuterSkuCode)) - } else { - outPutData := DataFailed{ - GoodsID: goodsID, - GoodsName: goodsDetail.Title, - Comment: "微盟上没有该商品的商品编码", - } - dataFailed.AppendData2(outPutData) - nameID = -1 - } - skuList, err := dao.GetStoreSkusByNameIDs(db, storeIDs, nameID) - if len(skuList) > 0 { - if goodsDetail.OuterGoodsCode != "" { - if goodsDetail.IsPutAway == weimobapi.GoodsTypeNormal { - storeSkuBindInfo := &cms.StoreSkuBindInfo{ - NameID: nameID, - UnitPrice: unitPrice, - } - retVal = []*cms.StoreSkuBindInfo{storeSkuBindInfo} - for _, v := range skuList { - outPutData := DataStoreSkusSuccess{ - StoreID: v.StoreID, - NameID: nameID, - Name: v.Name, - Unit: v.Unit, - OrgPrice: utils.Str2Float64(utils.Int64ToStr(v.UnitPrice)) / 100, - NowPrice: goodsDetail.SkuMap.SingleSku.CostPrice, - MixPrice: Float64Round((utils.Str2Float64(utils.Int64ToStr(v.UnitPrice)) / 100) - goodsDetail.SkuMap.SingleSku.CostPrice), - } - dataStoreSkusSuccess.AppendData3(outPutData) - } - } else { //如果微盟为下架 - outPutData := DataFailed{ - GoodsID: goodsID, - GoodsName: goodsDetail.Title, - Comment: "微盟已下架", - } - dataFailed.AppendData2(outPutData) - } - } else { - outPutData := DataFailed{ - GoodsID: goodsID, - GoodsName: goodsDetail.Title, - Comment: "微盟上没有该商品的spu编码", - } - dataFailed.AppendData2(outPutData) - } - } else { - outPutData := DataFailed{ - GoodsID: goodsID, - GoodsName: goodsDetail.Title, - Comment: "京西未关注该商品", - } - dataFailed.AppendData2(outPutData) - } - return retVal, err - } - taskParallel := tasksch.NewParallelTask("获取微盟商品", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc, goodsList) - tasksch.HandleTask(taskParallel, task, true).Run() - storeSkuBindInfoList, err = taskParallel.GetResult(0) - case 1: - for _, v := range storeSkuBindInfoList { - skuBindInfos = append(skuBindInfos, v.(*cms.StoreSkuBindInfo)) - } - cms.UpdateStoresSkus(ctx, 0, storeIDs, skuBindInfos, false, false, isAsync, isContinueWhenError) - case 2: - WriteToExcel3(task, dataStoreSkusSuccess.dataStoreSkusSuccessList, dataFailed.dataFailedList) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("根据微盟商品更新京西价", ctx, isContinueWhenError, taskSeqFunc, 3) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func WriteToExcel3(task *tasksch.SeqTask, dataSuccess []DataStoreSkusSuccess, dataFailed []DataFailed) (err error) { - var sheetList1 []*excel.Obj2ExcelSheetConfig - var sheetList2 []*excel.Obj2ExcelSheetConfig - var downloadURL1, downloadURL2, fileName1, fileName2 string - excelConf1 := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: dataSuccess, - CaptionList: titleListStoreSkusSuccess, - } - sheetList1 = append(sheetList1, excelConf1) - excelConf2 := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: dataFailed, - CaptionList: titleListFailed, - } - sheetList2 = append(sheetList2, excelConf2) - if excelConf1 != nil { - downloadURL1, fileName1, err = jxutils.UploadExeclAndPushMsg(sheetList1, "京西已更新商品") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!") - } - if excelConf2 != nil { - downloadURL2, fileName2, err = jxutils.UploadExeclAndPushMsg(sheetList2, "缺少商品_京西") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataFailed is nil!") - } - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName1, fileName2, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]path1=%s, path2=%s \n", downloadURL1, downloadURL2) - task.SetNoticeMsg(noticeMsg) - baseapi.SugarLogger.Debugf("WriteToExcel:upload %s ,%s success, downloadURL1:%s ,downloadURL2:%s", fileName1, fileName2, downloadURL1, downloadURL2) - } - return err -} - -func GetWeimobOrders(ctx *jxcontext.Context, fromTime, toTime string, params map[string]interface{}) (result []*OrderList, err error) { - if fromTime != "" && toTime != "" { - fromTimeParam := utils.Str2Time(fromTime).UnixNano() / 1e6 - toTimeParam := utils.Str2Time(toTime).UnixNano() / 1e6 - if params["keyword"] != nil { - if jxutils.GetPossibleVendorIDFromVendorOrderID(params["keyword"].(string)) > model.VendorIDUnknown { - resultList, err := GetSingleOrderResultList(params) - result = append(result, resultList...) - return result, err - } else { - orderList, err := GetWeimobOrdersList(fromTimeParam, toTimeParam, params["keyword"].(string)) - return orderList, err - } - } else { - orderList, err := GetWeimobOrdersList(fromTimeParam, toTimeParam, "") - return orderList, err - } - } - if fromTime == "" && toTime == "" && params["keyword"] != nil { - if jxutils.GetPossibleVendorIDFromVendorOrderID(params["keyword"].(string)) > model.VendorIDUnknown { - resultList, err := GetSingleOrderResultList(params) - result = append(result, resultList...) - return result, err - } else { - orderList, err := GetWeimobOrdersList(0, 0, params["keyword"].(string)) - return orderList, err - } - } - return result, err -} - -func GetWeimobOrdersList(fromTimeParam, toTimeParam int64, keyword string) (aList []*OrderList, err error) { - var queryParameter *weimobapi.MerchantOrderListQueryParameter - if fromTimeParam == 0 && toTimeParam == 0 { - queryParameter = &weimobapi.MerchantOrderListQueryParameter{ - CreateStartTime: time.Now().AddDate(0, -2, 0).UnixNano() / 1e6, - CreateEndTime: time.Now().UnixNano() / 1e6, - } - } else { - queryParameter = &weimobapi.MerchantOrderListQueryParameter{ - CreateStartTime: fromTimeParam, - CreateEndTime: toTimeParam, - } - } - param := &weimobapi.QueryOrdersListParam{ - PageNum: 1, - PageSize: weimobapi.QueryOrdersListPageSize, - QueryParameter: queryParameter, - } - for { - orderList, _, err2 := api.WeimobAPI.QueryOrdersList(param) - err = err2 - if len(orderList) > 0 { - if keyword != "" { - for _, v := range orderList { - if ContainsKeyword(v, keyword) { - var aOrder = &OrderList{ - Name: v.ReceiverName, - OrderNo: v.OrderNo, - Phone: v.ReceiverMobile, - } - aList = append(aList, aOrder) - } - } - } else { - for _, v := range orderList { - var aOrder = &OrderList{ - Name: v.ReceiverName, - OrderNo: v.OrderNo, - Phone: v.ReceiverMobile, - } - aList = append(aList, aOrder) - } - } - } - if len(orderList) < param.PageSize { - break - } - param.PageNum++ - } - return aList, err -} - -func GetWeimobOrderDetail(orderNo int64) (order *weimobapi.OrderDetail, err error) { - order, err = api.WeimobAPI.QueryOrderDetail2(orderNo, false) - if err != nil { - return nil, err - } - return order, err -} - -func GetSingleOrderResultList(params map[string]interface{}) (result []*OrderList, err error) { - weimobOrderID := params["keyword"].(string) - orderSingle, err := GetWeimobOrderDetail(utils.Str2Int64(weimobOrderID)) - orderList := &OrderList{ - Name: orderSingle.DeliveryDetail.LogisticsDeliveryDetail.ReceiverName, - Phone: orderSingle.DeliveryDetail.LogisticsDeliveryDetail.ReceiverMobile, - OrderNo: orderSingle.OrderNo, - } - result = append(result, orderList) - return result, err -} - -func ContainsKeyword(v *weimobapi.OrderInfo, keyword string) bool { - return strings.Contains(v.ReceiverName, keyword) || strings.Contains(utils.Int64ToStr(v.OrderNo), keyword) || strings.Contains(v.ReceiverMobile, keyword) -} - -func GetWeimobOrdersExcel(ctx *jxcontext.Context, OrderNo string) (result *WeimobOrderSkusExcelResult, err error) { - var ( - DataFineList []*Data //精品 - DataHairyList []*Data //毛菜 - ) - orderSingle, err := GetWeimobOrderDetail(utils.Str2Int64(OrderNo)) - if err != nil { - return result, err - } - if len(orderSingle.ItemList) > 0 { - itemList := orderSingle.ItemList - for _, v := range itemList { - if v.GoodsCode != "" { - var goodsTile string - if v.GoodsTitle[0:1] == "(" { - goodsTile = v.GoodsTitle[strings.Index(v.GoodsTitle, ")")+1 : len(v.GoodsTitle)] - } else { - goodsTile = v.GoodsTitle - } - if v.GoodsCode[0:1] == "0" { - DataHairy := &Data{ - GoodsID: v.GoodsCode[1:len(v.GoodsCode)], - GoodsName: goodsTile, - GoodsNum: v.SkuNum, - } - DataHairyList = append(DataHairyList, DataHairy) - } else { - DataFine := &Data{ - GoodsID: v.GoodsCode, - GoodsName: goodsTile, - GoodsNum: v.SkuNum, - } - DataFineList = append(DataFineList, DataFine) - } - } else { - return result, errors.New(fmt.Sprintf("此订单中该商品无spu编码,请检查!订单号:[%v] ,商品名: [%v]", OrderNo, v.GoodsTitle)) - } - } - } else { - return result, errors.New(fmt.Sprintf("此订单中无商品信息,请检查!订单号:[%v]", OrderNo)) - } - downloadURL1, downloadURL2, err := WriteToExcel2(ctx, DataFineList, DataHairyList) - result = &WeimobOrderSkusExcelResult{ - DownloadUrlFine: downloadURL1, - DownloadUrlHairy: downloadURL2, - } - return result, err -} - -func WriteToExcel2(ctx *jxcontext.Context, DataFineList, DataHairyList []*Data) (downloadURL1, downloadURL2 string, err error) { - var ( - sheetList1 []*excel.Obj2ExcelSheetConfig - sheetList2 []*excel.Obj2ExcelSheetConfig - fileName1, fileName2 string - noticeMsg string - ) - excelConf1 := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: DataFineList, - CaptionList: titleList, - } - sheetList1 = append(sheetList1, excelConf1) - excelConf2 := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: DataHairyList, - CaptionList: titleList, - } - sheetList2 = append(sheetList2, excelConf2) - noticeMsg += "[详情点我]" - if len(DataFineList) > 0 { - downloadURL1, fileName1, err = jxutils.UploadExeclAndPushMsg(sheetList1, "京西采购_精品") - noticeMsg += "path1=" + downloadURL1 + " " - } else { - baseapi.SugarLogger.Debug("WriteToExcel: DataFineList is nil!") - } - if len(DataHairyList) > 0 { - downloadURL2, fileName2, err = jxutils.UploadExeclAndPushMsg(sheetList2, "京西采购_毛菜") - noticeMsg += "path2=" + downloadURL2 - } else { - baseapi.SugarLogger.Debug("WriteToExcel: DataHairyList is nil!") - } - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName1, fileName2, err) - } else { - if authInfo, err := ctx.GetV2AuthInfo(); err == nil { - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, authInfo.UserID, "导出微盟订单商品成功", noticeMsg) - baseapi.SugarLogger.Debugf("WriteToExcel:upload %s ,%s success, downloadURL1:%s ,downloadURL2:%s", fileName1, fileName2, downloadURL1, downloadURL2) - } - } - return downloadURL1, downloadURL2, err -} diff --git a/main.go b/main.go index ffc814808..b00e64e88 100644 --- a/main.go +++ b/main.go @@ -34,8 +34,6 @@ import ( _ "git.rosy.net.cn/jx-callback/business/auth2/authprovider/password" _ "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" - _ "git.rosy.net.cn/jx-callback/business/jxstore/act" - _ "git.rosy.net.cn/jx-callback/routers" )