This commit is contained in:
邹宗楠
2026-03-25 09:13:44 +08:00
parent 9b49d15c86
commit 6f938bf0dc
9 changed files with 261 additions and 164 deletions

View File

@@ -1,12 +1,19 @@
package bidding
import (
"encoding/json"
"fmt"
"git.rosy.net.cn/baseapi/platformapi/ali_logistics_query"
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
"git.rosy.net.cn/baseapi/platformapi/tonglianpayapi"
"git.rosy.net.cn/baseapi/platformapi/weixinapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
"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/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"time"
)
@@ -37,6 +44,22 @@ func LoadingLogistics(paramLogistic []*model.UpdateMaterialLogistic) []error {
errList = append(errList, err)
continue
}
payList, _ := dao.GetOrderPayList(db, goodsOrder.VendorOrderID, goodsOrder.VendorID)
for _, pl := range payList {
if pl.OriginalData != "" {
originalData := &tonglianpayapi.CallBackResult{}
json.Unmarshal([]byte(pl.OriginalData), originalData)
if err = api.WeixinMiniAPI.SNSDeliveryGoodsOrder(&weixinapi.DeliveryOrder{
TransactionId: originalData.ChnlTrxID,
ReceivedTime: time.Now().Unix(),
}); err != nil {
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "微信物料送达推送", fmt.Sprintf("物料商城下单,送达错误:%s,请注意查看,err:%s", goodsOrder.VendorOrderID, err.Error()))
}
}
}
}
}

View File

@@ -571,29 +571,29 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS
if copyMap[storeSku.AppFoodCode] == nil || copyMap[storeSku.AppFoodCode].MainSkuId == "" {
param := &product_addV2_request.ProductAddV2Param{
Name: utils.LimitUTF8StringLen(storeSku.Name, 90),
PayType: tiktok_api.TiktokPayType1,
PayType: utils.Int64ToPointer(tiktok_api.TiktokPayType1),
ReduceType: tiktok_api.SkuReduceTypePayMakeOrder,
DeliveryDelayDay: tiktok_api.DeliveryDelayDayToDay,
PresellType: tiktok_api.SendGoodsTypeNow,
Supply7dayReturn: 0, // 是否支持7天无理由0不支持1支持2支持拆封后不支持
DeliveryDelayDay: utils.Int64ToPointer(tiktok_api.DeliveryDelayDayToDay),
PresellType: utils.Int64ToPointer(tiktok_api.SendGoodsTypeNow),
Supply7dayReturn: utils.Int64ToPointer(0), // 是否支持7天无理由0不支持1支持2支持拆封后不支持
Mobile: toStoreDetail.Tel1,
Commit: true,
//Specs: "重量|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit,
NeedRechargeMode: false,
NeedRechargeMode: nil,
SellChannel: []int64{0},
StartSaleType: 0,
PickupMethod: "0",
OuterProductId: storeSku.AppFoodCode, // 本地skuId为外部商品id
StartSaleType: utils.Int64ToPointer(0),
PickupMethod: utils.String2Pointer("0"),
OuterProductId: utils.String2Pointer(storeSku.AppFoodCode), // 本地skuId为外部商品id
}
specs := "重量|"
specsList := make([]string, 0, 0)
upc := ""
for _, sl := range storeSku.SkuList {
specsList = append(specsList, strings.Split(sl.Spec, "*")[0])
param.Weight = utils.Str2Float64(sl.Weight)
param.Weight = utils.Float64ToPointer(utils.Str2Float64(sl.Weight))
upc = sl.Upc
}
param.Specs = specs + strings.Join(specsList, ",")
param.Specs = utils.String2Pointer(specs + strings.Join(specsList, ","))
// 获取上传图,商品轮播图
imgs := make([]tiktok_api.Imgs, 0, 0)
for spk, spl := range storeSku.PictureList {
@@ -631,7 +631,7 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS
continue
}
if strings.Contains(til, "white_") {
param.WhiteBackGroundPicUrl = v.ByteUrl
param.WhiteBackGroundPicUrl = utils.String2Pointer(v.ByteUrl)
}
picList = append(picList, v.ByteUrl)
}
@@ -641,7 +641,7 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS
if len(param.Pic) != 0 {
var vendorCategoryId int64 = 0
// 根据图片推导分类
picList = append(picList, param.WhiteBackGroundPicUrl, param.Description)
picList = append(picList, *param.WhiteBackGroundPicUrl, param.Description)
vendorCategoryId, _ = toApi.GetRecommendCategory(picList)
// 根据名字推导分类
if vendorCategoryId == 0 {
@@ -660,16 +660,16 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS
// 是否支持七天无理由
isAfterSale, rule := toApi.GetProductUpdateRule(param.CategoryLeafId)
if isAfterSale {
param.AfterSaleService = map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)}
param.AfterSaleService = &map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)}
}
// weight_unit 目前抖音只支持g和kg两种
param.WeightUnit = tiktok_api.WeightUint_G
param.WeightUnit = utils.Int64ToPointer(tiktok_api.WeightUint_G)
// spec_prices
//param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, 0, storeSku)
skuSize := make([]*tiktok_api.SpecDetailList, 0, 0)
name1 := strings.Split(strings.Split(param.Specs, "|")[1], ",")
name1 := strings.Split(strings.Split(*param.Specs, "|")[1], ",")
for _, sl := range storeSku.SkuList {
for i := 0; i < len(name1); i++ {
if name1[i] == strings.Split(sl.Spec, "*")[0] {
@@ -693,16 +693,16 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS
}
}
data, _ := json.Marshal(skuSize)
param.SpecPrices = string(data)
param.SpecPrices = utils.String2Pointer(string(data))
// 获取商品的属性
//param.ProductFormatNew, param.StandardBrandId, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId)
if upc == "" {
param.StandardBrandId = 596120136
param.StandardBrandId = utils.Int64ToPointer(596120136)
} else {
brandName, err := tiktok_store.GetBrandByBrandName(upc)
if err != nil {
param.StandardBrandId = 596120136
param.StandardBrandId = utils.Int64ToPointer(596120136)
} else {
if strings.Contains(brandName, "/") || strings.Contains(brandName, "(") || strings.Contains(brandName, "") {
brandName = strings.Split(brandName, "/")[0]
@@ -715,14 +715,14 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS
}
standardBrandId, err := toApi.GetSkuBrand(param.CategoryLeafId, brandName)
if err != nil {
param.StandardBrandId = 596120136
param.StandardBrandId = utils.Int64ToPointer(596120136)
} else {
param.StandardBrandId = standardBrandId
param.StandardBrandId = &standardBrandId
}
}
}
if param.StandardBrandId == 0 {
param.StandardBrandId = 596120136
if param.StandardBrandId == utils.Int64ToPointer(0) {
param.StandardBrandId = utils.Int64ToPointer(596120136)
}
categoryList, err := toApi.GetCatePropertyV2(param.CategoryLeafId)
if err != nil {
@@ -753,11 +753,11 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS
}
}
param.ProductFormatNew = utils.Format4Output(categoryMap, false)
param.ProductFormatNew = utils.String2Pointer(utils.Format4Output(categoryMap, false))
//param.ProductFormatNew, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId)
if StoreTemp[toStoreDetail.VendorStoreID] != "" {
idList := strings.Split(StoreTemp[toStoreDetail.VendorStoreID], "_")
param.FreightId, param.SaleLimitId = utils.Str2Int64(idList[0]), utils.Str2Int64(idList[1])
param.FreightId, param.SaleLimitId = utils.Str2Int64(idList[0]), utils.Int64ToPointer(utils.Str2Int64(idList[1]))
} else {
// 运费模板
param.FreightId, err = tiktok_store.GetDeliveryTemp(toApi, toStoreDetail.VendorStoreID, toStoreDetail)
@@ -769,7 +769,7 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS
return errList, nil
}
// 获取门店限售模板
param.SaleLimitId, err = tiktok_store.CreateSaleTemp(utils.Str2Int64(toStoreDetail.VendorStoreID), toApi)
saleLimitId, err := tiktok_store.CreateSaleTemp(utils.Str2Int64(toStoreDetail.VendorStoreID), toApi)
if err != nil {
errList = append(errList, &mtwmapi.AppFoodResult{
AppFoodCode: storeSku.AppFoodCode,
@@ -777,6 +777,7 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS
})
return errList, nil
}
param.SaleLimitId = &saleLimitId
StoreTemp[toStoreDetail.VendorStoreID] = fmt.Sprintf("%d_%d", param.FreightId, param.SaleLimitId)
}

View File

@@ -2109,7 +2109,7 @@ type StoreOrderRank struct {
func GetOrderStatusList(vendorOrderId string, orderType, vendorId int) (orderStatus []*model.OrderStatus, err error) {
sql := ` SELECT * FROM order_status WHERE ref_vendor_order_id = ? AND vendor_id = ? AND order_type = ? ORDER BY status_time asc `
param := []interface{}{vendorOrderId, vendorId, orderType}
if err = GetRows(GetDB(), &orderStatus, sql, param); err != nil {
if err = GetRows(GetDB(), &orderStatus, sql, param...); err != nil {
return nil, err
}
return orderStatus, nil

View File

@@ -285,8 +285,7 @@ func (c *PrinterHandler) getOrderContentBigMiddle(order *model.GoodsOrder, store
`
}
orderFmt += `<QR>%s</QR><BR>
` + getCode +
orderFmt += getCode +
`<L>客户: %s</L><BR>
<L>电话: %s</L><BR>
<L>地址: %s</L><BR>
@@ -304,7 +303,7 @@ func (c *PrinterHandler) getOrderContentBigMiddle(order *model.GoodsOrder, store
utils.Time2Str(order.OrderCreatedAt),
utils.Time2Str(expectedDeliveryTime),
order.VendorOrderID,
order.VendorOrderID,
//order.VendorOrderID,
order.ConsigneeName,
order.ConsigneeMobile,
order.ConsigneeAddress,

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
"git.rosy.net.cn/baseapi/platformapi/weixinapi"
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
"git.rosy.net.cn/jx-callback/business/partner"
"strings"
@@ -156,6 +157,42 @@ func onTLpayFinished(call *tonglianpayapi.CallBackResult) (err error) {
}
//weixinmsg.SendUserMessage(jxcontext.AdminCtx, "商户购买物料信息推送", fmt.Sprintf("门店%s:%d,在物料商城下单了:%s,请注意查看", store.Name, store.ID, order.VendorOrderID), userID, true, true)
}
authList, _ := dao.GetUserBindAuthInfo(db, order.UserID, 0, nil, "", "", []string{api.WeixinMiniAppID2})
if authList != nil && len(authList) != 0 {
param := &weixinapi.SNSSendOrderParameter{
OrderKey: struct {
OrderNumberType int `json:"order_number_type"`
TransactionId string `json:"transaction_id"`
Mchid string `json:"mchid"`
OutTradeNo string `json:"out_trade_no"`
}{
OrderNumberType: 2,
TransactionId: call.ChnlTrxID,
},
LogisticsType: 1,
DeliveryMode: 1,
IsAllDelivered: false,
ShippingList: append([]weixinapi.ShippingList{}, weixinapi.ShippingList{
TrackingNo: order.VendorOrderID,
ExpressCompany: "YD",
ItemDesc: "背心袋",
Contact: struct {
ConsignorContact string `json:"consignor_contact"`
ReceiverContact string `json:"receiver_contact"`
}{},
}),
UploadTime: time.Now().Format(time.RFC3339),
Payer: struct {
Openid string `json:"openid"`
}{
Openid: authList[0].AuthID,
},
}
if err = api.WeixinMiniAPI.SNSSendGoodsOrder(param); err != nil {
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "物料发货推送", fmt.Sprintf("物料商城下单,发货错误:%s,请注意查看,err:%s", order.VendorOrderID, err.Error()))
}
}
}
}
} else {

View File

@@ -44,7 +44,7 @@ func (c *PurchaseHandler) GetVendorID() int {
}
func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) {
cats, err := getAPI("68023619", 0, "").GetShopCategory(0)
cats, err := getAPI("260477060", 0, "").GetShopCategory(0)
if err != nil {
return nil, err
}

View File

@@ -142,13 +142,7 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
}
// 根据本地商品id获取线上商品是否存在,存在则只创建子商品
// 获取本地存储映射关系,获取本地主商品id是否存在
//var mainProductId int64 = 0
//var mainOrderDetail *product_detail_response.ProductDetailData
localThing, _ := dao.GetThingToTiktokMapList(db, model.VendorIDDD, int64(storeSku.SkuID), storeDetail.VendorOrgCode)
//if len(localThing) != 0 && localThing[0].VendorThingID != "" {
// mainProductId = utils.Str2Int64(localThing[0].VendorThingID)
//}
if len(localThing) == 0 {
param, failedList2 := makeMainProductSku(db, api, storeSku, storeDetail, storeID, vendorStoreID, syncType)
if len(failedList2) != 0 {
@@ -179,7 +173,6 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
}
tiktokResult.Sku = specPrices
} else {
//storeSku.SkuSyncStatus = model.SyncFlagNewMask // 只创建主品,子品都没做
storeSku.SkuSyncStatus = 2 // 后续不在做定时任务更新
storeSku.VendorSonSkuID = "此商品已经创建抖音主商品了"
failedList = putils.GetErrMsg2FailedSingleList(storeSku, errCreate, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
@@ -207,7 +200,6 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
attrId = append(attrId, utils.Int64ToStr(v.SkuId))
}
//mainProductId = tiktokResult.ProductId
storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
storeSku.SkuSyncStatus = model.SyncFlagNewMask // 只创建主品,子品都没做
storeSku.VendorMainId = utils.Int64ToStr(tiktokResult.ProductId)
@@ -240,12 +232,9 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
for _, v := range tiktokResult.Sku {
attrId = append(attrId, utils.Int64ToStr(v.SkuId))
}
//mainProductId = tiktokResult.ProductId
//storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
storeSku.SkuSyncStatus = model.SyncFlagNewMask // 只创建主品,子品都没做
storeSku.VendorMainId = utils.Int64ToStr(tiktokResult.ProductId)
storeSku.VendorSkuAttrId = strings.Join(attrId, ",") // 属性id skuID
//storeSku.VendorSonSkuID = utils.Int2Str(storeSku.SkuID) // 还没同步子商品
failedList = putils.GetErrMsg2FailedSingleList(storeSku, errors.New("只创建了主商品,没创建子商品"), storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
case model.ThingTypeSyncing:
if time.Now().Unix()-localThing[0].CreatedAt.Unix() > 300 {
@@ -349,21 +338,21 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
// 更新主商品,在同步到子门店,考虑审核时间
param := &product_editV2_request.ProductEditV2Param{
Name: utils.LimitUTF8StringLen(storeSku.SkuName, 90),
PayType: tiktokShop.TiktokPayType1,
ReduceType: tiktokShop.SkuReduceTypePayMakeOrder,
Weight: utils.Int2Float64(storeSku.Weight),
DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay,
PresellType: tiktokShop.SendGoodsTypeNow,
Mobile: storeDetail.Tel1,
Name: utils.String2Pointer(utils.LimitUTF8StringLen(storeSku.SkuName, 90)),
PayType: utils.Int64ToPointer(tiktokShop.TiktokPayType1),
ReduceType: utils.Int64ToPointer(tiktokShop.SkuReduceTypePayMakeOrder),
Weight: utils.Float64ToPointer(utils.Int2Float64(storeSku.Weight)),
DeliveryDelayDay: utils.Int64ToPointer(tiktokShop.DeliveryDelayDayToDay),
PresellType: utils.Int64ToPointer(tiktokShop.SendGoodsTypeNow),
Mobile: utils.String2Pointer(storeDetail.Tel1),
Commit: true,
Specs: "重量|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit,
NeedRechargeMode: false,
Specs: utils.String2Pointer("总净重|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit),
NeedRechargeMode: nil,
SellChannel: []int64{0},
StartSaleType: 0,
PickupMethod: "0",
StartSaleType: utils.Int64ToPointer(0),
PickupMethod: utils.String2Pointer("0"),
}
param.Name = checkNameLenght(param.Name)
param.Name = utils.String2Pointer(checkNameLength(*param.Name))
// 暂时只考虑修改白底图,提高效率.其余图片不做修改
img, descImg, whiteImg, err := GetTiktokImgList(api, utils.Int2Str(storeSku.StoreID), storeSku.SkuID, storeSku.DescImg, storeSku.Img, []string{storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5})
@@ -371,31 +360,40 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
continue
}
param.Pic = img
param.Description = descImg
param.WhiteBackGroundPicUrl = whiteImg
param.WeightUnit = tiktokShop.WeightUint_G
param.Pic = utils.String2Pointer(img)
param.Description = utils.String2Pointer(descImg)
param.WhiteBackGroundPicUrl = utils.String2Pointer(whiteImg)
param.WeightUnit = utils.Int64ToPointer(tiktokShop.WeightUint_G)
// 部分商品没有所属的分类,直接跳过!
if storeSku.SkuVendorMapCatID != "" {
param.CategoryLeafId = utils.Str2Int64(storeSku.SkuVendorMapCatID)
} else if len(param.Pic) != 0 { // 自动推导分类id
var vendorCategoryId int64 = 0
// 根据图片推导分类
vendorCategoryId, _ = api.GetRecommendCategory(strings.Split(img, "|"))
if vendorCategoryId == 0 {
vendorCategoryId, _ = api.GetRecommendCategoryByName(storeSku.SkuName)
// 老的类目长度小于十
var vendorCategoryId int64 = 0
var isUpdate bool = false
if storeSku.SkuVendorMapCatID == "" {
if vendorCategoryId, _ = api.GetRecommendCategory(strings.Split(img, "|")); vendorCategoryId == 0 { // 根据图片推导分类
vendorCategoryId, _ = api.GetRecommendCategoryByName(storeSku.SkuName) // 根据名字推导分类
}
if vendorCategoryId == 0 || err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSku, errors.New("当前商品本地未设置抖音分类/抖音推荐分类查询错误:"+err.Error()), storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
isUpdate = true
} else if len(storeSku.SkuVendorMapCatID) < 10 {
// 用老的分类ID换取新的分类ID
newCategoryMap, err := api.BatchGetChannelCategoryMapping([]int64{utils.Str2Int64(storeSku.SkuVendorMapCatID)})
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
continue
}
param.CategoryLeafId = vendorCategoryId
vendorCategoryId = newCategoryMap[storeSku.VendorVendorCatID]
isUpdate = true
} else {
vendorCategoryId = utils.Str2Int64(storeSku.SkuVendorMapCatID)
}
if isUpdate {
dao.ExecuteSQL(db, `UPDATE sku_vendor_category_map SET vendor_category_id = ? WHERE name_id = ? AND vendor_id = ? `, []interface{}{utils.Int64ToStr(vendorCategoryId), storeSku.NameID, model.VendorIDDD})
}
param.CategoryLeafId = utils.Int64ToPointer(vendorCategoryId)
isAfterSale, rule := api.GetProductUpdateRule(param.CategoryLeafId)
isAfterSale, rule := api.GetProductUpdateRule(*param.CategoryLeafId)
if isAfterSale {
param.AfterSaleService = map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)}
param.AfterSaleService = &map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)}
}
// 获取主商品id
var mainIdInt int64
@@ -426,37 +424,39 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
//}
// 获取商品的属性
if storeSku.TiktokAttribute == "" || storeSku.TiktokAttribute == "{}" || storeSku.UpcTiktokBrandId == "" {
param.ProductFormatNew, param.StandardBrandId, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId)
if storeSku.TiktokAttribute != "" && storeSku.TiktokAttribute != "{}" && storeSku.UpcTiktokBrandId != "" {
param.ProductFormatNew = utils.String2Pointer(storeSku.TiktokAttribute)
} else {
productFormatNew, standardBrandId, err := MakeProductFormatNew(api, int64(storeSku.NameID), *param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
continue
}
} else {
param.ProductFormatNew = storeSku.TiktokAttribute
param.ProductFormatNew = utils.String2Pointer(productFormatNew)
param.StandardBrandId = utils.Int64ToPointer(standardBrandId)
}
// 获取品牌
if param.StandardBrandId == 0 {
param.StandardBrandId, _ = getTiktokBrandId(api, db, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId, param.CategoryLeafId)
}
if param.StandardBrandId == 0 {
param.StandardBrandId = 596120136 // 无品牌
if param.StandardBrandId == utils.Int64ToPointer(model.NO) {
standardBrandId, _ := getTiktokBrandId(api, db, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId, *param.CategoryLeafId)
if standardBrandId != 0 {
param.StandardBrandId = utils.Int64ToPointer(standardBrandId)
} else {
param.StandardBrandId = utils.Int64ToPointer(596120136)
}
}
// 修改商品
param.ProductId = mainIdInt
//param.MainProductId = mainIdInt
//param.FreightId, _ = api.GetStoreBindTemp(utils.Str2Int64(vendorStoreID))
param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, mainIdInt, storeSku)
param.SpecPrices = utils.String2Pointer(GetSpecPrices(*param.Specs, vendorStoreID, mainIdInt, storeSku))
err = api.EditStoreCommodity(param)
if err != nil && !strings.Contains(err.Error(), "您上传的商品主图存在重复") {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
//storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
} /* else {
// todo 暂时关闭之后解开
} else {
skuId, _ := upDateChildrenPriceStockLaunch(api, storeSku, utils.Str2Int64(storeSku.VendorSkuID), vendorStoreID, syncType)
storeSku.VendorSonSkuID = utils.Int64ToStr(skuId) // 品库修改 售卖状态待同步 价格待同步
}*/
}
//storeSku.SkuSyncStatus = model.SyncFlagStoreSkuModifiedMask // 品库修改 售卖状态待同步 价格待同步
storeSku.SkuSyncStatus = 0 // 品库修改 售卖状态待同步 价格待同步
}
@@ -468,21 +468,22 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
func makeMainProductSku(db *dao.DaoDB, api *tiktokShop.API, storeSku *dao.StoreSkuSyncInfo, storeDetail *dao.StoreDetail, storeID int, vendorStoreID, syncType string) (param *product_addV2_request.ProductAddV2Param, failedList []*partner.StoreSkuInfoWithErr) {
param = &product_addV2_request.ProductAddV2Param{
Name: utils.LimitUTF8StringLen(storeSku.SkuName, 90),
PayType: tiktokShop.TiktokPayType1,
PayType: utils.Int64ToPointer(tiktokShop.TiktokPayType1),
ReduceType: tiktokShop.SkuReduceTypePayMakeOrder,
Weight: utils.Int2Float64(storeSku.Weight),
DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay,
PresellType: tiktokShop.SendGoodsTypeNow,
Weight: utils.Float64ToPointer(utils.Int2Float64(storeSku.Weight)),
DeliveryDelayDay: utils.Int64ToPointer(tiktokShop.DeliveryDelayDayToDay),
PresellType: utils.Int64ToPointer(tiktokShop.SendGoodsTypeNow),
Mobile: storeDetail.Tel1,
Commit: true,
Specs: "重量|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit,
NeedRechargeMode: false,
Specs: utils.String2Pointer("总净重|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit),
NeedRechargeMode: nil,
SellChannel: []int64{0},
StartSaleType: 0,
PickupMethod: "0",
OuterProductId: utils.Int2Str(storeSku.SkuID), // 本地skuId为外部商品id
StartSaleType: utils.Int64ToPointer(0),
PickupMethod: utils.String2Pointer("0"),
OuterProductId: utils.String2Pointer(utils.Int2Str(storeSku.SkuID)), // 本地skuId为外部商品id
ProductType: 0,
}
param.Name = checkNameLenght(param.Name)
param.Name = checkNameLength(param.Name)
// 获取上传图,商品轮播图
img, detailImg, whiteImg, err := GetTiktokImgList(api, utils.Int2Str(storeSku.StoreID), storeSku.SkuID, storeSku.DescImg, storeSku.Img, []string{storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5})
@@ -492,23 +493,32 @@ func makeMainProductSku(db *dao.DaoDB, api *tiktokShop.API, storeSku *dao.StoreS
}
param.Pic = img
param.Description = detailImg
param.WhiteBackGroundPicUrl = whiteImg
param.WhiteBackGroundPicUrl = utils.String2Pointer(whiteImg)
// 部分商品没有所属的分类,直接跳过!
if storeSku.SkuVendorMapCatID != "" {
param.CategoryLeafId = utils.Str2Int64(storeSku.SkuVendorMapCatID)
} else if len(param.Pic) != 0 { // 自动推导分类id
var vendorCategoryId int64 = 0
vendorCategoryId, _ = api.GetRecommendCategory(strings.Split(img, "|")) // 根据图片推导分类
if vendorCategoryId == 0 {
// 老的类目长度小于十
var vendorCategoryId int64 = 0
var isUpdate bool = false
if storeSku.SkuVendorMapCatID == "" {
if vendorCategoryId, _ = api.GetRecommendCategory(strings.Split(img, "|")); vendorCategoryId == 0 { // 根据图片推导分类
vendorCategoryId, _ = api.GetRecommendCategoryByName(storeSku.SkuName) // 根据名字推导分类
}
if vendorCategoryId == 0 || err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSku, errors.New("当前商品本地未设置抖音分类/抖音推荐分类查询错误"), storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
return
isUpdate = true
} else if len(storeSku.SkuVendorMapCatID) < 10 {
// 用老的分类ID换取新的分类ID
newCategoryMap, err := api.BatchGetChannelCategoryMapping([]int64{utils.Str2Int64(storeSku.SkuVendorMapCatID)})
if err != nil {
return nil, putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
}
param.CategoryLeafId = vendorCategoryId
vendorCategoryId = newCategoryMap[storeSku.VendorVendorCatID]
isUpdate = true
} else {
vendorCategoryId = utils.Str2Int64(storeSku.SkuVendorMapCatID)
}
if isUpdate {
dao.ExecuteSQL(db, `UPDATE sku_vendor_category_map SET vendor_category_id = ? WHERE name_id = ? AND vendor_id = ? `, []interface{}{utils.Int64ToStr(vendorCategoryId), storeSku.NameID, model.VendorIDDD})
}
param.CategoryLeafId = vendorCategoryId
// 这个情况是原有商品不存在和推荐查询不到类目id是,使用京西类目和抖音类目的绑定关系
// 但是不太实用,导致商品类目错误被暂停营业等
//if storeSku.VendorVendorCatID != 0 && param.CategoryLeafId == 0 {
@@ -517,37 +527,43 @@ func makeMainProductSku(db *dao.DaoDB, api *tiktokShop.API, storeSku *dao.StoreS
isAfterSale, rule := api.GetProductUpdateRule(param.CategoryLeafId)
if isAfterSale {
param.AfterSaleService = map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)}
param.AfterSaleService = &map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)}
}
// weight_unit 目前抖音只支持g和kg两种
param.WeightUnit = tiktokShop.WeightUint_G
param.WeightUnit = utils.Int64ToPointer(tiktokShop.WeightUint_G)
// spec_prices
param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, 0, storeSku)
param.SpecPrices = utils.String2Pointer(GetSpecPrices(*param.Specs, vendorStoreID, 0, storeSku))
// 获取商品的属性
if storeSku.TiktokAttribute != "" && storeSku.TiktokAttribute != "{}" && storeSku.UpcTiktokBrandId != "" {
param.ProductFormatNew = storeSku.TiktokAttribute
param.ProductFormatNew = utils.String2Pointer(storeSku.TiktokAttribute)
} else {
param.ProductFormatNew, param.StandardBrandId, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId)
//param.ProductFormatNew, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId)
productFormatNew, standardBrandId, err := MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
return
}
param.ProductFormatNew = utils.String2Pointer(productFormatNew)
param.StandardBrandId = utils.Int64ToPointer(standardBrandId)
}
if param.StandardBrandId == 0 {
param.StandardBrandId, _ = getTiktokBrandId(api, db, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId, param.CategoryLeafId)
if param.StandardBrandId == utils.Int64ToPointer(model.NO) {
standardBrandId, _ := getTiktokBrandId(api, db, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId, param.CategoryLeafId)
if standardBrandId != 0 {
param.StandardBrandId = utils.Int64ToPointer(standardBrandId)
} else {
param.StandardBrandId = utils.Int64ToPointer(596120136)
}
}
if param.StandardBrandId == 0 {
param.StandardBrandId = 596120136
}
param.FreightId, param.SaleLimitId, err = getFreightIdAndSaleLimitId(api, db, storeDetail, vendorStoreID)
freightId, saleLimitId, err := getFreightIdAndSaleLimitId(api, db, storeDetail, vendorStoreID)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType)
return
}
param.FreightId = freightId
param.SaleLimitId = utils.Int64ToPointer(saleLimitId)
return
}
@@ -632,7 +648,7 @@ func loadMainProductId(api *tiktokShop.API, storeSku *dao.StoreSkuSyncInfo, main
return mainOrderDetailProductId
}
func checkNameLenght(name string) string {
func checkNameLength(name string) string {
var chinesLen int // 中文
var punctZh int // 中文标点
var punctEn int // 英文标点
@@ -952,6 +968,47 @@ func GetProductFormatNew(categoryLeftId int64, vendorOrgCode string) (*product_g
//return string(productFormatNew), nil
}
type VendorCategoryId struct {
VendorCategoryID string `orm:"column(vendor_category_id)" json:"vendorCategoryID"`
}
func BatchGetChannelCategoryMapping() error {
var db = dao.GetDB()
sql := ` SELECT vendor_category_id FROM sku_vendor_category_map WHERE vendor_id = 14 GROUP BY vendor_category_id`
data := make([]*VendorCategoryId, 0, 0)
if err := dao.GetRows(db, &data, sql, nil); err != nil {
return err
}
count := len(data) / 50
if len(data)%50 != 0 {
count = count + 1
}
categoryList := make([]int64, 0, len(data))
for _, v := range data {
if len(v.VendorCategoryID) < 10 {
categoryList = append(categoryList, utils.Str2Int64(v.VendorCategoryID))
}
}
api := getAPI("260477060", 0, "")
for i := 1; i <= count; i++ {
cats := make(map[int64]int64, 50)
if i == count {
cats, _ = api.BatchGetChannelCategoryMapping(categoryList[(i-1)*50:])
} else {
cats, _ = api.BatchGetChannelCategoryMapping(categoryList[(i-1)*50 : i*50])
}
for k, c := range cats {
sql2 := ` UPDATE sku_vendor_category_map SET vendor_category_id = ? WHERE vendor_category_id = ?`
param := []interface{}{utils.Int64ToStr(c), utils.Int64ToStr(k)}
dao.ExecuteSQL(db, sql2, param...)
}
}
return nil
}
// GetTiktokImgList 获取抖音图片链接 whiteImg 白底图,有的商品可能没有白底图随便用一张(创建商品专用,更新商品只考虑更新白底图,不然太慢了)
func GetTiktokImgList(api *tiktokShop.API, storeId string, skuId int, detailImg, whiteImg string, img []string) (string, string, string, error) {
detailTiktok := ""
@@ -1051,49 +1108,6 @@ func GetTiktokImgList(api *tiktokShop.API, storeId string, skuId int, detailImg,
return strings.Join(tiktokImg, "|"), detailTiktok, whiteTiktok, nil
}
// GetWhiteImg 更新专用暂时只考虑更新白底图
//func GetWhiteImg(api *tiktokShop.API, skuId int, storeId, whiteImg string) (string, error) {
// //每个图片都上传太慢了
// tiktokImgLocal, err := dao.GetVendorImg(skuId, model.VendorIDDD)
// if err == nil && tiktokImgLocal != nil && tiktokImgLocal.Img != "" {
// return tiktokImgLocal.Img, nil
// }
//
// imgs := make([]tiktokShop.Imgs, 0, 0)
// if whiteImg == "" {
// return "", fmt.Errorf("商品白底图不能为空")
// }
//
// imgs = append(imgs, tiktokShop.Imgs{
// Name: "white_" + storeId + "_" + whiteImg[21:54],
// Url: whiteImg,
// })
//
// tiktokImgList, err := api.BatchUploadImages(imgs)
// if err != nil {
// return "", err
// }
// if len(tiktokImgList) == model.NO {
// return "", fmt.Errorf("白底图片上传失败")
// }
//
// whiteTiktok := ""
// var tiktokImg []string
// for k, v := range tiktokImgList {
// if strings.Contains(k, "white_") {
// whiteTiktok = v.ByteUrl
// continue
// }
// tiktokImg = append(tiktokImg, v.ByteUrl)
// }
//
// if whiteTiktok == "" {
// whiteTiktok = tiktokImg[0]
// }
//
// return whiteTiktok, nil
//}
func MakeProductFormatNew(api *tiktokShop.API, skuNameId int64, categoryLeafId int64, upcCode, upcBrandName, upcTiktokBrandId string) (string, int64, error) {
db := dao.GetDB()
categoryList, err := api.GetCatePropertyV2(categoryLeafId)

View File

@@ -847,6 +847,19 @@ func (c *SkuController) GetTiktokCategoryValue() {
})
}
// @Title 更新最新的分类树
// @Description 更新最新的分类树
// @Param token header string true "认证token"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /BatchGetChannelCategoryMapping [get]
func (c *SkuController) BatchGetChannelCategoryMapping() {
c.callGetTiktokCategoryValue(func(params *tSkuGetTiktokCategoryValueParams) (interface{}, string, error) {
err := tiktok_store.BatchGetChannelCategoryMapping()
return nil, "", err
})
}
// @Title 根据美团分类id获取平台扩展规则
// @Description 根据美团分类id获取平台扩展规则
// @Param token header string true "认证token"

View File

@@ -2112,6 +2112,16 @@ func init() {
Filters: nil,
Params: nil})
// 更新最新的抖音分类树
web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"] = append(web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"],
web.ControllerComments{
Method: "BatchGetChannelCategoryMapping",
Router: `/BatchGetChannelCategoryMapping`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"] = append(web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"],
web.ControllerComments{
Method: "GetMTCategoryAttrList",