diff --git a/business/jxcallback/scheduler/defsch/defsch.go b/business/jxcallback/scheduler/defsch/defsch.go index f5b0da751..3bb952ccb 100644 --- a/business/jxcallback/scheduler/defsch/defsch.go +++ b/business/jxcallback/scheduler/defsch/defsch.go @@ -417,7 +417,11 @@ func (s *DefScheduler) OnOrderStatusChanged(order *model.GoodsOrder, status *mod } else if status.Status == model.OrderFlagMaskFailedDeliver { clearFlag = model.OrderFlagMaskFailedDeliver } - dao.ClearOrderFlag(dao.GetDB(), model.AdminName, order.VendorOrderID, order.VendorID, clearFlag) + if order.Flag > clearFlag { + dao.ClearOrderFlag2(dao.GetDB(), model.AdminName, order.VendorOrderID, order.VendorID, clearFlag|model.OrderFlagMaskPrinted) + } else { + dao.ClearOrderFlag(dao.GetDB(), model.AdminName, order.VendorOrderID, order.VendorID, clearFlag) + } } } } diff --git a/business/jxstore/cms/sku.go b/business/jxstore/cms/sku.go index 505d61c5a..6bea6d64b 100644 --- a/business/jxstore/cms/sku.go +++ b/business/jxstore/cms/sku.go @@ -7,8 +7,10 @@ import ( "strings" "time" + "git.rosy.net.cn/baseapi/platformapi/dingdingapi" "git.rosy.net.cn/baseapi/platformapi/ebaiapi" + "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/baseapi/platformapi/jdapi" @@ -39,6 +41,13 @@ var ( ebaiUploadRTFShopID string // 饿百找一个店用于调用SkuUploadRTF ) +var ( + sendNoCatSkusMobile = []string{ + "18048531223", + "18982250714", + } +) + // func getAndSetEbaiUploadRTFShopID() (shopID string) { // if ebaiUploadRTFShopID == "" { // if storeDetail, err := dao.GetStoreDetail(dao.GetDB(), 0, model.VendorIDEBAI); err == nil { @@ -564,7 +573,7 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma t1.ex_prefix, t1.ex_prefix_begin, t1.ex_prefix_end, - t4.mid_unit_price` + t1.yb_name_suffix` if isBySku { sql += `, t2.id` @@ -598,7 +607,7 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma t1.ex_prefix, t1.ex_prefix_begin, t1.ex_prefix_end, - t4.mid_unit_price, + t1.yb_name_suffix, CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"id":', t2.id, ',"comment":"', t2.comment, '","status":', t2.status, ',"createdAt":"', CONCAT(REPLACE(t2.created_at," ","T"),"+08:00"), '","updatedAt":"', CONCAT(REPLACE(t2.updated_at," ","T"),"+08:00"), '","lastOperator":"', t2.last_operator, '","specQuality":', t2.spec_quality, ',"specUnit":"', t2.spec_unit, @@ -724,6 +733,23 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s skuNameExt.SpecUnit = skuNameExt.Skus[0].SpecUnit } + if skuNameExt.YbNameSuffix == "" { + var name *model.SkuName + sql := "SELECT * FROM sku_name WHERE yb_name_suffix <> '' ORDER BY yb_name_suffix DESC LIMIT 1" + dao.GetRow(db, &name, sql, nil) + if name != nil { + prefix := utils.Int64ToStr(utils.Str2Int64(name.YbNameSuffix) + 1) + realPrefix := prefix + for i := 0; i < 4-len(prefix); i++ { + realPrefix = "0" + realPrefix + } + skuNameExt.YbNameSuffix = realPrefix + if utils.Str2Int64(prefix) > 9999 { + return nil, fmt.Errorf("银豹的商品后缀已超过9999!") + } + } + } + picType := true for _, imgName := range []string{skuNameExt.Img, skuNameExt.Img2} { if imgName != "" { @@ -1114,7 +1140,6 @@ func UpdateSku(ctx *jxcontext.Context, skuID int, payload map[string]interface{} err = refreshStoreSkuPrice(ctx, db, skuID) } } - errList := errlist.New() errList.AddErr(err) _, err = CurVendorSync.SyncSku(ctx, db, -1, sku.ID, false, false, userName) @@ -1374,10 +1399,11 @@ func GetJdUpcCodeByName(ctx *jxcontext.Context, name, upcCode string) (productIn return retVal, err } for _, v := range productInfo { - _, name, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.OriginalName) + _, name, _, specUnit, unit, specQuality := jxutils.SplitSkuName(v.OriginalName) v.Name = name v.SpecQuality = specQuality v.SpecUnit = specUnit + v.Unit = unit } retVal = productInfo return retVal, err @@ -1657,3 +1683,30 @@ func UpdateExianDaSkuCategory(ctx *jxcontext.Context, isAsync, isContinueWhenErr } return hint, err } + +func SendNoCatSkusToOperater(ctx *jxcontext.Context) (err error) { + var ( + db = dao.GetDB() + skuNames []*model.SkuName + ) + sql := ` + SELECT * FROM sku_name WHERE deleted_at = ? AND category_id = ? + ` + sqlParams := []interface{}{utils.DefaultTimeValue, model.NoCatCatgoryID} + err = dao.GetRows(db, &skuNames, sql, sqlParams) + if err != nil { + return err + } + if len(skuNames) > 10 { + noticeMsg := "有超过10个标品未进行分类!" + for _, v := range skuNames { + noticeMsg += "NameID:" + utils.Int2Str(v.ID) + ",商品名:" + v.Name + "," + } + for _, mobile := range sendNoCatSkusMobile { + if user, err := dao.GetUserByID(db, "mobile", mobile); err != nil { + ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "标品未分类", noticeMsg) + } + } + } + return err +} diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index 343f5bb8f..941662263 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -13,6 +13,8 @@ import ( "time" "unicode/utf8" + "git.rosy.net.cn/baseapi/platformapi/yinbaoapi" + "git.rosy.net.cn/jx-callback/globals/refutil" "github.com/360EntSecGroup-Skylar/excelize" @@ -1110,7 +1112,7 @@ func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, vendorID int, vend storeMap.Status = model.StoreStatusOpened storeMap.DeliveryType = model.StoreDeliveryTypeByStore storeMap.SyncStatus = 0 - if vendorID != model.VendorIDJX { + if vendorID != model.VendorIDJX && vendorID != model.VendorIDYB { if storeMap.VendorOrgCode == "" { return nil, fmt.Errorf("必须指定平台分账号信息") } @@ -1127,8 +1129,13 @@ func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, vendorID int, vend } else { err = ErrCanNotFindVendor } - } else { + } else if vendorID == model.VendorIDJX { ReCalculateJxPriceLight(db, ctx, storeID) + } else if vendorID == model.VendorIDYB { + err = checkYbParams(db, storeMap, storeID) + if err != nil { + return nil, err + } } if err == nil { dao.WrapAddIDCULDEntity(storeMap, userName) @@ -1250,7 +1257,7 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor } } - if vendorID != model.VendorIDJX { + if vendorID != model.VendorIDJX && vendorID != model.VendorIDYB { if vendorStoreID := utils.Interface2String(valid["vendorStoreID"]); vendorStoreID != "" { vendorStoreInfo, err2 := storeHandler.ReadStore(ctx, storeMap.VendorOrgCode, vendorStoreID) if err = err2; err == nil { @@ -2878,3 +2885,105 @@ func DeletePrinterSeq(ctx *jxcontext.Context, storeIDs []int) (err error) { } return err } + +func checkYbParams(db *dao.DaoDB, storeMap *model.StoreMap, storeID int) (err error) { + var ( + appID = storeMap.YbAppID + appKey = storeMap.YbAppKey + yinbaoCookie string + storeMap2 *model.StoreMap + ) + if appID == "" { + return fmt.Errorf("绑定银豹平台必须输入appID!") + } + if appKey == "" { + return fmt.Errorf("绑定银豹平台必须输入appKey!") + } + api.YinBaoAPI = yinbaoapi.New(appKey, appID) + _, err = api.YinBaoAPI.QueryProductByBarcode("") + if err != nil { + if errCode, ok := err.(*utils.ErrorWithCode); ok { + if errCode.Code() == yinbaoapi.AppIDErrCode { + return fmt.Errorf("请输入正确的银豹appID!,[%v]", appID) + } + if errCode.Code() == yinbaoapi.AppKeyErrCode { + return fmt.Errorf("请输入正确的银豹appKey!,[%v]", appKey) + } + } + } + storeMaps, err := dao.GetStoresMapList2(db, []int{model.VendorIDYB}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", false) + if len(storeMaps) > 0 { + for _, v := range storeMaps { + if v.YbAppID == appID { + return fmt.Errorf("appID和已有店铺重复![%v]", v.StoreID) + } + if v.YbAppKey == appKey { + return fmt.Errorf("appKey和已有店铺重复![%v]", v.StoreID) + } + } + } + stores, err := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, "") + if len(stores) > 0 { + if configs, err := dao.QueryConfigs(dao.GetDB(), "yinbaoCookie", model.ConfigTypeCookie, ""); err == nil { + yinbaoCookie = configs[0].Value + } + api.YinBaoAPI.SetCookie(".POSPALAUTH30220", yinbaoCookie) + result, err := loadSubStoresByUserIdDDLJson() + if err != nil { + return err + } + flag := false + for _, v := range result { + if v.Company == stores[0].Name { + storeMap.VendorStoreID = utils.Int2Str(v.ID) + flag = true + break + } + } + if !flag { + return fmt.Errorf("未在平台上找到该门店,请确保京西门店名和银豹门店名相同!") + } + } + sql := "SELECT * FROM store_map WHERE vendor_id = ? and deleted_at = ? ORDER BY yb_store_prefix DESC LIMIT 1" + sqlParams := []interface{}{model.VendorIDYB, utils.DefaultTimeValue} + err = dao.GetRow(db, &storeMap2, sql, sqlParams) + if err == nil { + prefix := utils.Int64ToStr(utils.Str2Int64(storeMap2.YbStorePrefix) + 1) + realPrefix := prefix + for i := 0; i < 3-len(prefix); i++ { + realPrefix = "0" + realPrefix + } + storeMap.YbStorePrefix = realPrefix + } + return err +} + +func loadSubStoresByUserIdDDLJson() (result []*yinbaoapi.LoadSubStoresByUserIdDDLJsonResult, err error) { + for { + result, err = api.YinBaoAPI.LoadSubStoresByUserIdDDLJson() + if err == nil { + break + } else { + if yinbaoapi.IsErrCookie(err) { + err = ChangeYbCookie() + if err != nil { + break + } + result, err = loadSubStoresByUserIdDDLJson() + } else { + break + } + } + } + return result, err +} + +func ChangeYbCookie() (err error) { + cookie, err := api.YinBaoAPI.TryGetCookie() + if err != nil { + return err + } + api.YinBaoAPI.SetCookie(".POSPALAUTH30220", cookie) + UpdateConfig(jxcontext.AdminCtx, "yinbaoCookie", model.ConfigTypeCookie, cookie) + return err +} diff --git a/business/jxstore/cms/store_sku.go b/business/jxstore/cms/store_sku.go index abcd89f1d..a2ea1bb36 100644 --- a/business/jxstore/cms/store_sku.go +++ b/business/jxstore/cms/store_sku.go @@ -30,6 +30,7 @@ import ( "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/baseapi/platformapi/dingdingapi" + "git.rosy.net.cn/baseapi/platformapi/jdapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils/errlist" "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" @@ -124,6 +125,7 @@ type tGetStoresSkusInfo struct { PayPercentage int `json:"-"` dao.StoreSkuExt RealMidUnitPrice int `json:"realMidUnitPrice"` //真实的该商品的全国中位价 + YbSkuName string } type SheetParam struct { @@ -244,6 +246,7 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool JOIN sku t2 FORCE INDEX(PRIMARY) ON t1.id = t2.name_id AND t2.deleted_at = ?/* AND t2.status = ?*/ JOIN store t3 ON t3.deleted_at = ? LEFT JOIN store_map sm ON sm.store_id = t3.id AND sm.vendor_id = ? AND sm.deleted_at = ? + LEFT JOIN store_map smm ON smm.store_id = t3.id AND smm.deleted_at = ? AND smm.vendor_id = ? LEFT JOIN thing_map t2m ON t2m.thing_type = ? AND t2m.thing_id = t2.id AND t2m.vendor_id = sm.vendor_id AND t2m.vendor_org_code = sm.vendor_org_code AND t2m.deleted_at = ? ` sqlParams = []interface{}{ @@ -251,6 +254,7 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool // model.SkuStatusNormal, utils.DefaultTimeValue, model.VendorIDJD, utils.DefaultTimeValue, // TODO 这里直接用JD有问题 + utils.DefaultTimeValue, model.VendorIDYB, model.ThingTypeSku, utils.DefaultTimeValue, } if isFocus { @@ -526,10 +530,10 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus, i t2.comment, t2.category_id sku_category_id, t2.status sku_status, t2.eclp_id, t4.created_at bind_created_at, t4.updated_at bind_updated_at, t4.last_operator bind_last_operator, t4.deleted_at bind_deleted_at, t4.sub_store_id, t4.price bind_price, IF(t4.unit_price IS NOT NULL, t4.unit_price, t1.price) unit_price, t4.status store_sku_status, t4.auto_sale_at, - t4.ebai_id, t4.mtwm_id, - t4.jd_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status, - t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price, - t4.jd_lock_time, t4.ebai_lock_time, t4.mtwm_lock_time, t4.jx_lock_time, + t4.ebai_id, t4.mtwm_id, t4.yb_id, CONCAT(smm.yb_store_prefix,t1.yb_name_suffix) yb_sku_name, + t4.jd_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status, t4.yb_sync_status, + t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price, t4.yb_price, + t4.jd_lock_time, t4.ebai_lock_time, t4.mtwm_lock_time, t4.jx_lock_time, t4.yb_lock_time, t4.status_sale_begin, t4.status_sale_end, t6.mid_unit_price real_mid_unit_price ` + sql @@ -559,6 +563,7 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus, i UnitPrice: v.UnitPrice, PayPercentage: v.PayPercentage, RealMidUnitPrice: v.RealMidUnitPrice, + YbSkuName: v.YbSkuName, } if !isBySku { storeNameMap[index] = storeName @@ -1119,6 +1124,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs model.FieldJdSyncStatus: model.SyncFlagDeletedMask, model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask, model.FieldMtwmSyncStatus: model.SyncFlagDeletedMask, + model.FieldYbSyncStatus: model.SyncFlagDeletedMask, }, userName, nil); err != nil { dao.Rollback(db) return nil, err @@ -2021,6 +2027,7 @@ func setStoreSkuBindStatus(skuBind *model.StoreSkuBind, status int8) { skuBind.JdSyncStatus |= status skuBind.EbaiSyncStatus |= status skuBind.MtwmSyncStatus |= status + skuBind.YbSyncStatus |= status } func checkStoreExisting(db *dao.DaoDB, storeID int) (store *model.Store, err error) { @@ -3209,6 +3216,7 @@ func AutoFocusStoreSkusForTopSkus(ctx *jxcontext.Context, isAsync, isContinueWhe skuName []*model.SkuName skuNameMap = make(map[int]int) ) + //物料店不自动关注畅销品 if v.ID == model.MatterStoreID { return retVal, err } @@ -3815,7 +3823,7 @@ func RefreshJxPriceByVendor2(ctx *jxcontext.Context, storeIDs []int, vendorID in for _, orgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) { outStoreSkuList, _ := mulitStoreSkuHandler.GetStoreSkusBareInfo(ctx, orgCode, task, storeID, storeDetail.VendorStoreID, bareStoreSkuMap[orgCode]) for _, sku := range outStoreSkuList { - price, nameID := getSkuNamePrice(db, sku.SkuID, sku.VendorPrice) + price, nameID := GetSkuNamePrice(db, sku.SkuID, sku.VendorPrice) if skuNameMap[nameID] < price { skuNameMap[nameID] = price } @@ -3835,7 +3843,7 @@ func RefreshJxPriceByVendor2(ctx *jxcontext.Context, storeIDs []int, vendorID in outSkuNameList, _ := singleStoreHandler.GetStoreSkusFullInfo(ctx, task, storeID, storeDetail.VendorStoreID, nil) for _, skuName := range outSkuNameList { sku := skuName.SkuList[0] - price, nameID := getSkuNamePrice(db, sku.SkuID, sku.VendorPrice) + price, nameID := GetSkuNamePrice(db, sku.SkuID, sku.VendorPrice) if skuNameMap[nameID] < price { skuNameMap[nameID] = price } @@ -3867,7 +3875,7 @@ func RefreshJxPriceByVendor2(ctx *jxcontext.Context, storeIDs []int, vendorID in return hint, err } -func getSkuNamePrice(db *dao.DaoDB, skuID int, orgPrice int64) (price int64, nameID int) { +func GetSkuNamePrice(db *dao.DaoDB, skuID int, orgPrice int64) (price int64, nameID int) { var ( specQuality float64 ) @@ -4048,3 +4056,224 @@ func RefreshMatterStock(ctx *jxcontext.Context, skuID int) (err error) { updateStoresSkusWithoutSync(ctx, db, []int{666666}, skuBindInfos, false) return err } + +func CreateSkusAndFocusFromYb(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { + var ( + vendorID = model.VendorIDYB + db = dao.GetDB() + ) + storeMaps, err := dao.GetStoresMapList2(db, []int{vendorID}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", false) + handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) + for _, storeMap := range storeMaps { + store, _ := dao.GetStoreDetail(db, storeMap.StoreID, vendorID) + + localSkuList, err := dao.GetStoreSkus2(db, vendorID, storeMap.StoreID, nil, false) + if err != nil { + return "", err + } + localSkuMap := make(map[string]*dao.StoreSkuSyncInfo) + for _, v := range localSkuList { + localSkuMap[v.VendorSkuID] = v + } + remoteSkuList, err := handler.GetStoreSkusFullInfo(ctx, nil, storeMap.StoreID, storeMap.VendorStoreID, nil) + if err != nil { + return "", err + } + task := tasksch.NewParallelTask("银豹平台拉取标品", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + var ( + pricePercentagePack []*model.PricePercentageItem + v = batchItemList[0].(*partner.SkuNameInfo) + ) + //长度大于7就可能是标品,非标品一般是7位,前三位是yb_store_prefix后4位是yb_name_suffix + if len(v.YbBarCode) > 7 { + if localSkuMap[v.SkuList[0].VendorSkuID] == nil { + skuNames, err := dao.GetSkuNames(db, nil, []string{v.YbBarCode}, "") + if err != nil { + return retVal, err + } + //表示我们商品库中没有这个upc商品,如果有就直接关注上 + if len(skuNames) == 0 { + //我们商品库中有这个商品,但是upc没有填,则尝试用upc去查一下 + productInfos, err2 := GetJdUpcCodeByName(ctx, "", v.YbBarCode) + err = err2 + //表示用upc也没有找到这个商品,则再尝试用银豹上的名字去查 + if len(productInfos) == 0 { + skuNames2, err := dao.GetSkuNames(db, nil, nil, v.Name) + if err != nil { + return retVal, err + } + if len(skuNames2) > 1 { + return retVal, fmt.Errorf("此商品名在京西库中查询出了大于1个商品,[%v]", v.Name) + } + //表示查到了,需要把upc更新上去,没查到就要新建(//TODO新建不起,没得规格这些) + if len(skuNames2) == 1 { + skuNames2[0].Upc = &v.YbBarCode + dao.UpdateEntity(db, skuNames2[0], "Upc") + buildStoreSkuBindInfosAndFocus(ctx, db, store, v, skuNames2[0].ID, pricePercentagePack) + } + } else { + productInfo := productInfos[0] + skuNames2, err := dao.GetSkuNames(db, nil, nil, productInfo.Name) + if err != nil { + return retVal, err + } + if len(skuNames2) > 1 { + return retVal, fmt.Errorf("此商品名在京西库中查询出了大于1个商品,[%v]", productInfo.Name) + } + //表示查到了,需要把upc更新上去,没查到就要新建 + if len(skuNames2) == 1 && (productInfo.SpecQuality == skuNames2[0].SpecQuality && productInfo.SpecUnit == skuNames2[0].SpecUnit) { + skuNames2[0].Upc = &v.YbBarCode + dao.UpdateEntity(db, skuNames2[0], "Upc") + buildStoreSkuBindInfosAndFocus(ctx, db, store, v, skuNames2[0].ID, pricePercentagePack) + } else { + skuNameExt := &model.SkuNameExt{ + SkuName: model.SkuName{ + Name: productInfo.Name, + Upc: &productInfo.UpcCode, + Status: model.SkuStatusNormal, + CategoryID: model.NoCatCatgoryID, + IsGlobal: model.YES, + Unit: productInfo.Unit, + }, + Skus: []*model.SkuWithVendor{ + &model.SkuWithVendor{ + Sku: &model.Sku{}, + }, + }, + // Places: []int{510100}, //默认成都 + } + if len(v.SkuList) > 0 { + skuNameExt.Price = int(v.SkuList[0].VendorPrice) + skuNameExt.Skus[0].SpecQuality = productInfo.SpecQuality + skuNameExt.Skus[0].SpecUnit = productInfo.SpecUnit + skuNameExt.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(productInfo.Weight)))) + skuNameExt.Skus[0].Status = model.SkuStatusNormal + } + if len(productInfo.ImgList) > 0 { + skuNameExt.Img = productInfo.ImgList[0] + } + outSkuNameExt, err := AddSkuName(ctx, skuNameExt, ctx.GetUserName()) + if err != nil { + return retVal, err + } + buildStoreSkuBindInfosAndFocus(ctx, db, store, v, outSkuNameExt.ID, pricePercentagePack) + } + } + } else { + buildStoreSkuBindInfosAndFocus(ctx, db, store, v, skuNames[0].ID, pricePercentagePack) + } + } + } + return retVal, err + }, remoteSkuList) + tasksch.HandleTask(task, nil, true).Run() + if isAsync { + hint = task.GetID() + } else { + _, err = task.GetResult(0) + hint = "1" + } + } + return hint, err +} + +func buildStoreSkuBindInfosAndFocus(ctx *jxcontext.Context, db *dao.DaoDB, store *dao.StoreDetail, v *partner.SkuNameInfo, nameID int, pricePercentagePack []*model.PricePercentageItem) (err error) { + skus, _ := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil) + err = jxutils.Strings2Objs(store.PricePercentagePackStr, &pricePercentagePack) + price := jxutils.CaculateJxPriceByPricePack(pricePercentagePack, 0, int(v.SkuList[0].VendorPrice)) + skuBind := &model.StoreSkuBind{ + StoreID: store.ID, + UnitPrice: price, + Price: price, + Status: model.StoreSkuBindStatusNormal, + YbID: utils.Str2Int64(v.SkuList[0].VendorSkuID), + YbPrice: int(v.SkuList[0].VendorPrice), + YbSyncStatus: 0, + } + if len(skus) > 0 { + skuBind.SkuID = skus[0].ID + } + dao.WrapAddIDCULDEntity(skuBind, ctx.GetUserName()) + err = dao.CreateEntity(db, skuBind) + return err +} + +func CreateSkusAndFocusFromWx(ctx *jxcontext.Context, productInfo *jdapi.ProductInfo, price, storeID int) (err error) { + var ( + db = dao.GetDB() + skuBindInfos []*StoreSkuBindInfo + ) + if productInfo == nil { + return fmt.Errorf("未查询到相关商品!") + } + if price == 0 { + return fmt.Errorf("请输入商品价格!") + } + focusSku := func(nameID int) { + skuBindInfo := &StoreSkuBindInfo{ + StoreID: storeID, + NameID: nameID, + UnitPrice: price, + IsFocus: 1, + IsSale: 1, + } + skuBindInfos = append(skuBindInfos, skuBindInfo) + _, err := UpdateStoresSkusByBind(ctx, nil, skuBindInfos, true, true) + if err != nil { + err = nil + } + } + skuNames, err := dao.GetSkuNames(db, nil, []string{productInfo.UpcCode}, "") + if err != nil { + return err + } + if len(skuNames) == 0 { + skuNames2, err := dao.GetSkuNames(db, nil, nil, productInfo.Name) + if err != nil { + return err + } + if productInfo.Name == "" { + return fmt.Errorf("暂时无法创建此商品,[%v]", productInfo.Name) + } + if len(skuNames2) > 1 { + return fmt.Errorf("此商品名在京西库中查询出了大于1个商品,[%v]", productInfo.Name) + } + //表示查到了,需要把upc更新上去,没查到就要新建 + if len(skuNames2) == 1 && (productInfo.SpecQuality == skuNames2[0].SpecQuality && productInfo.SpecUnit == skuNames2[0].SpecUnit) { + skuNames2[0].Upc = &productInfo.UpcCode + dao.UpdateEntity(db, skuNames2[0], "Upc") + focusSku(skuNames2[0].ID) + } else { + skuNameExt := &model.SkuNameExt{ + SkuName: model.SkuName{ + Name: productInfo.Name, + Upc: &productInfo.UpcCode, + Status: model.SkuStatusNormal, + CategoryID: model.NoCatCatgoryID, + IsGlobal: model.YES, + Unit: productInfo.Unit, + }, + Skus: []*model.SkuWithVendor{ + &model.SkuWithVendor{ + Sku: &model.Sku{}, + }, + }, + // Places: []int{510100}, //默认成都 + } + skuNameExt.Price = price + skuNameExt.Skus[0].SpecQuality = productInfo.SpecQuality + skuNameExt.Skus[0].SpecUnit = productInfo.SpecUnit + skuNameExt.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(productInfo.Weight)))) + skuNameExt.Skus[0].Status = model.SkuStatusNormal + if len(productInfo.ImgList) > 0 { + skuNameExt.Img = productInfo.ImgList[0] + } + outSkuNameExt, _ := AddSkuName(ctx, skuNameExt, ctx.GetUserName()) + focusSku(outSkuNameExt.ID) + } + } else { + focusSku(skuNames[0].ID) + } + return err +} diff --git a/business/jxstore/cms/sync.go b/business/jxstore/cms/sync.go index de53fadab..615861f35 100644 --- a/business/jxstore/cms/sync.go +++ b/business/jxstore/cms/sync.go @@ -663,7 +663,7 @@ func buildSetFinishHook(task tasksch.ITask, ctx *jxcontext.Context) { } else { globals.SugarLogger.Debugf("同步错误发送钉钉消息失败, authinfo [%v] , [%v]", *authInfo, err) } - }else { + } else { if time.Now().Hour() >= 20 || time.Now().Hour() < 7 { downloadURL, _, _ := WirteToExcelBySyncFailed(task) user, err := dao.GetUserByID(dao.GetDB(), "mobile", "18160030913") diff --git a/business/jxstore/cms/sync_store_sku.go b/business/jxstore/cms/sync_store_sku.go index df46cea91..e05026395 100644 --- a/business/jxstore/cms/sync_store_sku.go +++ b/business/jxstore/cms/sync_store_sku.go @@ -8,11 +8,13 @@ import ( "strings" "time" + "git.rosy.net.cn/baseapi/platformapi/yinbaoapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/partner/putils" "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/globals/refutil" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" @@ -85,7 +87,7 @@ func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo storeCatMap.ID = catInfo.MapID var failedList []*partner.StoreSkuInfoWithErr if catInfo.IsExdSpec == model.YES { - if vendorID == model.VendorIDJD || vendorID == model.VendorIDMTWM { + if vendorID == model.VendorIDJD || vendorID == model.VendorIDMTWM || vendorID == model.VendorIDYB { return nil, err } } @@ -104,9 +106,9 @@ func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo if cat, err2 := handler.GetStoreCategory(ctx, storeID, vendorStoreID, catInfo.Name); err2 == nil { catInfo.VendorCatID = cat.VendorCatID err = nil - } else if err != nil && !handler.IsErrCategoryExist(err) { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, model.VendorChineseNames[vendorID], "新增分类") } + } else if err != nil && !handler.IsErrCategoryExist(err) { + failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, model.VendorChineseNames[vendorID], "新增分类") } if err == nil { updateFields = append(updateFields, idFieldName) @@ -232,6 +234,8 @@ func storeSkuSyncInfo2Bare(inSku *dao.StoreSkuSyncInfo) (outSku *partner.StoreSk Status: inSku.MergedStatus, VendorPrice: inSku.VendorPrice, Seq: inSku.Seq, + JxPrice: inSku.Price, + JxUnitPrice: inSku.UnitPrice, } if !isStoreSkuSyncNeedDelete(inSku) { outSku.Stock = model.MaxStoreSkuStockQty @@ -325,10 +329,20 @@ func updateStoreSku(db *dao.DaoDB, vendorID int, storeSkuList []*dao.StoreSkuSyn updateItemList[k] = sku2Update(vendorID, v, syncStatus) } num, err = dao.BatchUpdateEntityByKV(db, updateItemList) + if vendorID == model.VendorIDYB { + err = updateYbOhterSku(db, storeSkuList) + } } return num, err } +func updateYbOhterSku(db *dao.DaoDB, storeSkuList []*dao.StoreSkuSyncInfo) (err error) { + for _, v := range storeSkuList { + err = dao.UpdateYbOtherSku(db, v) + } + return err +} + func isSkuLockTimeValid(sku *dao.StoreSkuSyncInfo) bool { return sku.LockTime != nil && time.Now().Sub(*sku.LockTime) < 0 } @@ -419,7 +433,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, causeFlag } } else { if sku.MergedStatus == model.SkuStatusNormal { - if dao.IsVendorThingIDEmpty(sku.VendorCatID) && !strings.Contains(sku.StoreName, model.ExdStoreName) { + if dao.IsVendorThingIDEmpty(sku.VendorCatID) && !strings.Contains(sku.StoreName, model.ExdStoreName) && vendorID != model.VendorIDYB { globals.SugarLogger.Warnf("syncStoreSkuNew 创建门店:%d商品:%d,但没有平台分类ID", storeID, sku.SkuID) } else { createList = append(createList, sku) @@ -498,6 +512,35 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, causeFlag return skuList } isContinueWhenError2 := true + //如果是银豹平台,则要按照商品skuname维度同步 + if vendorID == model.VendorIDYB { + if len(createList) > 0 { + rList1, _ := changeList2Yb(createList, nil) + createList = createList[:] + createList = rList1 + for _, v := range createList { + v.YbBarCode = storeDetail.YbStorePrefix + v.YbNameSuffix + v.VendorPrice = int64(jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), int(v.UnitPrice))) + price, _ := GetSkuNamePrice(db, v.SkuID, v.Price) + v.Price = price + } + } + if len(priceList) > 0 { + _, rList2 := changeList2Yb(nil, priceList) + priceList = priceList[:] + priceList = rList2 + for _, v := range priceList { + v.VendorPrice = int64(jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), int(v.JxUnitPrice))) + price, _ := GetSkuNamePrice(db, v.SkuID, v.JxPrice) + v.JxPrice = price + } + } + api.YinBaoAPI = yinbaoapi.New(storeDetail.YbAppKey, storeDetail.YbAppID) + if configs, err := dao.QueryConfigs(dao.GetDB(), "yinbaoCookie", model.ConfigTypeCookie, ""); err == nil { + yinbaoCookie := configs[0].Value + api.YinBaoAPI.SetCookie(".POSPALAUTH30220", yinbaoCookie) + } + } task := tasksch.NewParallelTask("syncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError2), ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { step := batchItemList[0].(int) @@ -1247,3 +1290,23 @@ func FullSyncStoreSkuBindAct(ctx *jxcontext.Context, parentTask tasksch.ITask, h _, err = task.GetResult(0) return err } + +func changeList2Yb(list1 []*dao.StoreSkuSyncInfo, list2 []*partner.StoreSkuInfo) (rList1 []*dao.StoreSkuSyncInfo, rList2 []*partner.StoreSkuInfo) { + var ( + skuNameMap = make(map[int]*dao.StoreSkuSyncInfo) + skuNameMap2 = make(map[int]*partner.StoreSkuInfo) + ) + for _, v := range list1 { + skuNameMap[v.NameID] = v + } + for _, v := range skuNameMap { + rList1 = append(rList1, v) + } + for _, v := range list2 { + skuNameMap2[v.NameID] = v + } + for _, v := range skuNameMap2 { + rList2 = append(rList2, v) + } + return rList1, rList2 +} diff --git a/business/jxstore/misc/misc.go b/business/jxstore/misc/misc.go index 430f6884f..7fd366742 100644 --- a/business/jxstore/misc/misc.go +++ b/business/jxstore/misc/misc.go @@ -123,6 +123,7 @@ var ( mtpsStoreToken string jd2StorePageCookie string JdStorePageCookie string + yinbaoCookie string ) func GetImportantTaskID(taskName string) string { @@ -205,6 +206,9 @@ func Init() { ScheduleTimerFunc("BackUpStoreSkuBind", func() { cms.BackUpStoreSkuBind(jxcontext.AdminCtx, true, true) }, backUpStoreSkuBindList) + ScheduleTimerFunc("SendNoCatSkusToOperater", func() { + cms.SendNoCatSkusToOperater(jxcontext.AdminCtx) + }, autoPayForPopluarManList) } ScheduleTimerFunc("AutoSaleStoreSku", func() { cms.AutoSaleStoreSku(jxcontext.AdminCtx, nil, false) @@ -247,6 +251,10 @@ func Init() { if configs, err := dao.QueryConfigs(dao.GetDB(), "jd2StorePageCookie", model.ConfigTypeCookie, ""); err == nil { jd2StorePageCookie = configs[0].Value } + 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) } @@ -266,9 +274,9 @@ func Init() { func syncStoreSku() { syncFlag := 0 // syncFlag := model.SyncFlagPriceMask - // if (time.Now().Unix()/24*3600)%10 == 0 { - // syncFlag |= model.SyncFlagSaleMask - // } + 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) diff --git a/business/jxstore/misc/store_sku_sales.go b/business/jxstore/misc/store_sku_sales.go index 0e42e5eb1..538d0f3bb 100644 --- a/business/jxstore/misc/store_sku_sales.go +++ b/business/jxstore/misc/store_sku_sales.go @@ -153,7 +153,7 @@ func GetStoreSkuSalesInfo(ctx *jxcontext.Context, storeID int) (outStoreSkuSales 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}) + skuNameList, err := dao.GetSkuNames(db, []int{skuAndNameInfo.NameID}, nil, "") prefix := "" if err == nil && len(skuNameList) > 0 { storeSkuSales.SkuImage = skuNameList[0].Img diff --git a/business/jxutils/datares/datares.go b/business/jxutils/datares/datares.go index 0019accf8..267ad6da7 100644 --- a/business/jxutils/datares/datares.go +++ b/business/jxutils/datares/datares.go @@ -92,7 +92,6 @@ func RegisterDataResource(ctx *jxcontext.Context, name, resourceURL, mimeType, h MainURL: resourceURL, UseType: int8(imgType), } - vendorID := jxutils.GuessDataResourceVendor(resourceURL) switch vendorID { case model.VendorIDQiNiuCloud: @@ -100,7 +99,6 @@ func RegisterDataResource(ctx *jxcontext.Context, name, resourceURL, mimeType, h case model.VendorIDEBAI: dataRes.EbaiURL = resourceURL } - dao.WrapAddIDCULEntity(dataRes, ctx.GetUserName()) if err = dao.CreateEntity(dao.GetDB(), dataRes); err != nil { if dao.IsDuplicateError(err) { diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index 97a011585..89c74be2c 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -38,6 +38,9 @@ var ( model.VendorIDEBAI: []string{ "image-star.elemecdn.com", }, + model.VendorIDYB: []string{ + "pospalstoreimg.area27.pospal.cn", + }, } ) diff --git a/business/model/api_config.go b/business/model/api_config.go index 7eaca8751..d51bffb6d 100644 --- a/business/model/api_config.go +++ b/business/model/api_config.go @@ -68,7 +68,7 @@ var ( VendorIDELM: "Elm", VendorIDEBAI: "Ebai", VendorIDWSC: "Wsc", - VendorIDYB: "YinBao", + VendorIDYB: "Yb", VendorIDJX: "Jx", VendorIDDada: "Dada", diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index c91a89b55..9cbd4c970 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -233,6 +233,15 @@ func ClearOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID i return err } +func ClearOrderFlag2(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int) (err error) { + _, err = ExecuteSQL(db, ` + UPDATE goods_order + SET flag = ? + WHERE vendor_order_id = ? AND vendor_id = ? + `, flag, vendorOrderID, vendorID) + return err +} + func SetAfsOrderFlag(db *DaoDB, userName string, afsOrderID string, vendorID int, flag int) (err error) { _, err = ExecuteSQL(db, ` UPDATE afs_order diff --git a/business/model/dao/sku.go b/business/model/dao/sku.go index 96505e549..206417257 100644 --- a/business/model/dao/sku.go +++ b/business/model/dao/sku.go @@ -78,7 +78,7 @@ func GetCategories(db *DaoDB, parentID, level int, catIDs []int, isExd bool) (ca func GetSkus(db *DaoDB, skuIDs, nameIDs, statuss, catIDs []int, eclpIDs []string) (skuList []*model.SkuAndName, err error) { sql := ` - SELECT t1.*, t2.name, t2.unit, t2.prefix, t2.is_spu, t2.ex_prefix, t2.ex_prefix_begin, t2.ex_prefix_end + SELECT t1.*, t2.name, t2.unit, t2.prefix, t2.is_spu, t2.ex_prefix, t2.ex_prefix_begin, t2.ex_prefix_end, t2.upc FROM sku t1 JOIN sku_name t2 ON t2.id = t1.name_id AND t2.deleted_at = ? ` @@ -121,7 +121,7 @@ func GetSkus(db *DaoDB, skuIDs, nameIDs, statuss, catIDs []int, eclpIDs []string return nil, err } -func GetSkuNames(db *DaoDB, nameIDs []int) (skuNameList []*model.SkuName, err error) { +func GetSkuNames(db *DaoDB, nameIDs []int, upcs []string, name string) (skuNameList []*model.SkuName, err error) { sql := ` SELECT * FROM sku_name t1 @@ -134,6 +134,14 @@ func GetSkuNames(db *DaoDB, nameIDs []int) (skuNameList []*model.SkuName, err er sql += " AND t1.id IN (" + GenQuestionMarks(len(nameIDs)) + ")" sqlParams = append(sqlParams, nameIDs) } + if len(upcs) > 0 { + sql += " AND t1.upc IN (" + GenQuestionMarks(len(upcs)) + ")" + sqlParams = append(sqlParams, upcs) + } + if name != "" { + sql += " AND t1.name LIKE ?" + sqlParams = append(sqlParams, "%"+name+"%") + } if err = GetRows(db, &skuNameList, sql, sqlParams...); err == nil { return skuNameList, nil } diff --git a/business/model/dao/store.go b/business/model/dao/store.go index 61338a1ac..2c7f5e606 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -46,6 +46,10 @@ type StoreDetail struct { JdStoreLevel string `json:"jdStoreLevel"` //京东门店等级 IsOrder int `json:"isOrder"` //是否是下预订单门店 + + YbAppID string `orm:"column(yb_app_id)" json:"ybAppID"` + YbAppKey string `json:"ybAppKey"` + YbStorePrefix string `json:"ybStorePrefix"` } // 带快递门店信息的 @@ -89,7 +93,7 @@ func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (sto sql := ` SELECT t1.*, t2.vendor_store_id, t2.status vendor_status, t2.delivery_fee_deduction_sill, t2.delivery_fee_deduction_fee, t2.sync_status, t2.vendor_org_code, - t2.price_percentage, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync, t2.vendor_store_name, t2.is_order, + t2.price_percentage, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync, t2.vendor_store_name, t2.is_order, t2.yb_app_id, t2.yb_app_key, t2.yb_store_prefix, t3.value price_percentage_pack_str, t4.value freight_deduction_pack_str, district.name district_name, @@ -420,6 +424,7 @@ func AddStoreCategoryMap(db *DaoDB, storeID, categoryID int, vendorID int, vendo CategoryID: categoryID, MtwmSyncStatus: model.SyncFlagNewMask, EbaiSyncStatus: model.SyncFlagNewMask, + YbSyncStatus: model.SyncFlagNewMask, } storeCat.DeletedAt = utils.DefaultTimeValue if err = GetEntity(db, storeCat, model.FieldStoreID, model.FieldCategoryID, model.FieldDeletedAt); err != nil && !IsNoRowsError(err) { @@ -431,6 +436,9 @@ func AddStoreCategoryMap(db *DaoDB, storeID, categoryID int, vendorID int, vendo } else if vendorID == model.VendorIDEBAI { storeCat.EbaiID = utils.Str2Int64WithDefault(vendorCategoryID, 0) storeCat.EbaiSyncStatus = status + } else if vendorID == model.VendorIDYB { + storeCat.YbID = utils.Str2Int64WithDefault(vendorCategoryID, 0) + storeCat.YbSyncStatus = status } else { panic("unsupported vendor") } diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go index 2f1bf76e9..9a2a3622c 100644 --- a/business/model/dao/store_sku.go +++ b/business/model/dao/store_sku.go @@ -80,7 +80,9 @@ type StoreSkuSyncInfo struct { IsGlobal int8 `orm:"default(1)" json:"isGlobal"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定 NameStatus int SellCities []string - NameCategoryID int `orm:"column(name_category_id)"` + NameCategoryID int `orm:"column(name_category_id)"` + YbNameSuffix string //银豹的商品条码后缀 + YbBarCode string //银豹的商品条码 // 平台相关的图片信息 Img string @@ -145,10 +147,11 @@ type StoreSkuNameExt struct { Skus []*StoreSkuExt `orm:"-" json:"skus,omitempty"` SkusStr string `json:"-"` - PendingOpType int8 `json:"pendingOpType"` // 取值同 StoreOpRequest.Type - PendingUnitPrice int `json:"pendingUnitPrice"` // 这个是待审核的价格申请 - RealMidUnitPrice int `json:"realMidUnitPrice"` - Count int `json:"count"` + PendingOpType int8 `json:"pendingOpType"` // 取值同 StoreOpRequest.Type + PendingUnitPrice int `json:"pendingUnitPrice"` // 这个是待审核的价格申请 + RealMidUnitPrice int `json:"realMidUnitPrice"` + Count int `json:"count"` + YbSkuName string `json:"ybSkuName"` } // GetStoreSkus用 @@ -212,20 +215,24 @@ type StoreSkuExt struct { JdID string `orm:"column(sku_jd_id);null;index" json:"jdID"` EbaiID string `orm:"column(ebai_id);index" json:"ebaiID"` MtwmID string `orm:"column(mtwm_id)" json:"mtwmID"` // 这个也不是必须的,只是为了DAO取数据语句一致 + YbID string `orm:"column(yb_id);index" json:"ybID"` JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` EbaiSyncStatus int8 `orm:"default(2)" json:"ebaiSyncStatus"` MtwmSyncStatus int8 `orm:"default(2)" json:"mtwmSyncStatus"` + YbSyncStatus int8 `orm:"default(2)" json:"ybSyncStatus"` JdPrice int `json:"jdPrice"` EbaiPrice int `json:"ebaiPrice"` MtwmPrice int `json:"mtwmPrice"` JxPrice int `json:"jxPrice"` + YbPrice int `json:"ybPrice"` JdLockTime *time.Time `orm:"null" json:"jdLockTime,omitempty"` EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime,omitempty"` MtwmLockTime *time.Time `orm:"null" json:"mtwmLockTime,omitempty"` JxLockTime *time.Time `orm:"null" json:"jxLockTime,omitempty"` + YbLockTime *time.Time `orm:"null" json:"ybLockTime,omitempty"` ActPrice int `json:"actPrice"` ActID int `orm:"column(act_id)" json:"actID"` @@ -335,7 +342,7 @@ func GetStoreCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level in fieldPrefixParams := []interface{}{fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix} if len(skuIDs) > 0 { sql += ` - JOIN ( + LEFT JOIN ( SELECT DISTINCT b.category_id FROM sku a JOIN sku_name b ON a.name_id = b.id AND b.deleted_at = ? @@ -382,12 +389,12 @@ func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty boo } sql := ` SELECT - t14.vendor_id, t14.vendor_org_code, + t14.vendor_id, t14.vendor_org_code, t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, %s vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time, t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end, t2.*, - t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.status name_status, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end, t3.category_id name_category_id, + t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.status name_status, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end, t3.category_id name_category_id, t3.yb_name_suffix, IF(t11.%s <> '', t11.%s, t3.img) img, IF(t12.%s <> '', t12.%s, t3.img2) img2, t13.%s desc_img, @@ -505,7 +512,7 @@ func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInf // 对于多门店平台,商品库删除后,不需要操作门店商品,所以sku_name用JOIN, sku与sku_name也可以直接排除下架的 sql := ` SELECT - sm.vendor_id, sm.vendor_org_code, + sm.vendor_id, sm.vendor_org_code, sm.yb_app_id, sm.yb_app_key, t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time, t1.store_id, t1.deleted_at bind_deleted_at, @@ -1471,3 +1478,22 @@ func GetStoreSkusAndSkuName(db *DaoDB, storeIDs, skuIDs, nameIDs []int) (storeSk err = GetRows(db, &storeSkuAndName, sql, sqlParams...) return storeSkuAndName, err } + +func UpdateYbOtherSku(db *DaoDB, storeSkuSyncInfo *StoreSkuSyncInfo) (err error) { + sql := ` + UPDATE store_sku_bind a + JOIN sku b ON a.sku_id = b.id AND b.name_id = ? + JOIN (SELECT * FROM store_sku_bind WHERE sku_id = ?)c ON c.store_id = a.store_id + SET a.yb_id = c.yb_id,a.yb_sync_status = c.yb_sync_status,a.yb_price = c.yb_price + WHERE a.store_id = ? + AND a.yb_sync_status <> ? + ` + sqlParams := []interface{}{ + storeSkuSyncInfo.NameID, + storeSkuSyncInfo.SkuID, + storeSkuSyncInfo.StoreID, + 0, + } + _, err = ExecuteSQL(db, sql, sqlParams) + return err +} diff --git a/business/model/model.go b/business/model/model.go index 584c5bf01..569b7fe41 100644 --- a/business/model/model.go +++ b/business/model/model.go @@ -18,6 +18,7 @@ const ( FieldEbaiSyncStatus = "EbaiSyncStatus" FieldMtwmSyncStatus = "MtwmSyncStatus" // FieldWscSyncStatus = "WscSyncStatus" + FieldYbSyncStatus = "YbSyncStatus" FieldVendorID = "VendorID" FieldStoreID = "StoreID" diff --git a/business/model/sku.go b/business/model/sku.go index c2e224049..87741def0 100644 --- a/business/model/sku.go +++ b/business/model/sku.go @@ -14,6 +14,10 @@ const ( SpecUnitML = 3 ) +const ( + NoCatCatgoryID = 291 +) + const ( SkuStatusDeleted = -1 SkuStatusDontSale = 0 @@ -145,6 +149,7 @@ type SkuCategory struct { JdCategoryID int64 `orm:"column(jd_category_id)" json:"jdCategoryID"` // 这个是指对应的京东商品类别 EbaiCategoryID int64 `orm:"column(ebai_category_id)" json:"ebaiCategoryID"` // 这个是指对应的饿百商品类别 MtwmCategoryID int64 `orm:"column(mtwm_category_id)" json:"mtwmCategoryID"` // 这个是指对应的美团外卖商品类别 + YbCategoryID int64 `orm:"column(yb_category_id)" json:"ybCategoryID"` // 这个是指对应的银豹商品类别 // ElmCategoryID int64 `orm:"column(elm_category_id)" json:"elmCategoryID"` // 这个是指对应的饿了么商品类别 // WscCategoryID int64 `orm:"column(wsc_category_id)" json:"wscCategoryID"` // 这个是指对应的美团外卖商品类别 @@ -200,6 +205,7 @@ type SkuName struct { // JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` // LinkID int `orm:"column(link_id);null;index" json:"linkID"` + YbNameSuffix string `json:"ybNameSuffix"` //银豹商品后缀 } func (*SkuName) TableUnique() [][]string { @@ -243,6 +249,7 @@ type SkuAndName struct { Unit string `json:"unit"` Prefix string `json:"prefix"` IsSpu int `json:"isSpu"` + Upc string `json:"upc"` ExPrefix string `json:"exPrefix"` ExPrefixBegin *time.Time `json:"exPrefixBegin"` ExPrefixEnd *time.Time `json:"eExPrefixEndxPrefixEnd"` diff --git a/business/model/store.go b/business/model/store.go index a97385159..0655c2ea9 100644 --- a/business/model/store.go +++ b/business/model/store.go @@ -422,6 +422,10 @@ type StoreMap struct { JdStoreLevel string `orm:"size(32)" json:"jdStoreLevel"` //京东门店等级 IsOrder int `orm:"default(0)" json:"isOrder"` //是否是下预订单门店 + + YbAppID string `orm:"column(yb_app_id);size(255)" json:"ybAppID"` + YbAppKey string `orm:"size(255)" json:"ybAppKey"` + YbStorePrefix string `orm:"size(255)" json:"ybStorePrefix"` } func (*StoreMap) TableUnique() [][]string { diff --git a/business/model/store_sku.go b/business/model/store_sku.go index 8911292cd..0519894d0 100644 --- a/business/model/store_sku.go +++ b/business/model/store_sku.go @@ -52,6 +52,8 @@ type StoreSkuCategoryMap struct { EbaiSyncStatus int8 `orm:"default(2)"` MtwmSyncStatus int8 `orm:"default(2)"` // WscSyncStatus int8 `orm:"default(2)"` + YbID int64 `orm:"column(yb_id);index"` + YbSyncStatus int8 `orm:"default(2)"` } func (*StoreSkuCategoryMap) TableUnique() [][]string { @@ -96,6 +98,7 @@ type StoreSkuBind struct { // ElmID int64 `orm:"column(elm_id);index"` MtwmID int64 `orm:"column(mtwm_id);index"` EbaiID int64 `orm:"column(ebai_id);index"` + YbID int64 `orm:"column(yb_id);index"` // WscID int64 `orm:"column(wsc_id);index"` // 表示微盟skuId // WscID2 int64 `orm:"column(wsc_id2);index"` // 表示微盟goodsId @@ -103,17 +106,20 @@ type StoreSkuBind struct { JdSyncStatus int8 `orm:"default(2)"` MtwmSyncStatus int8 `orm:"default(2)"` EbaiSyncStatus int8 `orm:"default(2)"` + YbSyncStatus int8 `orm:"default(2)"` // WscSyncStatus int8 `orm:"default(2)"` JdPrice int `json:"jdPrice"` MtwmPrice int `json:"mtwmPrice"` EbaiPrice int `json:"ebaiPrice"` JxPrice int `json:"jxPrice"` + YbPrice int `json:"ybPrice"` JdLockTime *time.Time `orm:"null" json:"jdLockTime"` MtwmLockTime *time.Time `orm:"null" json:"mtwmLockTime"` EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime"` JxLockTime *time.Time `orm:"null" json:"jxLockTime"` + YbLockTime *time.Time `orm:"null" json:"ybLockTime"` AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` diff --git a/business/partner/partner_store_sku.go b/business/partner/partner_store_sku.go index a471faeb9..2d3f6111b 100644 --- a/business/partner/partner_store_sku.go +++ b/business/partner/partner_store_sku.go @@ -49,6 +49,8 @@ type StoreSkuInfo struct { ActPrice int64 `json:"actPrice,omitempty"` VendorActID string `json:"vendorActID,omitempty"` IsSpecialty int `json:"isSpecialty,omitempty"` + JxPrice int64 `json:"jxPrice,omitempty"` + JxUnitPrice int64 `json:"jxUnitPrice,omitempty"` } type StoreSkuInfoWithErr struct { @@ -82,6 +84,7 @@ type SkuNameInfo struct { VendorCatIDList []string PictureList []string Status int `json:"status,omitempty"` + YbBarCode string SkuList []*SkuInfo } diff --git a/business/partner/purchase/jx/localjx/order.go b/business/partner/purchase/jx/localjx/order.go index 9c1eb3da3..b32992540 100644 --- a/business/partner/purchase/jx/localjx/order.go +++ b/business/partner/purchase/jx/localjx/order.go @@ -1261,6 +1261,8 @@ func RefreshAllMatterOrderStatus(ctx *jxcontext.Context) (err error) { } dao.Commit(db) changeOrderStatus(vv.VendorOrderID, model.OrderStatusFinished, "") + getTrackMessagePlusByOrderResult, _ := api.JdEclpAPI.GetTrackMessagePlusByOrder(vv.VendorOrderID) + updateJdWayBillInfo(db, vv, getTrackMessagePlusByOrderResult) } else { deliveringCount++ } @@ -1288,26 +1290,9 @@ func RefreshAllMatterOrderStatus(ctx *jxcontext.Context) (err error) { changeOrderStatus(v.VendorOrderID, v.Status, "") } else { queryOrderStatus, _ := api.JdEclpAPI.QueryOrderStatus(v.EclpOutID) - if len(queryOrderStatus.OrderStatusList) > 0 { - if queryOrderStatus.OrderStatusList[len(queryOrderStatus.OrderStatusList)-1].SoStatusCode == jdeclpapi.SoStatusCode10034 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - v.Status = model.OrderStatusFinished - dao.UpdateEntity(db, v, "Status") - waybills, err := dao.GetWaybills(db, v.VendorOrderID) - if err == nil && len(waybills) > 0 { - waybills[0].Status = model.WaybillStatusDelivered - dao.UpdateEntity(db, waybills[0], "Status") - } - dao.Commit(db) - changeOrderStatus(v.VendorOrderID, model.OrderStatusFinished, "") - } - } + getTrackMessagePlusByOrderResult, _ := api.JdEclpAPI.GetTrackMessagePlusByOrder(v.VendorOrderID) + updateMatterOrderStatus(db, v, queryOrderStatus) + updateJdWayBillInfo(db, v, getTrackMessagePlusByOrderResult) } } return err @@ -1357,54 +1342,63 @@ func GetMatterOrderStatus(ctx *jxcontext.Context, vendorOrderID string) (result } } if len(queryOrderStatus.OrderStatusList) > 0 { - if queryOrderStatus.OrderStatusList[len(queryOrderStatus.OrderStatusList)-1].SoStatusCode == jdeclpapi.SoStatusCode10034 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - order.Status = model.OrderStatusFinished - dao.UpdateEntity(db, order, "Status") - waybills, err := dao.GetWaybills(db, vendorOrderID) - if err == nil && len(waybills) > 0 { - waybills[0].Status = model.WaybillStatusDelivered - dao.UpdateEntity(db, waybills[0], "Status") - } - dao.Commit(db) - changeOrderStatus(vendorOrderID, model.OrderStatusFinished, "") - } + updateMatterOrderStatus(db, order, queryOrderStatus) } if len(getTrackMessagePlusByOrderResult.ResultData) > 0 { - var ( - waybillCode = getTrackMessagePlusByOrderResult.ResultData[0].WaybillCode - cName string - cMobile string - waybills []*model.Waybill - ) - for _, vv := range getTrackMessagePlusByOrderResult.ResultData { - if vv.OpeTitle == "配送员收货" { - result := regexpCnameAndCmobile.FindAllStringSubmatch(vv.OpeRemark, -1) - cName = result[0][1] - cMobile = result[0][2] - break - } - } - waybills, err = dao.GetWaybills(db, vendorOrderID) - if len(waybills) > 0 { - waybills[0].VendorWaybillID = waybillCode - waybills[0].CourierName = cName - waybills[0].CourierMobile = cMobile - order.VendorWaybillID = waybillCode - order.WaybillVendorID = model.VendorIDJDWL - dao.UpdateEntity(db, order, "VendorWaybillID", "WaybillVendorID") - dao.UpdateEntity(db, waybills[0], "VendorWaybillID", "CourierName", "CourierMobile") - } + updateJdWayBillInfo(db, order, getTrackMessagePlusByOrderResult) } return result, err } +func updateMatterOrderStatus(db *dao.DaoDB, order *model.GoodsOrder, queryOrderStatus *jdeclpapi.QueryOrderStatusResult) { + if queryOrderStatus.OrderStatusList[len(queryOrderStatus.OrderStatusList)-1].SoStatusCode == jdeclpapi.SoStatusCode10034 { + dao.Begin(db) + defer func() { + if r := recover(); r != nil { + dao.Rollback(db) + panic(r) + } + }() + order.Status = model.OrderStatusFinished + dao.UpdateEntity(db, order, "Status") + waybills, err := dao.GetWaybills(db, order.VendorOrderID) + if err == nil && len(waybills) > 0 { + waybills[0].Status = model.WaybillStatusDelivered + dao.UpdateEntity(db, waybills[0], "Status") + } + dao.Commit(db) + changeOrderStatus(order.VendorOrderID, model.OrderStatusFinished, "") + } +} + +func updateJdWayBillInfo(db *dao.DaoDB, order *model.GoodsOrder, getTrackMessagePlusByOrderResult *jdeclpapi.GetTrackMessagePlusByOrderResult) (err error) { + var ( + waybillCode = getTrackMessagePlusByOrderResult.ResultData[0].WaybillCode + cName string + cMobile string + waybills []*model.Waybill + ) + for _, vv := range getTrackMessagePlusByOrderResult.ResultData { + if vv.OpeTitle == "配送员收货" { + result := regexpCnameAndCmobile.FindAllStringSubmatch(vv.OpeRemark, -1) + cName = result[0][1] + cMobile = result[0][2] + break + } + } + waybills, err = dao.GetWaybills(db, order.VendorOrderID) + if len(waybills) > 0 { + waybills[0].VendorWaybillID = waybillCode + waybills[0].CourierName = cName + waybills[0].CourierMobile = cMobile + order.VendorWaybillID = waybillCode + order.WaybillVendorID = model.VendorIDJDWL + dao.UpdateEntity(db, order, "VendorWaybillID", "WaybillVendorID") + dao.UpdateEntity(db, waybills[0], "VendorWaybillID", "CourierName", "CourierMobile") + } + return err +} + func tryToSplitMatterOrder(jxOrder *JxOrderInfo) (outOrders []*JxOrderInfo, freightPrice int, err error) { var ( skus = jxOrder.Skus diff --git a/business/partner/purchase/yb/act.go b/business/partner/purchase/yb/act.go new file mode 100644 index 000000000..4434fa15a --- /dev/null +++ b/business/partner/purchase/yb/act.go @@ -0,0 +1,11 @@ +package yb + +import ( + "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" +) + +func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { + return err +} diff --git a/business/partner/purchase/yb/order.go b/business/partner/purchase/yb/order.go new file mode 100644 index 000000000..f8cace49e --- /dev/null +++ b/business/partner/purchase/yb/order.go @@ -0,0 +1,76 @@ +package yb + +import ( + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "git.rosy.net.cn/jx-callback/business/model" +) + +func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { + return err +} + +func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { + return order +} +func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) { + return order, err +} +func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { + return status, err +} + +func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { + return err +} +func (p *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { + return err +} + +func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { + return err +} // 取货失败后再次招唤平台配送 +func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { + return err +} // 投递失败后确认收到退货 +func (p *PurchaseHandler) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) { + return isCan, err +} +func (p *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { + return err +} +func (p *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { + return err +} +func (p *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { + return err +} +func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { + return err +} +func (p *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { + return mobile, err +} +func (p *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { + return err +} +func (p *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { + return err +} +func (p *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { + return err +} +func (p *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { + return err +} +func (p *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { + return err +} +func (p *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { + return err +} +func (p *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { + return err +} +func (p *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { + return err +} diff --git a/business/partner/purchase/yb/order_comment.go b/business/partner/purchase/yb/order_comment.go new file mode 100644 index 000000000..7206382e9 --- /dev/null +++ b/business/partner/purchase/yb/order_comment.go @@ -0,0 +1,5 @@ +package yb + +func (c *PurchaseHandler) StartRefreshComment() { + +} diff --git a/business/partner/purchase/yb/sku.go b/business/partner/purchase/yb/sku.go new file mode 100644 index 000000000..92e8d5f0f --- /dev/null +++ b/business/partner/purchase/yb/sku.go @@ -0,0 +1,76 @@ +package yb + +import ( + "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" + "git.rosy.net.cn/jx-callback/business/partner" +) + +func (p *PurchaseHandler) GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*partner.BareCategoryInfo, err error) { + return cats, err +} + +// func (p *PurchaseHandler) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error { +// return nil +// } + +// func (p *PurchaseHandler) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error { +// return nil +// } + +// func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error) { +// return err +// } + +func (p *PurchaseHandler) CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { + return err +} + +func (p *PurchaseHandler) UpdateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { + return err +} + +func (p *PurchaseHandler) DeleteCategory2(ctx *jxcontext.Context, vendorOrgCode, vendorCatID string) (err error) { + return err +} + +func (p *PurchaseHandler) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCode, vendorParentCatID string, vendorCatIDList []string) (err error) { + return err +} + +// func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { +// return err +// } + +// func (p *PurchaseHandler) ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) { +// return skuNameExt, err +// } + +// func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { +// return err +// } + +// func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { +// return err +// } + +func (p *PurchaseHandler) CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { + return err +} + +func (p *PurchaseHandler) UpdateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { + return err +} + +func (p *PurchaseHandler) DeleteSku2(ctx *jxcontext.Context, vendorOrgCode string, sku *partner.StoreSkuInfo) (err error) { + return err +} + +func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { + return vendorCats, err +} + +func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*partner.SkuNameInfo, err error) { + return skuNameList, err +} diff --git a/business/partner/purchase/yb/store.go b/business/partner/purchase/yb/store.go new file mode 100644 index 000000000..fea030fb1 --- /dev/null +++ b/business/partner/purchase/yb/store.go @@ -0,0 +1,44 @@ +package yb + +import ( + "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/dao" +) + +func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (storeDetail *dao.StoreDetail, err error) { + return storeDetail, err +} + +// stoerIDs为nil表示所有 +func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { + return err +} + +func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { + return hint, err +} + +func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { + return storeStatus, err +} + +func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { + return err +} + +func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { + return err +} + +func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { + return err +} + +func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { + return vendorStoreIDs, err +} + +func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { + return err +} diff --git a/business/partner/purchase/yb/store_sku.go b/business/partner/purchase/yb/store_sku.go new file mode 100644 index 000000000..dd78e14fd --- /dev/null +++ b/business/partner/purchase/yb/store_sku.go @@ -0,0 +1,514 @@ +package yb + +import ( + "fmt" + "regexp" + "strings" + + "git.rosy.net.cn/baseapi/platformapi/yinbaoapi" + "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/business/partner" + "git.rosy.net.cn/jx-callback/business/partner/putils" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" +) + +var ( + sensitiveWordRegexp = regexp.MustCompile(`商品名称中含有敏感词(\[.*\])`) +) + +func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { + if globals.EnableYbStoreWrite { + storeSku := storeSkuList[0] + var result *yinbaoapi.AddProductInfoResult + flag, err2 := checkYbSku(storeSku) //flag为true表示是标品,标品不用更新称编码 + if err2 != nil { + err = err2 + } else { + result, err = api.YinBaoAPI.AddProductInfo(buildProductInfoParam(storeSku)) + } + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "创建商品") + } else { + storeSku.VendorSkuID = utils.Int64ToStr(result.UID) + uploadYbImage(vendorStoreID, storeSku.YbBarCode, storeSku.Img) + if !flag { + updateYbSku(vendorStoreID, storeSku.YbBarCode) + } + } + } + return failedList, err +} + +func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { + return failedList, err +} + +func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { + if globals.EnableYbStoreWrite { + for _, v := range storeSkuList { + var productInfo = &yinbaoapi.ProductInfo{ + UID: utils.Str2Int64(v.VendorSkuID), + Enable: utils.Int2Pointer(yinbaoapi.SkuStatusDeleted), + } + err = api.YinBaoAPI.UpdateProductInfo(productInfo) + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "删除商品") + } + } + } + return failedList, err +} + +func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) { + storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDYB) + api.YinBaoAPI = yinbaoapi.New(storeDetail.YbAppKey, storeDetail.YbAppID) + if configs, err := dao.QueryConfigs(dao.GetDB(), "yinbaoCookie", model.ConfigTypeCookie, ""); err == nil { + yinbaoCookie := configs[0].Value + api.YinBaoAPI.SetCookie(".POSPALAUTH30220", yinbaoCookie) + } + if storeSkuList != nil { + if len(storeSkuList) == 1 { + storeSku := storeSkuList[0] + result, err := api.YinBaoAPI.QueryProductByBarcode(storeSku.VendorSkuID) + resultp, err := getProductImages(vendorStoreID, storeSku.VendorSkuID) + if err != nil { + return nil, err + } + if skuName := vendorSku2Jx(result, resultp); skuName != nil { + skuNameList = append(skuNameList, skuName) + } + } else { + var barcodes []string + for _, v := range storeSkuList { + barcodes = append(barcodes, v.VendorSkuID) + } + results, err := api.YinBaoAPI.QueryProductByBarcodes(barcodes) + if err != nil { + return nil, err + } + for _, v := range results { + resultp, err := getProductImages(vendorStoreID, v.Barcode) + if err != nil { + return nil, err + } + if skuName := vendorSku2Jx(v, resultp); skuName != nil { + skuNameList = append(skuNameList, skuName) + } + } + } + } else { + result, err := api.YinBaoAPI.QueryProductPages(nil) + if err != nil { + return nil, err + } + if result.PostBackParameter.ParameterType == yinbaoapi.PageMaxID { + for _, v := range result.Result { + resultp, err := getProductImages(vendorStoreID, v.Barcode) + if err != nil { + return nil, err + } + vv := &yinbaoapi.QueryProductByBarcodeResult{} + err = utils.Map2StructByJson(utils.Struct2MapByJson(v), vv, false) + if skuName := vendorSku2Jx(vv, resultp); skuName != nil { + skuNameList = append(skuNameList, skuName) + } + } + } else { + loopPages(result.PostBackParameter.ParameterType, result.PostBackParameter.ParameterValue, skuNameList, vendorStoreID) + } + } + return skuNameList, err +} + +func getProductImages(vendorStoreID, barCode string) (findProductResult *yinbaoapi.FindProductResult, err error) { + for { + ybSkuID, err := api.YinBaoAPI.LoadProductsByPage(vendorStoreID, barCode) + findProductResult, err = api.YinBaoAPI.FindProduct(ybSkuID) + if err == nil { + break + } else { + if yinbaoapi.IsErrCookie(err) { + err = cms.ChangeYbCookie() + if err != nil { + break + } + findProductResult, err = getProductImages(vendorStoreID, barCode) + } else { + break + } + } + } + return findProductResult, err +} + +func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { + if globals.EnableYbStoreWrite { + for _, v := range storeSkuList { + var productInfo = &yinbaoapi.ProductInfo{ + UID: utils.Str2Int64(v.VendorSkuID), + Enable: utils.Int2Pointer(ybSkuStatus2Jx(v.Status)), + } + err = api.YinBaoAPI.UpdateProductInfo(productInfo) + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "更新商品状态") + } + } + } + return failedList, err +} + +func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { + if globals.EnableYbStoreWrite { + for _, v := range storeSkuList { + var productInfo = &yinbaoapi.ProductInfo{ + UID: utils.Str2Int64(v.VendorSkuID), + SellPrice: utils.Float64ToPointer(jxutils.IntPrice2Standard(v.VendorPrice)), + BuyPrice: utils.Float64ToPointer(jxutils.IntPrice2Standard(v.JxPrice)), + } + err = api.YinBaoAPI.UpdateProductInfo(productInfo) + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "更新商品价格") + } + } + } + return failedList, err +} + +func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { + if globals.EnableYbStoreWrite { + for _, v := range storeSkuList { + var productInfo = &yinbaoapi.ProductInfo{ + UID: utils.Str2Int64(v.VendorSkuID), + Stock: utils.Float64ToPointer(utils.Str2Float64(utils.Int2Str(v.Stock))), + } + err = api.YinBaoAPI.UpdateProductInfo(productInfo) + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "更新商品库存") + } + } + } + return failedList, err +} + +func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { + remoteCats, err := loadCategorysWithOption(vendorStoreID) + cats = convertVendorCatList(remoteCats) + return cats, err +} + +func loadCategorysWithOption(vendorStoreID string) (remoteCats []*yinbaoapi.LoadCategorysWithOptionResult, err error) { + for { + remoteCats, err = api.YinBaoAPI.LoadCategorysWithOption(vendorStoreID) + if err == nil { + break + } else { + if yinbaoapi.IsErrCookie(err) { + err = cms.ChangeYbCookie() + if err != nil { + break + } + remoteCats, err = loadCategorysWithOption(vendorStoreID) + } else { + break + } + } + } + return remoteCats, err +} + +func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { + if globals.EnableYbStoreWrite { + var ( + catName = utils.FilterEmoji(storeCat.Name) + parentCatName = utils.FilterEmoji(storeCat.ParentCatName) + ) + vendorCatID, err := addNewCategory(vendorStoreID, catName, parentCatName) + if err == nil { + storeCat.VendorCatID = vendorCatID + } + return err + } + return err +} + +func addNewCategory(vendorStoreID, catName, parentCatName string) (vendorCatID string, err error) { + for { + vendorCatID, err = api.YinBaoAPI.AddNewCategory(vendorStoreID, catName, parentCatName) + if err == nil { + break + } else { + if yinbaoapi.IsErrCookie(err) { + err = cms.ChangeYbCookie() + if err != nil { + break + } + vendorCatID, err = addNewCategory(vendorStoreID, catName, parentCatName) + } else { + break + } + } + } + return vendorCatID, err +} + +func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { + if globals.EnableYbStoreWrite { + var ( + catName = utils.FilterEmoji(storeCat.Name) + parentCatName = utils.FilterEmoji(storeCat.ParentCatName) + ) + err = updateCategory(vendorStoreID, storeCat.VendorCatID, catName, parentCatName) + } + return err +} + +func updateCategory(vendorStoreID, vendorCatID, catName, parentCatName string) (err error) { + for { + err = api.YinBaoAPI.UpdateCategory(vendorStoreID, vendorCatID, catName, parentCatName) + if err == nil { + break + } else { + if yinbaoapi.IsErrCookie(err) { + err = cms.ChangeYbCookie() + if err != nil { + break + } + err = updateCategory(vendorStoreID, vendorCatID, catName, parentCatName) + } else { + break + } + } + } + return err +} + +func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) { + if globals.EnableYbStoreWrite { + err = deleteCategory(vendorStoreID, []string{vendorCatID}) + } + return err +} + +func deleteCategory(vendorStoreID string, vendorCatIDs []string) (err error) { + for { + err = api.YinBaoAPI.DeleteCategory(vendorStoreID, vendorCatIDs) + if err == nil { + break + } else { + if yinbaoapi.IsErrCookie(err) { + err = cms.ChangeYbCookie() + if err != nil { + break + } + err = api.YinBaoAPI.DeleteCategory(vendorStoreID, vendorCatIDs) + } else { + break + } + } + } + return err +} + +func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) { + return yinbaoapi.IsErrSkuExist(err) +} + +func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) { + return yinbaoapi.IsErrCategoryExist(err) +} + +func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) { + return false +} + +func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { + return 1 +} + +func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { + return sensitiveWordRegexp +} + +func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) { + return yinbaoapi.IsErrSkuNotExist(err) +} + +func ybSkuStatus2Jx(ybStatus int) (jxSkuStatus int) { + if ybStatus == yinbaoapi.SkuStatusEnable { + jxSkuStatus = model.SkuStatusNormal + } else if ybStatus == yinbaoapi.SkuStatusDisabled { + jxSkuStatus = model.SkuStatusDontSale + } else if ybStatus == yinbaoapi.SkuStatusDeleted { + jxSkuStatus = model.SkuStatusDeleted + } + return jxSkuStatus +} + +func vendorSku2Jx(result *yinbaoapi.QueryProductByBarcodeResult, resultp *yinbaoapi.FindProductResult) (skuName *partner.SkuNameInfo) { + var picList []string + if result == nil { + globals.SugarLogger.Warnf("vendorSku2Jx, strange result:%s", utils.Format4Output(result, true)) + return nil + } + if len(resultp.Productimages) > 0 { + for _, v := range resultp.Productimages { + picList = append(picList, yinbaoapi.ImageUrl+v.Path) + } + } + prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(result.Name) + skuName = &partner.SkuNameInfo{ + Prefix: prefix, + Name: name, + Unit: unit, + YbBarCode: result.Barcode, + SkuList: []*partner.SkuInfo{ + &partner.SkuInfo{ + StoreSkuInfo: partner.StoreSkuInfo{ + VendorSkuID: utils.Int64ToStr(result.UID), + Stock: int(utils.Float64TwoInt64(result.Stock)), + VendorPrice: jxutils.StandardPrice2Int(result.SellPrice), + Status: ybSkuStatus2Jx(result.Enable), + }, + SkuName: result.Name, + Comment: comment, + SpecQuality: float64(specQuality), + SpecUnit: specUnit, + Weight: int(utils.Float64TwoInt64(float64(specQuality))), + }, + }, + PictureList: picList, + } + return skuName +} + +func loopPages(parameterType, parameterValue string, skuNameList []*partner.SkuNameInfo, vendorStoreID string) (err error) { + var postBackParameter = &yinbaoapi.PostBackParameter{ + ParameterType: parameterType, + ParameterValue: parameterValue, + } + resultPages, err := api.YinBaoAPI.QueryProductPages(postBackParameter) + if err != nil { + return err + } + for _, v := range resultPages.Result { + resultp, err := getProductImages(vendorStoreID, v.Barcode) + if err != nil { + return err + } + vv := &yinbaoapi.QueryProductByBarcodeResult{} + err = utils.Map2StructByJson(utils.Struct2MapByJson(v), vv, false) + if skuName := vendorSku2Jx(vv, resultp); skuName != nil { + skuNameList = append(skuNameList, skuName) + } + } + if resultPages.PostBackParameter.ParameterType != yinbaoapi.PageMaxID { + err = loopPages(resultPages.PostBackParameter.ParameterType, resultPages.PostBackParameter.ParameterValue, skuNameList, vendorStoreID) + } + return err +} + +func buildProductInfoParam(storeSku *dao.StoreSkuSyncInfo) (productInfoParam *yinbaoapi.ProductInfoParam) { + var ( + buyPrice float64 = utils.Str2Float64(utils.Int64ToStr(storeSku.Price)) / 100 + sellPrice float64 = utils.Str2Float64(utils.Int64ToStr(storeSku.VendorPrice)) / 100 + _, name, _, _, _, _ = jxutils.SplitSkuName(storeSku.SkuName) + ) + productInfoParam = &yinbaoapi.ProductInfoParam{} + productInfo := &yinbaoapi.ProductInfo{ + Stock: utils.Float64ToPointer(utils.Str2Float64(utils.Int2Str(model.MaxStoreSkuStockQty))), + Name: name, + Barcode: storeSku.YbBarCode, + BuyPrice: &buyPrice, + SellPrice: &sellPrice, + CategoryUID: utils.Str2Int64(storeSku.VendorCatID), + } + productInfoParam.ProductInfo = productInfo + return productInfoParam +} + +func convertVendorCatList(remoteCats []*yinbaoapi.LoadCategorysWithOptionResult) (cats []*partner.BareCategoryInfo) { + for _, rCat := range remoteCats { + cat := &partner.BareCategoryInfo{ + VendorCatID: rCat.TxtUID, + Name: rCat.Name, + } + if rCat.TxtParentUID == "" { + cat.Level = 1 + } else { + cat.Level = 2 + } + cats = append(cats, cat) + } + return cats +} + +func updateYbSku(vendorStoreID, ybBarCode string) (err error) { + for { + err = api.YinBaoAPI.SaveProduct(vendorStoreID, ybBarCode) + if err == nil { + break + } else { + if yinbaoapi.IsErrCookie(err) { + err = cms.ChangeYbCookie() + if err != nil { + break + } + err = updateYbSku(vendorStoreID, ybBarCode) + } else { + break + } + } + } + return err +} + +func checkYbSku(storeSku *dao.StoreSkuSyncInfo) (flag bool, err error) { + skuID := storeSku.SkuID + skus, _ := dao.GetSkus(dao.GetDB(), []int{skuID}, nil, nil, nil, nil) + if len(skus) > 0 { + if skus[0].Unit != model.UnitNames[0] { + flag = true + if skus[0].Upc == "" { + return flag, fmt.Errorf("创建标品必须指定upc码,skuID[%v]", skuID) + } else { + storeSku.YbBarCode = skus[0].Upc + } + } + } + return flag, err +} + +func uploadYbImage(vendorStoreID, ybBarCode, img string) (err error) { + ybSkuID, err := api.YinBaoAPI.LoadProductsByPage(vendorStoreID, ybBarCode) + resBinary, _, err := jxutils.DownloadFileByURL(img) + fileName := img[strings.LastIndex(img, "/")+1:] + err = uploadYbImageLoop(vendorStoreID, ybSkuID, resBinary, fileName) + return err +} + +func uploadYbImageLoop(vendorStoreID, ybSkuID string, resBinary []byte, fileName string) (err error) { + for { + err = api.YinBaoAPI.UploadProductImage(vendorStoreID, ybSkuID, resBinary, fileName) + if err == nil { + break + } else { + if yinbaoapi.IsErrCookie(err) { + err = cms.ChangeYbCookie() + if err != nil { + break + } + err = uploadYbImageLoop(vendorStoreID, ybSkuID, resBinary, fileName) + } else { + break + } + } + } + return err +} diff --git a/business/partner/purchase/yb/yb.go b/business/partner/purchase/yb/yb.go new file mode 100644 index 000000000..7f6518213 --- /dev/null +++ b/business/partner/purchase/yb/yb.go @@ -0,0 +1,39 @@ +package yb + +import ( + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "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/api" +) + +var ( + CurPurchaseHandler *PurchaseHandler +) + +type PurchaseHandler struct { + partner.BasePurchasePlatform + putils.DefSingleStorePlatform +} + +func init() { + if api.YinBaoAPI != nil { + CurPurchaseHandler = New() + partner.RegisterPurchasePlatform(CurPurchaseHandler) + } +} + +func New() (obj *PurchaseHandler) { + obj = new(PurchaseHandler) + obj.ISingleStoreStoreSkuHandler = obj + return obj +} + +func (p *PurchaseHandler) GetVendorID() int { + return model.VendorIDYB +} + +func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { + return imgHint, err +} diff --git a/conf/app.conf b/conf/app.conf index 81beb4852..00efe89c7 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -31,6 +31,7 @@ enableEbaiStoreWrite = false enableElmStoreWrite = false enableMtwmStoreWrite = false enableWscStoreWrite = false +enableYbStoreWrite = true aliKey = "LTAI4FwZN7pp4dACQHoapkZQ" aliSecret = "NTegceUFX0FdfMovqCDzqcIKmhcoOu" @@ -102,6 +103,9 @@ feieKey = "2JfKh8TyheQ9mwss" xiaoWMAppID = 267 xiaoWMAppKey = "94337" +yinbaoAppKey = "682628966212343269" +yinbaoAppID = "18C0E0867E467DBC26EFF5E957B02EC4" + yilianyunClientID = "1039586024" yilianyunClientSecret = "4885d07c2997b661102e4b6099c0bf3b" yilianyunClientID2 = "1098307169" @@ -194,6 +198,9 @@ weixinSecret = "6bbbed1443cc062c20a015a64c07a531" weixinMiniAppID2 = "wx4b5930c13f8b1170" weixinMiniSecret2 = "2a57228a716ce991a52739f0ff41111d" +yinbaoAppKey = "682628966212343269" +yinbaoAppID = "18C0E0867E467DBC26EFF5E957B02EC4" + wxpayNotifyURL = "http://callback.jxc4.com/wxpay/msg/" tonglianPayAppID = "00183083" @@ -208,6 +215,7 @@ enableJdStoreWrite = true enableEbaiStoreWrite = true enableMtwmStoreWrite = true enableWscStoreWrite = true +enableYbStoreWrite = true disableWeimob = false weimobCallbackURL = "http://callback.jxc4.com/weimob" @@ -218,9 +226,6 @@ dingdingSecret = "LWrZAFeqUfuVv7n_tc8vPpCAx6PT4CwManx2XCVhJOqGsx2L5XCDuX1sAN_Jtv dingdingCallbackURL = "http://callback.jxc4.com/dingding/msg" -yinbaoAppID = "18C0E0867E467DBC26EFF5E957B02EC4" -yinbaoAppKey = "682628966212343269" - [jxgy] httpport = 8088 EnableDocs = false @@ -247,6 +252,7 @@ enableStoreWrite = true enableJdStoreWrite = true enableEbaiStoreWrite = true enableMtwmStoreWrite = true +enableYbStoreWrite = true mtpsAppKey = "3c0a05d464c247c19d7ec13accc78605" mtpsSecret = "b1M}9?:sTbsB[OF2gNORnN(|(iy9rB8(`7]|[wGLnbmt`evfM>E:A90DjHAW:UPE" @@ -290,9 +296,6 @@ jdEclpAccessToken = "bcb6201b5b3c45a0976dcda5e2dea8aejiwm" jdEclpAppKey = "0D397F05CF11C51BCDCC81744680EBC3" jdEclpAppSecret = "f16a5e57ff4f4f428b702c40d2d4b933" -yinbaoAppID = "18C0E0867E467DBC26EFF5E957B02EC4" -yinbaoAppKey = "682628966212343269" - storeName = "京西果园" [test] @@ -361,14 +364,16 @@ enableJdStoreWrite = true enableEbaiStoreWrite = true enableMtwmStoreWrite = true enableWscStoreWrite = false +enableYbStoreWrite = false [beta] -enableStoreWrite = false +enableStoreWrite = true enableJdStoreWrite = false enableEbaiStoreWrite = false enableElmStoreWrite = false enableMtwmStoreWrite = false enableWscStoreWrite = false +enableYbStoreWrite = true jdOrgCode = "320406" jdToken = "77e703b7-7997-441b-a12a-2e522efb117a" @@ -411,5 +416,5 @@ getWeimobTokenURL = "http://www.jxc4.com/v2/sys/GetWeimobToken" dbConnectStr = "root:WebServer@1@tcp(127.0.0.1:3306)/jxd_dev_0?charset=utf8mb4&loc=Local&parseTime=true" -yinbaoAppID = "18C0E0867E467DBC26EFF5E957B02EC4" -yinbaoAppKey = "682628966212343269" \ No newline at end of file +yinbaoAppKey = "682628966212343269" +yinbaoAppID = "18C0E0867E467DBC26EFF5E957B02EC4" \ No newline at end of file diff --git a/controllers/cms_store_sku.go b/controllers/cms_store_sku.go index 73025aa3d..c5558a912 100644 --- a/controllers/cms_store_sku.go +++ b/controllers/cms_store_sku.go @@ -4,6 +4,8 @@ import ( "math" "time" + "git.rosy.net.cn/baseapi/platformapi/jdapi" + "git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model/dao" @@ -760,3 +762,38 @@ func (c *StoreSkuController) RefreshMatterStock() { return retVal, "", err }) } + +// @Title 从银豹上拉取标品到京西创建 +// @Description 从银豹上拉取标品到京西创建 +// @Param token header string true "认证token" +// @Param isAsync formData bool false "是否异步,缺省是同步" +// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /CreateSkusAndFocusFromYb [post] +func (c *StoreSkuController) CreateSkusAndFocusFromYb() { + c.callCreateSkusAndFocusFromYb(func(params *tStoreSkuCreateSkusAndFocusFromYbParams) (retVal interface{}, errCode string, err error) { + retVal, err = cms.CreateSkusAndFocusFromYb(params.Ctx, params.IsAsync, params.IsContinueWhenError) + return retVal, "", err + }) +} + +// @Title 从微信上扫码标品到京西创建或关注 +// @Description 从微信上扫码标品到京西创建或关注 +// @Param token header string true "认证token" +// @Param payload formData string true "json数据,ProductInfo对象" +// @Param storeID formData int true "门店ID" +// @Param price formData int true "商品价格" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /CreateSkusAndFocusFromWx [post] +func (c *StoreSkuController) CreateSkusAndFocusFromWx() { + var productInfo *jdapi.ProductInfo + c.callCreateSkusAndFocusFromWx(func(params *tStoreSkuCreateSkusAndFocusFromWxParams) (retVal interface{}, errCode string, err error) { + if err = jxutils.Strings2Objs(params.Payload, &productInfo); err != nil { + return retVal, "", err + } + err = cms.CreateSkusAndFocusFromWx(params.Ctx, productInfo, params.Price, params.StoreID) + return retVal, "", err + }) +} diff --git a/globals/api/api.go b/globals/api/api.go index e47c0c46d..5edcafe87 100644 --- a/globals/api/api.go +++ b/globals/api/api.go @@ -159,11 +159,11 @@ func Init() { Ebai2API = nil } - // if !beego.AppConfig.DefaultBool("disableYb", false) { - // YinBaoAPI = yinbaoapi.New(beego.AppConfig.String("yinbaoAppKey"), beego.AppConfig.String("yinbaoAppID")) - // } else { - // YinBaoAPI = nil - // } + if !beego.AppConfig.DefaultBool("disableYb", false) { + YinBaoAPI = yinbaoapi.New(beego.AppConfig.String("yinbaoAppKey"), beego.AppConfig.String("yinbaoAppID")) + } else { + YinBaoAPI = nil + } if !beego.AppConfig.DefaultBool("disableMtps", false) { MtpsAPI = mtpsapi.New(beego.AppConfig.String("mtpsAppKey"), beego.AppConfig.String("mtpsSecret")) diff --git a/globals/globals.go b/globals/globals.go index e12384f76..48aa35b91 100644 --- a/globals/globals.go +++ b/globals/globals.go @@ -24,6 +24,7 @@ var ( EnableMtwmStoreWrite bool EnableWscStoreWrite bool EnablePendingChange bool + EnableYbStoreWrite bool QiniuBucket string WeimobCallbackURL string @@ -91,6 +92,7 @@ func Init() { EnableMtwmStoreWrite = EnableStoreWrite && beego.AppConfig.DefaultBool("enableMtwmStoreWrite", false) EnableWscStoreWrite = EnableStoreWrite && beego.AppConfig.DefaultBool("enableWscStoreWrite", false) // EnablePendingChange = beego.AppConfig.DefaultBool("enablePendingChange", false) + EnableYbStoreWrite = EnableStoreWrite && beego.AppConfig.DefaultBool("enableYbStoreWrite", false) QiniuBucket = beego.AppConfig.String("qiniuBucket") diff --git a/main.go b/main.go index 15feef3f3..c3b567b5b 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,8 @@ import ( "os" "time" + "git.rosy.net.cn/jx-callback/business/partner/purchase/yb" + "github.com/astaxie/beego" "git.rosy.net.cn/baseapi/platformapi/dingdingapi" @@ -74,6 +76,7 @@ func Init() { if globals.IsProductEnv() { ebai.CurPurchaseHandler.StartRefreshComment() mtwm.CurPurchaseHandler.StartRefreshComment() + yb.CurPurchaseHandler.StartRefreshComment() } misc.Init() } diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 061cf5d33..e2ad284dd 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1827,6 +1827,24 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], + beego.ControllerComments{ + Method: "CreateSkusAndFocusFromWx", + Router: `/CreateSkusAndFocusFromWx`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], + beego.ControllerComments{ + Method: "CreateSkusAndFocusFromYb", + Router: `/CreateSkusAndFocusFromYb`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], beego.ControllerComments{ Method: "FocusStoreSkusByExcel",