From 632c96f059ca3a780611ed4cbd77b6ff55068e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E5=AE=97=E6=A5=A0?= Date: Mon, 12 Dec 2022 09:33:24 +0800 Subject: [PATCH] 1 --- business/bidding/logistics_Loading.go | 215 ++++++++++++++++++ business/jxcallback/orderman/orderman_ext.go | 18 ++ .../jxcallback/scheduler/defsch/defsch.go | 8 +- business/jxstore/misc/misc.go | 8 + business/model/api_config.go | 3 +- business/model/dao/store_sku.go | 2 - business/model/dao/thing_map.go | 8 + business/model/order.go | 7 + .../purchase/tiktok_store/store_sku2.go | 36 +-- .../purchase/tiktok_store/store_sku2_utils.go | 162 +++++++------ conf/app.conf | 20 ++ controllers/jx_order.go | 20 ++ globals/api/api.go | 5 + routers/commentsRouter_controllers.go | 9 + 14 files changed, 432 insertions(+), 89 deletions(-) create mode 100644 business/bidding/logistics_Loading.go diff --git a/business/bidding/logistics_Loading.go b/business/bidding/logistics_Loading.go new file mode 100644 index 000000000..8c6bbd418 --- /dev/null +++ b/business/bidding/logistics_Loading.go @@ -0,0 +1,215 @@ +package bidding + +import ( + "git.rosy.net.cn/baseapi/platformapi/ali_logistics_query" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" + "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" +) + +func LoadingLogistics(paramLogistic []*model.UpdateMaterialLogistic) []error { + var param []*model.UpdateMaterialLogistic + if len(paramLogistic) == 0 || paramLogistic == nil { + param = GetLogisticOrder() + } else { + param = paramLogistic + } + + var db = dao.GetDB() + var errList = make([]error, 0, 0) + for _, logistics := range param { + // 获取当前订单物流状态 + statusList, err := orderman.FixedOrderManager.GetLogisticsOrderStatusList(logistics.OrderId, logistics.LogisticId, 9) + if err != nil { + errList = append(errList, err) + continue + } + + // 获取当前订单三方配送物流 + logisticsList, err := api.LogisticsApi.GetLogisticsInfo(logistics.LogisticId) + if err != nil { + errList = append(errList, err) + continue + } + + // 新订单,本地暂无物流信息,全部更新远端物流信息到本地 + var orderStatus = make([]*model.OrderStatus, 0, 0) + goodsOrderStatus := 0 + for _, v := range logisticsList.Info[0].LogisticsTraceDetailList { + orderStatusToLocal := &model.OrderStatus{ + VendorOrderID: logisticsList.OrderNo, + VendorID: model.VendorIDTotalWl, + OrderType: model.OrderTypeWaybill, + RefVendorOrderID: logistics.OrderId, + RefVendorID: model.VendorIDJX, + VendorStatus: v.SubLogisticsStatus, + StatusTime: time.Time{}, + DuplicatedCount: 0, + Remark: v.Desc, + ModelTimeInfo: model.ModelTimeInfo{CreatedAt: time.Now(), UpdatedAt: time.Now()}, + } + + switch v.SubLogisticsStatus { + case ali_logistics_query.LogisticsStatusRECEVIE: + orderStatusToLocal.Status = model.WaybillStatusNew // 新订单 + goodsOrderStatus = model.OrderStatusNew // 新订单 + case ali_logistics_query.LogisticsStatusWAIT_ACCEPT: + orderStatusToLocal.Status = model.WaybillStatusAccepted // 分配骑手 + goodsOrderStatus = model.OrderStatusAccepted // 拣货完成等待骑手 + case ali_logistics_query.LogisticsStatusACCEPT: + orderStatusToLocal.Status = model.WaybillStatusCourierArrived // 兼容骑手取货状态 + goodsOrderStatus = model.OrderStatusFinishedPickup + case ali_logistics_query.LogisticsStatusTRANSPORT, ali_logistics_query.LogisticsStatusSEND_ON, ali_logistics_query.LogisticsStatusARRIVE_CITY, ali_logistics_query.LogisticsStatusDELIVERING: + orderStatusToLocal.Status = model.WaybillStatusDelivering // 配送中 + goodsOrderStatus = model.OrderStatusDelivering + case ali_logistics_query.LogisticsStatusAGENT_SIGN, ali_logistics_query.LogisticsStatusSIGN, ali_logistics_query.LogisticsStatusSTA_SIGN: + orderStatusToLocal.Status = model.WaybillStatusDelivered // 配送结束 + goodsOrderStatus = model.OrderStatusFinished + default: // 剩余状态全部为异常状态,除非新加状态 + orderStatusToLocal.Status = model.WaybillStatusUnknown // 异常配送 + goodsOrderStatus = model.OrderStatusDeliverFailed // 投递失败 + } + orderStatusToLocal.StatusTime = utils.Timestamp2Time(v.Time) + orderStatus = append(orderStatus, orderStatusToLocal) + } + + if len(statusList) == 0 || statusList == nil { // 本地订单状态为空不存在 + for _, v := range orderStatus { + if err := dao.CreateEntity(db, v); err != nil { + errList = append(errList, err) + continue + } + } + } else { + for _, v := range orderStatus { + if statusList[len(statusList)-1].StatusTime.Unix() > v.StatusTime.Unix() && checkOrderStatus(statusList[len(statusList)-1].VendorStatus) { + continue + } + if err := dao.CreateEntity(db, v); err != nil { + errList = append(errList, err) + continue + } + } + } + + // 获取当前订单运单状态 + wayBill, err := dao.GetWaybills(db, logistics.OrderId) + if err != nil { + errList = append(errList, err) + continue + } + status := orderStatus[len(orderStatus)-1].Status + vendorStatus := orderStatus[len(orderStatus)-1].VendorStatus + statusTime := orderStatus[len(orderStatus)-1].StatusTime + if len(wayBill) == 0 || wayBill == nil { + wayBillObj := &model.Waybill{ + VendorWaybillID: logistics.LogisticId, + WaybillVendorID: model.VendorIDTotalWl, + VendorOrderID: logistics.OrderId, + OrderVendorID: model.VendorIDJX, + CourierName: logisticsList.Info[0].Courier, + CourierMobile: logisticsList.Info[0].CourierPhone, + Status: status, + VendorStatus: vendorStatus, + ActualFee: logistics.LogisticFee, + DesiredFee: logistics.LogisticFee, + DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled, + WaybillCreatedAt: time.Now(), + StatusTime: statusTime, + ModelTimeInfo: model.ModelTimeInfo{CreatedAt: time.Now(), UpdatedAt: time.Now()}, + } + if err := dao.CreateEntity(db, wayBillObj); err != nil { + errList = append(errList, err) + continue + } + } else { + wayBill[0].UpdatedAt = time.Now() + wayBill[0].Status = status + wayBill[0].VendorStatus = vendorStatus + wayBill[0].StatusTime = statusTime + if _, err := dao.UpdateEntity(db, wayBill[0], "Status", "UpdatedAt", "VendorStatus", "StatusTime"); err != nil { + errList = append(errList, err) + continue + } + } + + // 更新订单状态 + goodsOrder, err := partner.CurOrderManager.LoadOrder(logistics.OrderId, model.VendorIDJX) + if err != nil { + errList = append(errList, err) + continue + } + goodsOrder.Status = goodsOrderStatus + goodsOrder.VendorStatus = vendorStatus + goodsOrder.StatusTime = statusTime + if orderStatus[len(orderStatus)-1].Status >= model.OrderStatusEndBegin { + goodsOrder.OrderFinishedAt = time.Now() + } + if _, err := dao.UpdateEntity(db, goodsOrder, "Status", "VendorStatus", "StatusTime", "OrderFinishedAt"); err != nil { + errList = append(errList, err) + continue + } + } + + return errList +} + +func checkOrderStatus(orderStatus string) bool { + switch orderStatus { + case ali_logistics_query.LogisticsStatusRECEVIE: + return true + case ali_logistics_query.LogisticsStatusWAIT_ACCEPT: + return true + case ali_logistics_query.LogisticsStatusACCEPT: + return true + case ali_logistics_query.LogisticsStatusTRANSPORT, ali_logistics_query.LogisticsStatusSEND_ON, ali_logistics_query.LogisticsStatusARRIVE_CITY, ali_logistics_query.LogisticsStatusDELIVERING: + return true + case ali_logistics_query.LogisticsStatusAGENT_SIGN, ali_logistics_query.LogisticsStatusSIGN, ali_logistics_query.LogisticsStatusSTA_SIGN: + return true + case ali_logistics_query.LogisticsStatusSTA_INBOUND, ali_logistics_query.LogisticsStatusRETURN_SIGN, ali_logistics_query.LogisticsStatusFAILED, ali_logistics_query.LogisticsStatusREFUSE_SIGN, ali_logistics_query.LogisticsStatusDELIVER_ABNORMAL: + return true + case ali_logistics_query.LogisticsStatusRETENTION, ali_logistics_query.LogisticsStatusISSUE, ali_logistics_query.LogisticsStatusRETURN, ali_logistics_query.LogisticsStatusDAMAGE, ali_logistics_query.LogisticsStatusCANCEL_ORDER: + return true + default: + return false + } +} + +// GetLogisticOrder 查询未完成的物料订单,更新物流信息 +func GetLogisticOrder() []*model.UpdateMaterialLogistic { + var ( + timeNow = time.Now() + startTime = timeNow.AddDate(0, -1, 0) + endTime = timeNow + goodsList = make([]*model.GoodsOrder, 0, 0) + ) + + sql := ` SELECT * FROM goods_order g WHERE g.order_created_at >= ? AND g.order_created_at < ? AND g.store_id = ? AND order_type = ? AND g.status < ? ` // 一个月内状态未完成的订单 + sqlParam := []interface{}{ + startTime, endTime, "666666", 1, model.OrderStatusEndBegin, + } + if err := dao.GetRows(dao.GetDB(), &goodsList, sql, sqlParam...); err != nil { + globals.SugarLogger.Debugf("loading jx material order err :%s", err) + return nil + } + + if len(goodsList) == 0 { + return nil + } + + logisticsList := make([]*model.UpdateMaterialLogistic, 0, len(goodsList)) + for _, v := range goodsList { + logistics := &model.UpdateMaterialLogistic{ + OrderId: v.VendorOrderID, + LogisticId: v.VendorWaybillID, + LogisticFee: v.BaseFreightMoney, + } + logisticsList = append(logisticsList, logistics) + } + return logisticsList +} diff --git a/business/jxcallback/orderman/orderman_ext.go b/business/jxcallback/orderman/orderman_ext.go index c4322fe3e..a223f7b5a 100644 --- a/business/jxcallback/orderman/orderman_ext.go +++ b/business/jxcallback/orderman/orderman_ext.go @@ -697,6 +697,24 @@ func (c *OrderManager) GetOrderStatusList(ctx *jxcontext.Context, vendorOrderID return statusList, nil } +// GetLogisticsOrderStatusList 根据订单号和物流号查询运单的变化状态 +func (c *OrderManager) GetLogisticsOrderStatusList(orderId, LogisticsId string, vendorId int) ([]*model.OrderStatus, error) { + sql := `SELECT * + FROM order_status t1 + WHERE t1.vendor_order_id = ? AND t1.ref_vendor_order_id = ? AND t1.ref_vendor_id = ?` + sqlParams := []interface{}{ + LogisticsId, + orderId, + vendorId, + } + sql += ` ORDER BY status_time ASC ` + var result []*model.OrderStatus + if err := dao.GetRows(dao.GetDB(), &result, sql, sqlParams...); err != nil { + return nil, err + } + return result, nil +} + // GetOrderStatusList2 查询订单流程 refVendorOrderID 订单Id func GetOrderStatusList2(refVendorOrderID string, wayBillId string, orderType int, vendorID int) (statusList []*model.OrderStatus, err error) { sql := ` diff --git a/business/jxcallback/scheduler/defsch/defsch.go b/business/jxcallback/scheduler/defsch/defsch.go index b9f8848b3..14eae1cbb 100644 --- a/business/jxcallback/scheduler/defsch/defsch.go +++ b/business/jxcallback/scheduler/defsch/defsch.go @@ -815,11 +815,11 @@ func (s *DefScheduler) cancelWaybillNotInStoreOpentime(savedOrderInfo *WatchOrde if storeDetail.OpenTime1 != 0 && storeDetail.CloseTime1 != 0 { time1 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime1, time.Now()) time2 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime1, time.Now()) - if time.Now().Sub(time1) < 0 || time.Now().Sub(time2.Add(time.Minute*30)) > 0 { // 营业时间 + if time.Now().Sub(time1) < 0 || time.Now().Sub(time2.Add(time.Minute*180)) > 0 { // 营业时间 if storeDetail.OpenTime2 != 0 && storeDetail.CloseTime2 != 0 { // 休息时间 time3 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime2, time.Now()) time4 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime2, time.Now()) - if time.Now().Sub(time3) < 0 || time.Now().Sub(time4.Add(time.Minute*30)) > 0 { + if time.Now().Sub(time3) < 0 || time.Now().Sub(time4.Add(time.Minute*180)) > 0 { s.CancelWaybill(bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonNotInStoreOpenTime) //s.reverseBrandAccount(storeDetail, bill) } @@ -937,11 +937,11 @@ func (s *DefScheduler) createWaybillOn3rdProviders(savedOrderInfo *WatchOrderInf if storeDetail.OpenTime1 != 0 && storeDetail.CloseTime1 != 0 { time1 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime1, time.Now()) time2 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime1, time.Now()) - if time.Now().Sub(time1) < 0 || time.Now().Sub(time2.Add(time.Minute*120)) > 0 { + if time.Now().Sub(time1) < 0 || time.Now().Sub(time2.Add(time.Minute*180)) > 0 { if storeDetail.OpenTime2 != 0 && storeDetail.CloseTime2 != 0 { time3 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime2, time.Now()) time4 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime2, time.Now()) - if time.Now().Sub(time3) < 0 || time.Now().Sub(time4.Add(time.Minute*120)) > 0 { + if time.Now().Sub(time3) < 0 || time.Now().Sub(time4.Add(time.Minute*180)) > 0 { err = fmt.Errorf("不在门店营业时间范围内!") } } else { diff --git a/business/jxstore/misc/misc.go b/business/jxstore/misc/misc.go index 6e0d3fc68..e20ec70b3 100644 --- a/business/jxstore/misc/misc.go +++ b/business/jxstore/misc/misc.go @@ -2,6 +2,7 @@ package misc import ( "fmt" + "git.rosy.net.cn/jx-callback/business/bidding" "git.rosy.net.cn/jx-callback/business/partner/delivery" "git.rosy.net.cn/jx-callback/business/partner/purchase/tiktok_store" "sync" @@ -248,6 +249,13 @@ func Init() { cms.RefreshTiktokShopToken(jxcontext.AdminCtx) }, 60*time.Second, 30*time.Minute) + // 定时任务刷新当前订单的物流信息 + ScheduleTimerFunc("RefreshMaterialLogistics", func() { + bidding.LoadingLogistics(nil) + }, []string{ + "02:45:00", + }) + //刷新京东物竞天择订单结算价 ScheduleTimerFunc("RefreshJdShopOrdersEarningPrice", func() { orderman.RefreshJdShopOrdersEarningPrice(jxcontext.AdminCtx, utils.Time2Str(time.Now().AddDate(0, 0, -2)), utils.Time2Str(time.Now().AddDate(0, 0, -2))) diff --git a/business/model/api_config.go b/business/model/api_config.go index e5a26bcf0..ac3b6f7c9 100644 --- a/business/model/api_config.go +++ b/business/model/api_config.go @@ -31,7 +31,8 @@ const ( VendorIDMTPS = 102 // 美团配送 VendorIDFengNiao = 103 // 蜂鸟配送 VendorJXFakeWL = 300 // 京西假物流 - VendorIDJDWL = 401 //京东物流 + VendorIDJDWL = 401 // 京东物流 + VendorIDTotalWl = 402 // (综合物流[京东,圆通,申通....]) VendorIDDeliveryEnd = 500 VendorIDPrinterBegin = 201 diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go index 64d0e8598..82dcc9dab 100644 --- a/business/model/dao/store_sku.go +++ b/business/model/dao/store_sku.go @@ -687,8 +687,6 @@ func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty boo // } sql = fmt.Sprintf(sql, fmtParams...) sql += " ORDER BY t1.price" - globals.SugarLogger.Debugf("==========sql:= %s", sql) - globals.SugarLogger.Debugf("==========sqlParams:= %s", utils.Format4Output(sqlParams, false)) if err = GetRows(db, &skus, sql, sqlParams...); err != nil { return nil, err } diff --git a/business/model/dao/thing_map.go b/business/model/dao/thing_map.go index 67875ba97..16e4f193c 100644 --- a/business/model/dao/thing_map.go +++ b/business/model/dao/thing_map.go @@ -63,6 +63,14 @@ func GetThingToTiktokMapList(db *DaoDB, vendorId int, thingId int64) (cats []*mo return cats, err } +// DeleteThingToTiktokMapList 删除同步关联关系 +func DeleteThingToTiktokMapList(vendorId int, vendorThingId string) error { + sql := ` DELETE FROM thing_map t1 WHERE vendor_thing_id = ? AND vendor_id = ? ` + param := []interface{}{vendorThingId, vendorId} + _, err := ExecuteSQL(GetDB(), sql, param...) + return err +} + func GetThingMapMap(db *DaoDB, thingType int, vendorIDs, thingIDs []int) (thingMapMap map[int64][]*model.ThingMap, err error) { thingMapList, err := GetThingMapList(db, thingType, vendorIDs, thingIDs, nil) if err == nil { diff --git a/business/model/order.go b/business/model/order.go index 3c107b3a9..212e2e3c4 100644 --- a/business/model/order.go +++ b/business/model/order.go @@ -289,6 +289,13 @@ func (v *OrderStatus) TableIndex() [][]string { } } +// 更新物料订单物流信息 +type UpdateMaterialLogistic struct { + OrderId string `json:"orderId"` // 订单id + LogisticId string `json:"logisticId"` // 物料订单id + LogisticFee int64 `json:"logisticFee"` // 物流价格 分 +} + func Order2Status(order *GoodsOrder) (retVal *OrderStatus) { retVal = &OrderStatus{ VendorOrderID: order.VendorOrderID, diff --git a/business/partner/purchase/tiktok_store/store_sku2.go b/business/partner/purchase/tiktok_store/store_sku2.go index 0bd9fa706..dc1c3216b 100644 --- a/business/partner/purchase/tiktok_store/store_sku2.go +++ b/business/partner/purchase/tiktok_store/store_sku2.go @@ -209,6 +209,7 @@ func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, v if err = getAPI(storeSkuList[0].VendorOrgCode, storeID, vendorStoreID).DeleteStoreCommodity(utils.Str2Int64(v.VendorSkuID)); err != nil { failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "删除主商品")...) } + dao.DeleteThingToTiktokMapList(model.VendorIDDD, v.VendorMainId) } } if len(failedList) > 0 { @@ -282,28 +283,29 @@ func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrg api := getAPI(vendorOrgCode, storeID, vendorStoreID) for _, v := range storeSkuList { // 更新主品 (暂不支持渠道主商品) - //err = api.EditPrice(&sku_editPrice_request.SkuEditPriceParam{ - // Price: v.VendorPrice, - // SkuId: utils.Str2Int64(v.VendorSkuAttrId), - // ProductId: utils.Str2Int64(v.VendorMainId), - //}) - //if err != nil { - // failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "更新主品价格异常")...) - //} else { - // failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "更新主品价格正常")...) - //} - - // 更新子品 err = api.EditPrice(&sku_editPrice_request.SkuEditPriceParam{ Price: v.VendorPrice, - SkuId: utils.Str2Int64(v.VendorSonSkuID), - ProductId: utils.Str2Int64(v.VendorSkuID), + SkuId: utils.Str2Int64(v.VendorSkuAttrId), + ProductId: utils.Str2Int64(v.VendorMainId), }) if err != nil { - failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "更新价格异常")...) - } else { - failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "更新价格正常")...) + failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "更新主品价格异常")...) } + + // 更新子品 + if _, err := api.BatchApplyStoreProductPrice(utils.Str2Int64(v.VendorMainId)); err != nil { + failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "同步子品价格异常")...) + } + //err = api.EditPrice(&sku_editPrice_request.SkuEditPriceParam{ + // Price: v.VendorPrice, + // SkuId: utils.Str2Int64(v.VendorSonSkuID), + // ProductId: utils.Str2Int64(v.VendorSkuID), + //}) + //if err != nil { + // failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "更新价格异常")...) + //} else { + // failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDDD], "更新价格正常")...) + //} } if len(failedList) > 0 { diff --git a/business/partner/purchase/tiktok_store/store_sku2_utils.go b/business/partner/purchase/tiktok_store/store_sku2_utils.go index 8201d48af..5f0238247 100644 --- a/business/partner/purchase/tiktok_store/store_sku2_utils.go +++ b/business/partner/purchase/tiktok_store/store_sku2_utils.go @@ -14,6 +14,7 @@ import ( 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" + superm_product_batchRedistributeStoreProduct_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/superm_product_batchRedistributeStoreProduct/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" @@ -134,7 +135,7 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI continue } param := &product_addV2_request.ProductAddV2Param{ - Name: utils.LimitUTF8StringLen(storeSku.SkuName, mtwmapi.MaxSkuNameCharCount*2), + Name: utils.LimitUTF8StringLen(storeSku.SkuName, 90), PayType: tiktokShop.TiktokPayType1, ReduceType: tiktokShop.SkuReduceTypePayMakeOrder, Weight: utils.Int2Float64(storeSku.Weight), @@ -151,9 +152,9 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI OuterProductId: utils.Int2Str(storeSku.SkuID), // 本地skuId为外部商品id } if len(param.Name) < 23 { // 中文字符一个汉字三个长度符号/数字/字母两个长度,商品名称不能大于 - param.Name += utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit + param.Name += utils.Float64ToStr(float64(storeSku.SpecQuality)) + "/" + storeSku.SpecUnit if len(param.Name) < 23 { - param.Name += " 推荐产品 " + param.Name += "【惊喜到家】" } } else if len(param.Name) > 90 { // 抖音最大60个字符,三十个汉字 param.Name = param.Name[0:90] @@ -162,7 +163,8 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI // 获取上传图,商品轮播图 img, detailImg, err := GetTiktokImgList(api, utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.DescImg, storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5) if err != nil { - return nil, err + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + continue } param.Pic = img param.Description = detailImg @@ -173,10 +175,15 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI } else if len(param.Pic) != 0 { // 自动推导分类id param.CategoryLeafId = api.GetRecommendCategory(strings.Split(img, "|")) } - if storeSku.VendorVendorCatID != 0 && param.CategoryLeafId == 0 { - param.CategoryLeafId = storeSku.VendorVendorCatID + // 这个情况是原有商品不存在和推荐查询不到类目id是,使用京西类目和抖音类目的绑定关系 + // 但是不太实用,导致商品类目错误被暂停营业等 + //if storeSku.VendorVendorCatID != 0 && param.CategoryLeafId == 0 { + // param.CategoryLeafId = storeSku.VendorVendorCatID + //} + if param.CategoryLeafId == 0 { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, errors.New("当前商品本地未设置抖音分类/抖音推荐分类查询错误"), storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + continue } - // 是否支持七天无理由 if api.GetProductUpdateRule(param.CategoryLeafId) { param.Supply7dayReturn = 1 @@ -196,43 +203,14 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI param.ProductFormatNew = storeSku.TiktokAttribute } else { param.ProductFormatNew, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId) - if err != nil { - return nil, err - } - } - - // 获取品牌 - //param.StandardBrandId, err = api.GetSkuBrand(param.CategoryLeafId) - //if err != nil { - // return nil, err - //} - param.StandardBrandId = 789194134 // 默认品牌京西菜市 596120136 - - // 根据本地商品id获取线上商品是否存在,存在则只创建子商品 - var tiktokResultProductId int64 = 0 - // 获取本地存储映射关系 - localThing, err := dao.GetThingToTiktokMapList(db, model.VendorIDDD, int64(storeSku.SkuID)) - if len(localThing) == 0 { // 线上不存在创建 - 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 - err = dao.CreateThingMap(int64(storeSku.SkuID), utils.Int64ToStr(tiktokResult.ProductId), storeDetail.VendorOrgCode, storeSku.VendorSkuAttrId) - } else { - storeSku.VendorMainId = localThing[0].VendorThingID - storeSku.VendorSkuAttrId = localThing[0].Remark // 属性id skuID - tiktokResultProductId = utils.Str2Int64(localThing[0].VendorThingID) } + param.StandardBrandId = 789194134 // 默认品牌京西菜市 596120136 + // 创建子商品 temp, err := dao.QueryStoreBindInfo(storeDetail.Store.ID) if err != nil || temp == nil || temp.ID == 0 { @@ -283,12 +261,33 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI } } - param.MainProductId = tiktokResultProductId - param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, tiktokResultProductId, storeSku) + // 根据本地商品id获取线上商品是否存在,存在则只创建子商品 + var tiktokResultProductId int64 = 0 + // 获取本地存储映射关系,获取本地主商品id是否存在 + localThing, err := dao.GetThingToTiktokMapList(db, model.VendorIDDD, int64(storeSku.SkuID)) + if len(localThing) == 0 { // 线上不存在创建 + 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 + } - param.StoreId = utils.Str2Int64(vendorStoreID) - // 抖店创建子商品 - tiktokResultChildren, err := api.CreateStoreCommodity(param) + 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 + err = dao.CreateThingMap(int64(storeSku.SkuID), utils.Int64ToStr(tiktokResult.ProductId), storeDetail.VendorOrgCode, storeSku.VendorSkuAttrId) + } else { + storeSku.VendorMainId = localThing[0].VendorThingID + storeSku.VendorSkuAttrId = localThing[0].Remark // 属性id skuID + tiktokResultProductId = utils.Str2Int64(localThing[0].VendorThingID) + } + + // 上面说明要么已经创建了主商品,要么已经重新创建了主商品,将该商品同步到子门店就可以了. + childrenProductId, err := api.CreateSubProduct(param.MainProductId, utils.Str2Int64(vendorStoreID)) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) if storeSku.VendorSkuID == "" { @@ -296,13 +295,29 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI } continue } - var attrId2 []string - for _, v := range tiktokResultChildren.Sku { - attrId2 = append(attrId2, utils.Int64ToStr(v.SkuId)) - } - storeSku.VendorSonSkuID = strings.Join(attrId2, ",") // 属性id skuID - storeSku.VendorSkuID = utils.Int64ToStr(tiktokResultChildren.ProductId) // 子商品主id - storeSku.VendorMainId = utils.Int64ToStr(tiktokResultProductId) // 商品主id + storeSku.VendorSonSkuID = utils.Int64ToStr(childrenProductId) // 属性id skuID + storeSku.VendorSkuID = utils.Int64ToStr(childrenProductId) // 子商品主id + storeSku.VendorMainId = utils.Int64ToStr(tiktokResultProductId) // 商品主id + //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) + // if storeSku.VendorSkuID == "" { + // storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) + // } + // continue + //} + //var attrId2 []string + //for _, v := range tiktokResultChildren.Sku { + // attrId2 = append(attrId2, utils.Int64ToStr(v.SkuId)) + //} + //storeSku.VendorSonSkuID = strings.Join(attrId2, ",") // 属性id skuID + //storeSku.VendorSkuID = utils.Int64ToStr(tiktokResultChildren.ProductId) // 子商品主id + //storeSku.VendorMainId = utils.Int64ToStr(tiktokResultProductId) // 商品主id } } else { syncType = "更新商品" @@ -312,7 +327,7 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI } // 更新商品(目前只更新子商品,主商品暂不支持) param := &product_editV2_request.ProductEditV2Param{ - Name: storeSku.Name, + Name: utils.LimitUTF8StringLen(storeSku.SkuName, 90), PayType: tiktokShop.TiktokPayType1, ReduceType: tiktokShop.SkuReduceTypePayMakeOrder, Weight: utils.Int2Float64(storeSku.Weight), @@ -334,7 +349,10 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI } if len(param.Name) < 23 { // 中文字符一个汉字三个长度符号/数字/字母两个长度,商品名称不能大于 - param.Name += utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit + " " + param.Name += utils.Float64ToStr(float64(storeSku.SpecQuality)) + "/" + storeSku.SpecUnit + if len(param.Name) < 23 { + param.Name += "【惊喜到家】" + } } else if len(param.Name) > 90 { // 抖音最大60个字符,三十个汉字 param.Name = param.Name[0:90] } @@ -342,7 +360,8 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI // 获取上传图,商品轮播图 img, detailImg, err := GetTiktokImgList(api, utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.DescImg, storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5) if err != nil { - return nil, err + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + continue } param.Pic = img param.Description = detailImg @@ -360,7 +379,8 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI if storeSku.TiktokAttribute == "" || storeSku.TiktokAttribute == "{}" { param.ProductFormatNew, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId) if err != nil { - return nil, err + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + continue } } else { param.ProductFormatNew = storeSku.TiktokAttribute @@ -381,28 +401,40 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI param.ProductId = utils.Str2Int64(storeSku.VendorMainId) param.MainProductId = utils.Str2Int64(storeSku.VendorMainId) param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, param.MainProductId, storeSku) + param.ProductId = utils.Str2Int64(storeSku.VendorSkuID) + 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 } - 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 { + // 门店商品同步,先删除同步商品,在重新分配该商品 + if _, err := api.BatchRedistributeStoreProduct(&superm_product_batchRedistributeStoreProduct_request.TaskParams{ + MainProductId: param.MainProductId, + AddStoreIds: nil, + DelStoreIds: []int64{param.StoreId}, + }); err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) continue } + if _, err := api.BatchRedistributeStoreProduct(&superm_product_batchRedistributeStoreProduct_request.TaskParams{ + MainProductId: param.MainProductId, + AddStoreIds: []int64{param.StoreId}, + DelStoreIds: nil, + }); err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) + continue + } + //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 + //} + } return } diff --git a/conf/app.conf b/conf/app.conf index 9736a3203..02cf56875 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -218,6 +218,11 @@ tiktokAppSecret = "5c08a0465cf0f996af254a03b6c2548defef87ad" tiktokJXDJKey="ttaceeda5333d7a7ab01" #京西到家抖音小程序 TiktokJXDJApiID="ttaceeda5333d7a7ab01" tiktokJXDJSecret="5c8492ec2744fb72bb6cc356983f3cfc317f85d4" + +# 阿里云更物料新订单物流信息 +aliLogisticsAppKey = "23537670" +aliLogisticsAppSecret = "4a77a431c0bf01f6dfa63d1a1ec9ecd2" +aliLogisticsAppCode = "00a6eefba0204d3fa310ac0ee7a6fc54" [prod] EnableDocs = false @@ -342,6 +347,11 @@ tiktokAppSecret = "5c08a0465cf0f996af254a03b6c2548defef87ad" tiktokJXDJKey="ttaceeda5333d7a7ab01" #京西到家抖音小程序 TiktokJXDJApiID="ttaceeda5333d7a7ab01" tiktokJXDJSecret="5c8492ec2744fb72bb6cc356983f3cfc317f85d4" + +# 阿里云更物料新订单物流信息 +aliLogisticsAppKey = "23537670" +aliLogisticsAppSecret = "4a77a431c0bf01f6dfa63d1a1ec9ecd2" +aliLogisticsAppCode = "00a6eefba0204d3fa310ac0ee7a6fc54" [jxgy] httpport = 8088 EnableDocs = false @@ -446,6 +456,11 @@ tiktokAppSecret = "5c08a0465cf0f996af254a03b6c2548defef87ad" tiktokJXDJKey="ttaceeda5333d7a7ab01" #京西到家抖音小程序 TiktokJXDJApiID="ttaceeda5333d7a7ab01" tiktokJXDJSecret="5c8492ec2744fb72bb6cc356983f3cfc317f85d4" + +# 阿里云更物料新订单物流信息 +aliLogisticsAppKey = "23537670" +aliLogisticsAppSecret = "4a77a431c0bf01f6dfa63d1a1ec9ecd2" +aliLogisticsAppCode = "00a6eefba0204d3fa310ac0ee7a6fc54" [test] jdOrgCode = "82029" jdToken = "594ab45a-9a73-4a43-82b0-a64cbd55d883" @@ -634,3 +649,8 @@ tiktokAppSecret = "5c08a0465cf0f996af254a03b6c2548defef87ad" tiktokJXDJKey="ttaceeda5333d7a7ab01" #京西到家抖音小程序 TiktokJXDJApiID="ttaceeda5333d7a7ab01" tiktokJXDJSecret="5c8492ec2744fb72bb6cc356983f3cfc317f85d4" + +# 阿里云更物料新订单物流信息 +aliLogisticsAppKey = "23537670" +aliLogisticsAppSecret = "4a77a431c0bf01f6dfa63d1a1ec9ecd2" +aliLogisticsAppCode = "00a6eefba0204d3fa310ac0ee7a6fc54" \ No newline at end of file diff --git a/controllers/jx_order.go b/controllers/jx_order.go index 18d7fef24..ffa5c3071 100644 --- a/controllers/jx_order.go +++ b/controllers/jx_order.go @@ -1,7 +1,9 @@ package controllers import ( + "encoding/json" "fmt" + "git.rosy.net.cn/jx-callback/business/bidding" "strings" "time" @@ -432,6 +434,24 @@ func (c *OrderController) GetOrderStatusList() { }) } +// @Title 加载物流信息(物料单子加载物流配送流程) +// @Description 加载物流信息(物料单子加载物流配送流程) +// @Param token header string true "认证token" +// @Param data body string true "物流参数" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /LoadingLogisticsStatus [post] +func (c *OrderController) LoadingLogisticsStatus() { + c.callLoadingLogisticsStatus(func(params *tOrderLoadingLogisticsStatusParams) (interface{}, string, error) { + var param = make([]*model.UpdateMaterialLogistic, 0, 0) + if err := json.Unmarshal([]byte(params.Data), ¶m); err != nil { + return nil, "", err + } + errList := bidding.LoadingLogistics(param) + return errList, "", nil + }) +} + // @Title 查询门店营业数据 // @Description 查询门店营业数据 // @Param token header string true "认证token" diff --git a/globals/api/api.go b/globals/api/api.go index d5d209f47..82017b979 100644 --- a/globals/api/api.go +++ b/globals/api/api.go @@ -1,6 +1,7 @@ package api import ( + "git.rosy.net.cn/baseapi/platformapi/ali_logistics_query" enterprise "git.rosy.net.cn/baseapi/platformapi/enterprise_wechat" "git.rosy.net.cn/baseapi/platformapi/jxprintapi" "git.rosy.net.cn/baseapi/platformapi/qywxapi" @@ -121,6 +122,8 @@ var ( EnterpriseChatHeadApi *enterprise.API // 企业微信api EnterpriseChatMin *enterprise.API // 企业微信小程序api + + LogisticsApi *ali_logistics_query.API // 阿里云提供获取物流订单的配送信息 ) func init() { @@ -309,6 +312,8 @@ func Init() { if TiktokJXDJApiID = beego.AppConfig.DefaultString("TiktokJXDJApiID", ""); TiktokJXDJApiID != "" { TiktokJXDJApi = tiktok.New(beego.AppConfig.DefaultString("tiktokJXDJSecret", ""), beego.AppConfig.DefaultString("TiktokJXDJApiID", "")) } + + LogisticsApi = ali_logistics_query.New(beego.AppConfig.DefaultString("aliLogisticsAppKey", ""), beego.AppConfig.DefaultString("aliLogisticsAppSecret", ""), beego.AppConfig.DefaultString("aliLogisticsAppCode", "")) // 抖店 = "c397aa9f-3927-47c4-8cfe-4d84e02602e0" TiktokStore = tiktokShop.New(beego.AppConfig.DefaultString("tiktokShopAppId", ""), beego.AppConfig.DefaultString("tiktokShopAppSecret", ""), "") EnterpriseChatHeadApi = enterprise.New("ww9a156bfa070e1857", "0jBdCjSmoFiOoHIXyeCK9VbGQ82fVNJZ8uMl6JNN7X4") // 通讯录 diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 375d5bf7b..cb47fa3b8 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1341,6 +1341,15 @@ func init() { Filters: nil, Params: nil}) + web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], + web.ControllerComments{ + Method: "LoadingLogisticsStatus", + Router: `/LoadingLogisticsStatus`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], web.ControllerComments{ Method: "GetOrderUserBuyFirst",