Files
jx-callback/business/partner/purchase/tao_vegetable/store_sku2.go
邹宗楠 b15175006b 1
2025-02-20 17:08:28 +08:00

932 lines
38 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package tao_vegetable
import (
"bytes"
"fmt"
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
"git.rosy.net.cn/baseapi/platformapi/tao_vegetable"
request1475 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability1475/request"
domain585 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability585/domain"
request585 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability585/request"
"git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability587/domain"
"git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability587/request"
domain589 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability589/domain"
request589 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability589/request"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/business/partner/putils"
"git.rosy.net.cn/jx-callback/globals"
beego "github.com/astaxie/beego/server/web"
"image/jpeg"
"io/ioutil"
"net/http"
"regexp"
"strings"
"time"
)
const (
updateTypeStock = iota
updateTypeStatus
updateTypePrice
)
var (
sensitiveWordRegexp = regexp.MustCompile(`包含敏感词:(\[.*\])`)
)
func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) {
switch funcID {
case partner.FuncUpdateStoreSkusStock, partner.FuncUpdateStoreSkusStatus, partner.FuncUpdateStoreSkusPrice:
batchSize = 20
case partner.FuncDeleteStoreSkus:
batchSize = 20
case partner.FuncCreateStoreSkus:
batchSize = 20 // 可考虑用批量操作
case partner.FuncUpdateStoreSkus:
batchSize = 20 // mtwmapi.MaxStoreSkuBatchSize
case partner.FuncGetStoreSkusFullInfo:
batchSize = 20
case partner.FuncCreateActs:
batchSize = 20
case partner.FuncCancelActs:
batchSize = 20
}
return batchSize
}
func getStoreVendorOrgCode(storeID int) (vendorOrgCode string) {
if storeMap, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDTaoVegetable, ""); storeMap != nil {
return storeMap.VendorOrgCode
}
return vendorOrgCode
}
func getStoreVendorOrgCodeByVendorStoreID(vendorStoreID string) (vendorOrgCode string) {
if storeMap, _ := dao.GetStoreDetailForDD(dao.GetDB(), 0, model.VendorIDTaoVegetable, vendorStoreID, ""); storeMap != nil {
return storeMap.VendorOrgCode
}
return vendorOrgCode
}
// 门店分类
func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) {
remoteCats, err := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).GetStoreAllCategory()
if err == nil {
cats = convertVendorCatList(remoteCats)
}
return cats, err
}
func convertVendorCatList(remoteCats []*tao_vegetable.CategoryInfo) (cats []*partner.BareCategoryInfo) {
for _, rCat := range remoteCats {
cat := &partner.BareCategoryInfo{
VendorCatID: rCat.Code,
Name: rCat.Name,
Seq: rCat.Status,
Children: convertVendorCatList(rCat.ChildCategorys),
}
if len(rCat.ChildCategorys) == 0 {
cat.Level = 1
} else {
cat.Level = 2
}
if cat.VendorCatID == "" {
cat.VendorCatID = rCat.Name
}
cats = append(cats, cat)
}
return cats
}
func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) {
return tao_vegetable.IsErrCategoryExist(err)
}
func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) {
return tao_vegetable.IsErrCategoryNotExist(err)
}
func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
api := getAPI(storeCat.VendorOrgCode, storeID, vendorStoreID)
// 修改分类
if model.IsSyncStatusUpdate(storeCat.CatSyncStatus) {
err := api.UpdateStoreCategoryInfo(&request.AlibabaWdkSkuCategoryUpdateRequest{Param: &domain.AlibabaWdkSkuCategoryUpdateCategoryDo{
Code: utils.String2Pointer(utils.Int2Str(storeCat.StoreCatID)),
Name: &storeCat.StoreCatName,
}})
if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 && p.IsErrCategoryNotExist(err) && storeCat.StoreCatName != "" { // 修改分类名,但分类不存在
storeCat.CatSyncStatus |= model.SyncFlagNewMask
createCategory := &request.AlibabaWdkSkuCategoryAddRequest{Param: &domain.AlibabaWdkSkuCategoryAddCategoryDo{
Code: utils.String2Pointer(utils.Int2Str(storeCat.ID)),
Name: &storeCat.Name,
Leaf: utils.Bool2Point(false),
}}
if storeCat.ParentID != model.NO {
createCategory.Param.ParentCode = utils.String2Pointer(utils.Int2Str(storeCat.ParentID))
createCategory.Param.Leaf = utils.Bool2Point(true)
}
skuCode, err := api.AddStoreCategoryInfo(createCategory)
if err != nil {
return err
}
storeCat.VendorCatID = skuCode
}
}
// 创建分类
if model.IsSyncStatusNeedCreate(storeCat.CatSyncStatus) {
createCategoryParam := &request.AlibabaWdkSkuCategoryAddRequest{Param: &domain.AlibabaWdkSkuCategoryAddCategoryDo{
Code: utils.String2Pointer(utils.Int2Str(storeCat.ID)),
Name: &storeCat.Name,
Leaf: utils.Bool2Point(false),
}}
if storeCat.ParentID != model.NO {
createCategoryParam.Param.ParentCode = utils.String2Pointer(utils.Int2Str(storeCat.ParentID))
createCategoryParam.Param.Leaf = utils.Bool2Point(true)
}
skuCode, err := api.AddStoreCategoryInfo(createCategoryParam)
globals.SugarLogger.Debugf("IsSyncStatusNeedCreate AddStoreCategoryInfo : skucode : %s ,%v", utils.Format4Output(skuCode, false), err)
if err != nil {
return err
}
storeCat.VendorCatID = skuCode
}
return err
}
func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
return p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat)
}
func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) {
// 668594 正式服印象汇 668469 测试服芬姐(淘宝所有门店公用分类) , 模板门店才能删除
if storeID != 668594 && storeID != 668469 {
return nil
}
api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID)
// 只能删除叶子结点
// 看看这个level是不是代表子节点,感觉不是
category, err := api.GetStoreCategoryInfo(vendorCatID)
if err != nil {
return err
}
// 删除的是父节点,删除父节点下的所有子节点在删除父节点
if len(category.ChildCategorys) != 0 {
for _, v := range category.ChildCategorys {
err2 := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).DeleteStoreCategoryInfo(&request.AlibabaWdkSkuCategoryDeleteRequest{Param: &domain.AlibabaWdkSkuCategoryDeleteCategoryDo{Code: &v.Code}})
if err2 != nil && strings.Contains(err2.Error(), "类目已有子类目,不能被删除") {
p.DeleteStoreCategory(ctx, storeID, vendorStoreID, v.Code, 0)
}
}
}
return getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).DeleteStoreCategoryInfo(&request.AlibabaWdkSkuCategoryDeleteRequest{Param: &domain.AlibabaWdkSkuCategoryDeleteCategoryDo{Code: &vendorCatID}})
}
func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) {
return false
}
func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
return mtwmapi.IsErrSkuNotExist(err)
}
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false)
return failedList, err
}
func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true)
return failedList, err
}
// 对于多门店平台来说storeSkuList中只有SkuID与VendorSkuID有意义
func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isCreate bool) (failedList []*partner.StoreSkuInfoWithErr, err error) {
var syncType string
if isCreate {
syncType = "创建商品"
} else {
syncType = "更新商品"
}
api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID)
if isCreate {
failedList, err = createTaoVegetable(ctx, api, storeSkuList, vendorStoreID, storeID, syncType)
} else {
failedList, err = UpdateTaoVegetable(api, storeSkuList, vendorStoreID, storeID, syncType)
}
return failedList, err
}
// UpdateTaoVegetable 修改淘鲜达商品
func UpdateTaoVegetable(api *tao_vegetable.API, storeSkuList []*dao.StoreSkuSyncInfo, vendorStoreID string, storeID int, syncType string) (failedList []*partner.StoreSkuInfoWithErr, err error) {
param := &request585.AlibabaWdkSkuUpdateRequest{}
updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0)
for _, v := range storeSkuList {
price := utils.String2Pointer(utils.Float64ToStr(float64(v.VendorPrice) / float64(100)))
updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{
OuCode: utils.String2Pointer(vendorStoreID),
SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)),
SkuName: utils.String2Pointer(checkNameLength(v.SkuName, v.Weight, v.Unit)),
SkuPrice: price, // 优先使用skuPrice 靠后SalePrice
CategoryCode: utils.String2Pointer(utils.Int2Str(v.CategoryID)),
MerchantCatCode: utils.String2Pointer(v.VendorCatID), // 优先使用 靠后 category_code
CleanSkuMemberPrice: utils.Int64ToPointer(model.YES),
SubTitle: utils.String2Pointer("小时达"),
}
if v.MinOrderCount <= model.YES {
updateSku.PurchaseQuantity = utils.Int64ToPointer(model.YES) // 起购单位
} else {
updateSku.PurchaseQuantity = utils.Int64ToPointer(int64(v.MinOrderCount)) // 起购单位
}
// 修改暂时不修改图片,保持效率
updateSku.SkuPicUrls = uploadImg(api, v.SkuID, model.VendorIDTaoVegetable, []string{v.Img, v.Img2, v.Img3, v.Img4, v.Img5, v.DescImg})
if updateSku.SkuPicUrls == nil {
continue
}
updateSkuList = append(updateSkuList, updateSku)
}
param.ParamList = &updateSkuList
result, err := api.UpdateStoreSku(param)
if err != nil {
globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error())
}
// 记录失败的同步数据
createFailedList, _ := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], syncType)
failedList = append(failedList, createFailedList...)
return failedList, err
}
// createTaoVegetable 创建淘鲜达商品
func createTaoVegetable(ctx *jxcontext.Context, api *tao_vegetable.API, storeSkuList []*dao.StoreSkuSyncInfo, vendorStoreID string, storeID int, syncType string) (failedList []*partner.StoreSkuInfoWithErr, err error) {
createPram := &request585.AlibabaWdkSkuAddRequest{}
param := make([]domain585.AlibabaWdkSkuAddSkuDo, 0, 0)
vendorSkuIdMap := make(map[string]string, 0)
for _, storeSku := range storeSkuList {
price := utils.String2Pointer(utils.Float64ToStr(utils.Int64ToFloat64(storeSku.VendorPrice) / utils.Int64ToFloat64(100)))
sku := domain585.AlibabaWdkSkuAddSkuDo{
Barcodes: utils.String2Pointer(utils.Int2Str(storeSku.SkuID)),
BrandName: utils.String2Pointer(tao_vegetable.CreateSkuBrandName),
OuCode: utils.String2Pointer(vendorStoreID),
//InventoryUnit: utils.String2Pointer(storeSku.Unit),
InventoryUnit: utils.String2Pointer("份"),
ProducerPlace: utils.String2Pointer(tao_vegetable.CreateSkuProducerPlace),
SkuCode: utils.String2Pointer(utils.Int2Str(storeSku.SkuID)),
StorageType: utils.Int64ToPointer(tao_vegetable.CreateSkuStorageType),
SuggestedPrice: price,
Weight: utils.String2Pointer(utils.Int2Str(storeSku.Weight)),
ShelfLife: utils.Int64ToPointer(tao_vegetable.CreateShelfLife),
NetContent: utils.String2Pointer(utils.Int2Str(storeSku.Weight)),
SaleUnit: utils.String2Pointer("份"),
LifeStatus: utils.String2Pointer(tao_vegetable.CreateSkuLeafStatus),
SaleSpec: utils.String2Pointer(fmt.Sprintf("%d %s*1%s", storeSku.Weight, "g", storeSku.Unit)),
StepQuantity: utils.Int64ToPointer(model.YES), // 每次购买至少增加一个购买单位
OnlineSaleFlag: utils.Int64ToPointer(tao_vegetable.CreateOnlineSaleFlag), // 门店控制是否可见
SubTitle: utils.String2Pointer("小时达"),
SubTitle1: utils.String2Pointer("一小时速达"),
//DeliveryUnit: utils.String2Pointer(storeSku.Unit),
DeliveryUnit: utils.String2Pointer("份"),
DeliverySpec: utils.String2Pointer(utils.Int2Str(model.YES)),
Storage: utils.String2Pointer(tao_vegetable.CreateStorage),
PickFloatRate: utils.String2Pointer(utils.Int2Str(model.NO)), // ? 0
ForbidReceiveDays: utils.Int64ToPointer(tao_vegetable.CreateShelfLife), // ? 7
ForbidSalesDays: utils.Int64ToPointer(model.NO), // ? 0
OverloadRate: utils.String2Pointer(utils.Int2Str(model.NO)), // ? 0
WarnDays: utils.Int64ToPointer(model.NO), // ? 0
FixedFlag: utils.Int64ToPointer(model.NO), // ? 0
PurchaseSpec: utils.String2Pointer(utils.Int2Str(model.YES)), // ? 1
PurchaseUnit: utils.String2Pointer("份"), // ? 同上
LabelStyleType: utils.String2Pointer(tao_vegetable.CreateLabelStyleType), // 库存单位
ItemTypeNew: utils.Int64ToPointer(tao_vegetable.CreateItemTypeNewVegetable),
SkuPrice: price, // 优先使用skuPrice 靠后SalePrice
Period: utils.Int64ToPointer(tao_vegetable.CreateShelfLife), // 优先使用period 靠后shelf_life
FragileFlag: utils.Int64ToPointer(model.YES),
DeliveryStorage: utils.String2Pointer(tao_vegetable.CreateItemDeliveryStorage),
TemporaryFlag: utils.Int64ToPointer(model.NO),
IsOnline: utils.Int64ToPointer(tao_vegetable.CreateIsOnline),
MerchantCatCode: utils.String2Pointer(storeSku.VendorCatID), // 优先使用 靠后 category_code
RichText: utils.String2Pointer(storeSku.Name),
AllowAppSale: utils.Int64ToPointer(tao_vegetable.IsAllowAppSale),
}
// 赠品专区
if storeSku.VendorCatID == "175" {
sku.MerchantCatCode = utils.String2Pointer("1751")
}
sku.SkuPicUrls = uploadImg(api, storeSku.SkuID, model.VendorIDTaoVegetable, []string{storeSku.Img, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5, storeSku.DescImg})
if sku.SkuPicUrls == nil {
continue
}
sku.SkuName = utils.String2Pointer(checkNameLength(storeSku.Name, storeSku.Weight, storeSku.Unit))
if storeSku.MinOrderCount <= model.YES {
sku.PurchaseQuantity = utils.Int64ToPointer(model.YES) // 起购单位
} else {
sku.PurchaseQuantity = utils.Int64ToPointer(int64(storeSku.MinOrderCount)) // 起购单位
}
sku.WeightFlag = utils.Int64ToPointer(tao_vegetable.CreateSkuWeightFlagNo)
sku.AvgWeight = utils.String2Pointer("1") // (重量)
sku.PreMinusWeight = utils.String2Pointer("1") // 每个购买单位重量,预扣重量
sku.SkuSuppliers = &[]domain585.AlibabaWdkSkuAddSkuSupplierDo{
domain585.AlibabaWdkSkuAddSkuSupplierDo{
ReturnFlag: utils.Int64ToPointer(model.NO),
Minimum: utils.String2Pointer(utils.Int2Str(model.YES)),
},
}
sku.ChannelProps = &[]domain585.AlibabaWdkSkuAddChannelProp{
domain585.AlibabaWdkSkuAddChannelProp{
ChannelType: utils.String2Pointer(tao_vegetable.CreateChannelType),
Props: &[]domain585.AlibabaWdkSkuAddPropField{
domain585.AlibabaWdkSkuAddPropField{
Value: utils.String2Pointer(utils.Int2Str(model.YES)),
Key: utils.String2Pointer(tao_vegetable.CreateChannelTypeKey),
},
},
},
}
param = append(param, sku)
}
createPram.ParamList = &param
result, err := api.AddStoreSku(createPram)
if err != nil {
globals.SugarLogger.Debugf("创建淘鲜达商品异常:%s", err.Error())
}
// 记录失败的同步数据
failedList2, vendorSkuIdMap2 := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], syncType)
failedList = append(failedList, failedList2...)
for k, v := range vendorSkuIdMap2 {
vendorSkuIdMap[k] = v
}
var successSku = make(map[int]int, len(vendorSkuIdMap))
for _, v := range storeSkuList {
if k, ok := vendorSkuIdMap[utils.Int2Str(v.SkuID)]; ok {
v.VendorSkuID = k
if beego.BConfig.RunMode != model.ServerTypePet && v.Stock == model.NO {
successSku[v.SkuID] = 9999
} else {
successSku[v.SkuID] = v.Stock
}
} else {
v.VendorSkuID = "0"
v.SkuSyncStatus = 59
}
}
failedListStock := updateStoreSkusStockByCreate(ctx, api, storeID, vendorStoreID, successSku)
failedList = append(failedList, failedListStock...)
return failedList, nil
}
func checkNameLength(name string, weight int, uint string) string {
lastName := ""
if !strings.Contains(name, uint) {
name = fmt.Sprintf("%s %d/%s", name, weight, uint)
}
if strings.Contains(name, "其它") {
name = strings.ReplaceAll(name, "其它", "")
}
if strings.Contains(name, "其她") {
name = strings.ReplaceAll(name, "其她", "")
}
if strings.Contains(name, "其他") {
name = strings.ReplaceAll(name, "其他", "")
}
if len(name) <= tao_vegetable.NameMaxLength {
return name
}
lastName = name
if strings.Contains(name, "(") {
startIndex := strings.Index(name, "(")
endIndex := strings.Index(name, ")")
lastName = name[0:startIndex] + name[endIndex+1:]
if len(lastName) <= tao_vegetable.NameMaxLength {
return lastName
}
}
if strings.Contains(lastName, "") {
startIndex := strings.Index(lastName, "")
endIndex := strings.Index(lastName, "")
lastName = lastName[0:startIndex] + " " + lastName[endIndex+3:]
if len(lastName) <= tao_vegetable.NameMaxLength {
return lastName
}
}
if strings.Contains(lastName, "[") {
startIndex := strings.Index(lastName, "[")
endIndex := strings.Index(lastName, "]")
lastName = lastName[0:startIndex] + lastName[endIndex+1:]
if len(lastName) <= tao_vegetable.NameMaxLength {
return lastName
}
}
if strings.Contains(lastName, "【") {
startIndex := strings.Index(lastName, "【")
endIndex := strings.Index(lastName, "】")
lastName = lastName[0:startIndex] + " " + lastName[endIndex+3:]
if len(lastName) <= tao_vegetable.NameMaxLength {
return lastName
}
}
return lastName[0:60]
}
// 图片压缩,大于3M
func decodeImg(data []byte) []byte {
if float64(len(data))/float64(1024)/float64(1024) > float64(3) {
jpgimg, err := jpeg.Decode(strings.NewReader(string(data))) // 文件解码成图像对象
if err != nil {
return nil
}
var buf bytes.Buffer
err = jpeg.Encode(&buf, jpgimg, &jpeg.Options{Quality: 30})
if err != nil {
return nil
}
return buf.Bytes()
}
return data
}
func uploadImg(api *tao_vegetable.API, skuId, vendorId int, imgs []string) *string {
vendorImg, _ := dao.GetVendorImg(skuId, vendorId)
result := make([]string, 0, 0)
taoImgs := &model.TaoSkuImg{}
isCreate := false
if vendorImg == nil || (vendorImg.Img == "" && vendorImg.Img2 == "" && vendorImg.Img3 == "" && vendorImg.Img4 == "" && vendorImg.Img5 == "" && vendorImg.DescImg == "") {
isCreate = true
for i := 0; i < len(imgs); i++ {
if imgs[i] == "" {
continue
}
inputTitle := strings.LastIndex(imgs[i], "/")
title := strings.LastIndex(imgs[i], ".")
resp, err := http.Get(imgs[i])
if err != nil {
continue
}
body, _ := ioutil.ReadAll(resp.Body)
// 图片失效
if strings.Contains(string(body), "Document not found") || len(body) == 0 {
continue
}
// 检查图片大小
body = decodeImg(body)
newImg, _ := api.UploadImg(&request1475.AlibabaWdkPictureUploadRequest{
PictureCategoryId: utils.Int64ToPointer(0),
Img: &body,
ImgInputTitle: utils.String2Pointer(imgs[i][inputTitle:]),
Title: utils.String2Pointer(imgs[i][inputTitle:title]),
})
if newImg != "" {
result = append(result, newImg)
switch i {
case 0:
taoImgs.Img = newImg
case 1:
taoImgs.Img2 = newImg
case 2:
taoImgs.Img3 = newImg
case 3:
taoImgs.Img4 = newImg
case 4:
taoImgs.Img5 = newImg
case 5:
taoImgs.DescImg = newImg
}
}
}
} else {
if vendorImg.Img != "" {
result = append(result, vendorImg.Img)
}
if vendorImg.Img2 != "" {
result = append(result, vendorImg.Img2)
}
if vendorImg.Img3 != "" {
result = append(result, vendorImg.Img3)
}
if vendorImg.Img4 != "" {
result = append(result, vendorImg.Img4)
}
if vendorImg.Img5 != "" {
result = append(result, vendorImg.Img5)
}
if vendorImg.DescImg != "" {
result = append(result, vendorImg.DescImg)
}
}
if isCreate {
taoImgs.SkuID = skuId
taoImgs.VendorID = vendorId
dao.CreateEntity(dao.GetDB(), taoImgs)
}
// 商品图片最多五张
if len(result) > 5 {
return utils.String2Pointer(strings.Join(result[1:], ","))
}
return utils.String2Pointer(strings.Join(result, ","))
}
// DeleteStoreSkus 暂无删除API,使用下架接口
func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
param := &request585.AlibabaWdkSkuUpdateRequest{}
updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0)
api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID)
for _, v := range storeSkuList {
updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{
OuCode: utils.String2Pointer(vendorStoreID),
SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)),
OnlineSaleFlag: utils.Int64ToPointer(tao_vegetable.CreateOfflineSaleFlag),
}
updateSkuList = append(updateSkuList, updateSku)
}
param.ParamList = &updateSkuList
result, err := api.UpdateStoreSku(param)
if err != nil {
globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error())
}
// 记录失败的同步数据
createFailedList, _ := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "删除商品(暂无接口,下架处理)")
failedList = append(failedList, createFailedList...)
return failedList, err
}
// UpdateStoreSkusStatus 批量更新商品上下架状态
func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) {
param := &request585.AlibabaWdkSkuUpdateRequest{}
updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0)
api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID)
onlineStatus := skuStatusJX2Tao(status)
for _, v := range storeSkuList {
updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{
OuCode: utils.String2Pointer(vendorStoreID),
SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)),
OnlineSaleFlag: utils.Int64ToPointer(onlineStatus),
SubTitle: utils.String2Pointer("小时达"),
AllowAppSale: utils.Int64ToPointer(onlineStatus),
//CleanSkuMemberPrice: utils.Int64ToPointer(model.YES),
}
updateSkuList = append(updateSkuList, updateSku)
}
param.ParamList = &updateSkuList
result, err := api.UpdateStoreSku(param)
if err != nil {
globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error())
}
// 记录失败的同步数据
createFailedList, _ := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "批量更新商品上下架")
failedList = append(failedList, createFailedList...)
return failedList, err
}
func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
param := &request585.AlibabaWdkSkuUpdateRequest{}
updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0)
api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID)
for _, v := range storeSkuList {
price := utils.String2Pointer(fmt.Sprintf("%.2f", float64(v.VendorPrice)/float64(100)))
updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{
OuCode: utils.String2Pointer(vendorStoreID),
SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)),
SkuPrice: price,
CleanSkuMemberPrice: utils.Int64ToPointer(model.YES),
SubTitle: utils.String2Pointer("小时达"),
}
// 临时更新上传图片错误的,或图片上传失败的商品
updateSku.SkuPicUrls = uploadImg(api, v.SkuID, model.VendorIDTaoVegetable, nil)
updateSkuList = append(updateSkuList, updateSku)
}
param.ParamList = &updateSkuList
result, err := api.UpdateStoreSku(param)
if err != nil {
globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error())
}
// 记录失败的同步数据
createFailedList, _ := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "修改商品价格")
failedList = append(failedList, createFailedList...)
return failedList, err
}
// updateStoreSkusStockByCreate 创建时更新库存数量
func updateStoreSkusStockByCreate(ctx *jxcontext.Context, api *tao_vegetable.API, storeID int, vendorStoreID string, storeSkuList map[int]int) (failedList []*partner.StoreSkuInfoWithErr) {
param := request589.AlibabaWdkStockPublishRequest{}
batchStockPublishDto := &domain589.AlibabaWdkStockPublishBatchStockPublishDto{
UpdateType: utils.Int64ToPointer(tao_vegetable.UpdateTypeStoke),
BillNo: utils.String2Pointer(utils.Int64ToStr(time.Now().UnixNano())),
BillType: utils.Int64ToPointer(tao_vegetable.UpdateTypeStokeBillType),
PublishSource: utils.String2Pointer(vendorStoreID),
ShopCode: utils.String2Pointer(vendorStoreID),
Operator: utils.String2Pointer(ctx.GetUserName()),
StockPublishDtos: nil,
}
stockPublishDtos := make([]domain589.AlibabaWdkStockPublishStockPublishDto, 0, 0)
for skuId, stock := range storeSkuList {
stockPublishDtos = append(stockPublishDtos, domain589.AlibabaWdkStockPublishStockPublishDto{
SkuCode: utils.String2Pointer(utils.Int2Str(skuId)),
Quantity: utils.String2Pointer(utils.Int2Str(stock)),
OrderNo: utils.String2Pointer(fmt.Sprintf("%s_%d_%d", vendorStoreID, time.Now().UnixNano(), 84671)),
OrderType: utils.String2Pointer("10006800"), // 这个不太确定
})
//if (index+model.YES)%tao_vegetable.MAXHandleCount == model.NO || (index+1) == len(storeSkuList) {
// batchStockPublishDto.StockPublishDtos = &stockPublishDtos
// param.BatchStockPublishDto = batchStockPublishDto
// if err := api.StoreSkuStock(&param); err != nil {
// failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "更新库存错误")...)
// }
// stockPublishDtos = make([]domain589.AlibabaWdkStockPublishStockPublishDto, 0, 0)
// param.BatchStockPublishDto = nil
//}
}
batchStockPublishDto.StockPublishDtos = &stockPublishDtos
param.BatchStockPublishDto = batchStockPublishDto
if err := api.StoreSkuStock(&param); err != nil {
globals.SugarLogger.Debugf("Updat stock err := %s", err.Error())
//failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "更新库存错误")...)
}
return failedList
}
// UpdateStoreSkusStock 操作更新库存数量
func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID)
param := request589.AlibabaWdkStockPublishRequest{}
batchStockPublishDto := &domain589.AlibabaWdkStockPublishBatchStockPublishDto{
UpdateType: utils.Int64ToPointer(tao_vegetable.UpdateTypeStoke),
BillNo: utils.String2Pointer(utils.Int64ToStr(time.Now().UnixNano())),
BillType: utils.Int64ToPointer(tao_vegetable.UpdateTypeStokeBillType),
PublishSource: utils.String2Pointer(vendorStoreID),
ShopCode: utils.String2Pointer(vendorStoreID),
Operator: utils.String2Pointer(ctx.GetUserName()),
StockPublishDtos: nil,
}
stockPublishDtos := make([]domain589.AlibabaWdkStockPublishStockPublishDto, 0, 0)
for _, v := range storeSkuList {
stockPublishDtos = append(stockPublishDtos, domain589.AlibabaWdkStockPublishStockPublishDto{
SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)),
Quantity: utils.String2Pointer(utils.Int2Str(v.Stock)),
OrderNo: utils.String2Pointer(fmt.Sprintf("%s_%d_%d", vendorStoreID, time.Now().UnixNano(), 84671)),
OrderType: utils.String2Pointer("10006800"), // 这个不太确定
})
}
batchStockPublishDto.StockPublishDtos = &stockPublishDtos
param.BatchStockPublishDto = batchStockPublishDto
if err = api.StoreSkuStock(&param); err != nil {
failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "更新库存错误")...)
}
return failedList, err
}
func taoSkuStatus2Jx(taoSkuStatus int) (jxSkuStatus int) {
if taoSkuStatus == tao_vegetable.CreateIsOnline {
jxSkuStatus = model.SkuStatusNormal
} else {
jxSkuStatus = model.SkuStatusDontSale
}
return jxSkuStatus
}
// GetStoreSkusFullInfo 获取淘鲜达平台商品,由于参数商品id必填作为参数,storeSkuList不能为空,且skuCode最大长度为20
func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) {
if len(storeSkuList) == model.NO {
return nil, fmt.Errorf("淘鲜达获取门店商品需要参数商品id")
}
var storeSkuMap map[string]*partner.StoreSkuInfo
api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID)
if storeSkuList != nil {
storeSkuMap = putils.StoreSkuList2MapByVendorSkuID(storeSkuList)
}
skuCodeList := make([]string, 0, len(storeSkuList))
for _, v := range storeSkuList {
skuCodeList = append(skuCodeList, utils.Int2Str(v.SkuID))
}
forCount := len(storeSkuList) / tao_vegetable.MAXHandleCount
maxIndex := len(storeSkuList) % tao_vegetable.MAXHandleCount
if maxIndex != model.NO {
forCount += model.YES
}
for i := 1; i <= forCount; i++ {
// todo 待优化获取速度
data := &request585.AlibabaWdkSkuQueryRequest{
Param: &domain585.AlibabaWdkSkuQuerySkuQueryDo{
OuCode: &vendorStoreID,
},
}
if forCount == i {
data.Param.SetSkuCodes(skuCodeList[(i-1)*tao_vegetable.MAXHandleCount : len(skuCodeList)])
} else {
data.Param.SetSkuCodes(skuCodeList[(i-1)*tao_vegetable.MAXHandleCount : i*tao_vegetable.MAXHandleCount])
}
result, err := api.QueryStoreSKu(data)
if err != nil {
return nil, err
}
if storeSkuMap == nil {
skuNameList = append(skuNameList, vendorSkuList2Jx(result)...)
} else {
for _, v := range *result {
if storeSkuMap[*v.Model.SkuCode] != nil {
if skuName := vendorSku2Jx(v.Model); skuName != nil {
skuNameList = append(skuNameList, skuName)
}
}
}
}
}
return skuNameList, err
}
// vendorSku2Jx 淘鲜达商品解析到京西
func vendorSku2Jx(appFood *domain585.AlibabaWdkSkuQuerySkuDo) (skuName *partner.SkuNameInfo) {
if &appFood == nil {
return nil
}
prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(*appFood.SkuName)
weight := int(utils.Str2Int64WithDefault(*appFood.Weight, 0))
if weight <= 0 {
weight = jxutils.FormatSkuWeight(specQuality, specUnit)
}
skuID := int(utils.Str2Int64WithDefault(*appFood.SkuCode, 0))
skuName = &partner.SkuNameInfo{
NameID: int(utils.Str2Int64WithDefault(*appFood.SkuCode, 0)),
VendorNameID: *appFood.ProducerName,
UPC: *appFood.Barcodes,
Prefix: prefix,
Name: name,
Unit: unit,
Status: taoSkuStatus2Jx(int(*appFood.OnlineSaleFlag)),
SkuList: []*partner.SkuInfo{
&partner.SkuInfo{
StoreSkuInfo: partner.StoreSkuInfo{
VendorSkuID: utils.Int2Str(skuID),
SkuID: skuID,
IsSpecialty: 0, // 是否为力荐商品(淘宝没返回)
Stock: partner.UnlimitedStoreSkuStock, // 淘宝没返回
VendorPrice: jxutils.StandardPrice2Int(utils.Str2Float64WithDefault(*appFood.SalePrice, 0) * (utils.Str2Float64WithDefault(*appFood.Weight, 0) / float64(1000))),
Status: taoSkuStatus2Jx(int(*appFood.OnlineSaleFlag)),
},
SkuName: *appFood.SkuName,
Comment: comment,
SpecQuality: float64(specQuality),
SpecUnit: specUnit,
Weight: weight,
},
},
PictureList: utils.Interface2StringList(*appFood.SkuPicUrls),
}
if appFood.CategoryCode != nil {
skuName.VendorCatIDList = []string{}
}
return skuName
}
func vendorSkuList2Jx(appFoodList *[]domain585.AlibabaWdkSkuQueryApiResult) (skuNameList []*partner.SkuNameInfo) {
for _, appFood := range *appFoodList {
if skuName := vendorSku2Jx(appFood.Model); skuName != nil {
skuNameList = append(skuNameList, skuName)
}
}
return skuNameList
}
func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp {
return sensitiveWordRegexp
}
// SelectStoreSkuListByFoodList 淘宝批量返回
func SelectStoreSkuListByFoodList(storeSkuList interface{}, foodList []tao_vegetable.VegetableResultList, storeID int, vendorName, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr, successMap map[string]string) {
foodMap := make(map[string]string, len(foodList))
successMap = make(map[string]string)
if foodList != nil && len(foodList) > 0 {
for _, v := range foodList {
if v.ProductID != "" {
successMap[v.SkuID] = v.ProductID
} else {
foodMap[v.SkuID] = v.ErrMsg
}
}
if storeSkuLists, ok := storeSkuList.([]*partner.StoreSkuInfo); ok {
for _, v := range storeSkuLists {
if foodMap[utils.Int2Str(v.SkuID)] != "" {
foodFailed := &partner.StoreSkuInfoWithErr{
StoreSkuInfo: v,
ErrMsg: foodMap[utils.Int2Str(v.SkuID)],
StoreID: storeID,
VendoreName: vendorName,
SyncType: syncType,
}
selectedStoreSkuList = append(selectedStoreSkuList, foodFailed)
}
}
}
if storeSkuLists, ok := storeSkuList.([]*dao.StoreSkuSyncInfo); ok {
for _, v := range storeSkuLists {
if foodMap[utils.Int2Str(v.SkuID)] != "" {
storeSkuInfo := &partner.StoreSkuInfo{
SkuID: v.SkuID,
VendorSkuID: v.VendorSkuID,
NameID: v.NameID,
VendorNameID: v.VendorNameID,
VendorPrice: v.VendorPrice,
Status: v.Status,
}
foodFailed := &partner.StoreSkuInfoWithErr{
StoreSkuInfo: storeSkuInfo,
ErrMsg: foodMap[utils.Int2Str(v.SkuID)],
StoreID: storeID,
VendoreName: vendorName,
SyncType: syncType,
}
selectedStoreSkuList = append(selectedStoreSkuList, foodFailed)
}
}
}
}
return selectedStoreSkuList, successMap
}
func (p *PurchaseHandler) CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
actStoreSkuList := putils.StoreSku2ActStoreSku(model.SyncFlagNewMask, vendorStoreID, storeSkuList)
failedList, err = createOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, actStoreSkuList)
storeSkuMap := putils.StoreSkuList2MapBySkuID(storeSkuList)
for _, v := range actStoreSkuList {
storeSkuMap[v.SkuID].VendorActID = v.VendorActID
}
if len(failedList) > 0 {
err = nil
}
return failedList, err
}
func (p *PurchaseHandler) CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return cancelOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, putils.StoreSku2ActStoreSku(model.SyncFlagDeletedMask, vendorStoreID, storeSkuList))
}
// UpdateStoreSkusSpecTag 更新限购
func (p *PurchaseHandler) UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) {
var errList = make([]string, 0, 0)
param := &request585.AlibabaWdkSkuUpdateRequest{}
updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0)
api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID)
for _, v := range storeSkuList {
updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{
OuCode: utils.String2Pointer(vendorStoreID),
SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)),
}
if v.IsSpecialty <= model.YES {
updateSku.PurchaseQuantity = utils.Int64ToPointer(model.YES)
} else {
updateSku.PurchaseQuantity = utils.Int64ToPointer(int64(v.IsSpecialty))
}
updateSkuList = append(updateSkuList, updateSku)
}
param.ParamList = &updateSkuList
result, err := api.UpdateStoreSku(param)
if err != nil {
globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error())
}
// 记录失败的同步数据
for _, v := range *result {
if v.ErrMsg != "" {
errList = append(errList, v.ErrMsg)
}
}
return fmt.Errorf("%s", strings.Join(errList, ","))
}
func (p *PurchaseHandler) GetSkuCategoryIdByName(vendorOrgCode, skuName string) (vendorCategoryId string, err error) {
return "", err
}