diff --git a/business/jxcallback/orderman/order.go b/business/jxcallback/orderman/order.go index 93a9c6705..b8254c1d3 100644 --- a/business/jxcallback/orderman/order.go +++ b/business/jxcallback/orderman/order.go @@ -7,9 +7,15 @@ import ( "strings" "time" + "git.rosy.net.cn/jx-callback/business/jxstore/common" + "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" + "git.rosy.net.cn/jx-callback/business/partner/purchase/jdshop" + "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/platformapi/dingdingapi" + "git.rosy.net.cn/baseapi/platformapi/jdshopapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" "git.rosy.net.cn/jx-callback/business/jxutils" @@ -995,3 +1001,225 @@ func GetOrderSimpleInfo(ctx *jxcontext.Context, vendorOrderID string) (getOrderS return getOrderSimpleInfoResult, err } + +func SaveJdsOrders(ctx *jxcontext.Context, orderCreatedStart, orderCreatedEnd time.Time) (err error) { + var ( + pageNo = 1 + pageSize = 10 + ) + orderResult, err := jdshop.CurPurchaseHandler.GetJdsOrders(ctx, utils.Time2Str(orderCreatedStart), utils.Time2Str(orderCreatedEnd), pageNo, pageSize) + if err != nil { + noticeMsg := fmt.Sprintf("京东商城保存订单出错!(多半是cookie过期了),err :[%v]", err) + ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "DDC5657B43EE11E9A9FF525400E86DC0", "cookie", noticeMsg) + ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "cookie", noticeMsg) + globals.SugarLogger.Errorf("SaveJdsOrders : %v", err) + } + orders, err := result2Orders(ctx, orderResult) + for _, order := range orders { + // partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) + globals.SugarLogger.Debugf("SaveJdsOrders, order: [%v]", utils.Format4Output(order, false)) + noticeMsg := fmt.Sprintf("京东商城新订单,订单号:[%v] ,将要发到的门店id:[%v] , 门店名:[%v]", order.VendorOrderID, order.StoreID, order.StoreName) + ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "DDC5657B43EE11E9A9FF525400E86DC0", "京东商城来新订单了!", noticeMsg) + ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "京东商城来新订单了!", noticeMsg) + } + return err +} + +func result2Orders(ctx *jxcontext.Context, result *jdshopapi.AllOrdersResult) (orders []*model.GoodsOrder, err error) { + for _, jdsOrder := range result.OrderList { + //等待付款的排除 + if jdsOrder.OrderStatus != jdshopapi.JdsOrderStatusWaittingExport && jdsOrder.OrderStatus != jdshopapi.JdsOrderStatusPause { + continue + } + //有可能是库里已经有这个订单了 + orderE, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(jdsOrder.OrderID)+"01", model.VendorIDJDShop) + if orderE != nil { + continue + } + orderDetail, err := api.JdShopAPI.OrderDetail(utils.Int64ToStr(jdsOrder.OrderID)) + if err != nil { + globals.SugarLogger.Debugf("jds OrderDetail error: %v", err.Error()) + continue + } + order := &model.GoodsOrder{ + VendorOrderID2: utils.Int64ToStr(jdsOrder.OrderID), + VendorOrderID: utils.Int64ToStr(jdsOrder.OrderID) + "01", + VendorID: model.VendorIDJDShop, + BaseFreightMoney: jxutils.StandardPrice2Int(jdsOrder.Freight), + VendorStatus: utils.Int2Str(jdsOrder.OrderStatus), + VendorUserID: jdsOrder.UserPin, + BuyerComment: jdsOrder.UserRemark, + PickDeadline: utils.DefaultTimeValue, + OriginalData: string(utils.MustMarshal(jdsOrder)), + StoreName: jdsOrder.StoreName, + OrderCreatedAt: utils.Str2Time(jdsOrder.OrderCreateTime + ":00"), + ConsigneeAddress: orderDetail.ConsigneeAddress, + ConsigneeName: orderDetail.ConsigneeName, + ActualPayPrice: orderDetail.ActualPayPrice, + Status: model.OrderStatusNew, + TotalShopMoney: utils.Float64TwoInt64(math.Round(utils.Int64ToFloat64(orderDetail.ActualPayPrice) * jdshopapi.JdsPayPercentage)), + } + //获取真实手机号 + fakeMobile, err := api.JdShopAPI.PhoneSensltiveInfo(order.VendorOrderID2, orderDetail.MobileKey) + if err != nil { + globals.SugarLogger.Debugf("jds PhoneSensltiveInfo error: %v", err.Error()) + continue + } else { + order.ConsigneeMobile = jxutils.DecryptDESECB([]byte(fakeMobile), []byte(jdshopapi.JdsMobileKey)) + } + if order.TotalShopMoney < 100 { + order.TotalShopMoney = 100 + } + if order.ConsigneeAddress != "" { + lng, lat, _ := api.AutonaviAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "") + order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng) + order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat) + } + if order.StoreName != "" { + storeMaps, _ := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDJDShop}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", order.StoreName) + if len(storeMaps) > 0 { + order.StoreID = storeMaps[0].StoreID + order.VendorStoreID = storeMaps[0].VendorStoreID + } + } else { + storeList, err := common.GetStoreListByLocation(ctx, jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), 5000, false, true) + if err != nil { + globals.SugarLogger.Debugf("jds GetStoreListByLocation error: %v", err.Error()) + continue + } + order.StoreID = storeList[0].ID + order.StoreName = storeList[0].Name + } + //如果是暂停,表示是预订单 + if jdsOrder.OrderStatus == jdshopapi.JdsOrderStatusPause { + order.BusinessType = model.BusinessTypeDingshida + order.ExpectedDeliveredTime = utils.Str2Time(orderDetail.ExpectedDeliveredTime) + } else if jdsOrder.OrderStatus == jdshopapi.JdsOrderStatusWaittingExport { + order.ExpectedDeliveredTime = order.CreatedAt.Add(time.Hour) + order.BusinessType = model.BusinessTypeImmediate + } else { + globals.SugarLogger.Errorf("未知的京东商城订单状态!status : %v", jdsOrder.OrderStatus) + } + for _, v := range jdsOrder.OrderItems { + sku := &model.OrderSku{ + VendorID: model.VendorIDJDShop, + VendorOrderID: order.VendorOrderID, + Count: v.SkuNum, + VendorSkuID: utils.Int64ToStr(v.SkuID), + SkuName: v.SkuName, + VendorPrice: jxutils.StandardPrice2Int(v.JdPrice), + SalePrice: jxutils.StandardPrice2Int(v.JdPrice), + } + var storeSku *model.StoreSkuBind + sql := ` + SELECT * FROM store_sku_bind WHERE store_id = ? AND jds_id = ? AND deleted_at = ? + ` + sqlParams := []interface{}{model.JdShopMainStoreID, v.SkuID, utils.DefaultTimeValue} + err = dao.GetRow(dao.GetDB(), &storeSku, sql, sqlParams) + if storeSku != nil { + sku.SkuID = storeSku.SkuID + } + _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.SkuName) + sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit) + order.Skus = append(order.Skus, sku) + } + orders = append(orders, order) + } + return orders, err +} + +func TransferJdsOrder(ctx *jxcontext.Context, vendorOrderID string, storeID int) (vendorOrderIDJds string, err error) { + globals.SugarLogger.Debugf("jds TransferJdsOrder vendorOrderID: %v, storeID : %v", vendorOrderID, storeID) + var ( + db = dao.GetDB() + waybill *model.Waybill + ) + order, err := dao.GetSimpleOrder(db, vendorOrderID) + if err != nil || order == nil { + return "", fmt.Errorf("未查询到该订单!订单号:[%v]", vendorOrderID) + } + if order.Status >= model.OrderStatusDelivering { + return "", fmt.Errorf("暂不支持此状态的订单进行转移!") + } + if order.VendorID != model.VendorIDJDShop { + return "", fmt.Errorf("暂不支持非京狗的订单进行转移!") + } + skus, err := dao.GetSimpleOrderSkus(db, vendorOrderID) + if err != nil || order == nil { + return "", fmt.Errorf("未查询到该订单商品!订单号:[%v]", vendorOrderID) + } + //将订单和运单取消 + waybills, err := dao.GetWaybills(db, vendorOrderID) + if err != nil { + return "", err + } + if len(waybills) > 0 { + for _, v := range waybills { + if v.Status != model.WaybillStatusCanceled { + waybill = v + } + } + handler := partner.DeliveryPlatformHandlers[waybill.WaybillVendorID] + err = handler.Handler.CancelWaybill(waybill, 0, "订单转移被取消") + if err != nil { + return "", err + } + } + err = jdshop.ChangeOrderStatus(vendorOrderID, model.OrderStatusCanceled, "订单转移被取消") + if err != nil { + return "", err + } + //重新构建order的数据 + storeMaps, err := dao.GetStoresMapList(db, []int{order.VendorID}, []int{order.StoreID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") + if len(storeMaps) > 0 { + order.StoreID = storeID + order.StoreName = storeMaps[0].StoreName + } else { + return "", fmt.Errorf("未查询到该门店对应的平台信息!门店:[%v]", order.StoreID) + } + if len(order.VendorOrderID) > 12 { + suffix := utils.Str2Int(order.VendorOrderID[12:len(order.VendorOrderID)]) + suffix++ + order.VendorOrderID = order.VendorOrderID2 + utils.Int2Str(suffix) + } + for _, sku := range skus { + sku.VendorOrderID = order.VendorOrderID + order.Skus = append(order.Skus, sku) + } + order.Status = model.OrderStatusNew + err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) + vendorOrderIDJds = order.VendorOrderID + return vendorOrderIDJds, err +} + +func SendJdwlForJdsOrder(ctx *jxcontext.Context, vendorOrderID string) (err error) { + db := dao.GetDB() + order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJDShop) + if order == nil || err != nil { + return fmt.Errorf("目前只支持京狗订单创建!") + } + if order.Status >= model.OrderStatusDelivering { + return fmt.Errorf("订单当前状态不支持创建!") + } + waybill := &model.Waybill{} + waybills, err := dao.GetWaybills(db, vendorOrderID) + if err != nil { + return err + } + if len(waybills) > 0 { + for _, v := range waybills { + if v.Status != model.WaybillStatusCanceled { + waybill = v + } + } + handler := partner.DeliveryPlatformHandlers[waybill.WaybillVendorID] + err = handler.Handler.CancelWaybill(waybill, 0, "订单已发送其他物流") + if err != nil { + return err + } + } + handler := partner.DeliveryPlatformHandlers[model.VendorIDJDWL] + waybill2, err := handler.Handler.CreateWaybill(order, 0) + jdshop.CurPurchaseHandler.OrderExport(ctx, vendorOrderID, waybill2.VendorWaybillID, false) + return err +} diff --git a/business/jxcallback/scheduler/basesch/basesch_ext.go b/business/jxcallback/scheduler/basesch/basesch_ext.go index 556879844..facb99a89 100644 --- a/business/jxcallback/scheduler/basesch/basesch_ext.go +++ b/business/jxcallback/scheduler/basesch/basesch_ext.go @@ -41,13 +41,6 @@ func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order * courierVendorID := storeCourier.VendorID bill, err2 := c.CreateWaybill(courierVendorID, order, maxDeliveryFee) if err = err2; err == nil { - stores, _ := dao.GetStoreList(dao.GetDB(), []int{order.StoreID}, nil, nil, nil, "") - if len(stores) > 0 { - if stores[0].PayPercentage <= 50 { - order.NewEarningPrice = (order.TotalShopMoney - bill.DesiredFee) * int64((100 - stores[0].PayPercentage/2)) / 100 - dao.UpdateEntity(dao.GetDB(), order, "NewEarningPrice") - } - } globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d bill:%v", order.VendorOrderID, userName, courierVendorID, bill) bills = append(bills, bill) if createOnlyOne { diff --git a/business/jxcallback/scheduler/defsch/defsch.go b/business/jxcallback/scheduler/defsch/defsch.go index 1a3df3005..94c9ad097 100644 --- a/business/jxcallback/scheduler/defsch/defsch.go +++ b/business/jxcallback/scheduler/defsch/defsch.go @@ -7,6 +7,7 @@ import ( "time" "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" + "git.rosy.net.cn/jx-callback/business/partner/purchase/jdshop" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/netprinter" @@ -537,7 +538,10 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo } s.updateOrderByBill(order, bill, false) s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) - + //京东商城的话,需要去把订单出库,如果是转移过的订单,则需要修改转移订单号 + if order.VendorID == model.VendorIDJDShop { + s.solutionJdsOrder(bill) + } if model.IsWaybillPlatformOwn(bill) { if bill.Status == model.WaybillStatusDelivering && order.Status < model.OrderStatusEndBegin { // 强制将订单状态置为配送中? @@ -717,9 +721,10 @@ func (s *DefScheduler) createWaybillOn3rdProviders(savedOrderInfo *WatchOrderInf if savedOrderInfo.retryCount <= maxWaybillRetryCount { savedOrderInfo.isNeedCreate3rdWaybill = true excludeVendorIDs := savedOrderInfo.GetWaybillVendorIDs() - if order.VendorID == model.VendorIDJX { - excludeVendorIDs = append(excludeVendorIDs, model.VendorIDMTPS) - } + //TODO 取消京西不自动发美团 2020-06-02 + // if order.VendorID == model.VendorIDJX { + // excludeVendorIDs = append(excludeVendorIDs, model.VendorIDMTPS) + // } if _, err = s.CreateWaybillOnProviders4SavedOrder(jxcontext.AdminCtx, savedOrderInfo, nil, excludeVendorIDs, false, maxDeliveryFee); err == nil { savedOrderInfo.retryCount++ } @@ -751,6 +756,21 @@ func (s *DefScheduler) cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo return err } +func (s *DefScheduler) solutionJdsOrder(bill *model.Waybill) (err error) { + //表示此订单是京东商城转移的订单,不用出库,但要去修改运单号 + if len(bill.VendorOrderID) > 12 { + if utils.Str2Int(bill.VendorOrderID[12:len(bill.VendorOrderID)]) > 1 { + err = jdshop.CurPurchaseHandler.OrderTransfer(jxcontext.AdminCtx, bill.VendorOrderID, bill.VendorWaybillID, true) + if err != nil { + globals.SugarLogger.Errorf("京东商城订单自动转移失败!", err) + } + } else { + err = jdshop.CurPurchaseHandler.OrderExport(jxcontext.AdminCtx, bill.VendorOrderID, bill.VendorWaybillID, true) + } + } + return err +} + func (s *DefScheduler) cancelOtherWaybills(savedOrderInfo *WatchOrderInfo, bill2Keep *model.Waybill, cancelReasonID int, cancelReason string) (err error) { globals.SugarLogger.Debugf("cancelOtherWaybills, orderID:%s, bill:%v", savedOrderInfo.order.VendorOrderID, bill2Keep) for _, v := range savedOrderInfo.waybills { diff --git a/business/jxstore/cms/cms.go b/business/jxstore/cms/cms.go index 3a420aa95..94b5f0818 100644 --- a/business/jxstore/cms/cms.go +++ b/business/jxstore/cms/cms.go @@ -412,7 +412,7 @@ func DeleteConfig(ctx *jxcontext.Context, key, configType string) (err error) { db := dao.GetDB() switch configType { case model.ConfigTypePricePack: - storeMapList, err2 := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key) + storeMapList, err2 := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key, "") if err = err2; err == nil { var storeInfo []string for _, v := range storeMapList { @@ -423,7 +423,7 @@ func DeleteConfig(ctx *jxcontext.Context, key, configType string) (err error) { } } case model.ConfigTypeFreightPack: - storeMapList, err2 := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "") + storeMapList, err2 := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") if err = err2; err == nil { var storeInfo []string for _, v := range storeMapList { @@ -503,7 +503,7 @@ func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (hint s } switch configType { case model.ConfigTypePricePack: - storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key) + storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key, "") if err != nil { dao.Rollback(db) return "", err @@ -522,7 +522,7 @@ func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (hint s } case model.ConfigTypeFreightPack: dao.Commit(db) - storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "") + storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") if err != nil { return "", err } diff --git a/business/jxstore/cms/sku.go b/business/jxstore/cms/sku.go index 788bcd094..deac305ac 100644 --- a/business/jxstore/cms/sku.go +++ b/business/jxstore/cms/sku.go @@ -595,7 +595,8 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku, isQueryMidPric t1.ex_prefix, t1.ex_prefix_begin, t1.ex_prefix_end, - t1.yb_name_suffix + t1.yb_name_suffix, + t1.jds_stock_switch ` if isQueryMidPrice { sql += `, @@ -635,6 +636,7 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku, isQueryMidPric t1.ex_prefix_begin, t1.ex_prefix_end, t1.yb_name_suffix, + t1.jds_stock_switch, ` if isQueryMidPrice { sqlData += " t4.mid_unit_price," @@ -992,6 +994,12 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf dao.Rollback(db) return 0, err } + if valid["jdsStockSwitch"] != nil { + if _, err = SetStoreSkuSyncStatus2(db, []int{model.JdShopMainStoreID}, []int{model.VendorIDJDShop}, skuIDs, model.SyncFlagSaleMask); err != nil { + dao.Rollback(db) + return 0, err + } + } } dao.Commit(db) @@ -1124,7 +1132,7 @@ func AddSku(ctx *jxcontext.Context, nameID int, sku *model.Sku, userName string) storeSkus, err := dao.GetStoreSkusByNameIDs(db, []int{model.JdShopMainStoreID}, nameID) if len(storeSkus) > 0 { storeIDs := make(map[int]int) - storeMaps, err2 := dao.GetStoresMapList(db, []int{model.VendorIDJDShop}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "") + storeMaps, err2 := dao.GetStoresMapList(db, []int{model.VendorIDJDShop}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") err = err2 for _, v := range storeMaps { storeSkus2, err2 := dao.GetStoreSkusByNameIDs(db, []int{v.StoreID}, nameID) diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index 39b5697b9..714fe5943 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -78,55 +78,6 @@ type StoreExt struct { OrderCount int `json:"orderCount"` } -type Store4User struct { - model.ModelIDCULD - - OriginalName string `orm:"-" json:"originalName"` - Name string `orm:"size(255)" json:"name"` - OpenTime1 int16 `json:"openTime1"` // 930就表示9点半,用两个的原因是为了支持中午休息,1与2的时间段不能交叉,为0表示没有 - CloseTime1 int16 `json:"closeTime1"` // 格式同上 - OpenTime2 int16 `json:"openTime2"` // 格式同上 - CloseTime2 int16 `json:"closeTime2"` // 格式同上 - Status int `json:"status"` - CityCode int `orm:"default(0);null" json:"cityCode"` // todo ? - DistrictCode int `orm:"default(0);null" json:"districtCode"` // todo ? - Address string `orm:"size(255)" json:"address"` - Tel1 string `orm:"size(32);index" json:"tel1"` - Tel2 string `orm:"size(32);index" json:"tel2"` - Lng int `json:"-"` // 乘了10的6次方 - Lat int `json:"-"` // 乘了10的6次方 - DeliveryRangeType int8 `json:"-"` // 参见相关常量定义 - DeliveryRange string `orm:"type(text)" json:"-"` // 如果DeliveryRangeType为DeliveryRangeTypePolygon,则为逗号分隔坐标,分号分隔的坐标点(坐标与Lng和Lat一样,都是整数),比如 121361504,31189308;121420555,31150238。否则为半径,单位为米 - - FloatLng float64 `json:"lng"` - FloatLat float64 `json:"lat"` - CityName string `json:"cityName"` - DistrictName string `json:"districtName"` - - Distance int `json:"distance"` - WalkDistance int `json:"walkDistance"` -} - -type Store4UserList []*Store4User - -func (x Store4UserList) Len() int { - return len(x) -} - -func (x Store4UserList) Less(i, j int) bool { - if x[i].Status != x[j].Status { - return x[i].Status > x[j].Status - } - if x[i].WalkDistance != x[j].WalkDistance { - return x[i].WalkDistance < x[j].WalkDistance - } - return x[i].Distance < x[j].Distance -} - -func (x Store4UserList) Swap(i, j int) { - x[i], x[j] = x[j], x[i] -} - type StoresInfo struct { TotalCount int `json:"totalCount"` MapCenterLng float64 `json:"mapCenterLng"` @@ -426,7 +377,7 @@ func getStoresSql(ctx *jxcontext.Context, keyword string, params map[string]inte } func setStoreMapInfo(ctx *jxcontext.Context, db *dao.DaoDB, storesInfo *StoresInfo, storeIDs []int, briefLevel int) (err error) { - storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "") + storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") if err != nil { return err } @@ -1194,7 +1145,7 @@ func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, vendorID int, vend } } } - storeMapList, err := dao.GetStoresMapList2(db, []int{vendorID}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", true) + storeMapList, err := dao.GetStoresMapList2(db, []int{vendorID}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", true) if len(storeMapList) > 0 { _, err = CurVendorSync.SyncStore(ctx, db, storeMap.VendorID, storeID, false, userName) } else { @@ -1806,7 +1757,7 @@ type EbaiStoreHealthy struct { func ExportShopsHealthInfo(ctx *jxcontext.Context, vendorIDs, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { db := dao.GetDB() vendorID := model.VendorIDEBAI - storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "") + storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") if err != nil { return "", err } @@ -1924,7 +1875,7 @@ func GetCorporationInfo(ctx *jxcontext.Context, licenceCode string) (corporation func GetStoresVendorSnapshot(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs, storeIDs []int) (vendorStoreSnapshotList []*model.VendorStoreSnapshot, err error) { db := dao.GetDB() - storeMapList, err := dao.GetStoresMapList(db, vendorIDs, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "") + storeMapList, err := dao.GetStoresMapList(db, vendorIDs, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") if err != nil { return nil, err } @@ -1971,7 +1922,7 @@ func getCurrentSnapshotAt(now time.Time) (snapshotAt time.Time) { } func updateVendorStoreStatusBySnapshot(db *dao.DaoDB, curSnapshotList []*model.VendorStoreSnapshot) (err error) { - storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "") + storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") if err != nil { return err } @@ -2482,98 +2433,6 @@ func SyncStoresQualify(ctx *jxcontext.Context, storeIDs []int, isAsync, isContin return hint, err } -func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, needWalkDistance bool) (storeList []*Store4User, err error) { - const ( - maxRadius = 20000 - maxStoreCount4User = 5 - ) - - lng2, _ := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 90) - _, lat2 := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 0) - lng1 := lng - (lng2 - lng) - lat1 := lat - (lat2 - lat) - // globals.SugarLogger.Debugf("%f,%f,%f,%f\n", lng1, lng2, lat1, lat2) - sql := ` - SELECT t1.*, - city.name city_name - FROM store t1 - JOIN place city ON city.code = t1.city_code - JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status <> ? - WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.lng > ? AND t1.lng < ? AND t1.lat > ? AND t1.lat < ? - AND sm.is_order <> ? - AND t1.id <> ? - ORDER BY t1.id - ` - sqlParams := []interface{}{ - model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled, - utils.DefaultTimeValue, model.StoreStatusDisabled, jxutils.StandardCoordinate2Int(lng1), jxutils.StandardCoordinate2Int(lng2), jxutils.StandardCoordinate2Int(lat1), jxutils.StandardCoordinate2Int(lat2), - model.YES, - model.MatterStoreID, - } - var storeList1 []*Store4User - if err = dao.GetRows(dao.GetDB(), &storeList1, sql, sqlParams...); err == nil { - var storeList2 []*Store4User - for _, v := range storeList1 { - distance := jxutils.Point2StoreDistance(lng, lat, v.Lng, v.Lat, v.DeliveryRangeType, v.DeliveryRange) - if distance > 0 || (lng == jxutils.IntCoordinate2Standard(v.Lng) && lat == jxutils.IntCoordinate2Standard(v.Lat)) { - v.Distance = distance - storeList2 = append(storeList2, v) - } - } - - // 为了审核用 - if len(storeList2) == 0 { - sql2 := ` - SELECT t1.*, - city.name city_name - FROM store t1 - JOIN place city ON city.code = t1.city_code - WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.id = ? - ` - sqlParams2 := []interface{}{ - // model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled, - utils.DefaultTimeValue, - model.StoreStatusDisabled, - // jxutils.StandardCoordinate2Int(0), - // jxutils.StandardCoordinate2Int(10000), - // jxutils.StandardCoordinate2Int(0), - // jxutils.StandardCoordinate2Int(10000), - // model.YES, - 102919, //商城模板店 - } - dao.GetRows(dao.GetDB(), &storeList2, sql2, sqlParams2...) - // if len(storeList2) > 1 { - // storeList2 = storeList2[:1] - // } - } - - // 如果要求以步行距离来算 - if needWalkDistance { - var coordList []*autonavi.Coordinate - for _, v := range storeList2 { - coordList = append(coordList, &autonavi.Coordinate{ - Lng: v.FloatLng, - Lat: v.FloatLat, - }) - } - if distanceList, err2 := api.AutonaviAPI.BatchWalkingDistance(lng, lat, coordList); err2 == nil { - for k, v := range storeList2 { - v.WalkDistance = int(distanceList[k]) - } - } else { - return nil, err2 - } - } - - sort.Sort(Store4UserList(storeList2)) - storeList = storeList2 - if len(storeList) > maxStoreCount4User { - storeList = storeList[:maxStoreCount4User] - } - } - return storeList, err -} - func JdStoreInfoCoordinateRecover(ctx *jxcontext.Context, vendorOrgCode string, files []*multipart.FileHeader) (err error) { if len(files) == 0 { return errors.New("没有文件上传!") @@ -2583,7 +2442,7 @@ func JdStoreInfoCoordinateRecover(ctx *jxcontext.Context, vendorOrgCode string, defer file1.Close() db := dao.GetDB() - storeList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "") + storeList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") if err == nil { var validStoreList []*dao.StoreDetail for _, v := range storeList { @@ -2849,7 +2708,7 @@ func CreateStorePriceScore(ctx *jxcontext.Context) (err error) { func RefreshJdLevel(ctx *jxcontext.Context) (err error) { db := dao.GetDB() - storeMapList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, nil, model.StoreStatusOpened, -1, "") + storeMapList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, nil, model.StoreStatusOpened, -1, "", "") if len(storeMapList) > 0 { dao.Begin(db) defer func() { @@ -3036,7 +2895,7 @@ func checkYbParams(db *dao.DaoDB, storeMap *model.StoreMap, storeID int) (err er } } } - storeMaps, err := dao.GetStoresMapList2(db, []int{model.VendorIDYB}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", false) + storeMaps, err := dao.GetStoresMapList2(db, []int{model.VendorIDYB}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", false) if len(storeMaps) > 0 { for _, v := range storeMaps { if v.YbAppID == appID { @@ -3121,7 +2980,7 @@ func DisabledStoreWithoutVendor(ctx *jxcontext.Context, isContinueWhenError, isA task := tasksch.NewParallelTask("DisabledStoreWithoutVendor", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { store := batchItemList[0].(*model.Store) - storeMaps, err := dao.GetStoresMapList(db, []int{model.VendorIDYB, model.VendorIDJD, model.VendorIDJX, model.VendorIDEBAI, model.VendorIDMTWM}, []int{store.ID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "") + storeMaps, err := dao.GetStoresMapList(db, []int{model.VendorIDYB, model.VendorIDJD, model.VendorIDJX, model.VendorIDEBAI, model.VendorIDMTWM}, []int{store.ID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") if len(storeMaps) == 0 { store.Status = model.StoreStatusDisabled dao.UpdateEntity(db, store, "Status") diff --git a/business/jxstore/cms/store_sku.go b/business/jxstore/cms/store_sku.go index 6fa4ee8dc..80c7637ed 100644 --- a/business/jxstore/cms/store_sku.go +++ b/business/jxstore/cms/store_sku.go @@ -96,6 +96,7 @@ type tStoreSkuBindAndSpec struct { ExdSkuID string `orm:"column(exd_sku_id)"` StoreName string ChangePriceType int8 `json:"changePriceType"` // 修改价格类型,即是否需要审核 + NameID int `orm:"column(name_id)" json:"nameID"` } type SkuSaleInfo struct { @@ -128,6 +129,7 @@ type tGetStoresSkusInfo struct { dao.StoreSkuExt RealMidUnitPrice int `json:"realMidUnitPrice"` //真实的该商品的全国中位价 YbSkuName string + AuditUnitPrice int } type SheetParam struct { @@ -312,11 +314,13 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool JOIN store_sku_bind t4 ON t4.store_id = t3.id AND t4.sku_id = t2.id AND t4.deleted_at = ? LEFT JOIN sku_name_place_bind t5 ON t1.id = t5.name_id AND t3.city_code = t5.place_code LEFT JOIN price_refer_snapshot t6 ON t6.city_code = ? AND t6.sku_id = t2.id AND t6.snapshot_at = ? + LEFT JOIN store_sku_audit t7 ON t7.store_id = t3.id AND t7.name_id = t1.id AND t7.status = ? AND t7.deleted_at = ? WHERE t1.deleted_at = ? AND (t1.is_global = 1 OR t5.id IS NOT NULL OR 1 = ?)/* AND t1.status = ?*/ ` sqlParams = append(sqlParams, []interface{}{ utils.DefaultTimeValue, 0, utils.Time2Date(time.Now().AddDate(0, 0, -1)), + model.StoreAuditStatusOnline, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.Bool2Int(isFocus), }) @@ -544,7 +548,8 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus, i t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price, t4.yb_price, t4.jds_price, t4.jd_lock_time, t4.ebai_lock_time, t4.mtwm_lock_time, t4.jx_lock_time, t4.yb_lock_time, t4.jds_lock_time, t4.status_sale_begin, t4.status_sale_end, - t6.mid_unit_price real_mid_unit_price + t6.mid_unit_price real_mid_unit_price, + t7.unit_price audit_unit_price ` + sql if isHighPrice || priceType != 0 { sql += " , t4.unit_price DESC LIMIT 99" @@ -573,6 +578,7 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus, i PayPercentage: v.PayPercentage, RealMidUnitPrice: v.RealMidUnitPrice, YbSkuName: v.YbSkuName, + AuditUnitPrice: v.AuditUnitPrice, } if !isBySku { storeNameMap[index] = storeName @@ -702,7 +708,7 @@ func updateSaleInfo4StoreSkuName(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs } func getValidStoreVendorMap(db *dao.DaoDB, storeIDs []int) (realVendorMap map[int]int, err error) { - storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "") + storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") if err != nil { return nil, err } @@ -832,29 +838,43 @@ func UpdateStoreSku(ctx *jxcontext.Context, causeFlag, storeID int, skuBindInfo } func UpdateStoreSkus(ctx *jxcontext.Context, causeFlag, storeID int, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) { - return UpdateStoresSkus(ctx, causeFlag, []int{storeID}, skuBindInfos, false, isAsync, isContinueWhenError) + return UpdateStoresSkus(ctx, causeFlag, []int{storeID}, skuBindInfos, false, false, isAsync, isContinueWhenError) } -func UpdateStoresSkus(ctx *jxcontext.Context, causeFlag int, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isScale, isAsync, isContinueWhenError bool) (hint string, err error) { +func UpdateStoresSkus(ctx *jxcontext.Context, causeFlag int, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isScale, isRefreshHigh, isAsync, isContinueWhenError bool) (hint string, err error) { globals.SugarLogger.Debugf("UpdateStoresSkus:%s, storeIDs:%v, skuBindInfos:%s", ctx.GetTrackInfo(), storeIDs, utils.Format4Output(skuBindInfos, true)) - - var num int64 - db := dao.GetDB() - skuIDs, err := updateStoresSkusWithoutSync(ctx, db, storeIDs, skuBindInfos, isScale) - if err != nil { - return "", err - } - isAsync = asyncStoreSkuOpFilter(ctx, isAsync) - num = int64(len(skuIDs)) - if num > 0 { - hint, err = CurVendorSync.SyncStoresSkus(ctx, nil, causeFlag, db, nil, storeIDs, skuIDs, false, isAsync, isContinueWhenError) - } - if num == 0 || !isAsync || hint == "" { - hint = utils.Int64ToStr(num) + flag, err := doStoreSkuAudit(ctx, storeIDs, skuBindInfos) + if !flag { + var num int64 + db := dao.GetDB() + skuIDs, err := updateStoresSkusWithoutSync(ctx, db, storeIDs, skuBindInfos, isScale, isRefreshHigh) + if err != nil { + return "", err + } + isAsync = asyncStoreSkuOpFilter(ctx, isAsync) + num = int64(len(skuIDs)) + if num > 0 { + hint, err = CurVendorSync.SyncStoresSkus(ctx, nil, causeFlag, db, nil, storeIDs, skuIDs, false, isAsync, isContinueWhenError) + } + if num == 0 || !isAsync || hint == "" { + hint = utils.Int64ToStr(num) + } } return hint, err } +func UpdateStoresSkusWithoutSync(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isRefreshHigh bool) (err error) { + db := dao.GetDB() + if len(storeIDs) == 0 { + stores, _ := dao.GetStoreList(db, nil, nil, nil, nil, "") + for _, v := range stores { + storeIDs = append(storeIDs, v.ID) + } + } + updateStoresSkusWithoutSync(ctx, db, storeIDs, skuBindInfos, false, isRefreshHigh) + return err +} + func UpdateStoresSkusByBind(ctx *jxcontext.Context, parentTask tasksch.ITask, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError, isFos bool) (hint string, err error) { // if len(skuBindInfos) > maxStoreNameBind { // return "", fmt.Errorf("门店商品信息大于%d", maxStoreNameBind) @@ -880,7 +900,7 @@ func UpdateStoresSkusByBind(ctx *jxcontext.Context, parentTask tasksch.ITask, sk // } // }() for _, storeID := range storeIDs { - skuIDs, err2 := updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosMap[storeID], false) + skuIDs, err2 := updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosMap[storeID], false, false) if err = err2; err != nil { // dao.Rollback(db) return "", err @@ -960,7 +980,7 @@ func uniqueStoreNameBind(skuBindInfos []*StoreSkuBindInfo) (outSkuBindInfos []*S return outSkuBindInfos } -func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isScale bool) (needSyncSkus []int, err error) { +func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isScale, isRefreshHigh bool) (needSyncSkus []int, err error) { // if len(storeIDs)*len(skuBindInfos) > maxStoreNameBind2 { // return nil, fmt.Errorf("门店商品信息大于%d", maxStoreNameBind2) // } @@ -976,9 +996,6 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs // if err = checkStoresSkusSaleCity(ctx, db, storeIDs, skuBindInfos); err != nil { // return nil, err // } - // if storeIDs, skuBindInfos, err = filterStorePriceChange(ctx, storeIDs, skuBindInfos); err != nil { - // return nil, err - // } // globals.SugarLogger.Debugf("updateStoresSkusWithoutSync2, storeIDs:%v, skuBindInfos:%s", storeIDs, utils.Format4Output(skuBindInfos, false)) isUserCanDirectChangePrice := true if user := ctx.GetFullUser(); user != nil { @@ -1018,7 +1035,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs sql += " IF(t5.unit_price > 0, t5.unit_price, t3.price) sku_name_price," } sql += ` - t3.unit sku_name_unit, t3.name, t3.status sku_name_status, + t3.unit sku_name_unit, t3.name, t3.status sku_name_status, t3.id name_id, ts.change_price_type, ts.name store_name FROM sku t1 JOIN store ts ON ts.id = ? AND ts.deleted_at = ? @@ -1139,6 +1156,15 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs dao.Rollback(db) return nil, err } + //删除待审核商品信息 + storeAudits, err := dao.GetStoreSkuAuditLight(db, []int{storeID}, []int{v.NameID}, model.StoreAuditStatusOnline) + if len(storeAudits) > 0 { + storeAudits[0].DeletedAt = time.Now() + if _, err = dao.UpdateEntity(db, storeAudits[0], "DeletedAt"); err != nil { + dao.Rollback(db) + return nil, err + } + } } else { // 用了SELECT FOR UPDATE后,只更新修改字段是没有必要的,暂时保留 updateFieldMap := make(map[string]interface{}) @@ -1168,11 +1194,21 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs setStoreSkuBindStatus(skuBind, model.SyncFlagPriceMask) updateFieldMap["Price"] = 1 } - skuBind.UnitPrice = unitPrice - skuBind.Price = price - skuBind.JxPrice = jxPrice - updateFieldMap["UnitPrice"] = 1 - updateFieldMap["JxPrice"] = 1 + if isRefreshHigh { + if beforeMsg.UnitPrice > skuBindInfo.UnitPrice { + skuBind.UnitPrice = unitPrice + skuBind.Price = price + skuBind.JxPrice = jxPrice + updateFieldMap["UnitPrice"] = 1 + updateFieldMap["JxPrice"] = 1 + } + } else { + skuBind.UnitPrice = unitPrice + skuBind.Price = price + skuBind.JxPrice = jxPrice + updateFieldMap["UnitPrice"] = 1 + updateFieldMap["JxPrice"] = 1 + } } } if skuBindInfo.StatusSaleBegin != 0 && skuBindInfo.StatusSaleEnd != 0 { @@ -1851,7 +1887,7 @@ func AcceptStoreOpRequests(ctx *jxcontext.Context, reqIDs []int) (err error) { } } if err2 == nil { - _, err2 := UpdateStoresSkus(ctx, 0, []int{op.StoreID}, []*StoreSkuBindInfo{skuBindInfo}, false, false, false) + _, err2 := UpdateStoresSkus(ctx, 0, []int{op.StoreID}, []*StoreSkuBindInfo{skuBindInfo}, false, false, false, false) isLocalSucess := true if err2 != nil { subErrors[reqID] = err2 @@ -2067,7 +2103,7 @@ func RefreshStoresSkuByVendor(ctx *jxcontext.Context, storeIDs []int, vendorID i return "", fmt.Errorf("此功能当前只支持京东到家平台") } db := dao.GetDB() - storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "") + storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") if err != nil { return "", err } @@ -2570,7 +2606,7 @@ func RefershStoreSkusMidPrice(ctx *jxcontext.Context, storeIDs []int, isCountry } } } - updateStoresSkusWithoutSync(ctx, db, []int{v}, skuBindInfos, false) + updateStoresSkusWithoutSync(ctx, db, []int{v}, skuBindInfos, false, false) } if err == nil { CreateStorePriceScore(ctx) @@ -2712,7 +2748,7 @@ func RefreshJxPriceByExcelBin(ctx *jxcontext.Context, storeIDs []int, reader io. skuBindInfoList = append(skuBindInfoList, v.(*StoreSkuBindInfo)) } if isErr { - UpdateStoresSkus(ctx, 0, storeIDs, skuBindInfoList, false, isAsync, isContinueWhenError) + UpdateStoresSkus(ctx, 0, storeIDs, skuBindInfoList, false, false, isAsync, isContinueWhenError) } case 3: //写Excel @@ -3372,7 +3408,7 @@ func AutoFocusStoreSkusWithoutFocus(ctx *jxcontext.Context, skuIDs []int, isSync if isSync { UpdateStoreSkus(ctx, 0, v.StoreID, skuBindInfoList, true, true) } else { - updateStoresSkusWithoutSync(ctx, db, []int{v.StoreID}, skuBindInfoList, false) + updateStoresSkusWithoutSync(ctx, db, []int{v.StoreID}, skuBindInfoList, false, false) } } return err @@ -3479,7 +3515,7 @@ func SendSeckillSkusCountMsg(ctx *jxcontext.Context, vendorIDs []int, isAsync, i ddMsgresult []interface{} ) db := dao.GetDB() - storeList, err := dao.GetStoresMapList(db, vendorIDs, nil, []int{model.StoreStatusClosed, model.StoreStatusHaveRest, model.StoreStatusOpened}, model.StoreStatusOpened, model.StoreIsSyncAll, "") + storeList, err := dao.GetStoresMapList(db, vendorIDs, nil, []int{model.StoreStatusClosed, model.StoreStatusHaveRest, model.StoreStatusOpened}, model.StoreStatusOpened, model.StoreIsSyncAll, "", "") taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { switch step { case 0: @@ -4076,7 +4112,7 @@ func RefreshMatterStock(ctx *jxcontext.Context, skuID int) (err error) { } } //物料店666666 - updateStoresSkusWithoutSync(ctx, db, []int{666666}, skuBindInfos, false) + updateStoresSkusWithoutSync(ctx, db, []int{666666}, skuBindInfos, false, false) return err } @@ -4424,7 +4460,7 @@ func focusC4Matters(ctx *jxcontext.Context, db *dao.DaoDB, v *model.Sku) (err er } skuBindInfos = append(skuBindInfos, skuBindInfo) } - updateStoresSkusWithoutSync(ctx, db, []int{model.MatterStoreID}, skuBindInfos, false) + updateStoresSkusWithoutSync(ctx, db, []int{model.MatterStoreID}, skuBindInfos, false, false) } return err } @@ -4443,24 +4479,190 @@ func RefreshJdsSkusStatus(ctx *jxcontext.Context) (err error) { return err } -func GetStoreSkuAudit(ctx *jxcontext.Context, storeIDs, nameIDs, skuIDs []int, status int, name, remark string, applyTimeStart, applyTimeEnd, auditTimeStart, auditTimeEnd time.Time, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { - pagedInfo, err = dao.GetStoreSkuAudit(dao.GetDB(), storeIDs, nameIDs, skuIDs, status, name, remark, applyTimeStart, applyTimeEnd, auditTimeStart, auditTimeEnd, pageSize, offset) +func GetStoreSkuAudit(ctx *jxcontext.Context, storeIDs, nameIDs, skuIDs, statuss, types []int, name, remark, keyword, cityName, marketManPhone, applyTimeStart, applyTimeEnd, auditTimeStart, auditTimeEnd string, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { + var ( + applyTimeStartp, applyTimeEndp, auditTimeStartp, auditTimeEndp time.Time + ) + if applyTimeStart != "" { + applyTimeStartp = utils.Str2Time(applyTimeStart) + } + if applyTimeEnd != "" { + applyTimeEndp = utils.Str2Time(applyTimeEnd) + } + if auditTimeStart != "" { + auditTimeStartp = utils.Str2Time(auditTimeStart) + } + if auditTimeEnd != "" { + auditTimeEndp = utils.Str2Time(auditTimeEnd) + } + pagedInfo, err = dao.GetStoreSkuAudit(dao.GetDB(), storeIDs, nameIDs, skuIDs, statuss, types, name, remark, keyword, marketManPhone, cityName, applyTimeStartp, applyTimeEndp, auditTimeStartp, auditTimeEndp, pageSize, offset) return pagedInfo, err } -func SetJxPrice(jxSkuInfoDataMulti *dao.StoreSkuNamesInfo,storeId int) (err error){ +func doStoreSkuAudit(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo) (isAudit bool, err error) { + globals.SugarLogger.Debugf("doStoreSkuAudit storeIDs: %v", storeIDs) + time.Sleep(time.Second / 5) db := dao.GetDB() - storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, model.VendorIDJX) - if err != nil { - dao.Rollback(db) - return err - } - /*重新计算京西价格*/ - for _,values := range jxSkuInfoDataMulti.SkuNames{ - for _,value := range values.Skus{ - value.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), value.JxPrice) + for _, storeID := range storeIDs { + for _, skuBindInfo := range skuBindInfos { + globals.SugarLogger.Debugf("doStoreSkuAudit storeID: %v , nameID: %v", storeID, skuBindInfo.NameID) + storeAudits, err := dao.GetStoreSkuAuditLight(db, []int{storeID}, []int{skuBindInfo.NameID}, model.StoreAuditStatusOnline) + //取消关注,可售排除 + if skuBindInfo.IsFocus == -1 || skuBindInfo.IsSale != 0 || skuBindInfo.UnitPrice == 0 { + globals.SugarLogger.Debugf("doStoreSkuAudit return1 storeID : %v nameID: %v", storeID, skuBindInfo.NameID) + return false, err + } + //运营排除 + // if (ctx.GetFullUser().Type & model.UserTypeOperator) != 0 { + // if len(storeAudits) > 0 { + // storeAudits[0].DeletedAt = time.Now() + // dao.UpdateEntity(db, storeAudits[0], "DeletedAt") + // } + // globals.SugarLogger.Debugf("doStoreSkuAudit return2 storeID : %v nameID: %v", storeID, skuBindInfo.NameID) + // return false, err + // } + if ctx.GetLoginType() != weixin.AuthTypeMP && ctx.GetLoginType() != weixin.AuthTypeMini { + if len(storeAudits) > 0 { + storeAudits[0].DeletedAt = time.Now() + dao.UpdateEntity(db, storeAudits[0], "DeletedAt") + if globals.IsProductEnv() { + skuAndNames, err := dao.GetSkus(db, nil, []int{skuBindInfo.NameID}, nil, nil, nil) + if len(skuAndNames) > 0 && err == nil { + weixinmsg.NotifyStoreOpRequestStatus(true, storeID, skuBindInfo.NameID, jxutils.ComposeSpuName(skuAndNames[0].Prefix, skuAndNames[0].Name, 0), storeAudits[0].OriginUnitPrice, skuBindInfo.UnitPrice, "") + } + } + } + globals.SugarLogger.Debugf("doStoreSkuAudit return3 storeID : %v nameID: %v", storeID, skuBindInfo.NameID) + return false, err + } + storeSkuAudit := &model.StoreSkuAudit{ + StoreID: storeID, + NameID: skuBindInfo.NameID, + Status: model.StoreAuditStatusOnline, + UnitPrice: skuBindInfo.UnitPrice, + } + //如果是关注改价 + if skuBindInfo.IsFocus == 1 { + if len(storeAudits) > 0 { + storeAudits[0].DeletedAt = time.Now() + dao.UpdateEntity(db, storeAudits[0], "DeletedAt") + } + storeSkuAudit.Type = model.StoreSkuAuditTypeFocus + } else { + storeSkus, err := dao.GetStoreSkusByNameIDs(db, []int{storeID}, skuBindInfo.NameID) + if len(storeSkus) > 0 { + //如果改的价比原价低排除 + if skuBindInfo.UnitPrice <= int(storeSkus[0].UnitPrice) { + if len(storeAudits) > 0 { + storeAudits[0].DeletedAt = time.Now() + dao.UpdateEntity(db, storeAudits[0], "DeletedAt") + } + globals.SugarLogger.Debugf("doStoreSkuAudit return4 storeID : %v nameID: %v", storeID, skuBindInfo.NameID) + return false, err + } else { + if len(storeAudits) > 0 { + storeAudits[0].DeletedAt = time.Now() + dao.UpdateEntity(db, storeAudits[0], "DeletedAt") + } + globals.SugarLogger.Debugf("doStoreSkuAudit cover storeID : %v nameID: %v", storeID, skuBindInfo.NameID) + } + } else { + return false, fmt.Errorf("未查询到该门店商品价,storeID: %v, nameID: %V", storeID, skuBindInfo.NameID) + } + storeSkuAudit.Type = model.StoreSkuAuditTypePrice + storeSkuAudit.OriginUnitPrice = int(storeSkus[0].UnitPrice) + } + dao.WrapAddIDCULDEntity(storeSkuAudit, ctx.GetUserName()) + err = dao.CreateEntity(db, storeSkuAudit) } } - /*重新计算京西价格*/ - return nil -} \ No newline at end of file + return true, err +} + +func StoreSkuPriceAudit(ctx *jxcontext.Context, storeSkuAudits []*model.StoreSkuAudit, status int, isAsync, isContinueWhenError bool) (hint string, err error) { + db := dao.GetDB() + if status == model.StoreAuditStatusOnline { + return "", fmt.Errorf("审核标志不正确!") + } + task := tasksch.NewParallelTask("StoreSkuPriceAudit", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeAudit := batchItemList[0].(*model.StoreSkuAudit) + storeAudits, err := dao.GetStoreSkuAuditLight(db, []int{storeAudit.StoreID}, []int{storeAudit.NameID}, model.StoreAuditStatusOnline) + if len(storeAudits) == 0 || err != nil { + return retVal, fmt.Errorf("未查询到该门店该商品的待审核信息!storeID: %v, nameID: %v", storeAudit.StoreID, storeAudit.NameID) + } + if len(storeAudits) > 1 { + return retVal, fmt.Errorf("查询到该门店该商品的待审核信息大于1条!storeID: %v, nameID: %v", storeAudit.StoreID, storeAudit.NameID) + } + flag := false + //审核通过 + if status == model.StoreAuditStatusCreated { + flag = true + storeAudits[0].UserID = ctx.GetUserID() + storeAudits[0].Status = model.StoreAuditStatusCreated + storeAudits[0].Remark = storeAudit.Remark + storeAudits[0].AuditPrice = storeAudit.AuditPrice + _, err = dao.UpdateEntity(db, storeAudits[0], "UserID", "Status", "Remark", "AuditPrice") + var skuBindInfos = []*StoreSkuBindInfo{ + &StoreSkuBindInfo{ + NameID: storeAudit.NameID, + UnitPrice: storeAudits[0].UnitPrice, + }, + } + //证明填了额外的审核价格 + if storeAudit.AuditPrice != 0 { + skuBindInfos[0].UnitPrice = storeAudit.AuditPrice + } + //如果是关注改价 + if storeAudits[0].Type == model.StoreSkuAuditTypeFocus { + skuBindInfos[0].IsFocus = 1 + } + var num int64 + db := dao.GetDB() + skuIDs, err := updateStoresSkusWithoutSync(ctx, db, []int{storeAudit.StoreID}, skuBindInfos, false, false) + if err != nil { + return "", err + } + isAsync = asyncStoreSkuOpFilter(ctx, isAsync) + num = int64(len(skuIDs)) + if num > 0 { + hint, err = CurVendorSync.SyncStoresSkus(ctx, nil, 0, db, nil, []int{storeAudit.StoreID}, skuIDs, false, isAsync, isContinueWhenError) + } + if num == 0 || !isAsync || hint == "" { + hint = utils.Int64ToStr(num) + } + // _, err = UpdateStoresSkus(ctx, 0, []int{storeID}, skuBindInfos, false, isAsync, isContinueWhenError) + } else if status == model.StoreAuditStatusRejected { + storeAudits[0].UserID = ctx.GetUserID() + storeAudits[0].Status = model.StoreAuditStatusRejected + storeAudits[0].Remark = storeAudit.Remark + _, err = dao.UpdateEntity(db, storeAudits[0], "UserID", "Status", "Remark") + } else { + return retVal, fmt.Errorf("审核标志不正确!") + } + if err == nil { + if globals.IsProductEnv() { + skuAndNames, err := dao.GetSkus(db, nil, []int{storeAudit.NameID}, nil, nil, nil) + if len(skuAndNames) > 0 && err == nil { + price := 0 + if storeAudit.AuditPrice != 0 { + price = storeAudit.AuditPrice + } else { + price = storeAudits[0].UnitPrice + } + weixinmsg.NotifyStoreOpRequestStatus(flag, storeAudit.StoreID, storeAudit.NameID, jxutils.ComposeSpuName(skuAndNames[0].Prefix, skuAndNames[0].Name, 0), storeAudits[0].OriginUnitPrice, price, storeAudit.Remark) + } + } + } + return retVal, err + }, storeSkuAudits) + tasksch.HandleTask(task, nil, true).Run() + if isAsync { + hint = task.GetID() + } else { + _, err = task.GetResult(0) + hint = "1" + } + return hint, err +} + diff --git a/business/jxstore/cms/store_sku_check.go b/business/jxstore/cms/store_sku_check.go index c66fe58d8..562cec2ff 100644 --- a/business/jxstore/cms/store_sku_check.go +++ b/business/jxstore/cms/store_sku_check.go @@ -1017,7 +1017,7 @@ func WriteToExcel(task *tasksch.SeqTask, data map[int][]DiffData, depotData map[ } } -func SetAAJxPrice(jxSkuInfoDataMulti *dao.StoreSkuNamesInfo, storeId int) (err error) { +func SetJxPrice(jxSkuInfoDataMulti *dao.StoreSkuNamesInfo, storeId int) (err error) { db := dao.GetDB() storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, model.VendorIDJX) if err != nil { diff --git a/business/jxstore/cms/sync.go b/business/jxstore/cms/sync.go index aba24309c..e85044885 100644 --- a/business/jxstore/cms/sync.go +++ b/business/jxstore/cms/sync.go @@ -645,7 +645,7 @@ func (v *VendorSync) AmendAndPruneStoreStuff(ctx *jxcontext.Context, vendorIDs [ func (v *VendorSync) LoopStoresMap2(ctx *jxcontext.Context, parentTask tasksch.ITask, db *dao.DaoDB, taskName string, isAsync, isManageIt bool, vendorIDs []int, storeIDs []int, mustDirty bool, handler tasksch.WorkFunc, isContinueWhenError bool) (task tasksch.ITask, hint string, err error) { var storeMapList []*model.StoreMap - if storeMapList, err = dao.GetStoresMapList2(db, vendorIDs, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", mustDirty); err != nil { + if storeMapList, err = dao.GetStoresMapList2(db, vendorIDs, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "", mustDirty); err != nil { return nil, "", err } if len(storeMapList) == 0 { @@ -1028,7 +1028,7 @@ func syncStoreSkusFromYb(ctx *jxcontext.Context, storeID, vendorID int, vendorSt for _, v := range resultDel { skuBindInfosDel = append(skuBindInfosDel, v.(*StoreSkuBindInfo)) } - _, err = updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosDel, false) + _, err = updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosDel, false, false) } case 2: if len(updateList) > 0 { @@ -1071,7 +1071,7 @@ func syncStoreSkusFromYb(ctx *jxcontext.Context, storeID, vendorID int, vendorSt for _, v := range resultUpt { skuBindInfosUpt = append(skuBindInfosUpt, v.(*StoreSkuBindInfo)) } - _, err = updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosUpt, false) + _, err = updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosUpt, false, false) } case 3: _, err = CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{0, 1, 3}, nil, false, nil, nil, 0, true, true) @@ -1101,7 +1101,7 @@ func (v *VendorSync) SyncJdsStoresSkus(ctx *jxcontext.Context, storeIDs []int, i func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { storeMap := batchItemList[0].(*model.StoreMap) if storeMap.Status > model.StoreStatusDisabled && storeMap.StoreID != model.JdShopMainStoreID && storeMap.SyncRule != 0 { - _, err = syncJdsStoresSkus(ctx, db, task, storeMap, isAsync, isContinueWhenError) + err = syncJdsStoresSkus(ctx, db, task, storeMap, isAsync, isContinueWhenError) } return nil, err }, loopMapInfo.StoreMapList) @@ -1113,16 +1113,14 @@ func (v *VendorSync) SyncJdsStoresSkus(ctx *jxcontext.Context, storeIDs []int, i return hint, err } -func syncJdsStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, storeMap *model.StoreMap, isAsync, isContinueWhenError bool) (hint string, err error) { +func syncJdsStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, storeMap *model.StoreMap, isAsync, isContinueWhenError bool) (err error) { var ( - mainSkusMap = make(map[int]*model.StoreSkuBind) - skusMap = make(map[int]*model.StoreSkuBind) - updateList []*model.StoreSkuBind - addList []*model.StoreSkuBind - skuBindInfos1 []*StoreSkuBindInfo - skuBindInfos2 []*StoreSkuBindInfo - resultInterface1 []interface{} - resultInterface2 []interface{} + mainSkusMap = make(map[int]*model.StoreSkuBind) + skusMap = make(map[int]*model.StoreSkuBind) + updateList []*model.StoreSkuBind + addList []*model.StoreSkuBind + skuBindInfos1 []*StoreSkuBindInfo + skuBindInfos2 []*StoreSkuBindInfo ) storeSkusMain, err := dao.GetStoresSkusInfo(db, []int{model.JdShopMainStoreID}, nil) for _, v := range storeSkusMain { @@ -1142,53 +1140,20 @@ func syncJdsStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch } } } - // fmt.Println("updateList", utils.Format4Output(updateList, false)) - // fmt.Println("addList", utils.Format4Output(addList, false)) - task := tasksch.NewParallelTask("正在同步京东商城的库存商品", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(ptTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - if len(updateList) > 0 { - task := tasksch.NewParallelTask("同步门店库存", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeBind := batchItemList[0].(*model.StoreSkuBind) - retVal = []*StoreSkuBindInfo{buildStoreSkuBindInfo(db, storeMap.StoreID, storeBind, false)} - return retVal, err - }, updateList) - tasksch.HandleTask(task, ptTask, false).Run() - resultInterface1, err = task.GetResult(0) - for _, v := range resultInterface1 { - skuBindInfos1 = append(skuBindInfos1, v.(*StoreSkuBindInfo)) - } - hint, err = UpdateStoresSkusByBind(ctx, ptTask, skuBindInfos1, isAsync, isContinueWhenError, false) - } - case 1: - if len(addList) > 0 { - task := tasksch.NewParallelTask("同步门店商品", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeBind := batchItemList[0].(*model.StoreSkuBind) - retVal = []*StoreSkuBindInfo{buildStoreSkuBindInfo(db, storeMap.StoreID, storeBind, true)} - return retVal, err - }, addList) - tasksch.HandleTask(task, ptTask, false).Run() - resultInterface2, err = task.GetResult(0) - for _, v := range resultInterface2 { - skuBindInfos2 = append(skuBindInfos2, v.(*StoreSkuBindInfo)) - } - hint, err = UpdateStoresSkusByBind(ctx, ptTask, skuBindInfos2, isAsync, isContinueWhenError, false) - } - } - return retVal, err - }, []int{0, 1}) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - _, err = task.GetResult(0) - hint = "1" + if len(updateList) > 0 { + for _, v := range updateList { + skuBindInfos1 = append(skuBindInfos1, buildStoreSkuBindInfo(db, storeMap.StoreID, v, false)) + } + _, err = UpdateStoresSkusByBind(ctx, parentTask, skuBindInfos1, isAsync, isContinueWhenError, false) } - return hint, err + + if len(addList) > 0 { + for _, v := range addList { + skuBindInfos2 = append(skuBindInfos2, buildStoreSkuBindInfo(db, storeMap.StoreID, v, false)) + } + _, err = UpdateStoresSkusByBind(ctx, parentTask, skuBindInfos2, isAsync, isContinueWhenError, false) + } + return err } func buildStoreSkuBindInfo(db *dao.DaoDB, storeID int, storeBind *model.StoreSkuBind, isFocus bool) (skuBindInfo *StoreSkuBindInfo) { diff --git a/business/jxstore/cms/sync_store.go b/business/jxstore/cms/sync_store.go index dcb95dc1d..5c76fe676 100644 --- a/business/jxstore/cms/sync_store.go +++ b/business/jxstore/cms/sync_store.go @@ -16,7 +16,7 @@ func OpenRemoteStoreByJxStatus(ctx *jxcontext.Context, vendorIDs, storeIDs []int if !isForce { status = model.StoreStatusClosed } - storeMapList, err := dao.GetStoresMapList(db, vendorIDs, storeIDs, nil, status, model.StoreIsSyncYes, "") + storeMapList, err := dao.GetStoresMapList(db, vendorIDs, storeIDs, nil, status, model.StoreIsSyncYes, "", "") if err != nil { return "", err } diff --git a/business/jxstore/cms/sync_store_sku.go b/business/jxstore/cms/sync_store_sku.go index 3c0d35393..d5f5786a9 100644 --- a/business/jxstore/cms/sync_store_sku.go +++ b/business/jxstore/cms/sync_store_sku.go @@ -231,12 +231,13 @@ func storeSkuSyncInfo2Bare(inSku *dao.StoreSkuSyncInfo) (outSku *partner.StoreSk NameID: inSku.NameID, VendorNameID: inSku.VendorNameID, - Status: inSku.MergedStatus, - VendorPrice: inSku.VendorPrice, - Seq: inSku.Seq, - JxPrice: inSku.Price, - JxUnitPrice: inSku.UnitPrice, - VendorSkuID2: utils.Int64ToStr(inSku.JdsWareID), + Status: inSku.MergedStatus, + VendorPrice: inSku.VendorPrice, + Seq: inSku.Seq, + JxPrice: inSku.Price, + JxUnitPrice: inSku.UnitPrice, + VendorSkuID2: utils.Int64ToStr(inSku.JdsWareID), + JdsStockSwitch: inSku.JdsStockSwitch, } if !isStoreSkuSyncNeedDelete(inSku) { outSku.Stock = model.MaxStoreSkuStockQty diff --git a/business/jxstore/common/common.go b/business/jxstore/common/common.go new file mode 100644 index 000000000..8e236f12b --- /dev/null +++ b/business/jxstore/common/common.go @@ -0,0 +1,178 @@ +package common + +import ( + "sort" + + "git.rosy.net.cn/baseapi/platformapi/autonavi" + "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/globals/api" +) + +type Store4User struct { + model.ModelIDCULD + + OriginalName string `orm:"-" json:"originalName"` + Name string `orm:"size(255)" json:"name"` + OpenTime1 int16 `json:"openTime1"` // 930就表示9点半,用两个的原因是为了支持中午休息,1与2的时间段不能交叉,为0表示没有 + CloseTime1 int16 `json:"closeTime1"` // 格式同上 + OpenTime2 int16 `json:"openTime2"` // 格式同上 + CloseTime2 int16 `json:"closeTime2"` // 格式同上 + Status int `json:"status"` + CityCode int `orm:"default(0);null" json:"cityCode"` // todo ? + DistrictCode int `orm:"default(0);null" json:"districtCode"` // todo ? + Address string `orm:"size(255)" json:"address"` + Tel1 string `orm:"size(32);index" json:"tel1"` + Tel2 string `orm:"size(32);index" json:"tel2"` + Lng int `json:"-"` // 乘了10的6次方 + Lat int `json:"-"` // 乘了10的6次方 + DeliveryRangeType int8 `json:"-"` // 参见相关常量定义 + DeliveryRange string `orm:"type(text)" json:"-"` // 如果DeliveryRangeType为DeliveryRangeTypePolygon,则为逗号分隔坐标,分号分隔的坐标点(坐标与Lng和Lat一样,都是整数),比如 121361504,31189308;121420555,31150238。否则为半径,单位为米 + + FloatLng float64 `json:"lng"` + FloatLat float64 `json:"lat"` + CityName string `json:"cityName"` + DistrictName string `json:"districtName"` + + Distance int `json:"distance"` + WalkDistance int `json:"walkDistance"` +} + +type Store4UserList []*Store4User + +func (x Store4UserList) Len() int { + return len(x) +} + +func (x Store4UserList) Less(i, j int) bool { + if x[i].Status != x[j].Status { + return x[i].Status > x[j].Status + } + if x[i].WalkDistance != x[j].WalkDistance { + return x[i].WalkDistance < x[j].WalkDistance + } + return x[i].Distance < x[j].Distance +} + +func (x Store4UserList) Swap(i, j int) { + x[i], x[j] = x[j], x[i] +} + +func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, maxRadius int, needWalkDistance, isJds bool) (storeList []*Store4User, err error) { + const ( + maxStoreCount4User = 5 + ) + + var ( + sql string + sqlParams []interface{} + ) + + lng2, _ := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 90) + _, lat2 := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 0) + lng1 := lng - (lng2 - lng) + lat1 := lat - (lat2 - lat) + // globals.SugarLogger.Debugf("%f,%f,%f,%f\n", lng1, lng2, lat1, lat2) + if !isJds { + sql = ` + SELECT t1.*, + city.name city_name + FROM store t1 + JOIN place city ON city.code = t1.city_code + JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status <> ? + WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.lng > ? AND t1.lng < ? AND t1.lat > ? AND t1.lat < ? + AND sm.is_order <> ? + AND t1.id <> ? + ORDER BY t1.id + ` + sqlParams = []interface{}{ + model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled, + utils.DefaultTimeValue, model.StoreStatusDisabled, jxutils.StandardCoordinate2Int(lng1), jxutils.StandardCoordinate2Int(lng2), jxutils.StandardCoordinate2Int(lat1), jxutils.StandardCoordinate2Int(lat2), + model.YES, + model.MatterStoreID, + } + } else { + sql = ` + SELECT t1.*, + city.name city_name + FROM store t1 + JOIN place city ON city.code = t1.city_code + JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status = ? + WHERE t1.deleted_at = ? AND t1.status = ? AND t1.lng > ? AND t1.lng < ? AND t1.lat > ? AND t1.lat < ? + AND sm.is_order <> ? + AND t1.id <> ? + ORDER BY t1.id + ` + sqlParams = []interface{}{ + model.VendorIDJDShop, utils.DefaultTimeValue, model.StoreStatusOpened, + utils.DefaultTimeValue, model.StoreStatusOpened, jxutils.StandardCoordinate2Int(lng1), jxutils.StandardCoordinate2Int(lng2), jxutils.StandardCoordinate2Int(lat1), jxutils.StandardCoordinate2Int(lat2), + model.YES, + model.MatterStoreID, + } + } + var storeList1 []*Store4User + if err = dao.GetRows(dao.GetDB(), &storeList1, sql, sqlParams...); err == nil { + var storeList2 []*Store4User + for _, v := range storeList1 { + distance := jxutils.Point2StoreDistance(lng, lat, v.Lng, v.Lat, v.DeliveryRangeType, v.DeliveryRange) + if distance > 0 || (lng == jxutils.IntCoordinate2Standard(v.Lng) && lat == jxutils.IntCoordinate2Standard(v.Lat)) { + v.Distance = distance + storeList2 = append(storeList2, v) + } + } + + // 为了审核用 + if len(storeList2) == 0 { + sql2 := ` + SELECT t1.*, + city.name city_name + FROM store t1 + JOIN place city ON city.code = t1.city_code + WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.id = ? + ` + sqlParams2 := []interface{}{ + // model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled, + utils.DefaultTimeValue, + model.StoreStatusDisabled, + // jxutils.StandardCoordinate2Int(0), + // jxutils.StandardCoordinate2Int(10000), + // jxutils.StandardCoordinate2Int(0), + // jxutils.StandardCoordinate2Int(10000), + // model.YES, + 102919, //商城模板店 + } + dao.GetRows(dao.GetDB(), &storeList2, sql2, sqlParams2...) + // if len(storeList2) > 1 { + // storeList2 = storeList2[:1] + // } + } + + // 如果要求以步行距离来算 + if needWalkDistance { + var coordList []*autonavi.Coordinate + for _, v := range storeList2 { + coordList = append(coordList, &autonavi.Coordinate{ + Lng: v.FloatLng, + Lat: v.FloatLat, + }) + } + if distanceList, err2 := api.AutonaviAPI.BatchWalkingDistance(lng, lat, coordList); err2 == nil { + for k, v := range storeList2 { + v.WalkDistance = int(distanceList[k]) + } + } else { + return nil, err2 + } + } + + sort.Sort(Store4UserList(storeList2)) + storeList = storeList2 + if len(storeList) > maxStoreCount4User { + storeList = storeList[:maxStoreCount4User] + } + } + return storeList, err +} diff --git a/business/jxstore/misc/misc.go b/business/jxstore/misc/misc.go index 0668bdb23..88538c5e4 100644 --- a/business/jxstore/misc/misc.go +++ b/business/jxstore/misc/misc.go @@ -45,6 +45,9 @@ var ( dailyWorkTimeList = []string{ "22:00:00", } + dailyWorkTimeList2 = []string{ + "23:00:00", + } priceReferTimeList = []string{ "01:00:00", } @@ -158,6 +161,12 @@ func Init() { if globals.IsProductEnv() { ScheduleTimerFunc("doDailyWork", doDailyWork, dailyWorkTimeList) + ScheduleTimerFunc("doDailyWork2", doDailyWork2, dailyWorkTimeList2) + + ScheduleTimerFuncByInterval(func() { + orderman.SaveJdsOrders(jxcontext.AdminCtx, time.Now().Add(-15*time.Minute), time.Now()) + }, 10*time.Second, 10*time.Minute) + ScheduleTimerFuncByInterval(func() { RefreshRealMobile(jxcontext.AdminCtx, model.VendorIDEBAI, time.Now().Add(-24*time.Hour), utils.DefaultTimeValue, false, true) }, 5*time.Second, 1*time.Hour) @@ -261,8 +270,6 @@ func Init() { }, []string{ "04:05:06", }) - ScheduleTimerFuncByInterval(func() { - }, 5*time.Second, 5*time.Minute) } if configs, err := dao.QueryConfigs(dao.GetDB(), "ebaiStorePageCookieExdTOKEN", model.ConfigTypeCookie, ""); err == nil { ebaiStorePageCookieExdTOKEN = configs[0].Value @@ -373,6 +380,13 @@ func syncStoreSku() { tasksch.HandleTask(task, nil, true).Run() } +func doDailyWork2() { + globals.SugarLogger.Debug("doDailyWork2") + + //同步京东商城门店库存和商品 + cms.CurVendorSync.SyncJdsStoresSkus(jxcontext.AdminCtx, nil, true, true) +} + func doDailyWork() { globals.SugarLogger.Debug("doDailyWork") @@ -403,8 +417,6 @@ func doDailyWork() { cms.CurVendorSync.SyncStoreSkusFromYb(jxcontext.AdminCtx, nil, true, true) //刷新京东商城订单结算价 orderman.RefreshJdShopOrdersEarningPrice(jxcontext.AdminCtx, time.Now().AddDate(0, 0, -3).Format("20060102"), time.Now().Format("20060102")) - //同步京东商城门店库存和商品 - cms.CurVendorSync.SyncJdsStoresSkus(jxcontext.AdminCtx, nil, true, true) //同步上架京东商城待售商品 cms.RefreshJdsSkusStatus(jxcontext.AdminCtx) } diff --git a/business/jxstore/tempop/tempop.go b/business/jxstore/tempop/tempop.go index 9257cd023..59bd8017c 100644 --- a/business/jxstore/tempop/tempop.go +++ b/business/jxstore/tempop/tempop.go @@ -1236,7 +1236,7 @@ func FixMtwmCategory(ctx *jxcontext.Context, mtwmStoreIDs []int, isAsync, isCont func JdStoreInfo1125() (hint string, err error) { fileName := "老格恢复拓店进度.xlsx" db := dao.GetDB() - storeList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "") + storeList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") if err == nil { var validStoreList []*dao.StoreDetail for _, v := range storeList { @@ -1617,3 +1617,76 @@ func UploadJdsImage(ctx *jxcontext.Context) (err error) { }) return err } + +func RefreshJXPriceChange(ctx *jxcontext.Context, storeID int) (hint string, err error) { + db := dao.GetDB() + var ( + stores []*model.Store + vendorIDs = []int{0, 1, 3, 5, 9} + isAsync = true + isContinueWhenError = true + ) + sql := ` + SELECT * + FROM store + WHERE deleted_at = ? AND status <> ? + AND id <> 100118 AND id <> 100274 AND id <> 100205 + ` + sqlParams := []interface{}{utils.DefaultTimeValue, model.StoreStatusDisabled} + if storeID != 0 { + sql += " AND id = ?" + sqlParams = append(sqlParams, storeID) + } + err = dao.GetRows(db, &stores, sql, sqlParams) + task := tasksch.NewParallelTask("刷新门店价格", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + store := batchItemList[0].(*model.Store) + var skuBindInfos []*cms.StoreSkuBindInfo + for _, v := range vendorIDs { + storeMaps, _ := dao.GetStoresMapList(db, []int{v}, []int{store.ID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") + if len(storeMaps) > 0 { + storeMap := storeMaps[0] + switch v { + case model.VendorIDJD: + storeMap.PricePercentagePack = "京东测试报价=结算价" + dao.UpdateEntity(db, storeMap, "PricePercentagePack") + case model.VendorIDEBAI: + storeMap.PricePercentagePack = "美团测试报价=结算价" + dao.UpdateEntity(db, storeMap, "PricePercentagePack") + case model.VendorIDMTWM: + storeMap.PricePercentagePack = "饿百测试报价=结算价" + dao.UpdateEntity(db, storeMap, "PricePercentagePack") + case model.VendorIDJDShop: + storeMap.PricePercentagePack = "京西100-100" + dao.UpdateEntity(db, storeMap, "PricePercentagePack") + case model.VendorIDJX: + storeMap.PricePercentagePack = "京西100-100" + dao.UpdateEntity(db, storeMap, "PricePercentagePack") + } + } + } + storeSkus, err := dao.GetStoresSkusInfo(db, []int{store.ID}, nil) + for _, v := range storeSkus { + skuAndName, _ := dao.GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil) + skuBindInfo := &cms.StoreSkuBindInfo{ + // StoreID: store.ID, + NameID: skuAndName[0].NameID, + UnitPrice: v.UnitPrice * store.PayPercentage / 100, + } + skuBindInfos = append(skuBindInfos, skuBindInfo) + } + // cms.UpdateStoresSkusByBind(ctx, task, skuBindInfos, isAsync, isContinueWhenError, false) + cms.UpdateStoresSkusWithoutSync(ctx, []int{store.ID}, skuBindInfos, false) + store.PayPercentage = 100 + dao.UpdateEntity(db, store, "PayPercentage") + return retVal, err + }, stores) + tasksch.HandleTask(task, nil, true).Run() + if isAsync { + hint = task.GetID() + } else { + _, err = task.GetResult(0) + hint = "1" + } + return hint, err +} diff --git a/business/jxstore/yonghui/yonghui.go b/business/jxstore/yonghui/yonghui.go index a56207879..38cbb183d 100644 --- a/business/jxstore/yonghui/yonghui.go +++ b/business/jxstore/yonghui/yonghui.go @@ -851,7 +851,7 @@ func UpdateJxPriceByWeimob(ctx *jxcontext.Context, storeIDs []int, isAsync, isCo for _, v := range storeSkuBindInfoList { skuBindInfos = append(skuBindInfos, v.(*cms.StoreSkuBindInfo)) } - cms.UpdateStoresSkus(ctx, 0, storeIDs, skuBindInfos, false, isAsync, isContinueWhenError) + cms.UpdateStoresSkus(ctx, 0, storeIDs, skuBindInfos, false, false, isAsync, isContinueWhenError) case 2: WriteToExcel3(task, dataStoreSkusSuccess.dataStoreSkusSuccessList, dataFailed.dataFailedList) } diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index 723130186..945b0f832 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -3,6 +3,8 @@ package jxutils import ( "bytes" "context" + "crypto/aes" + "encoding/base64" "fmt" "io/ioutil" "math" @@ -882,3 +884,35 @@ func TranslateSoundSize(vendorID, soundPercentage int) (soundSize string) { } return soundSize } + +//ECB,AES模式解密 +//目前就京东商城订单手机号解密用 +func DecryptDESECB(d, key []byte) string { + data, err := base64.StdEncoding.DecodeString(string(d)) + if err != nil { + return "" + } + block, err := aes.NewCipher(key) + if err != nil { + return "" + } + bs := block.BlockSize() + if len(data)%bs != 0 { + return "" + } + out := make([]byte, len(data)) + dst := out + for len(data) > 0 { + block.Decrypt(dst, data[:bs]) + data = data[bs:] + dst = dst[bs:] + } + out = PKCS5UnPadding(out) + return string(out) +} + +func PKCS5UnPadding(origData []byte) []byte { + length := len(origData) + unpadding := int(origData[length-1]) + return origData[:(length - unpadding)] +} diff --git a/business/jxutils/smsmsg/smsmsg.go b/business/jxutils/smsmsg/smsmsg.go index 56d014418..6920761e7 100644 --- a/business/jxutils/smsmsg/smsmsg.go +++ b/business/jxutils/smsmsg/smsmsg.go @@ -86,7 +86,7 @@ func isPushSMS(order *model.GoodsOrder) bool { } else { storeID = order.StoreID } - stores, _ := dao.GetStoresMapList(dao.GetDB(), []int{order.VendorID}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "") + stores, _ := dao.GetStoresMapList(dao.GetDB(), []int{order.VendorID}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") if len(stores) > 0 { if stores[0].IsOrder == model.NO { if storeID == model.MatterStoreID { diff --git a/business/jxutils/weixinmsg/weixinmsg.go b/business/jxutils/weixinmsg/weixinmsg.go index 87795f53d..f8ecee65a 100644 --- a/business/jxutils/weixinmsg/weixinmsg.go +++ b/business/jxutils/weixinmsg/weixinmsg.go @@ -56,9 +56,9 @@ const ( WX_SALE_BILL_TEMPLATE_ID = "eTUuFZMWH7IsVBfcxNMpmaHYaxRkUaD6zG8wSGJDcic" - WX_NORMAL_STORE_MSG_TEMPLATE_ID = "EUeIJEz2TLUAn4TU2EffOGYLd3dEaYndD_y6Sw9FcSU" - // WX_CHANGE_APPROVED_TEMPLATE_ID = "gIG2olBZtQbjXmp6doNB_dESu60By5xuXYOGxksLv3Y" - // WX_CHANGE_REJECTED_TEMPLATE_ID = "tn2QXWi4HtSIwaztmtN6Bb2uzNL-jBxWltCZTDNJuYE" + WX_NORMAL_STORE_MSG_TEMPLATE_ID = "EUeIJEz2TLUAn4TU2EffOGYLd3dEaYndD_y6Sw9FcSU" + WX_CHANGE_APPROVED_TEMPLATE_ID = "gIG2olBZtQbjXmp6doNB_dESu60By5xuXYOGxksLv3Y" + WX_CHANGE_REJECTED_TEMPLATE_ID = "OBF4-d5inK95epHcUltpdb1zq9boVp2HESpASVRh1Oo" WX_ORDER_APPLY_CANCEL_TEMPLATE_ID = "e6urTtcm4PL0rgDMG_1qWNOwrE3Qxqcm_dx0kWWCmEI" WX_ORDER_ORDER_CANCELED_TEMPLATE_ID = "HXjuSAbIk77Xh18hjgwoxHzbciR9jX3Rn2CpLJz9dZw" @@ -460,50 +460,58 @@ func NotifySaleBill(storeID int, title, shopName, fileURL string) (err error) { } func NotifyStoreOpRequestStatus(isAccepted bool, storeID, nameID int, spuName string, originalUnitPrice, unitPrice int, rejectReason string) (err error) { - // globals.SugarLogger.Debugf("NotifyStoreOpRequestStatus isAccepted:%t, storeID:%d, nameID:%d, spuName:%s, originalUnitPrice:%d, unitPrice:%d, rejectReason:%s", isAccepted, storeID, nameID, spuName, originalUnitPrice, unitPrice, rejectReason) - // templateID := "" - // fileURL := globals.WxBackstageHost + fmt.Sprintf("%s%d", WX_TO_STORE_SKU_PAGE_URL, storeID) - // data := make(map[string]interface{}) - // if isAccepted { - // templateID = WX_CHANGE_APPROVED_TEMPLATE_ID - // data = map[string]interface{}{ - // "first": map[string]interface{}{ - // "value": fmt.Sprintf("%s%s元,修改为%s元,已经通过审核。^_^", spuName, jxutils.IntPrice2StandardString(int64(originalUnitPrice)), jxutils.IntPrice2StandardString(int64(unitPrice))), - // "color": "#333333", - // }, - // "keyword1": map[string]interface{}{ - // "value": "审核通过", - // "color": "#2E408E", - // }, - // "keyword2": map[string]interface{}{ - // "value": utils.Time2Str(time.Now()), - // "color": "#2E408E", - // }, - // "remark": map[string]interface{}{ - // "value": "点击查看详情", - // }, - // } - // } else { - // templateID = WX_CHANGE_REJECTED_TEMPLATE_ID - // data = map[string]interface{}{ - // "first": map[string]interface{}{ - // "value": fmt.Sprintf("您好!抱歉的通知您。%s%s元,修改为%s元,未通过审核。原因:%s", spuName, jxutils.IntPrice2StandardString(int64(originalUnitPrice)), jxutils.IntPrice2StandardString(int64(unitPrice)), rejectReason), - // "color": "#E80000", - // }, - // "keyword1": map[string]interface{}{ - // "value": "1", - // "color": "#2E408E", - // }, - // "keyword2": map[string]interface{}{ - // "value": utils.Time2Str(time.Now()), - // "color": "#2E408E", - // }, - // "remark": map[string]interface{}{ - // "value": "请您及时到商品管理修改价格,修改后请重新提交。", - // }, - // } - // } - // err = SendMsgToStore(storeID, templateID, fileURL, WX_MINI_TO_STORE_SKU_PAGE_URL, data) + globals.SugarLogger.Debugf("NotifyStoreOpRequestStatus isAccepted:%t, storeID:%d, nameID:%d, spuName:%s, originalUnitPrice:%d, unitPrice:%d, rejectReason:%s", isAccepted, storeID, nameID, spuName, originalUnitPrice, unitPrice, rejectReason) + templateID := "" + fileURL := globals.WxBackstageHost + fmt.Sprintf("%s%d", WX_TO_STORE_SKU_PAGE_URL, storeID) + data := make(map[string]interface{}) + if isAccepted { + templateID = WX_CHANGE_APPROVED_TEMPLATE_ID + data = map[string]interface{}{ + "first": map[string]interface{}{ + "value": fmt.Sprintf("%s%s元,修改为%s元,已经通过审核。^_^", spuName, jxutils.IntPrice2StandardString(int64(originalUnitPrice)), jxutils.IntPrice2StandardString(int64(unitPrice))), + "color": "#333333", + }, + "keyword1": map[string]interface{}{ + "value": "审核通过", + "color": "#2E408E", + }, + "keyword2": map[string]interface{}{ + "value": utils.Time2Str(time.Now()), + "color": "#2E408E", + }, + "remark": map[string]interface{}{ + "value": "点击查看详情", + }, + } + } else { + templateID = WX_CHANGE_REJECTED_TEMPLATE_ID + data = map[string]interface{}{ + "first": map[string]interface{}{ + "value": fmt.Sprintf("您好!抱歉的通知您。%s%s元,修改为%s元,未通过审核。原因:%s", spuName, jxutils.IntPrice2StandardString(int64(originalUnitPrice)), jxutils.IntPrice2StandardString(int64(unitPrice)), rejectReason), + "color": "#E80000", + }, + "keyword1": map[string]interface{}{ + "value": "1", + "color": "#2E408E", + }, + "keyword2": map[string]interface{}{ + "value": "审核不通过", + "color": "#2E408E", + }, + "keyword3": map[string]interface{}{ + "value": utils.Time2Str(time.Now()), + "color": "#2E408E", + }, + "keyword4": map[string]interface{}{ + "value": "审核不通过", + "color": "#2E408E", + }, + "remark": map[string]interface{}{ + "value": "请您及时到商品管理修改价格,修改后请重新提交。", + }, + } + } + err = SendMsgToStore(storeID, templateID, fileURL, WX_MINI_TO_STORE_SKU_PAGE_URL, data) return err } diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index fc8994645..6f090329b 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -1281,3 +1281,14 @@ func GetSimpleOrder(db *DaoDB, vendorOrderID string) (goods *model.GoodsOrder, e err = GetRow(db, &goods, sql, sqlParams) return goods, err } + +func GetSimpleOrderSkus(db *DaoDB, vendorOrderID string) (skus []*model.OrderSku, err error) { + sql := ` + SELECT * + FROM order_sku + WHERE vendor_order_id = ? + ` + sqlParams := []interface{}{vendorOrderID} + err = GetRows(db, &skus, sql, sqlParams) + return skus, err +} diff --git a/business/model/dao/store.go b/business/model/dao/store.go index cea3c67b6..ea87453c6 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -231,7 +231,7 @@ func GetStoreCourierList(db *DaoDB, storeIDs []int, status, auditStatus int) (co return nil, err } -func GetStoresMapList2(db *DaoDB, vendorIDs, storeIDs, storeStatuss []int, status, isSync int, pricePack string, mustDirty bool) (storeMapList []*model.StoreMap, err error) { +func GetStoresMapList2(db *DaoDB, vendorIDs, storeIDs, storeStatuss []int, status, isSync int, pricePack, name string, mustDirty bool) (storeMapList []*model.StoreMap, err error) { sql := ` SELECT t1.* FROM store_map t1 @@ -266,6 +266,10 @@ func GetStoresMapList2(db *DaoDB, vendorIDs, storeIDs, storeStatuss []int, statu sql += " AND t1.price_percentage_pack = ?" sqlParams = append(sqlParams, pricePack) } + if name != "" { + sql += " AND t2.name LIKE ?" + sqlParams = append(sqlParams, "%"+name+"%") + } if mustDirty { sql += " AND t1.sync_status <> 0" } @@ -300,8 +304,8 @@ func SetStoresMapSyncStatus(db *DaoDB, vendorIDs, storeIDs []int, syncStatus int return err } -func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs, storeStatuss []int, status, isSync int, pricePack string) (storeMapList []*model.StoreMap, err error) { - return GetStoresMapList2(db, vendorIDs, storeIDs, storeStatuss, status, isSync, pricePack, false) +func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs, storeStatuss []int, status, isSync int, pricePack, name string) (storeMapList []*model.StoreMap, err error) { + return GetStoresMapList2(db, vendorIDs, storeIDs, storeStatuss, status, isSync, pricePack, name, false) } func StoreMapList2Map(storeMapList []*model.StoreMap) (storeMapMap map[int][]*model.StoreMap) { diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go index 7ad56c0e0..404a477e4 100644 --- a/business/model/dao/store_sku.go +++ b/business/model/dao/store_sku.go @@ -86,6 +86,7 @@ type StoreSkuSyncInfo struct { NameCategoryID int `orm:"column(name_category_id)"` YbNameSuffix string //银豹的商品条码后缀 YbBarCode string //银豹的商品条码 + JdsStockSwitch int // 平台相关的图片信息 Img string @@ -155,6 +156,7 @@ type StoreSkuNameExt struct { RealMidUnitPrice int `json:"realMidUnitPrice"` Count int `json:"count"` YbSkuName string `json:"ybSkuName"` + AuditUnitPrice int `json:"auditUnitPrice"` //审核价格 } // GetStoreSkus用 @@ -402,6 +404,7 @@ func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty boo t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end, t1.jds_ware_id, t2.*, t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.status name_status, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end, t3.category_id name_category_id, t3.yb_name_suffix, + t3.jds_stock_switch, IF(t11.%s <> '', t11.%s, t3.img) img, IF(t12.%s <> '', t12.%s, t3.img2) img2, IF(t13.%s <> '', t13.%s, t3.desc_img) desc_img, @@ -1288,7 +1291,7 @@ func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesI vendorIDs = []int{actVendorID} } } else { - storeMapList, err := GetStoresMapList(db, nil, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "") + storeMapList, err := GetStoresMapList(db, nil, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") if err != nil { return err } @@ -1534,15 +1537,39 @@ func UpdateJdsWareID(db *DaoDB, storeSkuSyncInfo *StoreSkuSyncInfo) (err error) return err } -func GetStoreSkuAudit(db *DaoDB, storeIDs, nameIDs, skuIDs []int, status int, name, remark string, applyTimeStart, applyTimeEnd, auditTimeStart, auditTimeEnd time.Time, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { - var requestList []*model.StoreSkuAudit +type tStoreSkuAudit struct { + model.StoreSkuAudit + SkuName string `orm:"size(255)" json:"skuName"` + StoreName string `json:"storeName"` + Prefix string `orm:"size(255)" json:"prefix"` + Unit string `orm:"size(8)" json:"unit"` + SpecQuality float32 `json:"-"` // 为份必然为500,这个主要作用只是用于确保SkuName的唯一性 + SpecUnit string `orm:"size(8)" json:"-"` // 为份必然为克,这个主要作用只是用于确保SkuName的唯一性 + Img string `orm:"size(512)" json:"img"` + Name string `json:"name"` + MidUnitPrice int `json:"midUnitPrice"` + CityName string `json:"cityName"` + PayPercentage int `json:"payPercentage"` +} + +func GetStoreSkuAudit(db *DaoDB, storeIDs, nameIDs, skuIDs, statuss, types []int, name, remark, keyword, marketManPhone, cityName string, applyTimeStart, applyTimeEnd, auditTimeStart, auditTimeEnd time.Time, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { + var requestList []*tStoreSkuAudit sql := ` - SELECT SQL_CALC_FOUND_ROWS a.* - FROM store_sku_audit a, user b + SELECT SQL_CALC_FOUND_ROWS DISTINCT a.*, + c.name sku_name, c.prefix, c.unit, c.spec_quality, c.spec_unit, c.img, + d.name store_name, b.name, e.mid_unit_price, f.name city_name, d.pay_percentage + FROM store_sku_audit a + LEFT JOIN user b ON a.user_id = b.user_id + LEFT JOIN sku_name c ON c.id = a.name_id AND c.deleted_at = ? + LEFT JOIN store d ON d.id = a.store_id AND d.deleted_at = ? + LEFT JOIN place f ON f.code = d.city_code + LEFT JOIN price_refer_snapshot e ON e.name_id = c.id AND e.city_code = ? AND e.snapshot_at = ? WHERE a.deleted_at = ? - AND a.user_id = b.user_id ` - sqlParams := []interface{}{utils.DefaultTimeValue} + sqlParams := []interface{}{ + utils.DefaultTimeValue, utils.DefaultTimeValue, + 0, utils.Time2Date(time.Now().AddDate(0, 0, -1)), + utils.DefaultTimeValue} if len(storeIDs) > 0 { sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) @@ -1551,9 +1578,9 @@ func GetStoreSkuAudit(db *DaoDB, storeIDs, nameIDs, skuIDs []int, status int, na sql += " AND a.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" sqlParams = append(sqlParams, nameIDs) } - if status != model.StoreAuditStatusAll { - sql += " AND a.status = ? " - sqlParams = append(sqlParams, status) + if len(statuss) > 0 { + sql += " AND a.status IN (" + GenQuestionMarks(len(statuss)) + ")" + sqlParams = append(sqlParams, statuss) } if remark != "" { sql += " AND a.remark LIKE ? " @@ -1571,7 +1598,23 @@ func GetStoreSkuAudit(db *DaoDB, storeIDs, nameIDs, skuIDs []int, status int, na sql += " AND a.updated_at BETWEEN ? AND ?" sqlParams = append(sqlParams, applyTimeStart, applyTimeEnd) } - sql += "LIMIT ? OFFSET ?" + if len(types) > 0 { + sql += " AND a.type IN (" + GenQuestionMarks(len(types)) + ")" + sqlParams = append(sqlParams, types) + } + if keyword != "" { + sql += " AND (b.name LIKE ? OR a.remark LIKE ? OR a.name_id LIKE ? OR a.user_id LIKE ? OR a.store_id LIKE ? OR f.name LIKE ?)" + sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%") + } + if marketManPhone != "" { + sql += " AND d.market_man_phone LIKE ? " + sqlParams = append(sqlParams, "%"+marketManPhone+"%") + } + if cityName != "" { + sql += " AND f.name LIKE ? " + sqlParams = append(sqlParams, "%"+cityName+"%") + } + sql += " ORDER BY a.updated_at DESC LIMIT ? OFFSET ?" pageSize = jxutils.FormalizePageSize(pageSize) sqlParams = append(sqlParams, pageSize, offset) Begin(db) @@ -1584,3 +1627,26 @@ func GetStoreSkuAudit(db *DaoDB, storeIDs, nameIDs, skuIDs []int, status int, na } return pagedInfo, err } + +func GetStoreSkuAuditLight(db *DaoDB, storeIDs, nameIDs []int, status int) (storeSkuAudit []*model.StoreSkuAudit, err error) { + sql := ` + SELECT a.* + FROM store_sku_audit a + WHERE a.deleted_at = ? + ` + sqlParams := []interface{}{utils.DefaultTimeValue} + if len(storeIDs) > 0 { + sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" + sqlParams = append(sqlParams, storeIDs) + } + if len(nameIDs) > 0 { + sql += " AND a.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" + sqlParams = append(sqlParams, nameIDs) + } + if status != model.StoreAuditStatusAll { + sql += " AND a.status = ? " + sqlParams = append(sqlParams, status) + } + err = GetRows(db, &storeSkuAudit, sql, sqlParams...) + return storeSkuAudit, err +} diff --git a/business/model/sku.go b/business/model/sku.go index 1a467dd09..c6aa85847 100644 --- a/business/model/sku.go +++ b/business/model/sku.go @@ -187,7 +187,8 @@ type SkuName struct { // JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` // LinkID int `orm:"column(link_id);null;index" json:"linkID"` - YbNameSuffix string `json:"ybNameSuffix"` //银豹商品后缀 + YbNameSuffix string `json:"ybNameSuffix"` //银豹商品后缀 + JdsStockSwitch int8 `orm:"default(1)" json:"jdsStockSwitch"` } func (*SkuName) TableUnique() [][]string { diff --git a/business/model/store.go b/business/model/store.go index 647cc86d4..918c4e38d 100644 --- a/business/model/store.go +++ b/business/model/store.go @@ -25,6 +25,11 @@ const ( StoreAuditStatusAll = -9 ) +const ( + StoreSkuAuditTypePrice = 1 //改价 + StoreSkuAuditTypeFocus = 2 //关注 +) + const ( MainSubStoreName = "本店" MainSubStoreAddress = "本店" diff --git a/business/model/store_sku.go b/business/model/store_sku.go index 8bd9d72a7..66efb31c7 100644 --- a/business/model/store_sku.go +++ b/business/model/store_sku.go @@ -20,8 +20,8 @@ const ( const ( RequestStatusNew = 0 - RequestStatusRejected = 1 - RequestStatusAccepted = 2 + RequestStatusRejected = -1 + RequestStatusAccepted = 1 RequestStatusCanceled = 3 ) @@ -202,19 +202,13 @@ type StoreSkuAudit struct { Status int8 `json:"status"` // UserID string `orm:"size(48);column(user_id)" json:"userID"` OriginUnitPrice int `json:"originPrice"` // 表示原价 - UnitPrice int `json:"unitPrice"` + UnitPrice int `json:"unitPrice"` //老板申请的审核价格 + AuditPrice int `json:"auditPrice"` //运营录入的审核价格 Remark string `orm:"size(255)" json:"remark"` } -func (*StoreSkuAudit) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "Type", "NameID", "DeletedAt"}, - } -} - func (*StoreSkuAudit) TableIndex() [][]string { return [][]string{ - []string{"DeletedAt"}, - []string{"StoreID", "Status", "Type"}, + []string{"StoreID", "Type", "NameID", "Status", "DeletedAt"}, } } diff --git a/business/partner/delivery/jdeclp/waybill.go b/business/partner/delivery/jdeclp/waybill.go new file mode 100644 index 000000000..0a86dae61 --- /dev/null +++ b/business/partner/delivery/jdeclp/waybill.go @@ -0,0 +1,96 @@ +package jdeclp + +import ( + "fmt" + "time" + + "git.rosy.net.cn/baseapi/platformapi/jdeclpapi" + "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/globals/api" +) + +var ( + CurDeliveryHandler *DeliveryHandler +) + +type DeliveryHandler struct { +} + +func init() { + CurDeliveryHandler = new(DeliveryHandler) + partner.RegisterDeliveryPlatform(CurDeliveryHandler, true) +} + +func (c *DeliveryHandler) GetVendorID() int { + return model.VendorIDJDWL +} + +func (c *DeliveryHandler) CreateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (vendorStoreID string, status int, err error) { + return vendorStoreID, status, err +} +func (c *DeliveryHandler) GetStore(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeDetail *dao.StoreDetail2, err error) { + return storeDetail, err +} +func (c *DeliveryHandler) IsErrStoreNotExist(err error) bool { + return false +} +func (c *DeliveryHandler) IsErrStoreExist(err error) bool { + return false +} +func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) { + storeID := jxutils.GetShowStoreIDFromOrder(order) + stores, err := dao.GetStoreList(dao.GetDB(), []int{storeID}, nil, nil, nil, "") + if len(stores) == 0 || err != nil { + return bill, fmt.Errorf("未查询到该门店! 门店id :[%v]", storeID) + } + vendorWaybillID, err := api.JdEclpAPI.WaybillReceive(&jdeclpapi.WaybillReceiveParam{ + SalePlat: jdeclpapi.SalePlatSourceDelivery, + CustomerCode: jdeclpapi.CustomerCode, + OrderID: order.VendorOrderID, + SenderName: order.StoreName, + SenderAddress: stores[0].Address, + SenderTel: stores[0].Tel1, + ReceiveName: order.ConsigneeName, + ReceiveAddress: order.ConsigneeAddress, + ReceiveTel: order.ConsigneeMobile, + Weight: order.Weight, + Vloumn: order.Weight, + PackageCount: 1, + Description: "生鲜", + Aging: 5, + }) + waybill := &model.Waybill{ + VendorOrderID: order.VendorOrderID, + OrderVendorID: model.VendorIDJDShop, + VendorWaybillID: vendorWaybillID, + WaybillVendorID: model.VendorIDJDWL, + Status: model.WaybillStatusDelivering, + WaybillCreatedAt: time.Now(), + StatusTime: time.Now(), + WaybillFinishedAt: utils.DefaultTimeValue, + DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled, + } + dao.CreateEntity(dao.GetDB(), waybill) + return waybill, err +} +func (c *DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) { + err = api.JdEclpAPI.CancelWayBill(&jdeclpapi.CancelWayBillParam{ + WaybillCode: bill.VendorWaybillID, + CustomerCode: jdeclpapi.CustomerCode, + Source: "JOS", + CancelReason: cancelReason, + OperatorName: "jxadmin", + }) + return err +} +func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) { + return deliveryFeeInfo, err +} +func (c *DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) { + return err +} diff --git a/business/partner/delivery/jdeclp/waybill_test.go b/business/partner/delivery/jdeclp/waybill_test.go new file mode 100644 index 000000000..a8b1b4a51 --- /dev/null +++ b/business/partner/delivery/jdeclp/waybill_test.go @@ -0,0 +1 @@ +package jdeclp diff --git a/business/partner/partner_store_sku.go b/business/partner/partner_store_sku.go index 89867ba3c..46b73bdab 100644 --- a/business/partner/partner_store_sku.go +++ b/business/partner/partner_store_sku.go @@ -46,12 +46,13 @@ type StoreSkuInfo struct { Seq int `json:"seq,omitempty"` - ActPrice int64 `json:"actPrice,omitempty"` - VendorActID string `json:"vendorActID,omitempty"` - IsSpecialty int `json:"isSpecialty,omitempty"` - JxPrice int64 `json:"jxPrice,omitempty"` - JxUnitPrice int64 `json:"jxUnitPrice,omitempty"` - VendorSkuID2 string `json:"vendorSkuID2,omitempty"` + ActPrice int64 `json:"actPrice,omitempty"` + VendorActID string `json:"vendorActID,omitempty"` + IsSpecialty int `json:"isSpecialty,omitempty"` + JxPrice int64 `json:"jxPrice,omitempty"` + JxUnitPrice int64 `json:"jxUnitPrice,omitempty"` + VendorSkuID2 string `json:"vendorSkuID2,omitempty"` + JdsStockSwitch int `json:"jdsStockSwitch"` } type StoreSkuInfoWithErr struct { diff --git a/business/partner/purchase/jd/order.go b/business/partner/purchase/jd/order.go index 055ca98d8..273479a04 100644 --- a/business/partner/purchase/jd/order.go +++ b/business/partner/purchase/jd/order.go @@ -73,6 +73,7 @@ func (c *PurchaseHandler) updateOrderFinancialInfo(a *jdapi.API, orderID string) if err == nil { if orderSettlement != nil { updateOrderBySettleMent(order, orderSettlement) + globals.SugarLogger.Debugf("updateOrderBySettleMent: %v , %v", order.NewEarningPrice, order.TotalShopMoney) err = partner.CurOrderManager.UpdateOrderFields(order, []string{ /*"WaybillTipMoney", */ "TotalShopMoney", "PmSubsidyMoney", "NewEarningPrice"}) } } @@ -146,6 +147,8 @@ func updateOrderBySettleMent(order *model.GoodsOrder, orderSettlement *jdapi.Ord order.NewEarningPrice = order.EarningPrice } } + } else { + order.NewEarningPrice = order.EarningPrice } } } diff --git a/business/partner/purchase/jdshop/order.go b/business/partner/purchase/jdshop/order.go index f4f932caf..7b37f7363 100644 --- a/business/partner/purchase/jdshop/order.go +++ b/business/partner/purchase/jdshop/order.go @@ -1,11 +1,14 @@ package jdshop import ( + "time" + "git.rosy.net.cn/baseapi/platformapi/jdshopapi" "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/partner" "git.rosy.net.cn/jx-callback/globals/api" ) @@ -38,13 +41,31 @@ func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order * return p.Map2Order(utils.Struct2FlatMap(resultOrders)), err } func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { - return status, err + orderResult, err := api.JdShopAPI.AllOrders(&jdshopapi.AllOrdersParam{ + OrderID: vendorOrderID, + Current: 1, + PageSize: 1, + }) + return status2Jxstatus(orderResult.OrderList[0].OrderStatus), err } func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - return err + var status int + if isAcceptIt { + status = model.OrderStatusAccepted + } else { + status = model.OrderStatusCanceled + } + return ChangeOrderStatus(order.VendorOrderID, status, "") } func (p *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { + status, err := p.GetOrderStatus("", order.VendorOrderID2) + //说明此时该订单在平台上已经取消了 + if status == model.OrderStatusApplyCancel { + err = ChangeOrderStatus(order.VendorOrderID, model.OrderStatusFinishedPickup, "自动拣货完成") + } else { + err = ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, "订单状态发生了改变") + } return err } @@ -97,6 +118,62 @@ func (p *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, ord return err } -func GetJdsOrder(ctx *jxcontext.Context, vendorOrderID string) { - +func (p *PurchaseHandler) GetJdsOrders(ctx *jxcontext.Context, orderCreatedStart, orderCreatedEnd string, current, pageSize int) (orderResult *jdshopapi.AllOrdersResult, err error) { + orderResult, err = api.JdShopAPI.AllOrders(&jdshopapi.AllOrdersParam{ + Current: current, + PageSize: pageSize, + OrderCreateDateRange: []string{orderCreatedStart, orderCreatedEnd}, + }) + return orderResult, err +} + +func ChangeOrderStatus(vendorOrderID string, status int, remark string) (err error) { + orderStatus := &model.OrderStatus{ + VendorOrderID: vendorOrderID, + VendorID: model.VendorIDJDShop, + OrderType: model.OrderTypeOrder, + RefVendorOrderID: vendorOrderID, + RefVendorID: model.VendorIDJDShop, + VendorStatus: utils.Int2Str(status), + Status: status, + StatusTime: time.Now(), + Remark: remark, + } + jxutils.CallMsgHandlerAsync(func() { + err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus) + }, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJDShop)) + return err +} + +func (p *PurchaseHandler) OrderExport(ctx *jxcontext.Context, vendorOrderID, vendorWaybillID string, isAuto bool) (err error) { + companyID := jdshopapi.JdsDeliveryCompany3rd + //表示是门店手动发京东 + if !isAuto { + companyID = jdshopapi.JdsDeliveryCompanyJD + } + err = api.JdShopAPI.OrderShipment(utils.Str2Int64(vendorOrderID[:12]), companyID, vendorWaybillID) + return err +} + +func (p *PurchaseHandler) OrderTransfer(ctx *jxcontext.Context, vendorOrderID, vendorWaybillID string, isAuto bool) (err error) { + companyID := jdshopapi.JdsDeliveryCompany3rd + //表示是门店手动发京东 + if !isAuto { + companyID = jdshopapi.JdsDeliveryCompanyJD + } + err = api.JdShopAPI.UpdateWaybill(vendorOrderID[:12], companyID, vendorWaybillID) + return err +} + +func status2Jxstatus(status int) (statusJx int) { + if status == jdshopapi.JdsOrderStatusWaittingPay { + statusJx = model.OrderStatusWait4Pay + } else if status == jdshopapi.JdsOrderStatusWaittingPayDel { + statusJx = model.OrderStatusApplyCancel + } else if status == jdshopapi.JdsOrderStatusWaittingExport { + statusJx = model.OrderStatusAccepted + } else if status == jdshopapi.JdsOrderStatusPause { + statusJx = model.OrderStatusNew + } + return statusJx } diff --git a/business/partner/purchase/jdshop/store_sku.go b/business/partner/purchase/jdshop/store_sku.go index 6360dc257..c824cb56d 100644 --- a/business/partner/purchase/jdshop/store_sku.go +++ b/business/partner/purchase/jdshop/store_sku.go @@ -76,20 +76,15 @@ func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, v if img != "" { suffix := img[strings.LastIndex(img, "."):] if suffix != ".png" { - if resBinary, _, err := jxutils.DownloadFileByURL(img + model.SkuNameImgToPng); err == nil { - downloadURL, err2 := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())) - err = err2 - imageURL, err = uploadImg(downloadURL, name, "tou") + if resBinary, _, _ := jxutils.DownloadFileByURL(img + model.SkuNameImgToPng); err == nil { + downloadURL, _ := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())) + imageURL, _ = uploadImg(downloadURL, name, "tou") } } else { - imageURL, err = uploadImg(img, name, "tou") + imageURL, _ = uploadImg(img, name, "tou") } } - err2 := api.JdShopAPI.TransparentImageAdd(createSkuResult.WareID, imageURL) - if err2 != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") - return failedList, err - } + api.JdShopAPI.TransparentImageAdd(createSkuResult.WareID, imageURL) } var paramAttrs = make(map[string]*jdshopapi.CreateSkuParamSkus) var resultAttrs = make(map[string]int64) @@ -122,10 +117,11 @@ func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, v for _, v := range storeSkuList { name := filterSensitiveWord(v.Name) updateWareParam := &jdshopapi.UpdateWareParam{ - WareID: v.JdsWareID, - Title: name, - VenderID: jdshopapi.VenderID, - PromiseID: jdshopapi.JdsPromiseID, + WareID: v.JdsWareID, + Title: name, + VenderID: jdshopapi.VenderID, + PromiseID: jdshopapi.JdsPromiseID, + ShopCategorys: []int{utils.Str2Int(v.VendorCatID)}, } var desc string if v.DescImg != "" { @@ -157,7 +153,7 @@ func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, v }, &jdshopapi.CreateSkuParamFeatures{ Key: "tssp", //支持自提 - Value: "4", + Value: "", }, // &jdshopapi.CreateSkuParamFeatures{ // Key: "fdms", //分单? @@ -248,6 +244,9 @@ func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOr stock = 9999 } if storeID == model.JdShopMainStoreID { + if v.JdsStockSwitch == model.NO { + stock = 0 + } err = api.JdShopAPI.UpdateSkuStock(utils.Str2Int(v.VendorSkuID), stock) } else { storeSkus, err2 := dao.GetStoresSkusInfo(dao.GetDB(), []int{model.JdShopMainStoreID}, []int{v.SkuID}) @@ -309,6 +308,9 @@ func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID in if status == -1 { return fmt.Errorf("京东商城店内分类创建失败!") } + if err != nil { + return err + } time.Sleep(time.Second * 2) // flag := false // for { @@ -323,6 +325,9 @@ func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID in break } } + if storeCat.VendorCatID == "" { + return fmt.Errorf("京东商城店内分类创建可能失败了!storeID: %v", storeID) + } // if flag { // break // } @@ -480,6 +485,10 @@ func buildCreateWareParam(storeSku *dao.StoreSkuSyncInfo) (createSkuParamWare *j createSkuParamWare.PromiseID = jdshopapi.JdsPromiseID } + if storeSku.VendorVendorCatID == jdshopapi.JdsBeefCatID { + createSkuParamWare.MultiCategoryID = jdshopapi.JdsBeefLastCatID + } + //上传京东图片 //规则,有两张就传两张,没有就重复传一张 pic1, err := uploadImg(storeSku.Img, name, "1") @@ -527,6 +536,7 @@ func buildCreateWareParam(storeSku *dao.StoreSkuSyncInfo) (createSkuParamWare *j gcjkValueID int64 //国产,进口的id lbValueID int64 //类别的ID bcztValueID int64 //保存状态ID + rmsjValueID int64 //热卖时间ID attrsProp []*jdshopapi.CreateSkuParamAttrs ) attrs, err := api.JdShopAPI.FindAttrs(int(storeSku.VendorVendorCatID)) @@ -545,6 +555,8 @@ func buildCreateWareParam(storeSku *dao.StoreSkuSyncInfo) (createSkuParamWare *j attrIDs[v.Name] = v.ID } else if v.Name == "保存状态" { attrIDs[v.Name] = v.ID + } else if v.Name == "热卖时间" { + attrIDs[v.Name] = v.ID } } values, _, err := api.JdShopAPI.FindValuesByAttrId(attrIDs["贮存条件"]) @@ -581,6 +593,35 @@ func buildCreateWareParam(storeSku *dao.StoreSkuSyncInfo) (createSkuParamWare *j } attrsProp = append(attrsProp, attrbczt) } + if attrIDs["热卖时间"] != 0 { + values2, _, err2 := api.JdShopAPI.FindValuesByAttrId(attrIDs["热卖时间"]) + err = err2 + for _, v := range values2 { + if v.Name == "12月" { + rmsjValueID = v.ID + } + } + attrrmsj := &jdshopapi.CreateSkuParamAttrs{ + AttrID: utils.Int2Str(attrIDs["热卖时间"]), + AttrValues: []string{utils.Int64ToStr(rmsjValueID)}, + } + attrsProp = append(attrsProp, attrrmsj) + } + if storeSku.VendorVendorCatID == jdshopapi.JdsBeefCatID { + var exValueID int64 + values2, _, err2 := api.JdShopAPI.FindValuesByAttrId(150390) + err = err2 + for _, v := range values2 { + if v.Name == "其它" { + exValueID = v.ID + } + } + attrex := &jdshopapi.CreateSkuParamAttrs{ + AttrID: utils.Int2Str(150390), + AttrValues: []string{utils.Int64ToStr(exValueID)}, + } + attrsProp = append(attrsProp, attrex) + } attrZctj := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["贮存条件"]), AttrValues: []string{utils.Int64ToStr(zctjValueID)}, @@ -604,7 +645,7 @@ func buildCreateWareParam(storeSku *dao.StoreSkuSyncInfo) (createSkuParamWare *j }, &jdshopapi.CreateSkuParamFeatures{ Key: "tssp", //支持自提 - Value: "4", + Value: "", }, // &jdshopapi.CreateSkuParamFeatures{ // Key: "fdms", //分单? diff --git a/business/partner/purchase/jx/localjx/order.go b/business/partner/purchase/jx/localjx/order.go index 4613a34fd..7614f9449 100644 --- a/business/partner/purchase/jx/localjx/order.go +++ b/business/partner/purchase/jx/localjx/order.go @@ -49,7 +49,8 @@ const ( autoCancelOrderReason = "支付超时,系统自动取消!" cancelMatterOrderReason = "失败重发!" - splitMatterOrderMinWeight = 4500 //物料订单分包最少要4.5kg + splitMatterOrderMinWeight = 4500 //物料订单分包最少要4.5kg + jxwxfMatterEclpID = "EMG4418113943423" //京西五香粉物料编码 ) type JxSkuInfo struct { @@ -876,6 +877,7 @@ func orderSolutionForWuLiao(order *model.GoodsOrder) (err error) { goodsNos []string prices []string quantities []string + countSum int ) for _, v := range orderSkus { skus, err := dao.GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil) @@ -885,6 +887,28 @@ func orderSolutionForWuLiao(order *model.GoodsOrder) (err error) { goodsNos = append(goodsNos, skus[0].EclpID) prices = append(prices, "0") quantities = append(quantities, utils.Int2Str(v.Count)) + countSum += v.Count + } + //总订单不足3kg && 商品数量不足3个 && 五香粉有库存,要送五香粉,补足3个 + stockResult, err := api.JdEclpAPI.QueryStock(jxwxfMatterEclpID) + if err == nil && len(stockResult) > 0 && stockResult[0].UsableNum > 0 { + if order.Weight < 3000 && countSum < 3 { + //要判断他本身买没买五香粉EMG4418113943423 + var index = 9999 + for k, v := range goodsNos { + if v == jxwxfMatterEclpID { + index = k + } + } + //说明他买了五香粉 + if index != 9999 { + quantities[index] = utils.Int2Str(utils.Str2Int(quantities[index]) + 3 - countSum) + } else { + goodsNos = append(goodsNos, jxwxfMatterEclpID) + prices = append(prices, "0") + quantities = append(quantities, utils.Int2Str(3-countSum)) + } + } } result, err := api.JdEclpAPI.AddOrder(&jdeclpapi.AddOrderParam{ IsvUUID: order.VendorOrderID, diff --git a/business/partner/purchase/mtwm/order_comment.go b/business/partner/purchase/mtwm/order_comment.go index 5fbc55e7e..702682933 100644 --- a/business/partner/purchase/mtwm/order_comment.go +++ b/business/partner/purchase/mtwm/order_comment.go @@ -44,7 +44,7 @@ func formalizeTagList(mtwmTagList string) (outTagList string) { } func (c *PurchaseHandler) RefreshComment(fromTime, toTime time.Time) (err error) { - storeMapList, err2 := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDMTWM}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "") + storeMapList, err2 := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDMTWM}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") if err = err2; err != nil { return err } diff --git a/conf/app.conf b/conf/app.conf index ef6f86ce8..f9ab2bab5 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -395,7 +395,7 @@ enableElmStoreWrite = false enableMtwmStoreWrite = false enableWscStoreWrite = false enableYbStoreWrite = false -enableJdShopWrite = true +enableJdShopWrite = false jdOrgCode = "320406" jdLoginName = "jd_jxcs1223" diff --git a/controllers/cms_store.go b/controllers/cms_store.go index c2b7bc993..d24330b3c 100644 --- a/controllers/cms_store.go +++ b/controllers/cms_store.go @@ -3,6 +3,7 @@ package controllers import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxstore/cms" + "git.rosy.net.cn/jx-callback/business/jxstore/common" "git.rosy.net.cn/jx-callback/business/jxstore/misc" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/netprinter" @@ -546,7 +547,7 @@ func (c *StoreController) SyncStoresCourierInfo() { // @router /GetStoreListByLocation [get] func (c *StoreController) GetStoreListByLocation() { c.callGetStoreListByLocation(func(params *tStoreGetStoreListByLocationParams) (retVal interface{}, errCode string, err error) { - retVal, err = cms.GetStoreListByLocation(params.Ctx, params.Lng, params.Lat, params.NeedWalkDistance) + retVal, err = common.GetStoreListByLocation(params.Ctx, params.Lng, params.Lat, 20000, params.NeedWalkDistance, false) return retVal, "", err }) } diff --git a/controllers/cms_store_sku.go b/controllers/cms_store_sku.go index 04a5ee54c..0882031f8 100644 --- a/controllers/cms_store_sku.go +++ b/controllers/cms_store_sku.go @@ -4,6 +4,8 @@ import ( "math" "time" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/baseapi/platformapi/jdapi" "git.rosy.net.cn/jx-callback/business/jxstore/cms" @@ -214,6 +216,7 @@ func (c *StoreSkuController) SyncStoresSkus() { // @Param payload formData string true "json数据,StoreSkuBindInfo对象数组" // @Param isScale formData bool false "是否按门店结算比例缩放" // @Param causeFlag formData int false "操作类型" +// @Param isRefreshHigh formData bool false "是否只刷门店价高于给的价" // @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" // @Param isAsync formData bool false "是否异步操作" // @Success 200 {object} controllers.CallResult @@ -226,7 +229,28 @@ func (c *StoreSkuController) UpdateStoresSkus() { if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.Payload, &skuBindInfos); err != nil { return retVal, "", err } - retVal, err = cms.UpdateStoresSkus(params.Ctx, params.CauseFlag, storeIDs, skuBindInfos, params.IsScale, params.IsAsync, params.IsContinueWhenError) + retVal, err = cms.UpdateStoresSkus(params.Ctx, params.CauseFlag, storeIDs, skuBindInfos, params.IsScale, params.IsRefreshHigh, params.IsAsync, params.IsContinueWhenError) + return retVal, "", err + }) +} + +// @Title 批量修改多商家商品绑定(不同步) +// @Description 批量修改多商家商品绑定(不同步) +// @Param token header string true "认证token" +// @Param storeIDs formData string false "门店ID列表" +// @Param payload formData string true "json数据,StoreSkuBindInfo对象数组" +// @Param isRefreshHigh formData bool true "是否只刷门店价高于给的价" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /UpdateStoresSkusWithoutSync [put] +func (c *StoreSkuController) UpdateStoresSkusWithoutSync() { + c.callUpdateStoresSkusWithoutSync(func(params *tStoreSkuUpdateStoresSkusWithoutSyncParams) (retVal interface{}, errCode string, err error) { + var storeIDs []int + var skuBindInfos []*cms.StoreSkuBindInfo + if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.Payload, &skuBindInfos); err != nil { + return retVal, "", err + } + err = cms.UpdateStoresSkusWithoutSync(params.Ctx, storeIDs, skuBindInfos, params.IsRefreshHigh) return retVal, "", err }) } @@ -812,8 +836,8 @@ func (c *StoreSkuController) SyncMatterC4ToGy() { }) } -// @Title 得到商家商品修改价格请求信息 -// @Description 得到商家商品修改价格请求信息 +// @Title 查询商品审核信息 +// @Description 查询商品审核信息 // @Param token header string true "认证token" // @Param applyTimeStart query string false "申请开始时间" // @Param applyTimeEnd query string false "申请结束时间" @@ -823,7 +847,11 @@ func (c *StoreSkuController) SyncMatterC4ToGy() { // @Param remark query string false "不通过原因" // @Param storeIDs query string false "门店ID列表" // @Param nameIDs query string false "id列表对象,当前指skuname id" -// @Param status query int false "审核状态" +// @Param statuss query string false "审核状态" +// @Param types query string false "改价类型,1是普通改价,2是关注" +// @Param keyword query string false "关键字" +// @Param marketManPhone query string false "市场负责人电话" +// @Param cityName query string false "城市名" // @Param offset query int false "门店列表起始序号(以0开始,缺省为0)" // @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)" // @Success 200 {object} controllers.CallResult @@ -832,16 +860,33 @@ func (c *StoreSkuController) SyncMatterC4ToGy() { func (c *StoreSkuController) GetStoreSkuAudit() { c.callGetStoreSkuAudit(func(params *tStoreSkuGetStoreSkuAuditParams) (retVal interface{}, errCode string, err error) { var ( - timeList []time.Time - storeIDs, nameIDs []int + storeIDs, nameIDs, statuss, types []int ) - if timeList, err = jxutils.BatchStr2Time(params.ApplyTimeStart, params.ApplyTimeEnd, params.AuditTimeStart, params.AuditTimeEnd); err != nil { + if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.NameIDs, &nameIDs, params.Statuss, &statuss, params.Types, &types); err != nil { return retVal, "", err } - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.NameIDs, &nameIDs); err != nil { - return retVal, "", err - } - retVal, err = cms.GetStoreSkuAudit(params.Ctx, storeIDs, nameIDs, nil, params.Status, params.Name, params.Remark, timeList[0], timeList[1], timeList[2], timeList[3], params.PageSize, params.Offset) + retVal, err = cms.GetStoreSkuAudit(params.Ctx, storeIDs, nameIDs, nil, statuss, types, params.Name, params.Remark, params.Keyword, params.MarketManPhone, params.CityName, params.ApplyTimeStart, params.ApplyTimeEnd, params.AuditTimeStart, params.AuditTimeEnd, params.PageSize, params.Offset) + return retVal, "", err + }) +} + +// @Title 审核商品 +// @Description 审核商品 +// @Param token header string true "认证token" +// @Param payload formData string true "json数据,storeskuaudit对象" +// @Param status formData int false "审核标志,1通过,-1 不通过" +// @Param isAsync formData bool false "是否异步,缺省是同步" +// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /StoreSkuPriceAudit [post] +func (c *StoreSkuController) StoreSkuPriceAudit() { + c.callStoreSkuPriceAudit(func(params *tStoreSkuStoreSkuPriceAuditParams) (retVal interface{}, errCode string, err error) { + var storeSkuAudits []*model.StoreSkuAudit + if err = jxutils.Strings2Objs(params.Payload, &storeSkuAudits); err != nil { + return retVal, "", err + } + retVal, err = cms.StoreSkuPriceAudit(params.Ctx, storeSkuAudits, params.Status, params.IsAsync, params.IsContinueWhenError) return retVal, "", err }) } diff --git a/controllers/jx_order.go b/controllers/jx_order.go index 271794378..640f07f68 100644 --- a/controllers/jx_order.go +++ b/controllers/jx_order.go @@ -1059,3 +1059,32 @@ func (c *OrderController) GetOrderUserBuyFirst() { return retVal, "", err }) } + +// @Title 京东商城订单转移 +// @Description 京东商城订单转移 +// @Param token header string true "认证token" +// @Param storeID formData int true "转移的门店ID" +// @Param vendorOrderID formData string true "转移的订单号" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /TransferJdsOrder [post] +func (c *OrderController) TransferJdsOrder() { + c.callTransferJdsOrder(func(params *tOrderTransferJdsOrderParams) (retVal interface{}, errCode string, err error) { + retVal, err = orderman.TransferJdsOrder(params.Ctx, params.VendorOrderID, params.StoreID) + return retVal, "", err + }) +} + +// @Title 京东商城订单发送京东物流 +// @Description 京东商城订单发送京东物流 +// @Param token header string true "认证token" +// @Param vendorOrderID formData string true "订单号" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /SendJdwlForJdsOrder [post] +func (c *OrderController) SendJdwlForJdsOrder() { + c.callSendJdwlForJdsOrder(func(params *tOrderSendJdwlForJdsOrderParams) (retVal interface{}, errCode string, err error) { + err = orderman.SendJdwlForJdsOrder(params.Ctx, params.VendorOrderID) + return retVal, "", err + }) +} diff --git a/controllers/temp_op.go b/controllers/temp_op.go index 26d56039f..7ce1617d3 100644 --- a/controllers/temp_op.go +++ b/controllers/temp_op.go @@ -400,3 +400,17 @@ func (c *TempOpController) UploadJdsImage() { return retVal, "", err }) } + +// @Title 京西刷新调价包和门店价格 +// @Description 京西刷新调价包和门店价格 +// @Param token header string true "认证token" +// @Param storeID formData int false "门店ID" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /RefreshJXPriceChange [post] +func (c *TempOpController) RefreshJXPriceChange() { + c.callRefreshJXPriceChange(func(params *tTempopRefreshJXPriceChangeParams) (retVal interface{}, errCode string, err error) { + retVal, err = tempop.RefreshJXPriceChange(params.Ctx, params.StoreID) + return retVal, "", err + }) +} diff --git a/deploy/ansible.yml b/deploy/ansible.yml index 1eff26dd7..f9b033a69 100644 --- a/deploy/ansible.yml +++ b/deploy/ansible.yml @@ -1,7 +1,6 @@ --- - hosts: "{{ deploy_hosts }}" remote_user: ubuntu - become: True tasks: - name: copy shell copy: diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index a9c819671..23f402b42 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1242,6 +1242,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], + beego.ControllerComments{ + Method: "SendJdwlForJdsOrder", + Router: `/SendJdwlForJdsOrder`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], beego.ControllerComments{ Method: "SetOrderPrintStatus", @@ -1251,6 +1260,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], + beego.ControllerComments{ + Method: "TransferJdsOrder", + Router: `/TransferJdsOrder`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], beego.ControllerComments{ Method: "UpdateOrderWaybillTip", @@ -2097,6 +2115,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], + beego.ControllerComments{ + Method: "StoreSkuPriceAudit", + Router: `/StoreSkuPriceAudit`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], beego.ControllerComments{ Method: "SyncJdStoreProducts", @@ -2178,6 +2205,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], + beego.ControllerComments{ + Method: "UpdateStoresSkusWithoutSync", + Router: `/UpdateStoresSkusWithoutSync`, + AllowHTTPMethods: []string{"put"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"], beego.ControllerComments{ Method: "AddCreateFlagForJxStoreSku", @@ -2439,6 +2475,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], + beego.ControllerComments{ + Method: "RefreshJXPriceChange", + Router: `/RefreshJXPriceChange`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], beego.ControllerComments{ Method: "RefreshMtpsWaybillFee",