From f7c5e089ff0e5941198b46bd81c7f154e8d0ee16 Mon Sep 17 00:00:00 2001 From: gazebo Date: Tue, 11 Dec 2018 12:44:41 +0800 Subject: [PATCH] - jd spu support --- business/jxstore/cms/sku.go | 8 +- business/jxutils/jxutils.go | 14 +++ business/model/sku.go | 5 ++ business/partner/purchase/jd/sku.go | 134 +++++++++++++++++++++++++--- 4 files changed, 147 insertions(+), 14 deletions(-) diff --git a/business/jxstore/cms/sku.go b/business/jxstore/cms/sku.go index 40ffd385d..5f76c6891 100644 --- a/business/jxstore/cms/sku.go +++ b/business/jxstore/cms/sku.go @@ -419,6 +419,7 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s panic(r) } }() + skuNameExt.SkuName.JdSyncStatus = model.SyncFlagNewMask dao.WrapAddIDCULDEntity(&skuNameExt.SkuName, userName) if skuNameExt.Unit == model.SpecialUnit { skuNameExt.SpecQuality = float32(model.SpecialSpecQuality) @@ -481,7 +482,7 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf panic(r) } }() - if num, err = dao.UpdateEntityLogically(db, skuName, valid, userName, nil); err == nil && num == 1 { + if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, skuName, valid, userName, nil, model.FieldJdSyncStatus); err == nil && num == 1 { if utils.Interface2Int64WithDefault(payload["isGlobal"], 0) == 0 && payload["places"] != nil { if places, ok := payload["places"].([]interface{}); ok { if _, err = dao.DeleteSkuNamePlace(db, nameID, nil); err == nil { @@ -543,7 +544,10 @@ func DeleteSkuName(ctx *jxcontext.Context, nameID int, userName string) (num int } skuName := &model.SkuName{} skuName.ID = nameID - if num, err = dao.DeleteEntityLogically(db, skuName, nil, userName, nil); err != nil { + if num, err = dao.DeleteEntityLogically(db, skuName, map[string]interface{}{ + model.FieldJdSyncStatus: model.SyncFlagDeletedMask, + model.FieldStatus: model.SkuStatusDeleted, + }, userName, nil); err != nil { return 0, err } dao.Commit(db) diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index 9baab8279..93d8e6f2e 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -235,6 +235,20 @@ func ComposeSkuName(prefix, name, comment, unit string, spec_quality float32, sp return skuName } +func ComposeSpuName(prefix, name string, maxLen int) (spuName string) { + if prefix != "" { + spuName = "[" + prefix + "]" + } + spuName += name + if maxLen > 0 { + runeList := []rune(spuName) + if len(runeList) > maxLen { + spuName = string(runeList[:maxLen]) + } + } + return spuName +} + func ComposeSkuSpec(spec_quality float32, spec_unit string) (spec string) { if math.Round(float64(spec_quality)) == float64(spec_quality) || (spec_unit != "L" && spec_unit != "kg") { spec = fmt.Sprintf("%d", int(spec_quality)) diff --git a/business/model/sku.go b/business/model/sku.go index a36baac8b..8524a229d 100644 --- a/business/model/sku.go +++ b/business/model/sku.go @@ -163,6 +163,11 @@ type SkuName struct { Price int `json:"price"` // 单位为分,标准价,不为份的就为实际标准价,为份的为每市斤价,实际还要乘质量。todo 为份的确定必须有质量 Img string `orm:"size(255)" json:"img"` ElmImgHashCode string `orm:"size(255)" json:"-"` // 长度255的原因是从京东初始化数据时临时需要 + + Status int `orm:"default(1)" json:"status"` // skuname状态,取值同sku.Status + IsSpu int8 `orm:"column(is_spu)" json:"isSpu"` // 用于指明是否SKUNAME当成SPU + JdID int64 `orm:"column(jd_id);null" json:"jdID"` + JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` } func (*SkuName) TableUnique() [][]string { diff --git a/business/partner/purchase/jd/sku.go b/business/partner/purchase/jd/sku.go index 1517c07da..46cb48cb1 100644 --- a/business/partner/purchase/jd/sku.go +++ b/business/partner/purchase/jd/sku.go @@ -22,7 +22,7 @@ const ( type tSkuInfoExt struct { model.SkuName - JdID int64 `orm:"column(jd_id)"` // 商家类别 + JdCatID int64 `orm:"column(jd_cat_id)"` // 商家类别 JdCategoryID int `orm:"column(jd_category_id)"` // 到家类别 SkuCatID int64 `orm:"column(sku_cat_id)"` // 商家特殊类别 Comment string `orm:"size(255)" json:"comment"` @@ -108,7 +108,7 @@ func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, user func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (string, error)) (err error) { var skuInfoExt tSkuInfoExt err = dao.GetRow(nil, &skuInfoExt, ` - SELECT t2.*, t3.jd_id, t3.jd_category_id, t4.jd_id sku_cat_id + SELECT t2.*, t3.jd_id jd_cat_id, t3.jd_category_id, t4.jd_id sku_cat_id FROM sku t1 JOIN sku_name t2 ON t1.name_id = t2.id JOIN sku_category t3 ON t2.category_id = t3.id @@ -116,7 +116,7 @@ func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuE WHERE t1.id = ? `, sku.ID) if err == nil { - shopCategories := []int64{skuInfoExt.JdID} + shopCategories := []int64{skuInfoExt.JdCatID} if skuInfoExt.SkuCatID != 0 { shopCategories = append(shopCategories, skuInfoExt.SkuCatID) } @@ -154,8 +154,12 @@ func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuE func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { return p.cuSku(db, sku, func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) { - if globals.EnableStoreWrite { - vendorSkuID, err = api.JdAPI.AddSku(utils.Int2Str(sku.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{skuExt.Img}, 1, true, addParams) + if skuExt.IsSpu == 0 { + if globals.EnableStoreWrite { + vendorSkuID, err = api.JdAPI.AddSku(utils.Int2Str(sku.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{skuExt.Img}, jxStatus2jdStatus(sku.Status), true, addParams) + } + } else { + vendorSkuID, err = p.syncSkuNameAsSpu(db, sku, skuExt, price, skuName, shopCategories, addParams) } return vendorSkuID, err }) @@ -188,7 +192,7 @@ func (p *PurchaseHandler) ReadSku(vendorSkuID string) (skuNameExt *model.SkuName SpecUnit: specUnit, Weight: jxutils.FloatWeight2Int(float32(utils.MustInterface2Float64(mapData["weight"]))), JdID: utils.MustInterface2Int64(mapData["skuId"]), - Status: jdStatus2jxStatus(int(utils.MustInterface2Int64(mapData["fixedStatus"]))), + Status: jdStatus2jxStatus(int(utils.MustInterface2Int64(mapData[jdapi.KeyFixedStatus]))), Comment: comment, }, } @@ -236,9 +240,13 @@ func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName stri params["skuName"] = skuName params["weight"] = jxutils.IntWeight2Float(sku.Weight) params["images"] = []string{skuExt.Img} - params["fixedStatus"] = jxStatus2jdStatus(sku.Status) - if globals.EnableStoreWrite { - vendorSkuID, err = api.JdAPI.UpdateSku(utils.Int2Str(sku.ID), params) + params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status) + if skuExt.IsSpu == 0 { + if globals.EnableStoreWrite { + vendorSkuID, err = api.JdAPI.UpdateSku(utils.Int2Str(sku.ID), params) + } + } else { + vendorSkuID, err = p.syncSkuNameAsSpu(db, sku, skuExt, price, skuName, shopCategories, addParams) } return vendorSkuID, err }) @@ -246,10 +254,24 @@ func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName stri func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { params := map[string]interface{}{ - "fixedStatus": 4, + jdapi.KeyFixedStatus: 4, } - if globals.EnableStoreWrite { - _, err = api.JdAPI.UpdateSku(utils.Int2Str(sku.ID), params) + sql := ` + SELECT t2.* + FROM sku t1 + JOIN sku_name t2 ON t1.name_id = t2.id + WHERE t1.id = ? + ` + var skuExt tSkuInfoExt + err = dao.GetRow(db, &skuExt, sql, sku.ID) + if err == nil { + if skuExt.IsSpu == 0 { + if globals.EnableStoreWrite { + _, err = api.JdAPI.UpdateSku(utils.Int2Str(sku.ID), params) + } + } else { + _, err = p.syncSkuNameAsSpu(db, sku, &skuExt, 0, "", nil, nil) + } } return err } @@ -305,6 +327,94 @@ func (p *PurchaseHandler) RefreshAllSkusID(ctx *jxcontext.Context, parentTask ta return rootTask.ID, err } +func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) { + updateFields := []string{ + model.FieldJdSyncStatus, + } + + if sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除SKU + err = api.JdAPI.UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, 4)) + } else if sku.JdSyncStatus&model.SyncFlagNewMask != 0 && skuExt.JdSyncStatus&model.SyncFlagNewMask == 0 { // 非首次新增SKU + if globals.EnableStoreWrite { + vendorSkuID2, err2 := api.JdAPI.AppendSku(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{skuExt.Img}, jxStatus2jdStatus(sku.Status), true, addParams) + if err = err2; err == nil { + vendorSkuID = utils.Int64ToStr(vendorSkuID2) + } + } + } else if sku.JdSyncStatus&model.SyncFlagModifiedMask != 0 { + params := utils.MergeMaps(addParams) + params["categoryId"] = skuExt.JdCategoryID + params["shopCategories"] = shopCategories + params["brandId"] = skuExt.BrandID + params["skuName"] = skuName + params["weight"] = jxutils.IntWeight2Float(sku.Weight) + params["images"] = []string{skuExt.Img} + params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status) + if globals.EnableStoreWrite { + err = api.JdAPI.UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), params) + } + } + if err == nil { + if skuExt.JdSyncStatus&model.SyncFlagDeletedMask != 0 { + sql := ` + SELECT COUNT(*) ct + FROM sku t1 + WHERE t1.name_id = ? AND (t1.status <> ? OR t1.jd_sync_status <> 0) + ` + var count struct { + Ct int + } + if err = dao.GetRow(db, &count, sql, sku.NameID, model.SyncFlagDeletedMask); err != nil { + return "", err + } + if (count.Ct == 0 || count.Ct == 1 && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0) && globals.EnableStoreWrite { // 1就是最后删的那个 + err = api.JdAPI.UpdateSpu(utils.Int2Str(skuExt.ID), utils.Params2Map(jdapi.KeyFixedStatus, 4)) + } + } else if skuExt.JdSyncStatus&model.SyncFlagNewMask != 0 { + if globals.EnableStoreWrite { + spuName := jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0) + skus := []map[string]interface{}{ + map[string]interface{}{ + jdapi.KeyOutSkuId: utils.Int2Str(sku.ID), + jdapi.KeySkuName: skuName, + jdapi.KeyFixedStatus: jxStatus2jdStatus(sku.Status), + jdapi.KeySkuPrice: price, + jdapi.KeyWeight: jxutils.IntWeight2Float(sku.Weight), + jdapi.KeyIsSale: true, + }, + } + if globals.EnableStoreWrite { + vendorSpuID, skuPairs, err2 := api.JdAPI.AddSpu(utils.Int2Str(skuExt.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, spuName, []string{skuExt.Img}, jxStatus2jdStatus(skuExt.Status), addParams, skus) + if err = err2; err == nil { + skuExt.JdID = vendorSpuID + vendorSkuID = utils.Int64ToStr(skuPairs[0].SkuId) + updateFields = append(updateFields, model.FieldJdID) + } + } + } + } else if skuExt.JdSyncStatus&model.SyncFlagModifiedMask != 0 { + params := map[string]interface{}{ + "categoryId": skuExt.JdCategoryID, + "shopCategories": shopCategories, + "brandId": skuExt.BrandID, + "skuName": skuName, + "images": []string{skuExt.Img}, + jdapi.KeyFixedStatus: jxStatus2jdStatus(skuExt.Status), + } + if globals.EnableStoreWrite { + err = api.JdAPI.UpdateSpu(utils.Int2Str(skuExt.ID), params) + } + } + if err == nil { + if skuExt.JdSyncStatus != 0 { + skuExt.JdSyncStatus = 0 + _, err = dao.UpdateEntity(db, &skuExt.SkuName, updateFields...) + } + } + } + return vendorSkuID, err +} + func jdStatus2jxStatus(jdStatus int) (jxStatus int) { switch jdStatus { case 1: