1
This commit is contained in:
@@ -597,7 +597,7 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
|
||||
}
|
||||
v.JxSkuID = skuBindInfo.SkuID
|
||||
//京东商城的话,门店里可能取不到对应商品
|
||||
if order.VendorID == model.VendorIDJDShop {
|
||||
if order.VendorID == model.VendorIDJDShop || order.VendorID == model.VendorIDDD {
|
||||
if v.SkuID == 0 && v.JxSkuID != 0 {
|
||||
v.SkuID = v.JxSkuID
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/tiktok_store"
|
||||
"io"
|
||||
"math"
|
||||
"mime/multipart"
|
||||
@@ -6611,3 +6612,20 @@ func UpdateMtCatToJd(ctx *jxcontext.Context, mtCatID, jdCatID string) (err error
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func SyncTiktokMainIdToLocal(ctx *jxcontext.Context, param *tiktok_store.MainSku) error {
|
||||
codes, err := dao.GetVendorOrgCode(dao.GetDB(), model.VendorIDDD, "", "platform")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, code := range codes {
|
||||
result, err := tiktok_store.QueryAllMainSkuList(code.VendorOrgCode, param)
|
||||
globals.SugarLogger.Debugf("=====%s", utils.Format4Output(result, false))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
return OnCreateThing2Tiktok(ctx, dao.GetDB(), code.VendorOrgCode, result, model.ThingTypeSku, model.SyncFlagNewMask, false)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -331,6 +331,37 @@ func OnCreateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*mode
|
||||
return err
|
||||
}
|
||||
|
||||
func OnCreateThing2Tiktok(ctx *jxcontext.Context, db *dao.DaoDB, appOrgCode string, vendorThingList map[string]int64, thingType, syncFlag int8, vendorFlag bool) (err error) {
|
||||
if thingType == model.ThingTypeSkuName {
|
||||
return nil
|
||||
}
|
||||
errList := errlist.New()
|
||||
for k, v := range vendorThingList {
|
||||
thingMap := &model.ThingMap{
|
||||
ThingID: v,
|
||||
ThingType: thingType,
|
||||
VendorID: model.VendorIDDD,
|
||||
VendorOrgCode: appOrgCode,
|
||||
VendorThingID: k,
|
||||
}
|
||||
if thingType == model.ThingTypeCategory && !vendorFlag {
|
||||
syncFlag = 0
|
||||
}
|
||||
thingMap.SyncStatus = syncFlag
|
||||
dao.WrapAddIDCULDEntity(thingMap, ctx.GetUserName())
|
||||
if err2 := dao.CreateEntity(db, thingMap); err2 != nil {
|
||||
if err2 := getThingMap(db, thingMap); err2 == nil {
|
||||
thingMap.SyncStatus = 2
|
||||
thingMap.LastOperator = ctx.GetUserName()
|
||||
_, err2 = dao.UpdateEntity(db, thingMap)
|
||||
errList.AddErr(err2)
|
||||
}
|
||||
}
|
||||
}
|
||||
err = errList.GetErrListAsOne()
|
||||
return err
|
||||
}
|
||||
|
||||
func onUpdateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*model.VendorOrgCode, thingID int64, thingType int8, syncStatus int8) (err error) {
|
||||
if thingType == model.ThingTypeSkuName {
|
||||
return nil
|
||||
|
||||
@@ -442,13 +442,10 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, causeFlag
|
||||
vendorStoreID := storeDetail.VendorStoreID
|
||||
var skus []*dao.StoreSkuSyncInfo
|
||||
if isFull {
|
||||
globals.SugarLogger.Debugf("===============true")
|
||||
skus, err = dao.GetFullStoreSkus(db, vendorID, storeID)
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("===============false")
|
||||
skus, err = dao.GetStoreSkus(db, vendorID, storeID, skuIDs)
|
||||
}
|
||||
globals.SugarLogger.Debugf("===============skus:%s", utils.Format4Output(skus, false))
|
||||
|
||||
if err != nil || len(skus) == 0 {
|
||||
return err
|
||||
|
||||
@@ -3,6 +3,7 @@ package misc
|
||||
import (
|
||||
"fmt"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/delivery"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/tiktok_store"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -192,6 +193,21 @@ func Init() {
|
||||
"04:00:00",
|
||||
})
|
||||
|
||||
// 定时任务更新昨天的都要商品和本地商品id的映射关系
|
||||
ScheduleTimerFunc("RefreshStoreOperator", func() {
|
||||
t := time.Now()
|
||||
cms.SyncTiktokMainIdToLocal(jxcontext.AdminCtx, &tiktok_store.MainSku{
|
||||
AppOrgCode: "",
|
||||
CheckStatus: 3,
|
||||
StartTime: time.Date(t.Year(), t.Month(), t.Day()-1, 0, 0, 1, 0, time.Local).Unix(),
|
||||
EndTime: time.Date(t.Year(), t.Month(), t.Day()-1, 23, 59, 59, 0, time.Local).Unix(),
|
||||
Page: 1,
|
||||
PageSize: 100,
|
||||
})
|
||||
}, []string{
|
||||
"04:30:00",
|
||||
})
|
||||
|
||||
ScheduleTimerFuncByInterval(func() {
|
||||
defsch.FixedScheduler.ConfirmSelfTakeOrders(jxcontext.AdminCtx, []int{model.VendorIDJD}, time.Now().Add(-48*time.Hour), time.Now().Add(-30*time.Minute), true, true)
|
||||
}, 5*time.Second, 10*time.Minute)
|
||||
@@ -207,7 +223,7 @@ func Init() {
|
||||
|
||||
ScheduleTimerFuncByInterval(func() {
|
||||
curDate := utils.Time2Date(time.Now())
|
||||
orderman.FixedOrderManager.AmendMissingOrders(jxcontext.AdminCtx, []int{model.VendorIDJD, model.VendorIDMTWM, model.VendorIDEBAI}, 0, curDate, curDate, true, true)
|
||||
orderman.FixedOrderManager.AmendMissingOrders(jxcontext.AdminCtx, []int{model.VendorIDJD, model.VendorIDMTWM, model.VendorIDEBAI, model.VendorIDDD}, 0, curDate, curDate, true, true)
|
||||
}, 5*time.Second, 10*time.Minute)
|
||||
|
||||
//刷新京东物竞天择订单结算价
|
||||
@@ -330,7 +346,7 @@ func Init() {
|
||||
}, dailyWorkTimeList)
|
||||
ScheduleTimerFunc("doDailyWork3", func() {
|
||||
dao.SetStoresMapSyncStatus(dao.GetDB(), nil, nil, model.SyncFlagStoreStatus)
|
||||
cms.CurVendorSync.SyncStore2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDMTWM, model.VendorIDJD, model.VendorIDEBAI}, nil, true, true)
|
||||
cms.CurVendorSync.SyncStore2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDMTWM, model.VendorIDJD, model.VendorIDEBAI, model.VendorIDDD}, nil, true, true)
|
||||
|
||||
syncStoreSku()
|
||||
InitEx()
|
||||
@@ -339,7 +355,7 @@ func Init() {
|
||||
}, dailyWorkTimeList)
|
||||
ScheduleTimerFunc("doDailyWork4", func() {
|
||||
curDate := utils.Time2Date(time.Now())
|
||||
orderman.FixedOrderManager.AmendMissingOrders(jxcontext.AdminCtx, []int{model.VendorIDJD, model.VendorIDMTWM, model.VendorIDEBAI}, 0, curDate.Add(-72*time.Hour), curDate, true, true)
|
||||
orderman.FixedOrderManager.AmendMissingOrders(jxcontext.AdminCtx, []int{model.VendorIDJD, model.VendorIDMTWM, model.VendorIDEBAI, model.VendorIDDD}, 0, curDate.Add(-72*time.Hour), curDate, true, true)
|
||||
//只传toDate默认刷新toDate到5天以前的订单
|
||||
orderman.RefreshOrdersWithoutJxStoreID(jxcontext.AdminCtx, "", "", true, true)
|
||||
//禁用没有绑定的门店
|
||||
@@ -672,6 +688,7 @@ func ScheduleTimerFunc(name string, handler func(), timeList []string) {
|
||||
nextTime := jxutils.GetNextTimeFromList(now, timeList)
|
||||
duration := nextTime.Sub(now) + 1*time.Second
|
||||
utils.AfterFuncWithRecover(duration, func() {
|
||||
globals.SugarLogger.Debugf("循环时间序列=====%s", duration)
|
||||
handler()
|
||||
ScheduleTimerFunc(name, handler, timeList)
|
||||
})
|
||||
|
||||
@@ -346,7 +346,7 @@ func GetSkusWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, nameIDs
|
||||
LEFT JOIN sku_vendor_category_map tsy ON tsy.name_id = t2.id AND tsy.vendor_id = ? AND tsy.deleted_at = ?
|
||||
WHERE 1 = 1
|
||||
`
|
||||
sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue, utils.DefaultTimeValue, model.VendorIDJD, utils.DefaultTimeValue)
|
||||
sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue, utils.DefaultTimeValue, vendorIDs[0], utils.DefaultTimeValue)
|
||||
if mustDirty {
|
||||
sql += " AND t1m.sync_status IS NOT NULL AND t1m.sync_status <> 0"
|
||||
} else {
|
||||
|
||||
@@ -256,7 +256,7 @@ func (c *DeliveryHandler) getBillParams(db *dao.DaoDB, order *model.GoodsOrder)
|
||||
// storeTel = ",门店电话:" + storeDeatail.Tel2
|
||||
// }
|
||||
billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
|
||||
billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4("客户电话:"+order.ConsigneeMobile+","+order.BuyerComment+"取货失败或配送遇到问题请联系18048531223,禁止未配送直接完成定单!"))
|
||||
billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4("客户电话:"+order.ConsigneeMobile+","+order.BuyerComment+"配送遇到问题,可联系18048531223取消配送单。"))
|
||||
billParams.CargoType = dadaapi.CargoTypeFresh
|
||||
billParams.CargoWeight = float64(jxutils.IntWeight2Float(limitOrderWeight(order.Weight)))
|
||||
billParams.CargoNum = order.GoodsCount
|
||||
|
||||
@@ -303,7 +303,7 @@ func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee
|
||||
}
|
||||
}
|
||||
|
||||
billParams.Note = utils.FilterMb4("客户电话:" + order.ConsigneeMobile + "," + order.BuyerComment + ",取货失败或配送遇到问题请联系18048531223,禁止未配送直接完成定单!")
|
||||
billParams.Note = utils.FilterMb4("客户电话:" + order.ConsigneeMobile + "," + order.BuyerComment + ",配送遇到问题,可联系18048531223取消配送单,禁止未配送直接完成定单!")
|
||||
billParams.GoodsDetail = string(utils.MustMarshal(goods))
|
||||
billParams.GoodsPickupInfo = fmt.Sprintf("%s第%d号单", model.VendorChineseNames[order.VendorID], order.OrderSeq)
|
||||
billParams.PoiSeq = fmt.Sprintf("#%d", order.OrderSeq)
|
||||
|
||||
@@ -422,7 +422,7 @@ func GetDaDaBillParams(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dada
|
||||
// storeTel = ",门店电话:" + storeDeatail.Tel2
|
||||
// }
|
||||
billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
|
||||
billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4("客户电话:"+order.ConsigneeMobile+","+order.BuyerComment+"取货失败或配送遇到问题请联系18048531223,禁止未配送直接完成定单!"))
|
||||
billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4("客户电话:"+order.ConsigneeMobile+","+order.BuyerComment+"配送遇到问题,可联系18048531223取消配送单,禁止未配送直接完成定单!"))
|
||||
billParams.CargoType = dadaapi.CargoTypeFresh
|
||||
billParams.CargoWeight = float64(jxutils.IntWeight2Float(limitOrderWeight(order.Weight)))
|
||||
billParams.CargoNum = order.GoodsCount
|
||||
|
||||
@@ -90,7 +90,7 @@ func (p *PurchaseHandler) getOrder(vendorOrgCode, vendorOrderID, vendorStoreID s
|
||||
StoreID: 0,
|
||||
CoordinateType: model.CoordinateTypeMars,
|
||||
BuyerComment: result.BuyerWords,
|
||||
ExpectedDeliveredTime: getTimeFromTimestamp(utils.Interface2Int64WithDefault(result.TargetArrivalTime, 0)),
|
||||
ExpectedDeliveredTime: getTimeFromTimestamp(utils.Interface2Int64WithDefault(result.LatestReceiptTime, 0)), // 预计最晚送达时间
|
||||
PickDeadline: utils.DefaultTimeValue,
|
||||
VendorStatus: utils.Int64ToStr(result.OrderStatus), //1待支付/103部分支付/105已支付/2备货中/101部分发货/3已发货/4取消/完成/21发货前退款完成/22发货后退款/39收货后退款
|
||||
OrderSeq: 0,
|
||||
@@ -186,10 +186,10 @@ func (p *PurchaseHandler) getOrder(vendorOrgCode, vendorOrderID, vendorStoreID s
|
||||
closeTime = localStore.CloseTime2
|
||||
}
|
||||
h, m, _ := utils.Timestamp2Time(result.CreateTime).Clock()
|
||||
if utils.Str2Int16(fmt.Sprintf("%d%d", h, m)) >= openTime && utils.Str2Int16(fmt.Sprintf("%d%d", h, m)) < closeTime {
|
||||
order.BusinessType = model.BusinessTypeDingshida
|
||||
} else {
|
||||
if utils.Str2Int16(fmt.Sprintf("%d%d", h, m)) >= openTime && utils.Str2Int16(fmt.Sprintf("%d%d", h, m)) < closeTime && localStore.Status == model.StoreStatusOpened {
|
||||
order.BusinessType = model.BusinessTypeImmediate
|
||||
} else {
|
||||
order.BusinessType = model.BusinessTypeDingshida
|
||||
|
||||
}
|
||||
|
||||
@@ -640,7 +640,7 @@ func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *mod
|
||||
return err
|
||||
}
|
||||
|
||||
// CancelOrder 取消订单 (抖音商家无法发起退单操作)
|
||||
// CancelOrder 取消订单 (抖音商家无法发起退单操作,商家联系不到客户取消订单/拒收/缺货)
|
||||
func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
|
||||
if globals.EnableDdStoreWrite {
|
||||
return errors.New("抖音商家无法发起退单操作")
|
||||
|
||||
@@ -744,7 +744,6 @@ func (P *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (s
|
||||
return 0, errors.New("抖店暂不支持此操作")
|
||||
}
|
||||
|
||||
// /address/getProvince 获取四级地址全量省份信息
|
||||
//func (P *PurchaseHandler) GetProvince()([]) {
|
||||
//
|
||||
//}
|
||||
func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*partner.SkuNameInfo, err error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
package tiktok_store
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||
product_addV2_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_addV2/request"
|
||||
product_detail_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_detail/response"
|
||||
product_editV2_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_editV2/request"
|
||||
product_editV2_commit_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_editV2_commit/request"
|
||||
sku_editPrice_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/sku_editPrice/request"
|
||||
sku_syncStock_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/sku_syncStock/request"
|
||||
tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
|
||||
"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"
|
||||
@@ -20,7 +15,6 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/business/partner/putils"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -61,13 +55,6 @@ func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) {
|
||||
return batchSize
|
||||
}
|
||||
|
||||
func getStoreVendorOrgCode(storeID int) (vendorOrgCode string) {
|
||||
if storeMap, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDDD, ""); storeMap != nil {
|
||||
return storeMap.VendorOrgCode
|
||||
}
|
||||
return vendorOrgCode
|
||||
}
|
||||
|
||||
// GetStoreAllCategories 门店分类
|
||||
func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) {
|
||||
remoteCats, err := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).GetShopCategory(0)
|
||||
@@ -77,23 +64,6 @@ func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID
|
||||
return cats, err
|
||||
}
|
||||
|
||||
func convertVendorCatList(remoteCats []*tiktokShop.RetailCategoryInfo) (cats []*partner.BareCategoryInfo) {
|
||||
for _, rCat := range remoteCats {
|
||||
cat := &partner.BareCategoryInfo{
|
||||
VendorCatID: utils.Int64ToStr(rCat.Id),
|
||||
Name: rCat.Name,
|
||||
Level: int(rCat.Level),
|
||||
Seq: 0,
|
||||
Children: convertVendorCatList(rCat.Children),
|
||||
}
|
||||
if cat.VendorCatID == "" {
|
||||
cat.VendorCatID = rCat.Name
|
||||
}
|
||||
cats = append(cats, cat)
|
||||
}
|
||||
return cats
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) {
|
||||
return mtwmapi.IsErrCategoryExist(err)
|
||||
}
|
||||
@@ -102,23 +72,6 @@ func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) {
|
||||
return mtwmapi.IsErrCategoryNotExist(err)
|
||||
}
|
||||
|
||||
func catCode2Str(catCode int) (catCodeStr string) {
|
||||
if catCode > 0 {
|
||||
catCodeStr = utils.Int2Str(catCode)
|
||||
}
|
||||
return catCodeStr
|
||||
}
|
||||
|
||||
func tryCatName2Code(originName string) (catCodeStr string) {
|
||||
if intValue := utils.Str2Int64WithDefault(originName, 0); intValue > 0 {
|
||||
catCodeStr = utils.Int64ToStr(intValue)
|
||||
if catCodeStr != originName {
|
||||
catCodeStr = ""
|
||||
}
|
||||
}
|
||||
return catCodeStr
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
|
||||
//level := 1
|
||||
//if storeCat.ParentCatName != "" {
|
||||
@@ -204,10 +157,7 @@ func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID in
|
||||
return err
|
||||
}
|
||||
|
||||
// 门店商品
|
||||
|
||||
// 多门店平台不需要实现这个接口
|
||||
|
||||
func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) {
|
||||
return false
|
||||
}
|
||||
@@ -226,7 +176,6 @@ func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
|
||||
// }
|
||||
// return newStoreSkuList
|
||||
// }
|
||||
|
||||
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)
|
||||
// if err == nil && vendorStoreID == specialStoreID {
|
||||
@@ -248,230 +197,6 @@ func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, v
|
||||
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
|
||||
storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDDD, "")
|
||||
api := getAPI(storeDetail.VendorOrgCode, storeID, vendorStoreID)
|
||||
if isCreate {
|
||||
syncType = "创建商品"
|
||||
for _, storeSku := range storeSkuList {
|
||||
// 创建商品
|
||||
param := &product_addV2_request.ProductAddV2Param{
|
||||
CategoryLeafId: utils.Str2Int64(storeSku.SkuVendorMapCatID),
|
||||
Name: utils.LimitUTF8StringLen(storeSku.SkuName, mtwmapi.MaxSkuNameCharCount),
|
||||
PayType: tiktokShop.TiktokPayType1,
|
||||
ReduceType: tiktokShop.SkuReduceTypePayMakeOrder,
|
||||
Weight: utils.Int2Float64(storeSku.Weight),
|
||||
DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay,
|
||||
PresellType: tiktokShop.SendGoodsTypeNow,
|
||||
Supply7dayReturn: 2, // 是否支持7天无理由,0不支持,1支持,2支持(拆封后不支持)
|
||||
Mobile: storeDetail.Tel1,
|
||||
Commit: true,
|
||||
Specs: "净重|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit,
|
||||
NeedRechargeMode: false,
|
||||
SellChannel: []int64{0},
|
||||
StartSaleType: 0,
|
||||
PickupMethod: "0",
|
||||
OuterProductId: utils.Int2Str(storeSku.SkuID), // 本地skuId为外部商品id
|
||||
}
|
||||
// param.AccountTemplateId = ""
|
||||
// 获取上传图,商品轮播图
|
||||
img, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
param.Pic = img
|
||||
// 商品详情图
|
||||
if storeSku.DescImg == "" {
|
||||
param.Description = img
|
||||
} else {
|
||||
img2, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.DescImg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
param.Description = img2
|
||||
}
|
||||
|
||||
// weight_unit 目前抖音只支持g和kg两种
|
||||
switch storeSku.Unit {
|
||||
case "g", "ml", "G", "ML":
|
||||
param.WeightUnit = tiktokShop.WeightUint_G
|
||||
case "kg", "l", "L", "KG":
|
||||
param.WeightUnit = tiktokShop.WeightUint_G
|
||||
}
|
||||
|
||||
// spec_prices
|
||||
param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, 0, storeSku)
|
||||
param.ProductFormatNew = storeSku.TiktokAttribute
|
||||
|
||||
// 获取品牌
|
||||
//param.StandardBrandId, err = api.GetSkuBrand(param.CategoryLeafId)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
param.StandardBrandId = 596120136
|
||||
|
||||
// 根据本地商品id获取线上商品是否存在,存在则只创建子商品
|
||||
var tiktokResultProductId int64 = 0
|
||||
skuMain, err2 := api.GetSkuDetailLocalID("", param.OuterProductId)
|
||||
if err2 != nil { // 线上不存在创建
|
||||
tiktokResult, err := api.CreateStoreCommodity(param) // 创建主商品
|
||||
if err != nil {
|
||||
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
|
||||
storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
|
||||
continue
|
||||
}
|
||||
tiktokResultProductId = tiktokResult.ProductId
|
||||
var attrId []string
|
||||
for _, v := range tiktokResult.Sku {
|
||||
attrId = append(attrId, utils.Int64ToStr(v.SkuId))
|
||||
}
|
||||
storeSku.VendorSkuAttrId = strings.Join(attrId, ",") // 属性id skuID
|
||||
} else {
|
||||
storeSku.VendorMainId = utils.Int64ToStr(skuMain.ProductId)
|
||||
var attrId []string
|
||||
for _, v := range skuMain.SpecPrices {
|
||||
attrId = append(attrId, utils.Int64ToStr(v.SkuId))
|
||||
}
|
||||
storeSku.VendorSkuAttrId = strings.Join(attrId, ",") // 属性id skuID
|
||||
tiktokResultProductId = skuMain.ProductId
|
||||
}
|
||||
|
||||
// 创建子商品
|
||||
temp, err := dao.QueryStoreBindInfo(storeDetail.ID)
|
||||
if err != nil || temp == nil || temp.TemplateID == 0 {
|
||||
// 运费模板
|
||||
param.FreightId, err = GetDeliveryTemp(api, vendorStoreID, storeDetail)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 获取门店限售模板
|
||||
param.SaleLimitId, err = CreateSaleTemp(utils.Str2Int64(vendorStoreID), api)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 保存数据库
|
||||
freightTemplate := &model.FreightTemplate{
|
||||
StoreID: storeSku.StoreID,
|
||||
VendorStoreID: storeDetail.VendorStoreID,
|
||||
TemplateID: param.FreightId,
|
||||
WarehouseID: 0,
|
||||
FenceID: "",
|
||||
TradeLimitID: param.SaleLimitId,
|
||||
}
|
||||
dao.WrapAddIDCULDEntity(freightTemplate, "jxAdmin")
|
||||
err = dao.CreateEntity(dao.GetDB(), freightTemplate)
|
||||
} else {
|
||||
param.FreightId = temp.TemplateID
|
||||
param.SaleLimitId = temp.TradeLimitID
|
||||
}
|
||||
|
||||
param.MainProductId = tiktokResultProductId
|
||||
param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, tiktokResultProductId, storeSku)
|
||||
|
||||
param.StoreId = utils.Str2Int64(vendorStoreID)
|
||||
// 抖店创建子商品
|
||||
tiktokResultChildren, err := api.CreateStoreCommodity(param)
|
||||
if err != nil {
|
||||
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
|
||||
storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
|
||||
continue
|
||||
}
|
||||
storeSku.VendorSkuID = utils.Int64ToStr(tiktokResultChildren.ProductId) // 子商品主id
|
||||
storeSku.VendorMainId = utils.Int64ToStr(tiktokResultProductId) // 商品主id
|
||||
|
||||
}
|
||||
} else {
|
||||
syncType = "更新商品"
|
||||
for _, storeSku := range storeSkuList {
|
||||
// 更新商品(目前只更新子商品,主商品暂不支持)
|
||||
param := &product_editV2_request.ProductEditV2Param{
|
||||
CategoryLeafId: utils.Str2Int64(storeSku.SkuVendorMapCatID),
|
||||
Name: storeSku.Name,
|
||||
PayType: tiktokShop.TiktokPayType1,
|
||||
ReduceType: tiktokShop.SkuReduceTypePayMakeOrder,
|
||||
Weight: utils.Int2Float64(storeSku.Weight),
|
||||
DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay,
|
||||
PresellType: tiktokShop.SendGoodsTypeNow,
|
||||
Supply7dayReturn: 2,
|
||||
Mobile: storeDetail.Tel1,
|
||||
Commit: true,
|
||||
Specs: "净重|" + fmt.Sprintf("%f", storeSku.SpecQuality) + storeSku.SpecUnit,
|
||||
NeedRechargeMode: false,
|
||||
SellChannel: []int64{0},
|
||||
StartSaleType: 0,
|
||||
PickupMethod: "0",
|
||||
}
|
||||
// param.AccountTemplateId = ""
|
||||
// 获取上传图,商品轮播图
|
||||
img, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
param.Pic = img
|
||||
// 商品详情图
|
||||
img2, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.DescImg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
param.Description = img2
|
||||
|
||||
// weight_unit 目前抖音只支持g和kg两种
|
||||
switch storeSku.Unit {
|
||||
case "g", "ml", "G", "ML":
|
||||
param.WeightUnit = tiktokShop.WeightUint_G
|
||||
case "kg", "l", "L", "KG":
|
||||
param.WeightUnit = tiktokShop.WeightUint_G
|
||||
}
|
||||
|
||||
// spec_prices
|
||||
param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, utils.Str2Int64(storeSku.VendorSkuID), storeSku)
|
||||
param.ProductFormatNew = storeSku.TiktokAttribute
|
||||
|
||||
// 获取品牌
|
||||
//brandID, err := api.GetSkuBrand(param.CategoryLeafId)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//param.StandardBrandId = brandID
|
||||
|
||||
//tiktokResult, err := api.EditStoreCommodity(param) // 创建主商品
|
||||
//if err != nil {
|
||||
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
|
||||
// storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
|
||||
// continue
|
||||
//}
|
||||
|
||||
// 创建子商品
|
||||
//param.FreightId = freightId
|
||||
param.ProductId = utils.Str2Int64(storeSku.VendorSkuID)
|
||||
//param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, tiktokResult.ProductId, storeSku)
|
||||
// 获取门店限售模板
|
||||
//saleLimitId, err := CreateSaleTemp(utils.Str2Int64(vendorStoreID), api)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//param.SaleLimitId = saleLimitId
|
||||
//param.StoreId = utils.Str2Int64(vendorStoreID)
|
||||
// 抖店创建商品
|
||||
if err := api.EditStoreCommodity(param); err != nil {
|
||||
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
|
||||
storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
|
||||
continue
|
||||
}
|
||||
storeSku.VendorSkuID = storeSku.VendorSkuID
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if len(failedList) > 0 {
|
||||
err = nil
|
||||
}
|
||||
return failedList, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||
if globals.EnableDdStoreWrite {
|
||||
for _, v := range storeSkuList {
|
||||
@@ -486,32 +211,6 @@ func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, v
|
||||
return failedList, err
|
||||
}
|
||||
|
||||
func stockCount2Mtwm(stock int) (mtwmStock string) {
|
||||
return utils.Int2Str(stock)
|
||||
}
|
||||
|
||||
func storeSku2Mtwm(storeSkuList []*partner.StoreSkuInfo, updateType int) (skuList []*mtwmapi.BareStoreFoodInfo) {
|
||||
for _, storeSku := range storeSkuList {
|
||||
skuInfo := &mtwmapi.BareStoreFoodInfo{
|
||||
AppFoodCode: storeSku.VendorSkuID,
|
||||
Skus: []*mtwmapi.BareStoreSkuInfo{
|
||||
&mtwmapi.BareStoreSkuInfo{
|
||||
SkuID: storeSku.VendorSkuID,
|
||||
},
|
||||
},
|
||||
}
|
||||
if updateType == updateTypeStock {
|
||||
skuInfo.Skus[0].Stock = stockCount2Mtwm(storeSku.Stock)
|
||||
} else if updateType == updateTypePrice {
|
||||
skuInfo.Skus[0].Price = jxutils.IntPrice2StandardString(storeSku.VendorPrice)
|
||||
} else {
|
||||
skuInfo.Skus = nil
|
||||
}
|
||||
skuList = append(skuList, skuInfo)
|
||||
}
|
||||
return skuList
|
||||
}
|
||||
|
||||
// UpdateStoreSkusStatus 批量更新商品上下架
|
||||
func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||
api := getAPI(vendorOrgCode, storeID, vendorStoreID)
|
||||
@@ -612,15 +311,6 @@ func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrg
|
||||
return p.UpdateStoreSkusPrice(ctx, vendorOrgCode, storeID, vendorStoreID, storeSkuList)
|
||||
}
|
||||
|
||||
func tiktokSkuStatus2Jx(skuStatus int64) (jxSkuStatus int) {
|
||||
if skuStatus == mtwmapi.SellStatusOnline {
|
||||
jxSkuStatus = model.SkuStatusNormal
|
||||
} else {
|
||||
jxSkuStatus = model.SkuStatusDontSale
|
||||
}
|
||||
return jxSkuStatus
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) {
|
||||
// 查询单个门店商品
|
||||
tiktokApi := getAPI(storeSkuList[0].VendorOrgCode, storeID, vendorStoreID)
|
||||
@@ -667,48 +357,6 @@ func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTas
|
||||
return skuNameList, err
|
||||
}
|
||||
|
||||
func vendorSku2Jx(tiktokSku *product_detail_response.ProductDetailData) (skuName *partner.SkuNameInfo) {
|
||||
if len(tiktokSku.SpecPrices) == 0 {
|
||||
return nil
|
||||
}
|
||||
prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(tiktokSku.Name)
|
||||
vendorSku := tiktokSku.SpecPrices[0]
|
||||
weight := jxutils.FormatSkuWeight(specQuality, specUnit)
|
||||
|
||||
skuName = &partner.SkuNameInfo{
|
||||
NameID: utils.Str2Int(vendorSku.OuterSkuId),
|
||||
VendorNameID: utils.Int64ToStr(tiktokSku.MainProductId),
|
||||
UPC: tiktokSku.ProductIdStr,
|
||||
Prefix: prefix,
|
||||
Name: name,
|
||||
Unit: unit,
|
||||
Status: tiktokSkuStatus2Jx(tiktokSku.Status), //此处为之前一个bug 如果吧状态放到切片内层 对于内层函数中映射无法关联 永远获取到的初始值为0
|
||||
SkuList: []*partner.SkuInfo{
|
||||
&partner.SkuInfo{
|
||||
StoreSkuInfo: partner.StoreSkuInfo{
|
||||
VendorSkuID: utils.Int64ToStr(vendorSku.SkuId),
|
||||
SkuID: int(vendorSku.OutSkuId),
|
||||
IsSpecialty: 0,
|
||||
Stock: int(vendorSku.StockNum),
|
||||
VendorPrice: vendorSku.Price,
|
||||
Status: tiktokSkuStatus2Jx(tiktokSku.Status),
|
||||
},
|
||||
SkuName: tiktokSku.Name,
|
||||
Comment: comment,
|
||||
SpecQuality: float64(specQuality),
|
||||
SpecUnit: specUnit,
|
||||
Weight: weight,
|
||||
},
|
||||
},
|
||||
PictureList: tiktokSku.Pic,
|
||||
}
|
||||
if tiktokSku.CategoryDetail != nil {
|
||||
// todo, 因为当前我们用的是分类名操作这种方式,所以要返回分类名(而不是分类code)
|
||||
skuName.VendorCatIDList = []string{tiktokSku.CategoryDetail.FirstCname, tiktokSku.CategoryDetail.SecondCname, tiktokSku.CategoryDetail.ThirdCname, tiktokSku.CategoryDetail.FourthCname}
|
||||
}
|
||||
return skuName
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp {
|
||||
return sensitiveWordRegexp
|
||||
}
|
||||
|
||||
@@ -4,20 +4,332 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||
freightTemplate_create_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/freightTemplate_create/request"
|
||||
product_addV2_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_addV2/request"
|
||||
product_detail_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_detail/response"
|
||||
product_editV2_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_editV2/request"
|
||||
product_getCatePropertyV2_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_getCatePropertyV2/response"
|
||||
product_listV2_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_listV2/request"
|
||||
product_listV2_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/product_listV2/response"
|
||||
shop_bindStoreFreight_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/shop_bindStoreFreight/request"
|
||||
shop_bindStoreSaleLimit_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/shop_bindStoreSaleLimit/request"
|
||||
trade_createTradeLimitTemplate_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/trade_createTradeLimitTemplate/request"
|
||||
tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
|
||||
"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/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"
|
||||
"math/rand"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type MainSku struct {
|
||||
AppOrgCode string `json:"appOrgCode"` // 账号id
|
||||
CheckStatus int64 `json:"checkStatus"` // 7-审核通过待上架 3-审核通过;
|
||||
StartTime int64 `json:"startTime"` // 商品创建开始时间,unix时间戳,单位:秒;
|
||||
EndTime int64 `json:"endTime"` // 商品创建结束时间,unix时间戳,单位:秒;
|
||||
Page int64 `json:"page"`
|
||||
PageSize int64 `json:"pageSize"`
|
||||
}
|
||||
|
||||
// QueryAllMainSkuList 获取商户账号总的商品,主商品条数.
|
||||
func QueryAllMainSkuList(appOrgCode string, param *MainSku) (map[string]int64, error) {
|
||||
var (
|
||||
page int64 = 1
|
||||
pageSize int64 = 100
|
||||
tiktokIdAndLocalSkuId = make(map[string]int64, 0)
|
||||
api = getAPI(appOrgCode, 0, "")
|
||||
)
|
||||
if param.Page == 0 {
|
||||
param.Page = page
|
||||
}
|
||||
if param.PageSize == 0 {
|
||||
param.PageSize = pageSize
|
||||
}
|
||||
|
||||
for {
|
||||
mainSkuList, err := GetSkuDetailList(api, param)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range mainSkuList.Data {
|
||||
var localSkuId int64 = 0
|
||||
if v.OutProductId != 0 {
|
||||
localSkuId = v.ProductId
|
||||
} else if v.OuterProductId != "" {
|
||||
localSkuId = utils.Str2Int64(v.OuterProductId)
|
||||
} else {
|
||||
skuDetail, err := api.GetSkuDetail(utils.Int64ToStr(v.ProductId), "")
|
||||
if err != nil {
|
||||
localSkuId = 0
|
||||
}
|
||||
if skuDetail.OutProductId != 0 {
|
||||
localSkuId = skuDetail.OutProductId
|
||||
} else if skuDetail.OuterProductId != "" {
|
||||
localSkuId = utils.Str2Int64(skuDetail.OuterProductId)
|
||||
} else {
|
||||
localSkuId = 0
|
||||
}
|
||||
}
|
||||
tiktokIdAndLocalSkuId[utils.Int64ToStr(v.ProductId)] = localSkuId
|
||||
}
|
||||
|
||||
if int64(len(mainSkuList.Data)) < pageSize {
|
||||
return tiktokIdAndLocalSkuId, err
|
||||
}
|
||||
param.Page++
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func GetSkuDetailList(api *tiktokShop.API, param *MainSku) (*product_listV2_response.ProductListV2Data, error) {
|
||||
mainSkuList, err := api.GetSkuDetailList(&product_listV2_request.ProductListV2Param{
|
||||
Status: 0,
|
||||
CheckStatus: param.CheckStatus,
|
||||
ProductType: 0,
|
||||
StartTime: param.StartTime,
|
||||
EndTime: param.EndTime,
|
||||
Page: param.Page,
|
||||
Size: param.PageSize,
|
||||
UpdateStartTime: 0,
|
||||
UpdateEndTime: 0,
|
||||
StoreId: 0,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mainSkuList, nil
|
||||
}
|
||||
|
||||
// 对于多门店平台来说,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
|
||||
storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDDD, "")
|
||||
api := getAPI(storeDetail.VendorOrgCode, storeID, vendorStoreID)
|
||||
if isCreate {
|
||||
syncType = "创建商品"
|
||||
for _, storeSku := range storeSkuList {
|
||||
// 创建商品
|
||||
param := &product_addV2_request.ProductAddV2Param{
|
||||
CategoryLeafId: utils.Str2Int64(storeSku.SkuVendorMapCatID),
|
||||
Name: utils.LimitUTF8StringLen(storeSku.SkuName, mtwmapi.MaxSkuNameCharCount),
|
||||
PayType: tiktokShop.TiktokPayType1,
|
||||
ReduceType: tiktokShop.SkuReduceTypePayMakeOrder,
|
||||
Weight: utils.Int2Float64(storeSku.Weight),
|
||||
DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay,
|
||||
PresellType: tiktokShop.SendGoodsTypeNow,
|
||||
Supply7dayReturn: 2, // 是否支持7天无理由,0不支持,1支持,2支持(拆封后不支持)
|
||||
Mobile: storeDetail.Tel1,
|
||||
Commit: true,
|
||||
Specs: "净重|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit,
|
||||
NeedRechargeMode: false,
|
||||
SellChannel: []int64{0},
|
||||
StartSaleType: 0,
|
||||
PickupMethod: "0",
|
||||
OuterProductId: utils.Int2Str(storeSku.SkuID), // 本地skuId为外部商品id
|
||||
}
|
||||
// param.AccountTemplateId = ""
|
||||
// 获取上传图,商品轮播图
|
||||
img, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
param.Pic = img
|
||||
// 商品详情图
|
||||
if storeSku.DescImg == "" {
|
||||
param.Description = img
|
||||
} else {
|
||||
img2, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.DescImg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
param.Description = img2
|
||||
}
|
||||
|
||||
// weight_unit 目前抖音只支持g和kg两种
|
||||
switch storeSku.Unit {
|
||||
case "g", "ml", "G", "ML":
|
||||
param.WeightUnit = tiktokShop.WeightUint_G
|
||||
case "kg", "l", "L", "KG":
|
||||
param.WeightUnit = tiktokShop.WeightUint_G
|
||||
}
|
||||
|
||||
// spec_prices
|
||||
param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, 0, storeSku)
|
||||
param.ProductFormatNew = storeSku.TiktokAttribute
|
||||
|
||||
// 获取品牌
|
||||
//param.StandardBrandId, err = api.GetSkuBrand(param.CategoryLeafId)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
param.StandardBrandId = 596120136
|
||||
|
||||
// 根据本地商品id获取线上商品是否存在,存在则只创建子商品
|
||||
var tiktokResultProductId int64 = 0
|
||||
skuMain, err2 := api.GetSkuDetailLocalID("", param.OuterProductId)
|
||||
if err2 != nil { // 线上不存在创建
|
||||
tiktokResult, err := api.CreateStoreCommodity(param) // 创建主商品
|
||||
if err != nil {
|
||||
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
|
||||
storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
|
||||
continue
|
||||
}
|
||||
tiktokResultProductId = tiktokResult.ProductId
|
||||
var attrId []string
|
||||
for _, v := range tiktokResult.Sku {
|
||||
attrId = append(attrId, utils.Int64ToStr(v.SkuId))
|
||||
}
|
||||
storeSku.VendorSkuAttrId = strings.Join(attrId, ",") // 属性id skuID
|
||||
} else {
|
||||
storeSku.VendorMainId = utils.Int64ToStr(skuMain.ProductId)
|
||||
var attrId []string
|
||||
for _, v := range skuMain.SpecPrices {
|
||||
attrId = append(attrId, utils.Int64ToStr(v.SkuId))
|
||||
}
|
||||
storeSku.VendorSkuAttrId = strings.Join(attrId, ",") // 属性id skuID
|
||||
tiktokResultProductId = skuMain.ProductId
|
||||
}
|
||||
|
||||
// 创建子商品
|
||||
temp, err := dao.QueryStoreBindInfo(storeDetail.ID)
|
||||
if err != nil || temp == nil || temp.TemplateID == 0 {
|
||||
// 运费模板
|
||||
param.FreightId, err = GetDeliveryTemp(api, vendorStoreID, storeDetail)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 获取门店限售模板
|
||||
param.SaleLimitId, err = CreateSaleTemp(utils.Str2Int64(vendorStoreID), api)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 保存数据库
|
||||
freightTemplate := &model.FreightTemplate{
|
||||
StoreID: storeSku.StoreID,
|
||||
VendorStoreID: storeDetail.VendorStoreID,
|
||||
TemplateID: param.FreightId,
|
||||
WarehouseID: 0,
|
||||
FenceID: "",
|
||||
TradeLimitID: param.SaleLimitId,
|
||||
}
|
||||
dao.WrapAddIDCULDEntity(freightTemplate, "jxAdmin")
|
||||
err = dao.CreateEntity(dao.GetDB(), freightTemplate)
|
||||
} else {
|
||||
param.FreightId = temp.TemplateID
|
||||
param.SaleLimitId = temp.TradeLimitID
|
||||
}
|
||||
|
||||
param.MainProductId = tiktokResultProductId
|
||||
param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, tiktokResultProductId, storeSku)
|
||||
|
||||
param.StoreId = utils.Str2Int64(vendorStoreID)
|
||||
// 抖店创建子商品
|
||||
tiktokResultChildren, err := api.CreateStoreCommodity(param)
|
||||
if err != nil {
|
||||
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
|
||||
storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
|
||||
continue
|
||||
}
|
||||
storeSku.VendorSkuID = utils.Int64ToStr(tiktokResultChildren.ProductId) // 子商品主id
|
||||
storeSku.VendorMainId = utils.Int64ToStr(tiktokResultProductId) // 商品主id
|
||||
|
||||
}
|
||||
} else {
|
||||
syncType = "更新商品"
|
||||
for _, storeSku := range storeSkuList {
|
||||
// 更新商品(目前只更新子商品,主商品暂不支持)
|
||||
param := &product_editV2_request.ProductEditV2Param{
|
||||
CategoryLeafId: utils.Str2Int64(storeSku.SkuVendorMapCatID),
|
||||
Name: storeSku.Name,
|
||||
PayType: tiktokShop.TiktokPayType1,
|
||||
ReduceType: tiktokShop.SkuReduceTypePayMakeOrder,
|
||||
Weight: utils.Int2Float64(storeSku.Weight),
|
||||
DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay,
|
||||
PresellType: tiktokShop.SendGoodsTypeNow,
|
||||
Supply7dayReturn: 2,
|
||||
Mobile: storeDetail.Tel1,
|
||||
Commit: true,
|
||||
Specs: "净重|" + fmt.Sprintf("%f", storeSku.SpecQuality) + storeSku.SpecUnit,
|
||||
NeedRechargeMode: false,
|
||||
SellChannel: []int64{0},
|
||||
StartSaleType: 0,
|
||||
PickupMethod: "0",
|
||||
}
|
||||
// param.AccountTemplateId = ""
|
||||
// 获取上传图,商品轮播图
|
||||
img, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
param.Pic = img
|
||||
// 商品详情图
|
||||
img2, err := GetTiktokImgList(utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.DescImg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
param.Description = img2
|
||||
|
||||
// weight_unit 目前抖音只支持g和kg两种
|
||||
switch storeSku.Unit {
|
||||
case "g", "ml", "G", "ML":
|
||||
param.WeightUnit = tiktokShop.WeightUint_G
|
||||
case "kg", "l", "L", "KG":
|
||||
param.WeightUnit = tiktokShop.WeightUint_G
|
||||
}
|
||||
|
||||
// spec_prices
|
||||
param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, utils.Str2Int64(storeSku.VendorSkuID), storeSku)
|
||||
param.ProductFormatNew = storeSku.TiktokAttribute
|
||||
|
||||
// 获取品牌
|
||||
//brandID, err := api.GetSkuBrand(param.CategoryLeafId)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//param.StandardBrandId = brandID
|
||||
|
||||
//tiktokResult, err := api.EditStoreCommodity(param) // 创建主商品
|
||||
//if err != nil {
|
||||
// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
|
||||
// storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
|
||||
// continue
|
||||
//}
|
||||
|
||||
// 创建子商品
|
||||
//param.FreightId = freightId
|
||||
param.ProductId = utils.Str2Int64(storeSku.VendorSkuID)
|
||||
//param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, tiktokResult.ProductId, storeSku)
|
||||
// 获取门店限售模板
|
||||
//saleLimitId, err := CreateSaleTemp(utils.Str2Int64(vendorStoreID), api)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//param.SaleLimitId = saleLimitId
|
||||
//param.StoreId = utils.Str2Int64(vendorStoreID)
|
||||
// 抖店创建商品
|
||||
if err := api.EditStoreCommodity(param); err != nil {
|
||||
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
|
||||
storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
|
||||
continue
|
||||
}
|
||||
storeSku.VendorSkuID = storeSku.VendorSkuID
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if len(failedList) > 0 {
|
||||
err = nil
|
||||
}
|
||||
return failedList, err
|
||||
}
|
||||
|
||||
// CreateSaleTemp 创建限售模板
|
||||
func CreateSaleTemp(storeId int64, api *tiktokShop.API) (int64, error) {
|
||||
// 获取限售模板
|
||||
@@ -284,3 +596,78 @@ func GetSpecPrices(specs, storeId string, mainSkuId int64, localSku *dao.StoreSk
|
||||
data, _ := json.Marshal(skuSize)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func vendorSku2Jx(tiktokSku *product_detail_response.ProductDetailData) (skuName *partner.SkuNameInfo) {
|
||||
if len(tiktokSku.SpecPrices) == 0 {
|
||||
return nil
|
||||
}
|
||||
prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(tiktokSku.Name)
|
||||
vendorSku := tiktokSku.SpecPrices[0]
|
||||
weight := jxutils.FormatSkuWeight(specQuality, specUnit)
|
||||
|
||||
skuName = &partner.SkuNameInfo{
|
||||
NameID: utils.Str2Int(vendorSku.OuterSkuId),
|
||||
VendorNameID: utils.Int64ToStr(tiktokSku.MainProductId),
|
||||
UPC: tiktokSku.ProductIdStr,
|
||||
Prefix: prefix,
|
||||
Name: name,
|
||||
Unit: unit,
|
||||
Status: tiktokSkuStatus2Jx(tiktokSku.Status), //此处为之前一个bug 如果吧状态放到切片内层 对于内层函数中映射无法关联 永远获取到的初始值为0
|
||||
SkuList: []*partner.SkuInfo{
|
||||
&partner.SkuInfo{
|
||||
StoreSkuInfo: partner.StoreSkuInfo{
|
||||
VendorSkuID: utils.Int64ToStr(vendorSku.SkuId),
|
||||
SkuID: int(vendorSku.OutSkuId),
|
||||
IsSpecialty: 0,
|
||||
Stock: int(vendorSku.StockNum),
|
||||
VendorPrice: vendorSku.Price,
|
||||
Status: tiktokSkuStatus2Jx(tiktokSku.Status),
|
||||
},
|
||||
SkuName: tiktokSku.Name,
|
||||
Comment: comment,
|
||||
SpecQuality: float64(specQuality),
|
||||
SpecUnit: specUnit,
|
||||
Weight: weight,
|
||||
},
|
||||
},
|
||||
PictureList: tiktokSku.Pic,
|
||||
}
|
||||
if tiktokSku.CategoryDetail != nil {
|
||||
// todo, 因为当前我们用的是分类名操作这种方式,所以要返回分类名(而不是分类code)
|
||||
skuName.VendorCatIDList = []string{tiktokSku.CategoryDetail.FirstCname, tiktokSku.CategoryDetail.SecondCname, tiktokSku.CategoryDetail.ThirdCname, tiktokSku.CategoryDetail.FourthCname}
|
||||
}
|
||||
return skuName
|
||||
}
|
||||
|
||||
func tiktokSkuStatus2Jx(skuStatus int64) (jxSkuStatus int) {
|
||||
if skuStatus == mtwmapi.SellStatusOnline {
|
||||
jxSkuStatus = model.SkuStatusNormal
|
||||
} else {
|
||||
jxSkuStatus = model.SkuStatusDontSale
|
||||
}
|
||||
return jxSkuStatus
|
||||
}
|
||||
|
||||
func getStoreVendorOrgCode(storeID int) (vendorOrgCode string) {
|
||||
if storeMap, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDDD, ""); storeMap != nil {
|
||||
return storeMap.VendorOrgCode
|
||||
}
|
||||
return vendorOrgCode
|
||||
}
|
||||
|
||||
func convertVendorCatList(remoteCats []*tiktokShop.RetailCategoryInfo) (cats []*partner.BareCategoryInfo) {
|
||||
for _, rCat := range remoteCats {
|
||||
cat := &partner.BareCategoryInfo{
|
||||
VendorCatID: utils.Int64ToStr(rCat.Id),
|
||||
Name: rCat.Name,
|
||||
Level: int(rCat.Level),
|
||||
Seq: 0,
|
||||
Children: convertVendorCatList(rCat.Children),
|
||||
}
|
||||
if cat.VendorCatID == "" {
|
||||
cat.VendorCatID = rCat.Name
|
||||
}
|
||||
cats = append(cats, cat)
|
||||
}
|
||||
return cats
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user