diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index 7f1d99a0c..dca31d28e 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -4,9 +4,11 @@ import ( "fmt" "math" "math/rand" + "regexp" "strings" "sync" "time" + "unicode/utf8" "git.rosy.net.cn/baseapi/platformapi/autonavi" "git.rosy.net.cn/baseapi/utils" @@ -17,6 +19,7 @@ import ( var ( routinePool *routinepool.Pool + skuNamePat *regexp.Regexp ) type SyncMapWithTimeout struct { @@ -27,6 +30,10 @@ type SyncMapWithTimeout struct { func init() { rand.Seed(time.Now().Unix()) routinePool = routinepool.New(1000, 1000) + + // Go regex does not support lookarounds. + // https://stackoverflow.com/questions/38933898/error-parsing-regexp-invalid-or-unsupported-perl-syntax + skuNamePat = regexp.MustCompile(`([\((\[【][^\((\[【\))\]】]*[\))\]】])?(.*?)([((].*[))])?\s*约?([1-9][\d\.]*)(g|G|kg|kG|Kg|KG|l|L|ml|mL|Ml|ML|克)\s*([((].*[))])?\s*(?:\/|/|)\s*([^\s()()]{0,2})\s*([((].*[))])?$`) } func (m *SyncMapWithTimeout) StoreWithTimeout(key, value interface{}, timeout time.Duration) { @@ -191,3 +198,73 @@ func Errs2Str(sep string, errs ...error) (retVal string) { } return retVal } + +func IntWeight2Float(weight int) float32 { + return float32(weight) / 1000.0 +} + +func FloatWeight2Int(weight float32) int { + return int(math.Round(float64(weight * 1000))) +} + +func ComposeSkuName(prefix, name, comment, unit string, spec_quality float32, spec_unit string, maxLen int) (skuName string) { + if prefix != "" { + skuName = "[" + prefix + "]" + } + skuName += name + if unit == "份" { + skuName += "约" + } + if math.Round(float64(spec_quality)) == float64(spec_quality) || (spec_unit != "L" && spec_unit != "kg") { + skuName += fmt.Sprintf("%d", int(spec_quality)) + } else { + skuName += fmt.Sprintf("%.2f", spec_quality) + } + skuName += spec_unit + skuName += "/" + unit + if maxLen > 0 { + skuName = skuName[:maxLen] + } + return skuName +} + +// 1:商品特殊前缀 +// 2:商品名字 +// 3:商品说明1(可缺失) +// 4:质量数字 +// 5:质量单位 +// 6:商品说明2(可缺失) +// 7:商品单位 +// 8:商品说明3(可缺失) +func SplitSkuName(skuName string) (prefix, name, comment, specUnit, unit string, specQuality float32) { + searchResult := skuNamePat.FindStringSubmatch(skuName) + if searchResult != nil { + if searchResult[3] != "" { + comment = searchResult[3] + } else if searchResult[6] != "" { + comment = searchResult[6] + } else if searchResult[8] != "" { + comment = searchResult[8] + } + comment = strings.Trim(comment, " ()()") + name = strings.Trim(searchResult[2], " ") + if comment != "" { + if utf8.RuneCountInString(comment) <= 5 { + name += "-" + comment + comment = "" + } + } + specUnit = strings.ToLower(strings.Replace(searchResult[5], "克", "g", -1)) + if specUnit == "l" { + specUnit = "L" + } + if searchResult[7] == "" { + unit = "份" + } else { + unit = searchResult[7] + } + specQuality = float32(utils.Str2Float64(searchResult[4])) + prefix = strings.Trim(searchResult[1], " []()【】()") + } + return prefix, name, comment, specUnit, unit, specQuality +} diff --git a/business/jxutils/jxutils_test.go b/business/jxutils/jxutils_test.go index b2a3fc2a0..64450af30 100644 --- a/business/jxutils/jxutils_test.go +++ b/business/jxutils/jxutils_test.go @@ -32,22 +32,37 @@ func TestMapValue2Scope(t *testing.T) { func TestGetNameAndUnitFromSkuName(t *testing.T) { name, unit := GetNameAndUnitFromSkuName("【满59免运】蒜苔肉丝约400g/个(蒜苔约250g 肉丝约150g/份)") if name != "【满59免运】蒜苔肉丝约400g" || unit != "个" { - t.Fatalf("SplitSkuName wrong, name:%s, unit:%s", name, unit) + t.Fatalf("TestGetNameAndUnitFromSkuName wrong, name:%s, unit:%s", name, unit) } name, unit = GetNameAndUnitFromSkuName("【满59免运】蒜苔肉丝约400g/g份(蒜苔约250g 肉丝约150g/份)") if name != "【满59免运】蒜苔肉丝约400g" || unit != "g" { - t.Fatalf("SplitSkuName wrong, name:%s, unit:%s", name, unit) + t.Fatalf("TestGetNameAndUnitFromSkuName wrong, name:%s, unit:%s", name, unit) } name, unit = GetNameAndUnitFromSkuName("【满59免运】蒜苔肉丝约400g/个") if name != "【满59免运】蒜苔肉丝约400g" || unit != "个" { - t.Fatalf("SplitSkuName wrong, name:%s, unit:%s", name, unit) + t.Fatalf("TestGetNameAndUnitFromSkuName wrong, name:%s, unit:%s", name, unit) } name, unit = GetNameAndUnitFromSkuName("【满59免运】蒜苔肉丝约400g/") if name != "【满59免运】蒜苔肉丝约400g" || unit != "份" { - t.Fatalf("SplitSkuName wrong, name:%s, unit:%s", name, unit) + t.Fatalf("TestGetNameAndUnitFromSkuName wrong, name:%s, unit:%s", name, unit) } name, unit = GetNameAndUnitFromSkuName("【满59免运】蒜苔肉丝约400g") if name != "【满59免运】蒜苔肉丝约400g" || unit != "份" { + t.Fatalf("TestGetNameAndUnitFromSkuName wrong, name:%s, unit:%s", name, unit) + } +} + +func TestSplitSkuName(t *testing.T) { + prefix, name, comment, specUnit, unit, specQuality := SplitSkuName("[好吃]黄骨鱼约600G/非份(黄辣丁、昂刺鱼)") + if prefix != "好吃" || name != "黄骨鱼" || comment != "黄辣丁、昂刺鱼" || specUnit != "g" || unit != "非份" || specQuality != 600 { + t.Fatalf("SplitSkuName wrong, name:%s, unit:%s", name, unit) + } + prefix, name, comment, specUnit, unit, specQuality = SplitSkuName("【满59免运】蒜苔肉丝约400g") + if prefix != "满59免运" || name != "蒜苔肉丝" || comment != "" || specUnit != "g" || unit != "份" || specQuality != 400 { + t.Fatalf("SplitSkuName wrong, name:%s, unit:%s", name, unit) + } + prefix, name, comment, specUnit, unit, specQuality = SplitSkuName("【满59免运】蒜苔肉丝约400.1ML/") + if prefix != "满59免运" || name != "蒜苔肉丝" || comment != "" || specUnit != "ml" || unit != "份" || specQuality != 400.1 { t.Fatalf("SplitSkuName wrong, name:%s, unit:%s", name, unit) } } diff --git a/business/partner/purchase/jd/store.go b/business/partner/purchase/jd/store.go index 05a9fd753..6062fe052 100644 --- a/business/partner/purchase/jd/store.go +++ b/business/partner/purchase/jd/store.go @@ -6,29 +6,7 @@ import ( "git.rosy.net.cn/jx-callback/globals/api" ) -func (p *PurchaseHandler) GetAllStoreIDsFromRemote() ([]string, error) { - result, err := api.JdAPI.GetStationsByVenderId() - return result, err -} - -func (p *PurchaseHandler) GetAllStoresFromRemote() ([]*model.Store, error) { - ids, err := p.GetAllStoreIDsFromRemote() - if err == nil { - retVal := make([]*model.Store, len(ids)) - for index, id := range ids { - store, err2 := p.GetStoreFromRemote(id) - if err2 == nil { - retVal[index] = store - } else { - return nil, err2 - } - } - return retVal, nil - } - return nil, err -} - -func (p *PurchaseHandler) GetStoreFromRemote(vendorStoreID string) (*model.Store, error) { +func (p *PurchaseHandler) ReadStore(vendorStoreID string) (*model.Store, error) { result, err := api.JdAPI.GetStoreInfoByStationNo(vendorStoreID) if err == nil { retVal := &model.Store{ @@ -46,7 +24,7 @@ func (p *PurchaseHandler) GetStoreFromRemote(vendorStoreID string) (*model.Store return nil, err } -func (p *PurchaseHandler) SaveStore2Remote(vendorStoreID string, store *model.Store) error { +func (p *PurchaseHandler) UpdateStore(vendorStoreID string, store *model.Store, userName string) error { params := map[string]interface{}{ "outSystemId": utils.Int2Str(int(store.ID)), "stationName": store.Name, @@ -56,12 +34,60 @@ func (p *PurchaseHandler) SaveStore2Remote(vendorStoreID string, store *model.St "serviceTimeStart2": JxOperationTime2JdOperationTime(store.OpenTime2), "serviceTimeEnd2": JxOperationTime2JdOperationTime(store.CloseTime2), } - params["yn"], params["closeStatus"] = JxStoreStatus2JdStatus(store.Status) - _, err := api.JdAPI.UpdateStoreInfo4Open(vendorStoreID, "", params) - return err + _, params["closeStatus"] = JxStoreStatus2JdStatus(store.Status) + // globals.SugarLogger.Debug(utils.Format4Output(params, false)) + return api.JdAPI.UpdateStoreInfo4Open(vendorStoreID, userName, params) } +// 没用 +// func (p *PurchaseHandler) DeleteStore(vendorStoreID, userName string) error { +// params := map[string]interface{}{ +// "yn": 1, +// } +// _, err := api.JdAPI.UpdateStoreInfo4Open(vendorStoreID, userName, params) +// return err +// } + func (p *PurchaseHandler) EnableAutoAcceptOrder(vendorStoreID string, isEnabled bool) error { _, err := api.JdAPI.UpdateStoreConfig4Open(vendorStoreID, isEnabled) return err } + +func (p *PurchaseHandler) OpenStore(vendorStoreID string, userName string) error { + params := map[string]interface{}{ + "closeStatus": 0, + "storeNotice": "", + } + return api.JdAPI.UpdateStoreInfo4Open(vendorStoreID, userName, params) +} + +func (p *PurchaseHandler) CloseStore(vendorStoreID, closeNotice, userName string) error { + params := map[string]interface{}{ + "closeStatus": 1, + "storeNotice": closeNotice, + } + return api.JdAPI.UpdateStoreInfo4Open(vendorStoreID, userName, params) +} + +/////////////////////// +func (p *PurchaseHandler) GetAllStoreIDsFromRemote() ([]string, error) { + result, err := api.JdAPI.GetStationsByVenderId() + return result, err +} + +func (p *PurchaseHandler) GetAllStoresFromRemote() ([]*model.Store, error) { + ids, err := p.GetAllStoreIDsFromRemote() + if err == nil { + retVal := make([]*model.Store, len(ids)) + for index, id := range ids { + store, err2 := p.ReadStore(id) + if err2 == nil { + retVal[index] = store + } else { + return nil, err2 + } + } + return retVal, nil + } + return nil, err +}