diff --git a/business/auth2/authprovider/douyin/tiktop_mini.go b/business/auth2/authprovider/douyin/tiktop_mini.go index ed588c7f8..0be0039ab 100644 --- a/business/auth2/authprovider/douyin/tiktop_mini.go +++ b/business/auth2/authprovider/douyin/tiktop_mini.go @@ -1,89 +1,91 @@ package douyin -// -//import ( -// "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" -// -// "git.rosy.net.cn/baseapi/platformapi/weixinapi" -// "git.rosy.net.cn/jx-callback/business/auth2" -// "git.rosy.net.cn/jx-callback/business/auth2/authprovider" -// "git.rosy.net.cn/jx-callback/business/model" -// "git.rosy.net.cn/jx-callback/globals" -// "git.rosy.net.cn/jx-callback/globals/api" -//) -// -//const ( -// AuthTypeTiktokMini = "tiktokmini" // 抖音小程序 -//) -// -//type TiktopMiniAuther struct { -// authprovider.DefAuther -//} -// -// -//var ( -// AutherObjMini *TiktopMiniAuther -//) -// -//func init() { -// AutherObjMini = new(TiktopMiniAuther) -// auth2.RegisterAuther(AuthTypeTiktokMini, AutherObjMini) -//} -// -//func (a *TiktopMiniAuther) VerifySecret(dummy, code string) (authBindEx *auth2.AuthBindEx, err error) { -// globals.SugarLogger.Debugf("toktok mini VerifySecret jsCode:%s", code) -// -// sessionInfo, err := api.TiktokApi.GetTiktokToken(code) -// if err == nil { -// if authBindEx, err = a.UnionFindAuthBind(AuthTypeTiktokMini, api.TiktokApi.GetAppID(), []string{AuthTypeTiktokMini}, sessionInfo.Data.OpenId, sessionInfo.Data.UnionId, sessionInfo); err == nil { -// authBindEx.UserData = sessionInfo.Data -// } -// } -// return authBindEx, err -//} -// -//// 特殊接口 -//func (a *TiktopMiniAuther) DecryptData(authInfo *auth2.AuthInfo, jsCode, encryptedData, iv string) (decryptedDataBase64 string, err error) { -// globals.SugarLogger.Debugf("weixin mini DecryptData jsCode:%s, encryptedData:%s, iv:%s", jsCode, encryptedData, iv) -// var sessionKey string -// appID, jsCode := weixin.SplitJsCode(jsCode) -// if jsCode != "" { -// sessionInfo, err := getWxApp(appID).SNSCode2Session(jsCode) -// if err == nil { -// // if authBindEx, err := a.UnionFindAuthBind(AuthTypeMini, getWxApp(appID).GetAppID(), []string{AuthTypeMini}, sessionInfo.OpenID, "", nil); err == nil { -// // if authBindEx.UserID != authInfo.GetID() { -// // return "", fmt.Errorf("jsCode与token不匹配") -// // } -// // } else { -// // return "", err -// // } -// sessionKey = sessionInfo.SessionKey -// } else { -// return "", err -// } -// } else { -// if authInfo.AuthBindInfo.Type != AuthTypeTiktokMini { -// // return "", ErrAuthTypeShouldBeMini -// } -// sessionKey = authInfo.AuthBindInfo.UserData.(string) -// } -// decryptedData, err := weixinapi.SNSDecodeMiniProgramData(encryptedData, sessionKey, iv) -// if err != nil { -// return "", err -// } -// return string(decryptedData), nil -//} -// -//func (a *TiktopMiniAuther) GetUserType() (userType int8) { -// return model.UserTypeStoreBoss -//} -// -//func getWxApp(appID string) (miniApi *weixinapi.API) { -// miniApi = api.WeixinMiniAPI -// if len(appID) > 0 && appID == api.WeixinMiniAppID2 { -// miniApi = api.WeixinMiniAPI2 -// } -// if len(appID) > 0 && appID == api.WeixinMiniAppIDsc { -// miniApi = api.WeixinMiniAPIsc -// } -// return miniApi -//} + +import ( + "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" + + "git.rosy.net.cn/baseapi/platformapi/weixinapi" + "git.rosy.net.cn/jx-callback/business/auth2" + "git.rosy.net.cn/jx-callback/business/auth2/authprovider" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" +) + +const ( + AuthTypeTiktokMini = "tiktokmini" // 抖音小程序 +) + +type TiktopMiniAuther struct { + authprovider.DefAuther +} + +var ( + AutherObjMini *TiktopMiniAuther +) + +func init() { + AutherObjMini = new(TiktopMiniAuther) + auth2.RegisterAuther(AuthTypeTiktokMini, AutherObjMini) +} + +func (a *TiktopMiniAuther) VerifySecret(dummy, code string) (authBindEx *auth2.AuthBindEx, err error) { + globals.SugarLogger.Debugf("toktok mini VerifySecret jsCode:%s", code) + + sessionInfo, err := api.TiktokApi.GetTiktokToken2(code) + if err == nil { + sessionKey := sessionInfo.Data.SessionKey + sessionInfo.Data.SessionKey = "" + if authBindEx, err = a.UnionFindAuthBind(AuthTypeTiktokMini, api.TiktokApi.GetAppID(), []string{AuthTypeTiktokMini}, sessionInfo.Data.OpenId, sessionInfo.Data.Unionid, sessionInfo); err == nil { + authBindEx.UserData = sessionKey + } + } + + return authBindEx, err +} + +// 特殊接口 +func (a *TiktopMiniAuther) DecryptData(authInfo *auth2.AuthInfo, jsCode, encryptedData, iv string) (decryptedDataBase64 string, err error) { + globals.SugarLogger.Debugf("weixin mini DecryptData jsCode:%s, encryptedData:%s, iv:%s", jsCode, encryptedData, iv) + var sessionKey string + appID, jsCode := weixin.SplitJsCode(jsCode) + if jsCode != "" { + sessionInfo, err := getWxApp(appID).SNSCode2Session(jsCode) + if err == nil { + // if authBindEx, err := a.UnionFindAuthBind(AuthTypeMini, getWxApp(appID).GetAppID(), []string{AuthTypeMini}, sessionInfo.OpenID, "", nil); err == nil { + // if authBindEx.UserID != authInfo.GetID() { + // return "", fmt.Errorf("jsCode与token不匹配") + // } + // } else { + // return "", err + // } + sessionKey = sessionInfo.SessionKey + } else { + return "", err + } + } else { + if authInfo.AuthBindInfo.Type != AuthTypeTiktokMini { + // return "", ErrAuthTypeShouldBeMini + } + sessionKey = authInfo.AuthBindInfo.UserData.(string) + } + decryptedData, err := weixinapi.SNSDecodeMiniProgramData(encryptedData, sessionKey, iv) + if err != nil { + return "", err + } + return string(decryptedData), nil +} + +func (a *TiktopMiniAuther) GetUserType() (userType int8) { + return model.UserTypeStoreBoss +} + +func getWxApp(appID string) (miniApi *weixinapi.API) { + miniApi = api.WeixinMiniAPI + if len(appID) > 0 && appID == api.WeixinMiniAppID2 { + miniApi = api.WeixinMiniAPI2 + } + if len(appID) > 0 && appID == api.WeixinMiniAppIDsc { + miniApi = api.WeixinMiniAPIsc + } + return miniApi +} diff --git a/business/jxcallback/scheduler/basesch/basesch_ext.go b/business/jxcallback/scheduler/basesch/basesch_ext.go index 0a9a74f7c..5f0f48d15 100644 --- a/business/jxcallback/scheduler/basesch/basesch_ext.go +++ b/business/jxcallback/scheduler/basesch/basesch_ext.go @@ -35,12 +35,13 @@ func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order * courierVendorIDMap := jxutils.IntList2Map(courierVendorIDs) excludeCourierVendorIDMap := jxutils.IntList2Map(excludeCourierVendorIDs) errList := errlist.New() + for _, storeCourier := range storeCourierList { if (courierVendorIDs == nil || courierVendorIDMap[storeCourier.VendorID] == 1) && (excludeCourierVendorIDs == nil || excludeCourierVendorIDMap[storeCourier.VendorID] == 0) { if handler := partner.GetDeliveryPlatformFromVendorID(storeCourier.VendorID); handler != nil && handler.Use4CreateWaybill { courierVendorID := storeCourier.VendorID - // 创建订单 + // 创建运单 bill, err2 := c.CreateWaybill(courierVendorID, order, maxDeliveryFee) if err = err2; err == nil { globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d bill:%v", order.VendorOrderID, userName, courierVendorID, bill) diff --git a/business/jxcallback/scheduler/defsch/defsch.go b/business/jxcallback/scheduler/defsch/defsch.go index b9fb9bd87..022aa1d37 100644 --- a/business/jxcallback/scheduler/defsch/defsch.go +++ b/business/jxcallback/scheduler/defsch/defsch.go @@ -591,7 +591,7 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo globals.SugarLogger.Infof("OnWaybillStatusChanged orderID:%s purchase platform waybill arrvied later, may cause problem", order.VendorOrderID) } s.updateOrderByBill(order, bill, false) - // 转自送 + // 取消三方平台 s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) //若接单时间不在门店的营业时间范围内要取消运单 s.cancelWaybillNotInStoreOpentime(savedOrderInfo, bill) @@ -623,6 +623,7 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) s.SelfDeliverDelivered(order, "自送或三方") } + // 判断订单来源与运单是否为同一来源 if model.IsWaybillPlatformOwn(bill) { if bill.Status == model.WaybillStatusDelivering && order.Status < model.OrderStatusEndBegin { // 强制将订单状态置为配送中? @@ -630,10 +631,14 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order) } } else { + // 判断订单是否为自送 if model.IsOrderDeliveryByStore(savedOrderInfo.order) { // 转自送失败,取消三方配送 - if err := s.SelfDeliverDelivering(savedOrderInfo.order, bill.CourierMobile); err != nil { - s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrSwitch2SelfFailed) + if err := s.SelfDeliverDelivering(order, bill.CourierMobile); err != nil { + if err := s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrSwitch2SelfFailed); err != nil { + // 如果转自送失败,且取消三方失败,循环多次转自送 + s.swtich2SelfDeliverWithRetry(savedOrderInfo, bill, switch2SelfDeliverRetryCount, switch2SelfDeliverRetryGap) + } partner.CurOrderManager.OnOrderMsg(order, "自送出设置失败", err.Error()) } s.notify3rdPartyWaybill(order, bill, isBillAlreadyCandidate) @@ -980,7 +985,8 @@ func (s *DefScheduler) cancelOtherWaybills(savedOrderInfo *WatchOrderInfo, bill2 if err == nil { err = err2 } - partner.CurOrderManager.OnOrderMsg(savedOrderInfo.order, "取消三方运单失败", err2.Error()) + partner.CurOrderManager.OnOrderMsg(savedOrderInfo.order, ""+ + "", err2.Error()) } } diff --git a/business/jxstore/cms/order_excel.go b/business/jxstore/cms/order_excel.go new file mode 100644 index 000000000..0d5330353 --- /dev/null +++ b/business/jxstore/cms/order_excel.go @@ -0,0 +1,292 @@ +package cms +// +//import ( +// "encoding/json" +// "errors" +// "fmt" +// "git.rosy.net.cn/baseapi/utils" +// "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" +// "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" +// "git.rosy.net.cn/jx-callback/business/model" +// "git.rosy.net.cn/jx-callback/business/model/dao" +// "git.rosy.net.cn/jx-callback/business/partner/purchase/jx/localjx" +// "github.com/360EntSecGroup-Skylar/excelize" +// "io" +// "mime/multipart" +// "strings" +//) +// +//// 根据excel新增待拣货订单 +//func CreateOrderByExcel(ctx *jxcontext.Context, files []*multipart.FileHeader) (hint string, err error) { +// if len(files) == 0 { +// return "", errors.New("没有文件上传!") +// } +// fileHeader := files[0] +// file, err := fileHeader.Open() +// hint, err = RefreshJxPriceByExcelBin(ctx, file, true, true) +// file.Close() +// return hint, err +//} +// +//type CreateOrderByExcelStore struct { +// BuyerComment int // 备注 +// StoreID int // 门店id +// Skus int // 商品列表 +// ExpectedDeliveredTimestamp int // 预期送达时间 +// TotalPrice int // 总价格 +// FreightPrice int // 运费 +// OrderPrice int // 订单价格 +// ActualPayPrice int // 顾客实际支付 +// OrderID int // 订单id +// StoreName int // 门店名称 +// Weight int // 重量 +// FromStoreID int // 物料ID +// EarningType int // 结算方式(1为报价,2为扣点),0无 +// OrderType int // 订单类型 +// IsBuyNowPrice int // 守价的值只有0和1 +// IsPriceDefend int +// OrderID2 int +// UserID int // 用户id +// AddressID int // 收货地址id +// CreateType int // "创建类型, 0:预创建, 1:创建" +// IsDeliverySelf int // 自提 +//} +// +//// 赋值excel表字段排序 +//func SortExcelTable() *CreateOrderByExcelStore { +// return &CreateOrderByExcelStore{ +// StoreID: 1, +// StoreName: 2, +// UserID: 3, +// AddressID: 4, +// Skus: 5, +// Weight: 6, +// TotalPrice: 7, +// FreightPrice: 8, +// OrderPrice: 9, +// ActualPayPrice: 10, +// ExpectedDeliveredTimestamp: 11, +// OrderType: 12, +// FromStoreID: 13, +// EarningType: 14, +// BuyerComment: 15, +// +// CreateType: 16, +// IsDeliverySelf: 17, +// IsPriceDefend: 18, +// IsBuyNowPrice: 19, +// OrderID: 20, +// OrderID2: 21, +// } +//} +// +//// 订单结构体 +//type ExcelOrderStruct struct { +// BuyerComment string `json:"buyerComment"` // 备注 +// StoreID int `json:"storeID"` +// Skus []*JxSkuInfo `json:"skus"` +// ExpectedDeliveredTimestamp int64 `json:"expectedDeliveredTimestamp"` // 预期送达时间 +// TotalPrice int64 `json:"totalPrice"` // 单位为分 订单总价 +// FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费 +// OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格 +// ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付 +// OrderID int64 `json:"orderID"` +// StoreName string `json:"storeName"` +// Weight int `json:"weight"` +// FromStoreID int `json:"fromStoreID"` // +// EarningType int `json:"earningType"` +// OrderType int `json:"orderType"` +// IsBuyNowPrice int `json:"isBuyNowPrice"` +// IsPriceDefend int `json:"isPriceDefend"` +// OrderID2 string `json:"-"` // 订单id2 +// UserID string `json:"userID"` // 用户id +// AddressId int64 `json:"address_id"` // 地址id +//} +// +//// 商品列表 +//type JxSkuInfo struct { +// SkuID int `json:"skuID"` +// Count int `json:"count"` +// Price int64 `json:"price,omitempty"` // 原价 +// SalePrice int64 `json:"salePrice,omitempty"` // 售卖价 +// Name string `json:"name"` +// Weight int `json:"weight"` +// GroupSign bool `json:"groupSign"` +// DefendPrice int64 `json:"defendPrice"` //守价 +//} +// +//// 解析excel到订单结构体当中 +//func GetCellIntoOrder(rowNum int, row []string, sheetParam *CreateOrderByExcelStore, order *ExcelOrderStruct, nameMap map[string]string) (errMsg string) { +// address := make(map[string]int64, 0) +// for k, cell := range row { +// switch k { +// case sheetParam.StoreID: +// order.StoreID = utils.Str2Int(cell) +// case sheetParam.StoreName: +// order.StoreName = cell +// case sheetParam.UserID: +// order.UserID = cell +// case sheetParam.AddressID: +// order.AddressId = utils.Str2Int64(cell) +// case sheetParam.Skus: +// shop := make([]*JxSkuInfo, 0, 0) +// if err := json.Unmarshal([]byte(cell), shop); err != nil { +// return fmt.Sprintf("解析excel文档用户商品列表错,检查数据格式是否正确") +// } +// order.Skus = shop +// case sheetParam.Weight: +// order.Weight = utils.Str2Int(cell) +// case sheetParam.TotalPrice: +// order.TotalPrice = utils.Str2Int64(cell) +// case sheetParam.FreightPrice: +// order.FreightPrice = utils.Str2Int64(cell) +// case sheetParam.OrderPrice: +// order.OrderPrice = utils.Str2Int64(cell) +// case sheetParam.ActualPayPrice: +// order.ActualPayPrice = utils.Str2Int64(cell) +// case : +// +// +// +// } +// +// if k == sheetParam.SkuNameIDCol { +// cellReplace := strings.ReplaceAll(cell, ",", ",") +// if cellReplace != "" { +// if cellReplace[len(cellReplace)-1:len(cellReplace)] == "," { +// cellReplace = cellReplace[0 : len(cellReplace)-1] +// } +// nameIDs := strings.Split(cellReplace, ",") +// for _, v := range nameIDs { +// if nameMap[v] != "" { +// return fmt.Sprintf(" Excel中含有重复的nameID![%v]列,[%v]行,nameID [%v]\n", k+1, rowNum+1, v) +// } else { +// nameMap[v] = v +// } +// } +// } +// storeSkuNamePrice.NameIDGroup = cellReplace +// } +// if k == sheetParam.SkuPriceCol { +// if IsChineseChar(cell) { +// return fmt.Sprintf("Excel格式排版发生了变化!在[%v]列,[%v]行附近可能增加或减少了一列", k+1, rowNum+1) +// } +// storeSkuNamePrice.Price = int(utils.Float64TwoInt64(utils.Str2Float64(cell) * 100)) +// } +// if k == sheetParam.SkuUnitCol { +// storeSkuNamePrice.Unit = cell +// } +// } +// return errMsg +//} +// +//func AnalysisExcelOrder(ctx *jxcontext.Context, reader io.Reader, isAsync, isContinueWhenError bool) { +// excelSort := SortExcelTable() +// taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { +// switch step { +// case 0: +// xlsx, err := excelize.OpenReader(reader) +// if err != nil { +// return "", err +// } +// rows, _ := xlsx.GetRows(xlsx.GetSheetName(1)) +// for rowNum, row := range rows { +// if rowNum < model.YES { // 第一行跳过 +// continue +// } +// storeSkuNamePrice := &localjx.JxOrderInfo{} +// errMsg += GetCellIntoStruct(rowNum, row, excelSort, storeSkuNamePrice, nameMap) +// storeSkuNamePriceList = append(storeSkuNamePriceList, storeSkuNamePrice) +// } +// if errMsg != "" { +// return "", errors.New(errMsg) +// } else { +// isErr = true +// } +// case 1: +// db := dao.GetDB() +// storeSkuNamePriceListOrg, _ := dao.GetStoreSkuNamePrice(db) +// CreateOrUpdateStoreSkuNamePriceByExcel(db, ctx, storeSkuNamePriceList, storeSkuNamePriceListOrg) +// storeSkuNamePriceListNew, _ := dao.GetStoreSkuNamePrice(db) +// storeSkuNamePriceMapNew := StoreSkuNamePriceList2Map(ctx, storeSkuNamePriceListNew) +// for _, v := range storeSkuNamePriceList { +// if storeSkuNamePriceMapNew[v.OutSkuID] != nil { +// storeSkuNamePriceListUpdate = append(storeSkuNamePriceListUpdate, storeSkuNamePriceMapNew[v.OutSkuID]) +// } +// } +// taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { +// storeSkuNamePrice := batchItemList[0].(*model.StoreSkuNamePrice) +// var skuBindInfos []*StoreSkuBindInfo +// nameIDGroup := strings.Split(storeSkuNamePrice.NameIDGroup, ",") +// for _, v := range nameIDGroup { +// if v != "" { +// nameID := int(utils.Str2Int64(v)) +// for _, vv := range storeIDs { +// skuList, err2 := dao.GetStoreSkusByNameIDs(db, []int{vv}, nameID) +// err = err2 +// if len(skuList) > 0 { +// unitPrice := 0 +// if skuList[0].Unit == model.UnitNames[0] { +// if storeSkuNamePrice.Unit == "KG" { +// unitPrice = storeSkuNamePrice.Price / 2 +// } else { +// unitPrice = storeSkuNamePrice.Price +// } +// } else { +// unitPrice = storeSkuNamePrice.Price +// } +// storeSkuBindInfo := &StoreSkuBindInfo{ +// NameID: nameID, +// UnitPrice: unitPrice, +// } +// skuBindInfos = append(skuBindInfos, storeSkuBindInfo) +// outSuccess := DataSuccess{ +// NameID: nameID, +// Name: skuList[0].Name, +// Unit: storeSkuNamePrice.Unit, +// OrgPrice: utils.Str2Float64(utils.Int64ToStr(skuList[0].UnitPrice)) / 100, +// NowPrice: utils.Str2Float64(utils.Int64ToStr(int64(unitPrice))) / 100, +// MixPrice: utils.Str2Float64(utils.Int64ToStr(int64(unitPrice)-skuList[0].UnitPrice)) / 100, +// } +// dataLock.AppendDataSuccess(outSuccess) +// } else { +// //京西xx门店没有关注该商品 +// outFailed := DataFailed{ +// NameID: nameID, +// Name: storeSkuNamePrice.Name, +// Comment: fmt.Sprintf("京西[%v]门店没有关注该商品,商品nameID[%v],Excel上商品名[%v]", vv, nameID, storeSkuNamePrice.Name), +// } +// dataLock.AppendDataFailed(outFailed) +// } +// } +// } else { +// //nameID为空,还未填写nameID +// outFailed := DataFailed{ +// NameID: 0, +// Name: storeSkuNamePrice.Name, +// Comment: fmt.Sprintf("商品nameID为空!,还未填写商品nameID,Excel上商品名[%v]", storeSkuNamePrice.Name), +// } +// dataLock.AppendDataFailed(outFailed) +// } +// } +// retVal = skuBindInfos +// return retVal, err +// } +// taskParallel := tasksch.NewParallelTask("刷新京西价", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeSkuNamePriceListUpdate) +// tasksch.HandleTask(taskParallel, task, true).Run() +// skuBindInfosInter, err = taskParallel.GetResult(0) +// case 2: +// //更新京西价 +// for _, v := range skuBindInfosInter { +// skuBindInfoList = append(skuBindInfoList, v.(*StoreSkuBindInfo)) +// } +// if isErr { +// UpdateStoresSkus(ctx, 0, storeIDs, skuBindInfoList, false, false, isAsync, isContinueWhenError) +// } +// case 3: +// //写Excel +// WriteToExcelJx(task, dataLock.dataSuccessList, dataLock.dataFailedList) +// } +// return result, err +// } +//} diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index 8dc0169a9..641617979 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -740,7 +740,7 @@ func GetVendorStore(ctx *jxcontext.Context, vendorID int, vendorOrgCode, vendorS return nil, err } if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { - result, err2 := handler.ReadStore(ctx, vendorOrgCode, vendorStoreID) + result, err2 := handler.ReadStore(ctx, vendorOrgCode, vendorStoreID, "") if err = err2; err == nil { retVal = &StoreExt{ Store: result.Store, @@ -1361,7 +1361,7 @@ func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, vendorID int, vend } if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { if vendorOrgCode != globals.Mtwm2Code { - store, err2 := handler.ReadStore(ctx, vendorOrgCode, storeMap.VendorStoreID) + store, err2 := handler.ReadStore(ctx, vendorOrgCode, storeMap.VendorStoreID, storeMap.VendorStoreName) if err = err2; err == nil || storeMap.IsSync == 0 { if store != nil { storeMap.DeliveryType = store.DeliveryType @@ -1398,7 +1398,7 @@ func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, vendorID int, vend storeMap.SyncStatus = model.SyncFlagNewMask //京东商城要去建店 } else { if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { - store, err2 := handler.ReadStore(ctx, vendorOrgCode, storeMap.VendorStoreID) + store, err2 := handler.ReadStore(ctx, vendorOrgCode, storeMap.VendorStoreID,storeMap.VendorStoreName) if err = err2; err == nil || storeMap.IsSync == 0 { if store != nil { storeMap.Status = store.Status @@ -1567,7 +1567,7 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor if vendorID != model.VendorIDJX && vendorID != model.VendorIDYB { if vendorStoreID := utils.Interface2String(valid["vendorStoreID"]); vendorStoreID != "" { - vendorStoreInfo, err2 := storeHandler.ReadStore(ctx, storeMap.VendorOrgCode, vendorStoreID) + vendorStoreInfo, err2 := storeHandler.ReadStore(ctx, storeMap.VendorOrgCode, vendorStoreID,storeMap.VendorStoreName) if err = err2; err == nil { valid["deliveryType"] = vendorStoreInfo.DeliveryType } @@ -2256,7 +2256,7 @@ func GetStoresVendorSnapshot(ctx *jxcontext.Context, parentTask tasksch.ITask, v storeMap := batchItemList[0].(*model.StoreMap) if model.IsVendorRemote(storeMap.VendorID) { if handler := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID); handler != nil { - store, err2 := handler.ReadStore(ctx, storeMap.VendorOrgCode, storeMap.VendorStoreID) + store, err2 := handler.ReadStore(ctx, storeMap.VendorOrgCode, storeMap.VendorStoreID,storeMap.VendorStoreName) if err = err2; err == nil { retVal = []interface{}{&model.VendorStoreSnapshot{ StoreID: storeMap.StoreID, @@ -2910,13 +2910,13 @@ func GetVendorStoreInfo(ctx *jxcontext.Context, vendorIDList []int, isAsync, isC storeID := batchItemList[0].(string) if partner.IsMultiStore(vendorID) { multiHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) - storeDetail, err = multiHandler.ReadStore(ctx, "", storeID) + storeDetail, err = multiHandler.ReadStore(ctx, "", storeID,"") if err != nil { return retVal, err } } else { singleHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreHandler) - storeDetail, err = singleHandler.ReadStore(ctx, "", storeID) + storeDetail, err = singleHandler.ReadStore(ctx, "", storeID,"") if err != nil { return retVal, err } @@ -5279,7 +5279,7 @@ func RefreshStoreIsOnline(ctx *jxcontext.Context) (err error) { func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { storeMap := batchItemList[0].(*model.StoreMap) if handler := CurVendorSync.GetStoreHandler(storeMap.VendorID); handler != nil { - if store, err := handler.ReadStore(ctx, storeMap.VendorOrgCode, storeMap.VendorStoreID); err == nil && store != nil { + if store, err := handler.ReadStore(ctx, storeMap.VendorOrgCode, storeMap.VendorStoreID,""); err == nil && store != nil { if store.Status != model.StoreStatusDisabled { storeMap.IsOnline = 1 } else { diff --git a/business/jxstore/cms/store_sku.go b/business/jxstore/cms/store_sku.go index 615bc7e38..40939d1c2 100644 --- a/business/jxstore/cms/store_sku.go +++ b/business/jxstore/cms/store_sku.go @@ -3948,6 +3948,7 @@ func RefershStoreSkusMidPrice(ctx *jxcontext.Context, storeIDs []int, isCountry return err } +// 根据excel刷新门店商品信息 func RefreshJxPriceByExcel(ctx *jxcontext.Context, storeIDs []int, files []*multipart.FileHeader, isAsync, isContinueWhenError bool) (hint string, err error) { if len(files) == 0 { return "", errors.New("没有文件上传!") @@ -4268,13 +4269,13 @@ func GetVendorStoreSkuPrice(ctx *jxcontext.Context, vendorIDs []int, skuID int, } if partner.IsMultiStore(vendorID) { multiHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) - storeDetail, err = multiHandler.ReadStore(ctx, v, vendorStoreID) + storeDetail, err = multiHandler.ReadStore(ctx, v, vendorStoreID, "") if len(skuList) > 0 { inStoreSku.VendorSkuID = skuList[0].VendorSkuID } } else { singleHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreHandler) - storeDetail, err = singleHandler.ReadStore(ctx, v, vendorStoreID) + storeDetail, err = singleHandler.ReadStore(ctx, v, vendorStoreID, "") inStoreSku.SkuID = skuID } inStoreSkuList = append(inStoreSkuList, inStoreSku) diff --git a/business/jxstore/report/report.go b/business/jxstore/report/report.go index 58c2a4f73..b848745d4 100644 --- a/business/jxstore/report/report.go +++ b/business/jxstore/report/report.go @@ -481,7 +481,7 @@ func buildStoreManageState(ctx *jxcontext.Context, db *dao.DaoDB, storeMap *mode } dao.WrapAddIDCULEntity(storeManage, ctx.GetUserName()) handler := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID) - store, err := handler.ReadStore(ctx, storeDetail.VendorOrgCode, storeDetail.VendorStoreID) + store, err := handler.ReadStore(ctx, storeDetail.VendorOrgCode, storeDetail.VendorStoreID, storeDetail.VendorStoreName) if err != nil || store == nil { return nil } diff --git a/business/model/api_config.go b/business/model/api_config.go index eac9c0ad4..eadcc99d5 100644 --- a/business/model/api_config.go +++ b/business/model/api_config.go @@ -19,7 +19,8 @@ const ( VendorIDJDShop = 5 //京东商城 VendorIDWSC = 11 // 微盟微商城 VendorIDPurchaseEnd = 11 - VendorIDJX = 9 // 这是一个假的京西VendorID + VendorIDJX = 9 // 这是一个假的京西VendorID + VendorGoMei = 12 // 国美 VendorIDWXPay = 51 // 微信支付 @@ -87,6 +88,7 @@ var ( VendorIDQiNiuCloud: "Qiniu", VendorIDJDWL: "Jdwl", + VendorGoMei: "GoMei", } VendorTypeName = map[int]string{ @@ -127,6 +129,7 @@ var ( VendorIDAutonavi: "高德导航", VendorIDQiNiuCloud: "七牛云", VendorIDShowAPI: "万维易源", + VendorGoMei: "国美", } VendorInfoMap = map[int]*VendorInfo{ diff --git a/business/model/const.go b/business/model/const.go index a54fae944..4642887ed 100644 --- a/business/model/const.go +++ b/business/model/const.go @@ -425,9 +425,11 @@ const ( ) const ( - YES = 1 //通用 - NO = 0 - DISABLED = -1 + YES = 1 //通用 + NO = 0 + DISABLED = -1 + B2BTag = "B2B" + B2BNumberId = 10 ) func IsPurchaseVendorExist(vendorID int) bool { diff --git a/business/model/dao/store.go b/business/model/dao/store.go index e8d7401e8..d5c2fa7a7 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -1486,3 +1486,29 @@ func InsertBrandCategories(db *DaoDB, userName string, brandID int) (err error) _, err = ExecuteSQL(db, sql, sqlParams) return err } +// +//// 根据国美门店id获取门店名称 +//func GetStoreByVendorId(db *DaoDB, vendorOrderID string, vendorCode int) (storeMaps []*model.StoreCourierMap, err error) { +// if vendorOrderID == "" || vendorCode == 0 { +// return nil, err +// } +// sql := ` +// SELECT t1.* +// FROM store_courier_map t1 +// LEFT JOIN store t2 ON t1.store_id = t2.id AND t1.deleted_at = ? +// WHERE t1.deleted_at = ? AND t2. +// ` +// sqlParams := []interface{}{ +// utils.DefaultTimeValue, +// } +// if len(vendorOrderID) > 0 { +// sql += " AND t1.vendor_store_id = ? " +// sqlParams = append(sqlParams, vendorOrderID) +// } +// +// sql += " AND t1.audit_status IN (" + GenQuestionMarks(len(auditStatuss)) + ")" +// sqlParams = append(sqlParams, auditStatuss) +// if err = GetRows(db, &courierStoreList, sql, sqlParams...); err == nil { +// return courierStoreList, nil +// } +//} diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go index bfe0095e5..6d2f20ed0 100644 --- a/business/model/dao/store_sku.go +++ b/business/model/dao/store_sku.go @@ -73,8 +73,8 @@ type StoreSkuSyncInfo struct { Stock int // 平台相关的store sku信息 - StoreSkuStatus int - SkuSyncStatus int8 + StoreSkuStatus int // 库存状态 + SkuSyncStatus int8 // 锁定状态 VendorSkuID string `orm:"column(vendor_sku_id)"` JdsWareID int64 `orm:"column(jds_ware_id)" json:"jdsWareID"` BindDeletedAt time.Time `orm:"type(datetime)" json:"bindDeletedAt"` @@ -128,7 +128,7 @@ type StoreSkuSyncInfo struct { VendorCatID string `orm:"column(vendor_cat_id)"` SkuVendorMapCatID string `orm:"column(sku_vendor_map_cat_id)"` - VendorPrice int64 + VendorPrice int64 // 平台价格 LockTime *time.Time MergedStatus int @@ -476,7 +476,7 @@ func GetStoreCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level in result := make([]*SkuStoreCatInfo, 0, 0) for _, v := range cats { if v.BrandId == 1 { // 京西菜市才做此判断 - if !strings.HasPrefix(v.ParentCatName, "B2B") { + if !strings.Contains(v.ParentCatName, model.B2BTag) { result = append(result, v) } } diff --git a/business/model/order.go b/business/model/order.go index e106b6f77..d7a784c81 100644 --- a/business/model/order.go +++ b/business/model/order.go @@ -548,7 +548,7 @@ func IsOrderHaveWaybill(order *GoodsOrder) bool { // 订单是否有自己平台的有效运单 func IsOrderHaveOwnWaybill(order *GoodsOrder) bool { - return order.VendorID == order.WaybillVendorID && order.VendorWaybillID != "" + return order.VendorID == order.WaybillVendorID && order.VendorWaybillID != "" } // 订单的初始配送方式是否是门店自配送 diff --git a/business/model/sku.go b/business/model/sku.go index 09242cb71..294f43fca 100644 --- a/business/model/sku.go +++ b/business/model/sku.go @@ -127,11 +127,12 @@ type SkuCategory struct { Type int8 `json:"type"` // 类别类型,即是普通类别还是特殊用于做活动的类别 Seq int `json:"seq"` - JdCategoryID int64 `orm:"column(jd_category_id)" json:"jdCategoryID"` // 这个是指对应的京东商品类别 - EbaiCategoryID int64 `orm:"column(ebai_category_id)" json:"ebaiCategoryID"` // 这个是指对应的饿百商品类别 - MtwmCategoryID int64 `orm:"column(mtwm_category_id)" json:"mtwmCategoryID"` // 这个是指对应的美团外卖商品类别 - YbCategoryID int64 `orm:"column(yb_category_id)" json:"ybCategoryID"` // 这个是指对应的银豹商品类别 - JdsCategoryID int64 `orm:"column(jds_category_id)" json:"jdsCategoryID"` // 这个是指对应的京东商城类别 + JdCategoryID int64 `orm:"column(jd_category_id)" json:"jdCategoryID"` // 这个是指对应的京东商品类别 + EbaiCategoryID int64 `orm:"column(ebai_category_id)" json:"ebaiCategoryID"` // 这个是指对应的饿百商品类别 + MtwmCategoryID int64 `orm:"column(mtwm_category_id)" json:"mtwmCategoryID"` // 这个是指对应的美团外卖商品类别 + YbCategoryID int64 `orm:"column(yb_category_id)" json:"ybCategoryID"` // 这个是指对应的银豹商品类别 + JdsCategoryID int64 `orm:"column(jds_category_id)" json:"jdsCategoryID"` // 这个是指对应的京东商城类别 + GoMeiCategoryID int64 `orm:"column(go_mei_category_id)" json:"goMeiCategoryID"` // 这个是指对应的国美商城类别 // ElmCategoryID int64 `orm:"column(elm_category_id)" json:"elmCategoryID"` // 这个是指对应的饿了么商品类别 // WscCategoryID int64 `orm:"column(wsc_category_id)" json:"wscCategoryID"` // 这个是指对应的美团外卖商品类别 diff --git a/business/model/store.go b/business/model/store.go index 5f3d08a0d..c0b8e0ac8 100644 --- a/business/model/store.go +++ b/business/model/store.go @@ -35,7 +35,8 @@ const ( BrandOpenSMS = 8 //短信 BrandOpenVoice = 16 //语音 - BrandBalanceLimit = 1000 + BrandBalanceLimit = 1000 + GoMeiMaxCountNumber = 50 // 国美最大数据返回条数 ) const ( @@ -86,11 +87,13 @@ const ( ) const ( - ExdStoreName = "饿鲜达" - MatterStoreID = 666666 - JdShopMainVendorStoreID = "9999999" + ExdStoreName = "饿鲜达" + MatterStoreID = 666666 + JdShopMainVendorStoreID = "9999999" // 三方平台总商户id + GoMeiShopMainVendorStoreID = "GMJ-MS-XOMRF-1J1" // 三方平台总商户id // JdShopMainVendorStoreID2 = "9999999" - JdShopMainStoreID = 100000 + JdShopMainStoreID = 100000 // 本地商户门店地 + GoMeiShopMainStoreID = 200000 // 本店商户门店id // JdShopMainStoreID2 = 100000 VendorStoreTel = "18011597879" diff --git a/business/model/store_sku.go b/business/model/store_sku.go index 36a56fe55..3a3053347 100644 --- a/business/model/store_sku.go +++ b/business/model/store_sku.go @@ -99,11 +99,12 @@ type StoreSkuBind struct { Status int // ElmID int64 `orm:"column(elm_id);index"` - MtwmID int64 `orm:"column(mtwm_id);index"` - EbaiID int64 `orm:"column(ebai_id);index"` - YbID int64 `orm:"column(yb_id);index"` - JdsID int64 `orm:"column(jds_id);index"` - JdsWareID int64 `orm:"column(jds_ware_id)"` + MtwmID int64 `orm:"column(mtwm_id);index"` + EbaiID int64 `orm:"column(ebai_id);index"` + YbID int64 `orm:"column(yb_id);index"` + JdsID int64 `orm:"column(jds_id);index"` + JdsWareID int64 `orm:"column(jds_ware_id)"` + GmID string `orm:"column(gm_id)"` // WscID int64 `orm:"column(wsc_id);index"` // 表示微盟skuId // WscID2 int64 `orm:"column(wsc_id2);index"` // 表示微盟goodsId @@ -113,6 +114,7 @@ type StoreSkuBind struct { EbaiSyncStatus int8 `orm:"default(2)"` YbSyncStatus int8 `orm:"default(2)"` JdsSyncStatus int8 `orm:"default(2)"` //京东商城 + GmSyncStatus int8 `orm:"default(2)"` //京东商城 // WscSyncStatus int8 `orm:"default(2)"` JdPrice int `json:"jdPrice"` @@ -121,6 +123,7 @@ type StoreSkuBind struct { JxPrice int `json:"jxPrice"` YbPrice int `json:"ybPrice"` JdsPrice int `json:"jdsPrice"` + GmPrice int `json:"gmPrice"` JdLockTime *time.Time `orm:"null" json:"jdLockTime"` JdsLockTime *time.Time `orm:"null" json:"jdsLockTime"` @@ -128,6 +131,7 @@ type StoreSkuBind struct { EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime"` JxLockTime *time.Time `orm:"null" json:"jxLockTime"` YbLockTime *time.Time `orm:"null" json:"ybLockTime"` + GmLockTime *time.Time `orm:"null" json:"gmLockTime"` AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` diff --git a/business/partner/delivery/dada/waybill.go b/business/partner/delivery/dada/waybill.go index e82171a4e..1f6790d7e 100644 --- a/business/partner/delivery/dada/waybill.go +++ b/business/partner/delivery/dada/waybill.go @@ -94,6 +94,7 @@ func (c *DeliveryHandler) onWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaap default: order.Status = model.WaybillStatusUnknown } + delivery.GetOrderRiderInfoToPlatform(order.VendorOrderID)// 骑手位置更新 return dadaapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), utils.Int2Str(order.Status)) } diff --git a/business/partner/delivery/delivery.go b/business/partner/delivery/delivery.go index efd789ba5..9fa7a9989 100644 --- a/business/partner/delivery/delivery.go +++ b/business/partner/delivery/delivery.go @@ -2,7 +2,6 @@ package delivery import ( "fmt" - "git.rosy.net.cn/baseapi/platformapi/mtpsapi" "math" "time" @@ -149,73 +148,3 @@ func OnWaybillCreated(waybill *model.Waybill) { model.VendorChineseNames[waybill.WaybillVendorID], waybill.VendorWaybillID, jxutils.IntPrice2StandardCurrencyString(deliveryFee), jxutils.IntPrice2StandardCurrencyString(alarmFee)) } } - -// 订单骑手信息推送:将获取到的三方配送订单,且订单状态为配送中的订单,将配送人员的信息返回给订单方 -// 该方法为定时任务,没五分钟推送一次订单消息,订单状态发生变化时 -//配送状态code,如下提供配送状态枚举值, -//以及各配送状态对应在C端(用户端)和B端(商家PC端)后台展示的配送状态信息。 -//未同步配送状态时(C端:商家已接单;B端:待发配送) -//0-配送单发往配送(C端:商家已接单;B端:待骑手接单) -//1-已创建配送包裹(C端:商家已接单;B端:待骑手接单) -//5-已分配骑手(C端:商家已接单;B端:已分配骑手) -//10-骑手已接单(C端:骑手正在赶往商家;B端:待骑手取货) -//15-骑手已到店(C端:骑手到店取货中;B端:骑手已到店) -//20-骑手已取货(C端:商品配送中/骑手正在送货;B端:骑手已取货) -//40-骑手已送达(C端:商品已送达;B端:骑手已送达) -//100-配送单已取消(C端:商家已接单;B端:配送已取消) -//注:若同步配送状态为“配送单已取消”,接口仍支持继续同步配送状态。 说明:商家如未上传此信息,则平台默认值为20(现已要求必传)。 -func GetOrderRiderInfoToPlatform(orderId string) { - params := make(map[string]interface{}, 0) - params["brandID"] = 0 - params["statuss"] = 20 - params["isDateFinish"] = false - params["isIncludeFake"] = true - params["mustInvoice"] = false - params["adjustCount"] = 0 - params["waybillVendorIDs"] = `[101,102,103]` - if orderId != "" { // 订单id会忽略其他参数 - params["keyword"] = orderId - } - //params["offset"] = 0 - //params["pageSize"] = 10000 - // 查询三天内一万条数据 - orders, _, err := dao.GetOrders(dao.GetDB(), nil, false, true, time.Now().Add(-24*3*time.Hour).Format("2006-01-02"), time.Now().Format("2006-01-02"), false, nil, false, "", params, 0, 10000) - if err != nil { - globals.SugarLogger.Errorf("GetOrder err :%v", err) - return - } - - for _, v := range orders { - var riderInfo *mtpsapi.RiderInfo - if handlerInfo := partner.GetDeliveryPlatformFromVendorID(v.WaybillVendorID); handlerInfo != nil { - riderInfo, err = handlerInfo.Handler.GetRiderInfo(v.VendorOrderID, utils.Str2Int64(v.VendorWaybillId2Waybill), v.VendorWaybillID) - if err != nil { - globals.SugarLogger.Errorf("Get Order waybill rider info err :%v", err) - continue - } - } - - // 目前只推送美团骑手信息 - switch v.VendorID { - case model.VendorIDMTWM: // 美团发单 - paramsMap := utils.Struct2Map(riderInfo, "", true) - if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.VendorID); handler != nil { - if err := handler.GetOrderRider(v.VendorOrgCode, v.VendorOrderID, paramsMap); err != nil { - globals.SugarLogger.Errorf("Error pushing meituan rider information :%v", err) - } - } - case model.VendorIDELM: // 饿了么 - case model.VendorIDEBAI: // 饿百发单 - - case model.VendorIDJD: // 京东发单 - case model.VendorIDGD: // 美团发单 - case model.VendorIDYB: // 银豹发单 - case model.VendorIDJDShop: // 京东商城 - case model.VendorIDWSC: // 微盟微商城 - default: - globals.SugarLogger.Errorf("Order source error, non system order") - return - } - } - return -} diff --git a/business/partner/delivery/fn/waybill.go b/business/partner/delivery/fn/waybill.go index 98157f34e..44548e4cc 100644 --- a/business/partner/delivery/fn/waybill.go +++ b/business/partner/delivery/fn/waybill.go @@ -249,6 +249,7 @@ func OnWaybillMsg(msg *fnpsapi.OrderStatusNottify) (resp *fnpsapi.CallbackRespon globals.SugarLogger.Debugf("FNPS partner.CurOrderManager.OnWaybillStatusChanged fail :[%s]", err) return fnpsapi.Err2CallbackResponse(err, "") } + delivery.GetOrderRiderInfoToPlatform(order.VendorOrderID) // 骑手位置更新 return fnpsapi.Err2CallbackResponse(nil, "") } @@ -284,7 +285,7 @@ func GetDesiredFee(vendorOrderID string) (desiredFee int64) { } // 获取骑手信息 -func (c *DeliveryHandler) GetRiderInfo(orderId string, deliveryId int64, mtPeisongId string) (rider *mtpsapi.RiderInfo, err error) { +func (c *DeliveryHandler) GetRiderInfo(orderId string, deliveryId int64, mtPeisongId string) (rider *mtpsapi.RiderInfo, err error) { // 获取订单状态 order, err := api.FnAPI.QueryOrder(orderId) if err != nil { diff --git a/business/partner/delivery/mtps/waybill.go b/business/partner/delivery/mtps/waybill.go index fc1efcdc2..b3126a828 100644 --- a/business/partner/delivery/mtps/waybill.go +++ b/business/partner/delivery/mtps/waybill.go @@ -119,6 +119,7 @@ func (c *DeliveryHandler) onWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal *m c.pushToGy(msg) return mtpsapi.SuccessResponse } + delivery.GetOrderRiderInfoToPlatform(order.VendorOrderID)// 骑手位置更新 // 加入调度器 return mtpsapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), order.VendorStatus) } diff --git a/business/partner/delivery/rider.go b/business/partner/delivery/rider.go new file mode 100644 index 000000000..19c2c7c8d --- /dev/null +++ b/business/partner/delivery/rider.go @@ -0,0 +1,82 @@ +package delivery + +import ( + "git.rosy.net.cn/baseapi/platformapi/mtpsapi" + "git.rosy.net.cn/baseapi/utils" + "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" + "time" +) + +// 订单骑手信息推送:将获取到的三方配送订单,且订单状态为配送中的订单,将配送人员的信息返回给订单方 +// 该方法为定时任务,没五分钟推送一次订单消息,订单状态发生变化时 +//配送状态code,如下提供配送状态枚举值, +//以及各配送状态对应在C端(用户端)和B端(商家PC端)后台展示的配送状态信息。 +//未同步配送状态时(C端:商家已接单;B端:待发配送) +//0-配送单发往配送(C端:商家已接单;B端:待骑手接单) +//1-已创建配送包裹(C端:商家已接单;B端:待骑手接单) +//5-已分配骑手(C端:商家已接单;B端:已分配骑手) +//10-骑手已接单(C端:骑手正在赶往商家;B端:待骑手取货) +//15-骑手已到店(C端:骑手到店取货中;B端:骑手已到店) +//20-骑手已取货(C端:商品配送中/骑手正在送货;B端:骑手已取货) +//40-骑手已送达(C端:商品已送达;B端:骑手已送达) +//100-配送单已取消(C端:商家已接单;B端:配送已取消) +//注:若同步配送状态为“配送单已取消”,接口仍支持继续同步配送状态。 说明:商家如未上传此信息,则平台默认值为20(现已要求必传)。 +func GetOrderRiderInfoToPlatform(orderId string) { + globals.SugarLogger.Debug("==========GetOrderRiderInfoToPlatform", time.Now()) + params := make(map[string]interface{}, 0) + params["brandID"] = 0 + params["statuss"] = []int{20} + params["isDateFinish"] = false + params["isIncludeFake"] = true + params["mustInvoice"] = false + params["adjustCount"] = 0 + params["waybillVendorIDs"] = `[101,102,103]` + if orderId != "" { // 订单id会忽略其他参数 + params["keyword"] = orderId + } + + // 每五分钟查询当前订单信息,待配送状态订单1 + orders, _, err := dao.GetOrders(dao.GetDB(), nil, false, true, time.Now().Add(-24*time.Hour).Format("2006-01-02"), time.Now().Format("2006-01-02"), false, nil, false, "", params, 0, 10000) + if err != nil { + globals.SugarLogger.Errorf("GetOrder err :%v", err) + return + } + + for _, v := range orders { + globals.SugarLogger.Debug("==========orderId,vendorId,waybillId", v.VendorOrderID, v.VendorID, v.WaybillVendorID) + var riderInfo *mtpsapi.RiderInfo + if handlerInfo := partner.GetDeliveryPlatformFromVendorID(v.WaybillVendorID); handlerInfo != nil { + riderInfo, err = handlerInfo.Handler.GetRiderInfo(v.VendorOrderID, utils.Str2Int64(v.VendorWaybillId2Waybill), v.VendorWaybillID) + if err != nil { + globals.SugarLogger.Errorf("Get Order waybill rider info err :%v", err) + continue + } + } + + // 目前只推送美团骑手信息 + switch v.VendorID { + case model.VendorIDMTWM: // 美团发单 + paramsMap := utils.Struct2Map(riderInfo, "", true) + if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.VendorID); handler != nil { + if err := handler.GetOrderRider(v.VendorOrgCode, v.VendorOrderID, paramsMap); err != nil { + globals.SugarLogger.Errorf("Error pushing meituan rider information :%v", err) + } + } + case model.VendorIDELM: // 饿了么 + case model.VendorIDEBAI: // 饿百发单 + + case model.VendorIDJD: // 京东发单 + case model.VendorIDGD: // 美团发单 + case model.VendorIDYB: // 银豹发单 + case model.VendorIDJDShop: // 京东商城 + case model.VendorIDWSC: // 微盟微商城 + default: + globals.SugarLogger.Errorf("Order source error, non system order") + return + } + } + return +} diff --git a/business/partner/partner.go b/business/partner/partner.go index 0d8c828a3..63d4b1418 100644 --- a/business/partner/partner.go +++ b/business/partner/partner.go @@ -147,7 +147,7 @@ type IPurchasePlatformHandler interface { //////// // Store - ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (store *dao.StoreDetail, err error) + ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorStoreName string) (store *dao.StoreDetail, err error) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) CreateStore2(db *dao.DaoDB, storeID int, userName string, params map[string]interface{}, storeDetail *dao.StoreDetail) (vendorStoreID string, err error) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) diff --git a/business/partner/purchase/ebai/store.go b/business/partner/purchase/ebai/store.go index c4f6db65e..b926a954e 100644 --- a/business/partner/purchase/ebai/store.go +++ b/business/partner/purchase/ebai/store.go @@ -171,7 +171,7 @@ func getCoordintate(data interface{}) float64 { return utils.MustInterface2Float64(data) } -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (*dao.StoreDetail, error) { +func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorStoreName string) (*dao.StoreDetail, error) { baiduShopID := utils.Str2Int64WithDefault(vendorStoreID, 0) if baiduShopID == 0 { return nil, fmt.Errorf("饿百门店ID:%s非法,应该是一个整数", vendorStoreID) @@ -264,7 +264,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin if store.SyncStatus&model.SyncFlagDeletedMask == 0 { shopID = store.ID } - store2, err2 := p.ReadStore(jxcontext.AdminCtx, store.VendorOrgCode, store.VendorStoreID) + store2, err2 := p.ReadStore(jxcontext.AdminCtx, store.VendorOrgCode, store.VendorStoreID,"") // globals.SugarLogger.Debugf("ebai UpdateStore2 store2:%s, err2:%v", utils.Format4Output(store2, true), err2) if err = err2; err == nil { if store2.ID == store.ID { @@ -284,16 +284,16 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin if err = p.UpdateStoreStatus(jxcontext.AdminCtx, store.VendorOrgCode, storeID, store.VendorStoreID, mergeStatus); err != nil { return err } - store := fmt.Sprintf("门店id:%d,门店名称:%s,第三方门店状态:%d,本地修改前门店状态%d,本地门店修改后状态:%d,第三方平台Id(ebai):%d", storeID,store.Name, store2.Status, store.Status, mergeStatus,store.VendorOrgCode) - event.AddOperateEvent(jxcontext.AdminCtx,jxcontext.AdminCtx.GetTrackInfo(), store, "", "", 10, "UpdateStore") + store := fmt.Sprintf("门店id:%d,门店名称:%s,第三方门店状态:%d,本地修改前门店状态%d,本地门店修改后状态:%d,第三方平台Id(ebai):%d", storeID, store.Name, store2.Status, store.Status, mergeStatus, store.VendorOrgCode) + event.AddOperateEvent(jxcontext.AdminCtx, jxcontext.AdminCtx.GetTrackInfo(), store, "", "", 10, "UpdateStore") } params := genStoreMapFromStore(store) if err = api.EbaiAPI.ShopUpdate(params); err == nil { if store.PromoteInfo != "" { err = api.EbaiAPI.ShopAnnouncementSet("", utils.Str2Int64(store.VendorStoreID), store.PromoteInfo) } - store := fmt.Sprintf("门店id:%d,门店名称:%s,第三方门店状态:%d,本地修改前门店状态%d,本地门店修改后状态:%d,第三方平台Id(ebai):%d", storeID,store.Name, store2.Status, store.Status, 100,store.VendorOrgCode) - event.AddOperateEvent(jxcontext.AdminCtx,jxcontext.AdminCtx.GetTrackInfo(), store, "", "", 10, "UpdateStore") + store := fmt.Sprintf("门店id:%d,门店名称:%s,第三方门店状态:%d,本地修改前门店状态%d,本地门店修改后状态:%d,第三方平台Id(ebai):%d", storeID, store.Name, store2.Status, store.Status, 100, store.VendorOrgCode) + event.AddOperateEvent(jxcontext.AdminCtx, jxcontext.AdminCtx.GetTrackInfo(), store, "", "", 10, "UpdateStore") } } diff --git a/business/partner/purchase/gomei/act.go b/business/partner/purchase/gomei/act.go new file mode 100644 index 000000000..8c9cf5861 --- /dev/null +++ b/business/partner/purchase/gomei/act.go @@ -0,0 +1,15 @@ +package gomei + +import ( + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" + "git.rosy.net.cn/jx-callback/business/model" +) + +func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { + return err +} + +func (c *PurchaseHandler) GetActAmple(ctx *jxcontext.Context, vendorStoreID, vendorOrgCode string) (ample int, err error) { + return ample, err +} diff --git a/business/partner/purchase/gomei/callback.go b/business/partner/purchase/gomei/callback.go new file mode 100644 index 000000000..37b4695d7 --- /dev/null +++ b/business/partner/purchase/gomei/callback.go @@ -0,0 +1,502 @@ +package gomei +// +//import ( +// "bytes" +// "encoding/base64" +// "encoding/hex" +// "encoding/json" +// "fmt" +// "math" +// "strings" +// "time" +// +// "git.rosy.net.cn/jx-callback/business/authz/autils" +// "git.rosy.net.cn/jx-callback/business/partner/delivery/dada" +// +// "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" +// beego "github.com/astaxie/beego/server/web" +// +// "git.rosy.net.cn/baseapi/platformapi/dadaapi" +// "git.rosy.net.cn/baseapi/platformapi/dingdingapi" +// "git.rosy.net.cn/baseapi/platformapi/jcqapi" +// "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/ddmsg" +// "git.rosy.net.cn/jx-callback/business/model" +// "git.rosy.net.cn/jx-callback/business/model/dao" +// "git.rosy.net.cn/jx-callback/business/partner" +// "git.rosy.net.cn/jx-callback/globals" +// "git.rosy.net.cn/jx-callback/globals/api" +// "git.rosy.net.cn/jx-callback/globals/api2" +//) +// +////TODO 以下是京东商城云顶推送消息使用的代码,现在都是以网页爬取的形式拿订单了,下面的都不用了 +////TODO 位置在 orderman/order.go 的 SaveJdsOrders +//func OnCallbackMsg(msg *jdshopapi.CallBackResult) (err error) { +// msgType := msg.MsgType +// switch msgType { +// case jcqapi.TopicOrderPay: +// utils.CallFuncAsync(func() { +// SaveJdsOrders(msg) +// }) +// case jcqapi.TopicOrderCancel: +// utils.CallFuncAsync(func() { +// order := getRealOrderID(msg.OrderID) +// if order != nil { +// if order.Status != model.OrderStatusCanceled { +// CurPurchaseHandler.CancelOrder(jxcontext.AdminCtx, order, "系统取消") +// } +// } +// }) +// case jcqapi.TopicOrderOut: +// utils.CallFuncAsync(func() { +// globals.SugarLogger.Debugf("jdsOrderOut", utils.Format4Output(msg, false)) +// orders := getAllRealOrderID(msg.OrderID) +// if len(orders) > 0 { +// for _, order := range orders { +// if order.ActualPayPrice == 0 { +// if jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)) == 0 { +// order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderTotalPrice) + utils.Str2Float64(msg.FreightPrice) - utils.Str2Float64(msg.SellerDiscount)) +// } else { +// order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)) +// } +// order.TotalShopMoney = utils.Float64TwoInt64(float64(order.ActualPayPrice) * jdshopapi.JdsPayPercentage) +// partner.CurOrderManager.UpdateOrderFields(order, []string{"ActualPayPrice", "TotalShopMoney"}) +// } +// } +// } +// }) +// default: +// return fmt.Errorf("暂不支持的topic类型!topic: %v", msgType) +// } +// return err +//} +// +//func SaveJdsOrders(msg *jdshopapi.CallBackResult) (err error) { +// if msg.OrderState == "TRADE_CANCELED" { +// return nil +// } //清洗脏数据 部分数据按照 +// order, err := result2Orders(msg) +// if err != nil && order == nil { +// return err +// } +// globals.SugarLogger.Debugf("SaveJdsOrders : %v", utils.Format4Output(order, false)) +// partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) +// noticeMsg := fmt.Sprintf("京东商城新订单,订单号:[%v] ,将要发到的门店id:[%v] , 门店名:[%v]", order.VendorOrderID, order.StoreID, order.StoreName) +// if order.OrderType == model.OrderTypeAddressErr { +// noticeMsg += " 此订单地址有问题,需要矫正坐标!" +// } +// var role = autils.NewRole("jdshop", 0) +// userIDList, err := api2.RoleMan.GetRoleUserList(role) +// for _, v := range userIDList { +// ddmsg.SendUserMessage(dingdingapi.MsgTyeText, v, "京东商城来新订单了!", noticeMsg) +// } +// // ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "京东商城来新订单了!", noticeMsg) +// return err +//} +// +//func result2Orders(msg *jdshopapi.CallBackResult) (order *model.GoodsOrder, err error) { +// var ( +// db = dao.GetDB() +// ) +// //有可能是库里已经有这个订单了 +// orderE, err := partner.CurOrderManager.LoadOrder(msg.OrderID+"00000001", model.VendorIDJDShop) +// if orderE != nil { +// return order, fmt.Errorf("已经存在此订单!") +// } +// order = &model.GoodsOrder{ +// VendorOrderID2: msg.OrderID, +// VendorOrderID: msg.OrderID + "00000001", +// VendorID: model.VendorIDJDShop, +// BaseFreightMoney: jxutils.StandardPrice2Int(utils.Str2Float64(msg.FreightPrice)), +// VendorStatus: msg.OrderState, +// VendorUserID: msg.Pin, +// BuyerComment: msg.OrderRemark, +// PickDeadline: utils.DefaultTimeValue, +// OriginalData: string(utils.MustMarshal(msg)), +// OrderCreatedAt: utils.Str2Time(msg.OrderStartTime), +// ConsigneeAddress: Decrypt(msg.ConsigneeInfo.FullAddress, msg.VendorOrgCode), +// ConsigneeName: Decrypt(msg.ConsigneeInfo.Fullname, msg.VendorOrgCode), +// // ConsigneeMobile: Decrypt(msg.ConsigneeInfo.Mobile), +// // ConsigneeMobile2: Decrypt(msg.ConsigneeInfo.Telephone), +// ActualPayPrice: jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)), +// Status: model.OrderStatusNew, +// TotalShopMoney: utils.Float64TwoInt64(math.Round(float64(jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment))) * jdshopapi.JdsPayPercentage)), +// DeliveryType: model.OrderDeliveryTypeStoreSelf, +// StatusTime: utils.Str2Time(msg.OrderStartTime), +// OrderSeq: 0, +// VendorOrgCode: msg.VendorOrgCode, +// } +// if utils.Str2Float64(msg.BalanceUsed) != 0 { +// order.ActualPayPrice += jxutils.StandardPrice2Int(utils.Str2Float64(msg.BalanceUsed)) +// order.TotalShopMoney += utils.Float64TwoInt64(math.Round(float64(jxutils.StandardPrice2Int(utils.Str2Float64(msg.BalanceUsed))) * jdshopapi.JdsPayPercentage)) +// } +// if len(msg.ConsigneeInfo.Mobile) != 11 { +// order.ConsigneeMobile = Decrypt(msg.ConsigneeInfo.Mobile, msg.VendorOrgCode) +// } else { +// order.ConsigneeMobile = msg.ConsigneeInfo.Mobile +// } +// if len(msg.ConsigneeInfo.Telephone) != 11 { +// order.ConsigneeMobile2 = Decrypt(msg.ConsigneeInfo.Telephone, msg.VendorOrgCode) +// } else { +// order.ConsigneeMobile2 = msg.ConsigneeInfo.Telephone +// } +// if order.TotalShopMoney < 100 { +// order.TotalShopMoney = 100 +// } +// if order.ConsigneeAddress != "" { +// var cityCode int +// place, err := dao.GetPlaceByJdsCode(db, utils.Str2Int(msg.ConsigneeInfo.CityID)) +// if place == nil { +// cityCode = 510100 +// } else { +// if place.Level == 3 { +// cityCode = place.ParentCode +// } else if place.Level == 2 { +// cityCode = place.Code +// } +// } +// lng, lat, err2 := api.AutonaviAPI.GetCoordinateFromAddressByPage(order.ConsigneeAddress, cityCode) +// if err = err2; err != nil { +// globals.SugarLogger.Infof("高德page err: %v", err) +// } +// lng2, lat2, _ := api.AutonaviAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "") +// distance := jxutils.EarthDistance(lng, lat, lng2, lat2) +// if distance > 1 { +// order.OrderType = model.OrderTypeAddressErr +// } +// if err == nil && lng != 0 && lat != 0 { +// order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng) +// order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat) +// } else { +// order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng2) +// order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat2) +// } +// order.CoordinateType = model.CoordinateTypeMars +// } +// // storeList, err := common.GetStoreListByLocation(jxcontext.AdminCtx, jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), 3000, false, true, 0) +// // if err != nil { +// // globals.SugarLogger.Debugf("jds GetStoreListByLocation error: %v", err.Error()) +// // return order, err +// // } +// // if len(storeList) > 0 { +// // for _, store := range storeList { +// for _, v := range msg.ItemInfoList { +// sku := &model.OrderSku{ +// VendorID: model.VendorIDJDShop, +// VendorOrderID: order.VendorOrderID, +// Count: utils.Str2Int(v.ItemTotal), +// VendorSkuID: v.SkuID, +// SkuName: v.SkuName, +// VendorPrice: jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)), +// SalePrice: jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)), +// // SkuID: utils.Str2Int(v.OuterSkuID), +// } +// if v.OuterSkuID != "" { +// sku.SkuID = utils.Str2Int(v.OuterSkuID) +// } +// _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.SkuName) +// sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit) +// order.Skus = append(order.Skus, sku) +// } +// if order.ActualPayPrice > 100000 { +// buildOrderTo102919(order) +// globals.SugarLogger.Debugf("resultjdsOrders return 8") +// } +// var store *dao.StoreDetail +// if msg.OrderExt != "" { +// orderExt := &jdshopapi.OrderExt{} +// if err = json.Unmarshal([]byte(msg.OrderExt), &orderExt); err == nil { +// order.VendorStoreID = orderExt.SiteID +// if store, err = dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, model.VendorIDJDShop, ""); store != nil && err == nil { +// order.StoreID = store.ID +// order.JxStoreID = store.ID +// order.StoreName = store.Name +// globals.SugarLogger.Debugf("jds GetStoreListByLocation, orderID: %v storeID :%v", order.VendorOrderID, order.StoreID) +// //结算类型 +// if store.PayPercentage < 50 { +// order.EarningType = model.EarningTypePoints +// } else { +// order.EarningType = model.EarningTypeQuote +// } +// var ( +// shopPriceSum int +// // saleNormalSum int +// ) +// for _, sku := range order.Skus { +// storeSkuList, _ := dao.GetStoresSkusInfo(db, []int{order.StoreID}, []int{sku.SkuID}) +// if len(storeSkuList) > 0 { +// // if storeSkuList[0].Status == model.StoreSkuBindStatusNormal { +// // saleNormalSum += 1 +// // } +// shopPriceSum += storeSkuList[0].Price * sku.Count +// sku.ShopPrice = int64(storeSkuList[0].Price) +// } else { +// shopPriceSum += int(sku.SalePrice) * 70 / 100 +// } +// } +// //可售数小于一半就不行 +// // if math.Mod(float64(len(order.Skus)), float64(2)) == 0 { +// // if saleNormalSum < len(order.Skus)/2 { +// // buildOrderTo102919(order) +// // globals.SugarLogger.Debugf("resultjdsOrders return 1") +// // } else { +// if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) { +// buildOrderTo102919(order) +// globals.SugarLogger.Debugf("resultjdsOrders return 2") +// } +// // } +// // } else { +// // if saleNormalSum <= len(order.Skus)/2 { +// // buildOrderTo102919(order) +// // globals.SugarLogger.Debugf("resultjdsOrders return 3") +// // } else { +// // if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) { +// // buildOrderTo102919(order) +// // globals.SugarLogger.Debugf("resultjdsOrders return 4") +// // } +// // } +// // } +// } else { +// buildOrderTo102919(order) +// globals.SugarLogger.Debugf("resultjdsOrders return 5") +// } +// } else { +// buildOrderTo102919(order) +// globals.SugarLogger.Debugf("resultjdsOrders return 6") +// } +// } else { +// buildOrderTo102919(order) +// globals.SugarLogger.Debugf("resultjdsOrders return 7") +// } +// // 如果是暂停,表示是预订单g +// if msg.OrderState == jdshopapi.OrderStatusPause || msg.OrderState == jdshopapi.OrderStatusPopPause { +// order.BusinessType = model.BusinessTypeDingshida +// if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil { +// if time2 == "" { +// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) +// } else { +// order.ExpectedDeliveredTime = utils.Str2Time(time2) +// } +// } else { +// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) +// err = nil +// } +// order.PickDeadline = order.ExpectedDeliveredTime.Add(-time.Hour) +// } else if msg.OrderState == jdshopapi.OrderStatusWait || msg.OrderState == "WAIT_GOODS_RECEIVE_CONFIRM" || msg.OrderState == "FINISHED_L" { +// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) +// order.BusinessType = model.BusinessTypeImmediate +// } else if msg.OrderState == "UN_KNOWN" { +// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) +// order.BusinessType = model.BusinessTypeImmediate +// } else { +// globals.SugarLogger.Debugf("暂不支持的京东商城订单类型!type: %v", msg.OrderState) +// return nil, err +// } +// +// if msg.IDSopShipmenttype == jdshopapi.IdSopShipmenttypeTC { +// if msg.VendorOrgCode == "1" { +// if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil { +// order.BusinessType = model.BusinessTypeDingshida +// if time2 == "" { +// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) +// } else { +// order.ExpectedDeliveredTime = utils.Str2Time(time2) +// } +// } +// } else { +// order.BusinessType = model.BusinessTypeImmediate +// if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil { +// if time2 == "" { +// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) +// } else { +// order.ExpectedDeliveredTime = utils.Str2Time(time2) +// } +// } else { +// order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) +// } +// } +// } +// setJdsOrderSeq(order) +// if order.OrderType == model.OrderTypeAddressErr { +// buildOrderTo102919(order) +// globals.SugarLogger.Debugf("resultjdsOrders return 9") +// } +// // billParams, _ := GetDaDaBillParams(db, order) +// // if result, err := api.DadaAPI.QueryDeliverFee(billParams); err == nil { +// // if result.Fee > 10 { +// // buildOrderTo102919(order) +// // globals.SugarLogger.Debugf("resultjdsOrders return 10") +// // } +// // } +// if store != nil { +// distance := jxutils.EarthDistance(jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat)) +// if distance > 4 { +// buildOrderTo102919(order) +// globals.SugarLogger.Debugf("resultjdsOrders return 4") +// } +// } +// if order.ExpectedDeliveredTime.Sub(order.OrderCreatedAt) <= time.Hour+time.Minute { +// order.BusinessType = model.BusinessTypeImmediate +// } +// // buildOrderTo102919(order) +// return order, err +//} +// +//func buildOrderTo102919(order *model.GoodsOrder) { +// // if order.VendorOrgCode == "1" { +// // order.StoreID = 102919 +// // order.JxStoreID = 102919 +// // order.StoreName = "商城模板(成都发货)" +// // order.VendorStoreID = model.JdShopMainVendorStoreID +// // } else { +// order.StoreID = model.JdShopMainStoreID +// order.JxStoreID = model.JdShopMainStoreID +// order.StoreName = "商城模板店2" +// order.VendorStoreID = model.JdShopMainVendorStoreID +// // } +// order.DeliveryFlag = model.OrderDeliveryFlagMaskScheduleDisabled +//} +// +//func setJdsOrderSeq(order *model.GoodsOrder) (err error) { +// type tCount struct { +// Count int `json:"count"` +// } +// var count = &tCount{} +// sql := ` +// SELECT count(*) count FROM goods_order WHERE store_id = ? AND order_create_at >= ? AND order_create_at <= ? AND vendor_id = ? +// ` +// sqlParams := []interface{}{ +// order.StoreID, utils.Time2Date(time.Now()), utils.Time2Date(time.Now().AddDate(0, 0, 1)), order.VendorID, +// } +// err = dao.GetRow(dao.GetDB(), &count, sql, sqlParams) +// order.OrderSeq = count.Count + 1 +// return err +//} +// +//func Decrypt(p, vendorOrgCode string) (result string) { +// if p == "" { +// return "" +// } +// data, _ := base64.StdEncoding.DecodeString(strings.ReplaceAll(p, " ", "+")) +// key := GetKey(hex.EncodeToString(data)[4:36], vendorOrgCode) +// globals.SugarLogger.Debugf("Decrypt keys : %v", key) +// data2, _ := base64.StdEncoding.DecodeString(key) +// b := bytes.NewBuffer(data) +// b.Next(18) +// iv := make([]byte, 16) +// b.Read(iv) +// main := make([]byte, len(data)-18-16) +// b.Read(main) +// decryptedData, _ := utils.AESCBCDecpryt(main, data2[:16], iv) +// return string(decryptedData) +//} +// +//func getRealOrderID(orderID string) (order *model.GoodsOrder) { +// var ( +// db = dao.GetDB() +// ) +// sql := ` +// SELECT * FROM goods_order WHERE vendor_order_id2 = ? ORDER BY vendor_order_id DESC LIMIT 1 +// ` +// sqlParams := []interface{}{ +// orderID, +// } +// dao.GetRow(db, &order, sql, sqlParams) +// return order +//} +// +//func getAllRealOrderID(orderID string) (orders []*model.GoodsOrder) { +// var ( +// db = dao.GetDB() +// ) +// sql := ` +// SELECT * FROM goods_order WHERE vendor_order_id2 = ? +// ` +// sqlParams := []interface{}{ +// orderID, +// } +// dao.GetRows(db, &orders, sql, sqlParams) +// return orders +//} +// +//func GetDaDaBillParams(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dadaapi.OperateOrderParams, err error) { +// billParams = &dadaapi.OperateOrderParams{ +// OriginID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), +// CargoPrice: jxutils.IntPrice2Standard(limitOrderPrice(order.ActualPayPrice)), +// IsPrepay: 0, +// ReceiverName: utils.FilterMb4(order.ConsigneeName), +// ReceiverAddress: utils.FilterMb4(order.ConsigneeAddress), +// ReceiverPhone: order.ConsigneeMobile, +// } +// if billParams.ShopNo, err = getDadaShopID(order, db); err == nil { +// if billParams.CityCode, err = getDataCityCodeFromOrder(order, db); err == nil { +// // storeTel := "" +// // storeID := jxutils.GetSaleStoreIDFromOrder(order) +// // storeDeatail, _ := dao.GetStoreDetail(db, storeID, order.VendorID) +// // if storeDeatail.Tel2 != "" { +// // storeTel = ",门店电话:" + storeDeatail.Tel2 +// // } +// billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType) +// billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4("客户电话:"+order.ConsigneeMobile+","+order.BuyerComment+"取货失败或配送遇到问题请联系18048531223,禁止未配送直接完成定单!")) +// billParams.CargoType = dadaapi.CargoTypeFresh +// billParams.CargoWeight = float64(jxutils.IntWeight2Float(limitOrderWeight(order.Weight))) +// billParams.CargoNum = order.GoodsCount +// } +// } +// return billParams, err +//} +// +//func limitOrderPrice(price int64) int64 { +// var maxOrderPrice int64 = 6399 +// if price > maxOrderPrice { +// return maxOrderPrice +// } +// return price +//} +// +//func limitOrderWeight(weight int) int { +// maxOrderWeight := 5000 // 5公斤 +// if weight > maxOrderWeight { +// return maxOrderWeight +// } +// return weight +//} +// +//func getDadaShopID(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) { +// saleStoreID := jxutils.GetSaleStoreIDFromOrder(order) +// storeCourierList, err2 := dao.GetOpenedStoreCouriersByStoreID(db, saleStoreID, model.VendorIDDada) +// if err = err2; err != nil && !dao.IsNoRowsError(err) { +// return "", err +// } +// if len(storeCourierList) == 0 { +// return "", partner.ErrStoreHaveNoCourier +// } +// retVal = storeCourierList[0].VendorStoreID +// if beego.BConfig.RunMode == "dev" { +// retVal = "test_0001" +// } +// return retVal, nil +//} +// +//func getDataCityCodeFromOrder(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) { +// jxStoreID := jxutils.GetSaleStoreIDFromOrder(order) +// sql := ` +// SELECT t2.tel_code +// FROM store t1 +// JOIN place t2 on t1.city_code = t2.code +// WHERE t1.id = ? +// ` +// codeInfo := &struct { +// TelCode string +// }{} +// if err = dao.GetRow(db, codeInfo, sql, jxStoreID); err != nil { +// globals.SugarLogger.Errorf("GetDataCityCodeFromOrder can not find store info for vendorID:%d, store:%s, error:%v", order.VendorID, order.VendorStoreID, err) +// if err == nil { +// err = dada.ErrCanNotFindDadaCityCode +// } +// return "", err +// } +// return codeInfo.TelCode, nil +//} diff --git a/business/partner/purchase/gomei/callback_test.go b/business/partner/purchase/gomei/callback_test.go new file mode 100644 index 000000000..5301bb558 --- /dev/null +++ b/business/partner/purchase/gomei/callback_test.go @@ -0,0 +1,34 @@ +package gomei +// +//import ( +// "fmt" +// "git.rosy.net.cn/baseapi/platformapi/jdshopapi" +// "testing" +//) +// +//func TestSaveJdsOrders(t *testing.T) { +// type args struct { +// msg *jdshopapi.CallBackResult +// } +// tests := []struct { +// name string +// args args +// wantErr bool +// }{ +// // TODO: Add test cases. +// } +// fmt.Println("测试1") +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// if err := SaveJdsOrders(tt.args.msg); (err != nil) != tt.wantErr { +// t.Errorf("SaveJdsOrders() error = %v, wantErr %v", err, tt.wantErr) +// } +// }) +// } +// fmt.Println("测试2") +//} +// +//func TestDecrypt(t *testing.T) { +// InitKey() +// fmt.Println(Decrypt("dGeoMeGNcXeT8iCHn3hTrCFYY8qfMnOptNcMFzAJA2/Dx/CPiZ526ec0NN0kWKs4+HwEGCLu9hAB9D0MIf8UB6q4G8IVgD3oXlOb89CFgGe0yO1HA9j51ESPFXh8=", "1")) +//} diff --git a/business/partner/purchase/gomei/gomei.go b/business/partner/purchase/gomei/gomei.go new file mode 100644 index 000000000..41248b37e --- /dev/null +++ b/business/partner/purchase/gomei/gomei.go @@ -0,0 +1,120 @@ +package gomei + +import ( + "encoding/base64" + gomei "git.rosy.net.cn/baseapi/platformapi/gome_live_show" + "git.rosy.net.cn/baseapi/platformapi/jdshopapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/model/dao" + "git.rosy.net.cn/jx-callback/business/partner" + "git.rosy.net.cn/jx-callback/business/partner/putils" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" +) + +var ( + CurPurchaseHandler *PurchaseHandler +) + +type PurchaseHandler struct { + partner.BasePurchasePlatform + putils.DefSingleStorePlatform +} + +func init() { + if api.GuoMeiApi != nil { + CurPurchaseHandler = New() + partner.RegisterPurchasePlatform(CurPurchaseHandler) + } +} + +func New() (obj *PurchaseHandler) { + obj = new(PurchaseHandler) + obj.ISingleStoreStoreSkuHandler = obj + return obj +} + +func getAPI(appOrgCode string) (apiObj *gomei.API) { + if appOrgCode == "" { + globals.SugarLogger.Warnf("getAPI appOrgCode is empty") + } + + return partner.CurAPIManager.GetAPI(model.VendorGoMei, appOrgCode).(*gomei.API) +} + +func GetAPI(appOrgCode string) (apiObj *jdshopapi.API) { + apiObj = partner.CurAPIManager.GetAPI(model.VendorGoMei, appOrgCode).(*jdshopapi.API) + if configs, err := dao.QueryConfigs(dao.GetDB(), "jdsCookie2", model.ConfigTypeCookie, ""); err == nil { + apiObj.SetCookieWithStr(configs[0].Value) + } + return apiObj +} + +func (p *PurchaseHandler) GetVendorID() int { + return model.VendorGoMei +} + +func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { + if globals.EnableJdShopWrite { + if imgType > model.ImgTypeLocal { + result, err := getAPI(vendorOrgCode).UploadPicture(base64.StdEncoding.EncodeToString(imgData), 0, imgName) + if err == nil { + imgHint = result.Data.Url + } + } + } else { + imgHint = utils.GetUpperUUID() + } + return imgHint, err +} + +// 获取国美商户的分类标签,官方未提供接口.->查询所有门店分类,去重复!目前国美分类只有一级 +func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { + storeList, err := getAPI(string(model.VendorGoMei)).QueryStoreList(&gomei.GetStoreListReq{ + Page: gomei.Page{ + PageSize: model.BrandBalanceLimit, + PageNumber: 1, + }, + }) + if err != nil { + return nil, err + } + + if storeList.Data.Total == 0 { + return nil, nil + } + + result := make(map[string]*model.SkuVendorCategory, 0) + for _, v := range storeList.Data.Records { + storeCategoryList, err := GetAllStoreCategories(string(model.VendorGoMei), v.StoreCode) + //storeCategoryList, err := api.GuoMeiApi.QueryStoreCategoryList(&gomei.QueryStoreGoodsCategoryListReq{ + // Page: gomei.Page{PageNumber: 1, PageSize: model.BrandBalanceLimit}, + // StoreCode: v.StoreCode, + //}) + if err != nil || len(storeCategoryList) <= 0 { + continue + } + for _, c := range storeCategoryList { + cat := &model.SkuVendorCategory{ + VendorID: model.VendorGoMei, + Name: c.CategoryName, + Level: 1, + VendorCategoryID: c.CategoryCode, + ParentID: "", + IsLeaf: 0, + } + result[cat.Name] = cat + } + } + + for _, v := range result { + vendorCats = append(vendorCats, v) + } + return vendorCats, err +} + +func (p *PurchaseHandler) GetOrderRider(vendorOrgCode, vendorStoreID string, param map[string]interface{}) (err error) { + return nil +} diff --git a/business/partner/purchase/gomei/key.go b/business/partner/purchase/gomei/key.go new file mode 100644 index 000000000..f8f93d861 --- /dev/null +++ b/business/partner/purchase/gomei/key.go @@ -0,0 +1,78 @@ +package gomei + +import ( + "encoding/base64" + "encoding/hex" + "encoding/json" + "git.rosy.net.cn/baseapi/platformapi/jdshopapi" + + "git.rosy.net.cn/jx-callback/globals" +) + +var ( + KeyList []*Key + KeyList2 []*Key +) + +type Key struct { + ID string `json:"id"` + KeyExp int64 `json:"key_exp"` + KeyStatus int `json:"key_status"` + KeyDigest string `json:"key_digest"` + KeyType string `json:"key_type"` + KeyString string `json:"key_string"` + KeyEffective int64 `json:"key_effective"` + Version int `json:"version"` +} + +func InitKey() { + newapi := jdshopapi.New("37d36b62c0d14bd4b872f948b335c95czinj", "E1D746D42474D5F1F1A10CECE75D99F6", "efa7e1d1a22640fa990e6cf164b28608") + keyResult, err := newapi.KeyGet() + if err != nil { + return + } + for _, v := range keyResult.Response.ServiceKeyList[0].Keys { + data, _ := json.Marshal(v) + vv := &Key{} + err = json.Unmarshal(data, &vv) + KeyList = append(KeyList, vv) + } + keyResult2, err := jdshopapi.New("f9c5ce9a5ce24218936924f7c4864cc9owe1", "E1D746D42474D5F1F1A10CECE75D99F6", "efa7e1d1a22640fa990e6cf164b28608").KeyGet() + if err != nil { + return + } + for _, v := range keyResult2.Response.ServiceKeyList[0].Keys { + data, _ := json.Marshal(v) + vv := &Key{} + err = json.Unmarshal(data, &vv) + KeyList2 = append(KeyList2, vv) + } + globals.SugarLogger.Debugf("jdshop key refreshed..") +} + +func GetKey(keySign, vendorOrgCode string) (key string) { + if vendorOrgCode == "1" { + for _, v := range KeyList { + data, _ := base64.StdEncoding.DecodeString(v.ID) + if keySign == hex.EncodeToString(data) { + return v.KeyString + } + } + } else { + for _, v := range KeyList2 { + //data, _ := base64.StdEncoding.DecodeString(v.ID) + //if keySign == hex.EncodeToString(data) { + return v.KeyString + } + } + // } else { + // for _, v := range KeyList2 { + // data, _ := base64.StdEncoding.DecodeString(v.ID) + // if keySign == hex.EncodeToString(data) { + // return v.KeyString + // } + // } + // } + globals.SugarLogger.Debugf("no key can equal..") + return key +} diff --git a/business/partner/purchase/gomei/order.go b/business/partner/purchase/gomei/order.go new file mode 100644 index 000000000..627e0b5fe --- /dev/null +++ b/business/partner/purchase/gomei/order.go @@ -0,0 +1,322 @@ +package gomei + +import ( + "fmt" + "git.rosy.net.cn/jx-callback/globals" + "net/http" + "strings" + "time" + + "git.rosy.net.cn/jx-callback/business/model/dao" + + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/platformapi" + "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/jxutils/tasksch" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/partner" + "git.rosy.net.cn/jx-callback/globals/api" +) + +func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { + return err +} + +func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { + result := &jdshopapi.AllOrdersResult{} + if err := utils.Map2StructByJson(orderData, &result, false); err != nil { + fmt.Println("err===============", err) + return nil + } + fmt.Println("err===============", orderData) + + jdsOrder := result.OrderList[0] + order = &model.GoodsOrder{ + VendorOrderID: utils.Int64ToStr(jdsOrder.OrderID), + 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)), + Status: status2Jxstatus(jdsOrder.OrderStatus), + } + return order +} +func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID, vendorStoreID string) (order *model.GoodsOrder, err error) { + resultOrders, err := api.JdShopAPI.AllOrders(&jdshopapi.AllOrdersParam{ + OrderID: vendorOrderID, + Current: 1, + PageSize: 10, + }) + if err != nil { + return nil, err + } + fmt.Println("resultOrders===============", resultOrders) + return p.Map2Order(utils.Struct2FlatMap(resultOrders)), err +} +func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { + //jdsOrder, err := GetJdsOrder(vendorOrderID, vendorOrgCode) + //jdsOrder, err := GetJdsOrder2(vendorOrderID, vendorOrgCode) + //r := regexp.MustCompile(`"orderState":"(.*)","orderType`) + //if len(r.FindStringSubmatch(jdsOrder)) > 0 { + // return status2Jxstatus(r.FindStringSubmatch(jdsOrder)[1]), err + //} + if order, err := p.GetOrder(vendorOrgCode, vendorOrderID, ""); err == nil && order != nil { + return order.Status, err + } + return 0, err +} + +func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { + //var ( + // status int + // remark string + //) + //if isAcceptIt { + // status = model.OrderStatusAccepted + // //京东商城第二个号要自动接单 + // if order.VendorOrgCode == "2" { + // err = getAPI(order.VendorOrgCode).SetOrderStateToWait(utils.Str2Int64(order.VendorOrderID2)) + // } + //} else { + // status = model.OrderStatusCanceled + //} + //return ChangeOrderStatus(order.VendorOrderID, status, remark) + return err +} +func (p *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { + status, err := p.GetOrderStatus(order.VendorOrgCode, order.VendorOrderID2) + if err != nil { + globals.SugarLogger.Debug("jdShop GetOrders err := ", err) + return err + } + //说明此时该订单在平台上已经取消了 + if status == model.OrderStatusCanceled { + err = ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, "订单在京东商城已被取消!") + } else { + if jxutils.GetSaleStoreIDFromOrder(order) != model.JdShopMainStoreID { + //可能还没接单? + if status == model.OrderStatusNew { + p.AcceptOrRefuseOrder(order, true, "") + } + err = ChangeOrderStatus(order.VendorOrderID, model.OrderStatusFinishedPickup, "自动拣货完成") + //if status == model.OrderStatusAccepted { + err = p.OrderExport(jxcontext.AdminCtx, order.VendorOrderID, order.VendorOrderID, true) + //} + } + } + return err +} + +func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { + return err +} // 取货失败后再次招唤平台配送 +func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { + return err +} // 投递失败后确认收到退货 +func (p *PurchaseHandler) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) { + return isCan, err +} +func (p *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { + return err +} +func (p *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { + return err +} +func (p *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { + ChangeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "") + return err +} +func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { + //ChangeOrderStatus(order.VendorOrderID, model.OrderStatusFinished, "") + //if order.VendorOrgCode == "2" { + // getAPI(order.VendorOrgCode).SetOrderStateToFinish(utils.Str2Int64(order.VendorOrderID2)) + //} + return err +} +func (p *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { + return mobile, err +} +func (p *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { + return err +} +func (p *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { + return err +} +func (p *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { + ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, reason) + if order.EclpOutID != "" { + _, err = api.JdEclpAPI.CancelOrder(order.EclpOutID) + } + return err +} +func (p *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { + var ( + db = dao.GetDB() + diffShopPrice int64 + diffSalePrice int64 + ) + if order.Status >= model.OrderStatusDelivering { + return fmt.Errorf("配送中以后的订单无法进行售前退款!") + } + //1、删除原order_sku 中售前调整的商品 + for _, sku := range removedSkuList { + sql := `DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ? AND sku_id = ?` + sqlParams := []interface{}{order.VendorOrderID, order.VendorID, sku.SkuID} + dao.ExecuteSQL(db, sql, sqlParams) + + diffShopPrice += sku.ShopPrice + diffSalePrice += sku.SalePrice + } + //2、修改goods_order 中的shopprice,若是扣点的订单,还要改new_earning_price和total_shop_money + order.AdjustCount += 1 + order.ShopPrice = order.ShopPrice - diffShopPrice + if order.EarningType == model.EarningTypePoints { + order.TotalShopMoney = utils.Float64TwoInt64(float64(float64(order.TotalShopMoney)/jdshopapi.JdsPayPercentage-float64(diffSalePrice)) * jdshopapi.JdsPayPercentage) + jxutils.RefreshOrderEarningPrice2(order, order.OrderPayPercentage) + partner.CurOrderManager.UpdateOrderFields(order, []string{"TotalShopMoney", "NewEarningPrice"}) + } + partner.CurOrderManager.UpdateOrderFields(order, []string{"AdjustCount", "ShopPrice"}) + return err +} + +func (p *PurchaseHandler) GetJdsOrders(ctx *jxcontext.Context, orderCreatedStart, orderCreatedEnd string, current, pageSize int) (orderResult *jdshopapi.AllOrdersResult, err error) { + //jdsapi := getAPI("2") + //globals.SugarLogger.Debugf("此时的cookie , %d", jdsapi.GetCookieCount()) + //orderResult, err = jdsapi.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 + //} + //if order, _ := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJDShop); order != nil { + // err = getAPI(order.VendorOrgCode).OrderShipment(utils.Str2Int64(order.VendorOrderID2), 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, vendorOrderID) + return err +} + +func status2Jxstatus(status int) (statusJx int) { + //if status == jdshopapi.OrderStatusPopPause || status == jdshopapi.OrderStatusPause { + // statusJx = model.OrderStatusNew + //} else if status == jdshopapi.OrderStatusWait { + // statusJx = model.OrderStatusAccepted + //} else if status == jdshopapi.OrderStatusCancel { + // statusJx = model.OrderStatusCanceled + //} + if status == jdshopapi.OrderStatusFinishedPickup { + statusJx = model.OrderStatusAccepted + } else if status == jdshopapi.OrderStatusNew { + statusJx = model.OrderStatusNew + } else if status == jdshopapi.OrderStatusCancelm2 { + statusJx = model.OrderStatusCanceled + } + return statusJx +} + +const ( + ProdURL = "http://116.196.82.188:8080/v2/" +) + +func apiToYd(url string, params map[string]interface{}) (retVal map[string]interface{}, err error) { + cl := &http.Client{} + err = platformapi.AccessPlatformAPIWithRetry(cl, + func() *http.Request { + request, _ := http.NewRequest(http.MethodPost, ProdURL+url, strings.NewReader(utils.Map2URLValues(params).Encode())) + request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + return request + }, + nil, + func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { + if jsonResult1 == nil { + return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") + } + if err == nil { + if jsonResult1["code"] != nil { + if utils.Interface2Int64WithDefault(jsonResult1["code"], 0) != 0 { + errLevel = platformapi.ErrLevelGeneralFail + err = utils.NewErrorCode(jsonResult1["desc"].(string), jsonResult1["code"].(string)) + baseapi.SugarLogger.Debugf("yd AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) + } + } + retVal = jsonResult1 + } + return errLevel, err + }) + return retVal, err +} + +func GetJdsOrder(vendorOrderID, vendorOrgCode string) (jdsOrder *jdshopapi.GetEnOrderResult, err error) { + jdmcshopapi := jdshopapi.New("f9c5ce9a5ce24218936924f7c4864cc9owe1", "E1D746D42474D5F1F1A10CECE75D99F6", "efa7e1d1a22640fa990e6cf164b28608") + result, err := jdmcshopapi.GetOrderById(utils.Str2Int64(vendorOrderID[0:12]), false) + if err != nil { + return nil, err + } + return result, err +} + +func GetJdsOrder2(vendorOrderID, vendorOrgCode string) (jdsOrder string, err error) { + params := make(map[string]interface{}) + params["orderID"] = vendorOrderID + params["token"] = jdshopapi.JdsYdToken + params["vendorOrgCode"] = vendorOrgCode + result, err := apiToYd("order/GetJdsOrder", params) + //jdsOrder2 := &jdshopapi.GetOrderResult{} + return strings.ReplaceAll(result["data"].(string), "\\", ""), err +} + +func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, order *model.GoodsOrder) (selfTakeCode string, err error) { + return selfTakeCode, err +} + +func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) { + return err +} + +func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { + return vendorOrderIDs, err +} + +func (c *PurchaseHandler) ComplaintRider(vendorOrderId string, resonID int, resonContent string) (err error) { + return err +} diff --git a/business/partner/purchase/gomei/order_afs.go b/business/partner/purchase/gomei/order_afs.go new file mode 100644 index 000000000..6e3344826 --- /dev/null +++ b/business/partner/purchase/gomei/order_afs.go @@ -0,0 +1,138 @@ +package gomei + +import ( + "crypto/md5" + "fmt" + "math" + "time" + + "git.rosy.net.cn/jx-callback/business/model/dao" + + "git.rosy.net.cn/baseapi/utils" + "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" +) + +func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, afsOrder *model.AfsOrder, approveType int, reason string) (err error) { + var status int + if approveType == partner.AfsApproveTypeRefused { + status = model.AfsOrderStatusFailed + } else { + status = model.AfsOrderStatusFinished + + } + orderStatus := &model.OrderStatus{ + VendorOrderID: afsOrder.AfsOrderID, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 + VendorID: afsOrder.VendorID, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: afsOrder.VendorOrderID, + RefVendorID: afsOrder.VendorID, + VendorStatus: utils.Int2Str(status), + Status: status, + StatusTime: time.Now(), + Remark: reason, + } + partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus) + return err +} + +// 确认收到退货 +func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { + err = fmt.Errorf("京东商城当前不支持ConfirmReceivedReturnGoods") + return err +} + +// 发起全款退款 +func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { + err = c.PartRefundOrder(ctx, order, order.Skus, reason) + return err +} + +// 发起部分退款 +func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { + globals.SugarLogger.Debugf("PartRefundOrder jdshop, order :%v", utils.Format4Output(order, true)) + var ( + skuMap = make(map[int]*model.OrderSku) + salePrice int64 + db = dao.GetDB() + ) + for _, sku := range order.Skus { + skuMap[sku.SkuID] = sku + } + orderStatus := buildOrderStatus(ctx, order, reason) + afsOrder := &model.AfsOrder{ + VendorID: order.VendorID, + AfsOrderID: orderStatus.VendorOrderID, + VendorOrderID: orderStatus.RefVendorOrderID, + // VendorStoreID: order.VendorStoreID, + // StoreID: jxutils.GetSaleStoreIDFromOrder(order), + AfsCreatedAt: time.Now(), + VendorAppealType: "", + AppealType: model.AfsAppealTypeRefund, + VendorReasonType: utils.Int2Str(model.AfsReasonNotOthers), + ReasonType: model.AfsReasonNotOthers, + ReasonDesc: utils.LimitUTF8StringLen(reason, 1024), + ReasonImgList: "", + RefundType: model.AfsTypePartRefund, + + VendorOrgCode: "", + } + for _, sku := range refundSkuList { + orderSku := &model.OrderSkuFinancial{ + Count: sku.Count, + VendorSkuID: utils.Int2Str(sku.SkuID), + SkuID: sku.SkuID, + } + storeSkus, _ := dao.GetStoresSkusInfo(db, []int{model.JdShopMainStoreID}, []int{sku.SkuID}) + if len(storeSkus) > 0 { + orderSku.VendorSkuID = utils.Int64ToStr(storeSkus[0].JdsID) + } + if skuMap[sku.SkuID] != nil { + orderSku.Name = skuMap[sku.SkuID].SkuName + orderSku.UserMoney = skuMap[sku.SkuID].SalePrice * int64(sku.Count) + salePrice += skuMap[sku.SkuID].SalePrice * int64(sku.Count) + } + afsOrder.SkuUserMoney += orderSku.UserMoney + afsOrder.Skus = append(afsOrder.Skus, orderSku) + } + err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) + return err +} + +func buildOrderStatus(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (orderStatus *model.OrderStatus) { + orderStatus = &model.OrderStatus{ + VendorOrderID: utils.Int64ToStr(GenAfsOrderNo(ctx)), // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 + VendorID: order.VendorID, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: order.VendorOrderID, + RefVendorID: order.VendorID, + VendorStatus: utils.Int2Str(model.AfsOrderStatusWait4Approve), + Status: model.AfsOrderStatusWait4Approve, + StatusTime: time.Now(), + Remark: reason, + } + orderStatus.Status = model.AfsOrderStatusWait4Approve + return orderStatus +} + +func GenAfsOrderNo(ctx *jxcontext.Context) (orderNo int64) { + const prefix = 70 + const randPartNum = 100 + orderNoBeginTimestamp := utils.Str2Time("2010-01-01 00:00:00").Unix() + orderNo = time.Now().Unix() - orderNoBeginTimestamp + orderNo = orderNo * randPartNum + md5Bytes := md5.Sum([]byte(utils.GetUUID())) + randPart := 0 + for k, v := range md5Bytes { + randPart += int(v) << ((k % 3) * 8) + } + orderNo += int64(randPart % randPartNum) + orderNo += int64(math.Pow10(int(math.Log10(float64(orderNo)))+1)) * prefix + return orderNo +} + +func (c *PurchaseHandler) GetOrderAfsInfo(ctx *jxcontext.Context, vendorOrderID, afsOrderID string) (orderAfsInfo *partner.OrderAfsInfo, err error) { + return &partner.OrderAfsInfo{}, err +} diff --git a/business/partner/purchase/gomei/order_comment.go b/business/partner/purchase/gomei/order_comment.go new file mode 100644 index 000000000..906073b16 --- /dev/null +++ b/business/partner/purchase/gomei/order_comment.go @@ -0,0 +1,5 @@ +package gomei + +func (c *PurchaseHandler) StartRefreshComment() { + +} diff --git a/business/partner/purchase/gomei/store.go b/business/partner/purchase/gomei/store.go new file mode 100644 index 000000000..c56ee622a --- /dev/null +++ b/business/partner/purchase/gomei/store.go @@ -0,0 +1,87 @@ +package gomei + +import ( + "fmt" + gomei "git.rosy.net.cn/baseapi/platformapi/gome_live_show" + "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/jxutils/tasksch" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/model/dao" + "git.rosy.net.cn/jx-callback/globals/api" +) + +func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorStoreName string) (storeDetail *dao.StoreDetail, err error) { + if vendorStoreName != "" { + result2, _ := api.GuoMeiApi.QueryStoreList(&gomei.GetStoreListReq{ + StoreName: vendorStoreName, + }) + if len(result2.Data.Records) != model.YES { + return storeDetail, fmt.Errorf("国美未查询到该平台门店,平台门店ID:[%v]", vendorStoreID) + } + storeDetail = &dao.StoreDetail{} + storeDetail.Name = result2.Data.Records[0].StoreName + storeDetail.Lat = jxutils.StandardCoordinate2Int(utils.Str2Float64("0.000")) + storeDetail.Lng = jxutils.StandardCoordinate2Int(utils.Str2Float64("0.000")) + } + return storeDetail, err +} + +// stoerIDs为nil表示所有 +func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { + return nil +} + +func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string, params map[string]interface{}, storeDetail *dao.StoreDetail) (vendorStoreID string, err error) { + return "", err +} + +func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) { + return err +} + +func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { + return hint, err +} + +func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { + return storeStatus, err +} + +func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { + return err +} + +func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { + err = api.JdShopAPI.UpdateStatus(utils.Str2Int(vendorStoreID), jxStatus2JdsStatus(status)) + return err +} + +func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { + return err +} + +func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { + return vendorStoreIDs, err +} + +func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { + return err +} + +func jxStatus2JdsStatus(status int) (result int) { + if status == model.StoreStatusOpened { + result = jdshopapi.JdsStoreStatusOnline + } else if status == model.StoreStatusHaveRest || status == model.StoreStatusClosed { + result = jdshopapi.JdsStoreStatusRest + } else { + result = jdshopapi.JdsStoreStatusDisable + } + return result +} + +func (c *PurchaseHandler) UpdateStoreLineStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, lineStatus int) (err error) { + return err +} diff --git a/business/partner/purchase/gomei/store_sku.go b/business/partner/purchase/gomei/store_sku.go new file mode 100644 index 000000000..40d595241 --- /dev/null +++ b/business/partner/purchase/gomei/store_sku.go @@ -0,0 +1,911 @@ +package gomei + +import "regexp" + +// +//import ( +// "fmt" +// gomei "git.rosy.net.cn/baseapi/platformapi/gome_live_show" +// "regexp" +// "strings" +// "time" +// +// "git.rosy.net.cn/baseapi/platformapi/jdshopapi" +// +// "git.rosy.net.cn/jx-callback/globals/api" +// +// "git.rosy.net.cn/baseapi/utils" +// "git.rosy.net.cn/jx-callback/business/jxutils" +// "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" +// "git.rosy.net.cn/jx-callback/business/model" +// "git.rosy.net.cn/jx-callback/business/model/dao" +// "git.rosy.net.cn/jx-callback/business/partner" +// "git.rosy.net.cn/jx-callback/business/partner/putils" +// "git.rosy.net.cn/jx-callback/globals" +//) +// +const ( + deleteErr1 = "已经删除的不能直接下架" + deleteErr2 = "SKU" + deleteErr3 = "已删除" +) + +var ( + sensitiveWordRegexp = regexp.MustCompile(`商品名称中含有敏感词(\[.*\])`) +) + +//func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { +// if globals.EnableJdShopWrite { +// if vendorStoreID == model.GoMeiShopMainVendorStoreID { +// for _, v := range storeSkuList { +// //判断京东商城上是否有这个商品了,如果有就是添加规格而不是创建商品 +// //如果是京东商城2,是下架的商品,弄上架 ,先改为有下架的不管,重新建 +// name := filterSensitiveWord(v.Name) +// flag := false +// result, err := getAPI(v.VendorOrgCode).SearchWare4Valid(name, 1, 100) +// if err != nil { +// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") +// return failedList, err +// } +// for _, v := range result.Data { +// if v.Title == name { +// flag = true +// //下架 +// if v.WareStatus == 2 || v.WareStatus == 1028 { +// flag = false +// //wareStatusUpdateWareID = utils.Int64ToStr(v.WareID) +// } +// break +// } +// } +// if flag { +// wareSaveParam := &jdshopapi.WareSaveParam{ +// WareID: result.Data[0].WareID, +// Title: v.Name, +// CategoryID: int(v.VendorVendorCatID), +// VenderID: jdshopapi.VendorID2, +// Length: 200, +// Wide: 100, +// Height: 100, +// Weight: "1", +// BrandID: jdshopapi.BrandIdNO, +// ShopCategorys: []int{utils.Str2Int(v.VendorCatID)}, +// PromiseID: -1, +// MultiCateProps: []interface{}{}, +// PropsSet: []interface{}{}, +// SaleAttrs: []interface{}{}, +// WareStatus: 8, +// } +// var wareSaveSkus []*jdshopapi.WareSaveSkus +// //先把已有的规格放进去 +// wareResult, _ := getAPI(v.VendorOrgCode).FindWareById(wareSaveParam.WareID) +// if wareResult != nil { +// for _, v := range wareResult.Images { +// wareSaveParam.ImageMap.Num0000000000 = append(wareSaveParam.ImageMap.Num0000000000, &jdshopapi.CreateSkuParamImages{ +// ColorID: v.ColorID, +// ImgURL: v.ImgURL, +// ImgIndex: v.ImgIndex, +// }) +// } +// } +// skus, _, _ := getAPI(v.VendorOrgCode).SearchSkuList2([]int{int(wareSaveParam.WareID)}) +// if len(skus) > 0 { +// for _, vv := range skus { +// sku := &jdshopapi.WareSaveSkus{ +// SkuID: vv.SkuID, +// JdPrice: utils.Float64ToStr(vv.JdPrice), +// StockNum: vv.StockNum, +// Props: []*jdshopapi.WareSaveSkusProp{ +// &jdshopapi.WareSaveSkusProp{ +// AttrID: utils.Str2Int(vv.SaleAttrs[0].AttrID), +// AttrValues: utils.Str2Int64(vv.SaleAttrs[0].AttrValues[0]), +// AttrValueAlias: vv.SaleAttrs[0].AttrValueAlias[0], +// }, +// }, +// OuterID: vv.OuterID, +// } +// wareSaveSkus = append(wareSaveSkus, sku) +// } +// } +// // } +// for _, vv := range v.StoreSkuSyncInfoJds { +// v.JdsWareID = result.Data[0].WareID +// vv.JdsWareID = result.Data[0].WareID +// _, wareSaveSku, err := buildUpdateSkusParam(v, vv, true) +// wareSaveSkus = append(wareSaveSkus, wareSaveSku) +// if err != nil { +// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") +// return failedList, err +// } +// +// wareSaveParam.Skus = wareSaveSkus +// if wareResult, err2 := getAPI(v.VendorOrgCode).WareSave(wareSaveParam); err2 == nil { +// for _, vvv := range wareResult { +// if vvv.OuterID == wareSaveSku.OuterID { +// vv.VendorSkuID = utils.Int64ToStr(vvv.SkuID) +// break +// } +// } +// //创建商品后要上架,改价,库存,门店关注商品等 +// if err = getAPI(v.VendorOrgCode).WareDoUpdate("up", utils.Int64ToStr(wareSaveParam.WareID)); err == nil { +// err = getAPI(v.VendorOrgCode).StoreSkuBindStore(true, []string{vv.VendorSkuID}, nil) +// } +// } +// // } +// } +// } else { +// // 商品不存在,直接添加商品,添加分类,添加规格,门店关注上线 +// otherImg := make([]string, 0, 0) +// if v.Img2 != "" { +// otherImg = append(otherImg, v.Img2) +// } +// if v.Img3 != "" { +// otherImg = append(otherImg, v.Img3) +// } +// if v.Img4 != "" { +// otherImg = append(otherImg, v.Img4) +// } +// if v.Img5 != "" { +// otherImg = append(otherImg, v.Img5) +// } +// +// // 规格集合 +// spec := &gomei.SpecProperty{ +// SpecCode: v.VendorNameID, +// SpecName: v.Unit, +// SpecValues: nil, +// } +// specValuesList := make([]*gomei.SpecValues, 0, 0) +// for _, c := range v.StoreSkuSyncInfoJds { +// specValues := &gomei.SpecValues{ +// SpecValueCode: c.JdsStockSwitch, +// SpecValueName: fmt.Sprintf("%f", c.SpecQuality) + c.SpecUnit, +// } +// specValuesList = append(specValuesList, specValues) +// } +// spec.SpecValues = append(spec.SpecValues, specValuesList...) +// specProperty := append(make([]*gomei.SpecProperty, 0, 0), spec) +// +// api.GuoMeiApi.CreateMerchantGoodsOnStore(&gomei.CreateGoodsListToStore{ +// GoodsName: v.SkuName, +// MainPictureURL: v.Img, +// Detail: v.Name, +// Cat3Code: v.VendorCatID, +// SpecProperty: specProperty, // 规格集合 +// SkuSaleList: nil, // 售卖组 +// GoodsType: v.SkuVendorCatID, +// OtherPictureURL: otherImg, +// VideoURL: "", +// SpecCode: "", +// SpecName: "", +// SpecValues: "", +// SpecValueCode: "", +// SpecValueName: "", +// Specification: "", // 规格集合 +// MarketPrice: utils.Int64ToFloat64(v.Price), +// ThirdSkuCode: string(v.SkuID), +// }) +// _, _, wareSaveParam, err := buildCreateWareParam(v) +// if err != nil { +// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") +// return failedList, err +// } +// var ( +// wareID int64 +// resultAttrs = make(map[string]int64) +// ) +// var createSkuResult []*jdshopapi.WareSaveResult +// createSkuResult, err = getAPI(v.VendorOrgCode).WareSave(wareSaveParam) +// wareID = createSkuResult[0].WareID +// +// var paramAttrs = make(map[string]*jdshopapi.WareSaveSkus) +// for _, vv := range wareSaveParam.Skus { +// for _, vvv := range vv.Props { +// paramAttrs[vvv.AttrValueAlias] = vv +// } +// } +// for _, vv1 := range createSkuResult { +// for _, vvv1 := range vv1.Props { +// if paramAttrs[vvv1.AttrValueAlias] != nil { +// resultAttrs[paramAttrs[vvv1.AttrValueAlias].OuterID] = vv1.SkuID +// } +// } +// } +// for _, vv2 := range v.StoreSkuSyncInfoJds { +// vv2.JdsWareID = createSkuResult[0].WareID +// if resultAttrs[utils.Int2Str(vv2.SkuID)] != 0 { +// vv2.VendorSkuID = utils.Int64ToStr(resultAttrs[utils.Int2Str(vv2.SkuID)]) +// } +// } +// //创建商品后要上架,改价,库存,门店关注商品等 +// if err = getAPI(v.VendorOrgCode).WareDoUpdate("up", utils.Int64ToStr(wareID)); err == nil { +// for _, vv2 := range v.StoreSkuSyncInfoJds { +// if resultAttrs[utils.Int2Str(vv2.SkuID)] != 0 { +// err = getAPI(v.VendorOrgCode).StoreSkuBindStore(true, []string{utils.Int64ToStr(resultAttrs[utils.Int2Str(vv2.SkuID)])}, nil) +// } +// } +// } +// // } +// if err != nil { +// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") +// return failedList, err +// } else { +// //追加商品透图 +// imageURL := "" +// img := v.Img +// if img != "" { +// suffix := img[strings.LastIndex(img, "."):] +// if suffix != ".png" { +// if resBinary, _, _ := jxutils.DownloadFileByURL(img + model.SkuNameImgToPng); err == nil { +// downloadURL, _ := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())) +// imageURL, _ = uploadImg(downloadURL, name, "tou", v.VendorOrgCode) +// } +// } else { +// imageURL, _ = uploadImg(img, name, "tou", v.VendorOrgCode) +// } +// } +// if v.VendorOrgCode == "1" { +// api.JdShopAPI.TransparentImageAdd(wareID, imageURL) +// } +// } +// } +// if err != nil { +// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") +// return failedList, err +// } +// +// } +// } else { +// //如果是普通店关注商品 +// for _, v := range storeSkuList { +// for _, vv := range v.StoreSkuSyncInfoJds { +// storeSkus, _ := dao.GetStoresSkusInfo(dao.GetDB(), []int{model.GoMeiShopMainStoreID}, []int{vv.SkuID}) +// if len(storeSkus) > 0 { +// for _, storeSku := range storeSkus { +// if storeSku.JdsID != 0 { +// status := vv.Status +// stock := vv.Stock +// price := vv.VendorPrice +// // 商品上架 +// if status == model.StoreSkuBindStatusNormal { +// _, err = getAPI(vv.VendorOrgCode).OnOffLineGoodsOnStore(&gomei.ShelfGoodsForStoreReq{ +// StoreCode: vendorStoreID, +// SkuCode: []string{storeSku.GmID}, +// ShelveStatus: gomei.PutOnTheShelf, +// }) +// if err != nil { +// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorGoMei], "国美商品已经存在,关注商品") +// return failedList, err +// } +// } +// // 修改库存 +// if stock != 0 { +// _, err = getAPI(vv.VendorOrgCode).UpdateStockForStore(&gomei.StoreGoodsStockUpdateReq{ +// StoreCode: vendorStoreID, +// ItemStocks: []*gomei.StoreSkuNum{{SkuCode: storeSku.GmID, StockNum: gomei.GoMeiMaxStock}}, +// }) +// if err != nil { +// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "国美修改商品库存") +// return failedList, err +// } +// } +// // 同步价格 +// _, err = getAPI(v.VendorOrgCode).UpdateOnGoodsPriceForStore(&gomei.StoreGoodsPriceUpdateReq{ +// StoreCode: vendorStoreID, +// SkuCode: storeSku.GmID, +// SalePrice: utils.Int64ToFloat64(price), +// }) +// if err != nil { +// failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "国美关注商品价格同步") +// return failedList, err +// } +// } +// } +// } +// } +// } +// } +// } +// return failedList, err +//} +// +//func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { +// if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { +// if vendorStoreID == model.JdShopMainVendorStoreID { +// for _, v := range storeSkuList { +// name := filterSensitiveWord(v.Name) +// updateWareParam := &jdshopapi.UpdateWareParam{ +// WareID: v.JdsWareID, +// Title: name, +// VenderID: jdshopapi.VenderID, +// // PromiseID: jdshopapi.JdsPromiseID, +// ShopCategorys: []int{utils.Str2Int(v.VendorCatID)}, +// JdPrice: jxutils.IntPrice2Standard(v.UnitPrice), +// } +// if v.VendorVendorCatID != jdshopapi.JdsOtherMeatCatID { +// updateWareParam.PromiseID = jdshopapi.JdsPromiseID +// } +// var desc string +// if v.DescImg != "" { +// pic3, err2 := uploadImg2(v.DescImg, name, "desc", v.VendorOrgCode) +// err = err2 +// desc = `