Merge remote-tracking branch 'origin/mark' into don
This commit is contained in:
@@ -46,9 +46,11 @@ const (
|
||||
time2Schedule3rdCarrierKey = "waitminute4mt"
|
||||
dingShiDaAheadTime = 30 * time.Minute // 定时达订单开始召唤配送的提前时间
|
||||
|
||||
minAddWaybillTipMinute = 20 // 最少开始加小费分钟(距离拣货完成)
|
||||
addWaybillTipGap = 15 // 加一元小费间隔的分钟数
|
||||
baseWaybillFee = 600 // 基本运费
|
||||
minAddWaybillTipMinute = 20 // 最少开始加小费分钟(距离拣货完成)
|
||||
addWaybillTipGap = 15 // 加一元小费间隔的分钟数
|
||||
maxWaybillTipMoney = 400 // 最大小费
|
||||
baseWaybillFee = 600 // 基本运费
|
||||
ebaiCancelWaybillMaxFee = 1000 // 饿百取消运单最高运费
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -222,7 +224,7 @@ func init() {
|
||||
},
|
||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore { // 自配送商家使用
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
@@ -244,7 +246,7 @@ func init() {
|
||||
savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore &&
|
||||
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
|
||||
savedOrderInfo.order.VendorID != model.VendorIDEBAI { // 非自配送商家使用
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
@@ -268,7 +270,7 @@ func init() {
|
||||
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
|
||||
savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore &&
|
||||
order.VendorID == model.VendorIDEBAI { // 非自配送商家使用
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, ebaiCancelWaybillMaxFee, nil)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
@@ -535,7 +537,7 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
|
||||
// OrderStatusFinishedPickup状态的订单依赖于TIMER重新建运单
|
||||
if bill.DeliveryFlag&model.WaybillDeliveryFlagMaskActiveCancel == 0 {
|
||||
if (order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) && (bill.WaybillVendorID != order.VendorID /* || bill.WaybillVendorID == model.VendorIDEBAI*/) {
|
||||
s.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||
s.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -583,7 +585,7 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
|
||||
// s.resetTimer(savedOrderInfo, bill, isPending)
|
||||
// s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID)
|
||||
// if order.WaybillVendorID == model.VendorIDUnknown {
|
||||
// s.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||
// s.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
|
||||
// }
|
||||
default:
|
||||
s.resetTimer(savedOrderInfo, bill, isPending)
|
||||
@@ -614,17 +616,20 @@ func (s *DefScheduler) removeWaybillFromMap(savedOrderInfo *WatchOrderInfo, wayb
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DefScheduler) createWaybillOn3rdProviders(savedOrderInfo *WatchOrderInfo, excludeBill *model.Waybill) (err error) {
|
||||
func (s *DefScheduler) createWaybillOn3rdProviders(savedOrderInfo *WatchOrderInfo, maxDeliveryFee int64, excludeBill *model.Waybill) (err error) {
|
||||
order := savedOrderInfo.order
|
||||
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, status:%d, excludeBill:%v", order.VendorOrderID, order.Status, excludeBill)
|
||||
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, status:%d, maxDeliveryFee:%d, excludeBill:%v", order.VendorOrderID, order.Status, maxDeliveryFee, excludeBill)
|
||||
if order.VendorID == model.VendorIDELM {
|
||||
return nil
|
||||
}
|
||||
if maxDeliveryFee == 0 {
|
||||
maxDeliveryFee = s.getMaxDeliveryFee(savedOrderInfo)
|
||||
}
|
||||
if err = s.canOrderCreateWaybillNormally(order); err == nil {
|
||||
if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 {
|
||||
if savedOrderInfo.retryCount <= maxWaybillRetryCount {
|
||||
savedOrderInfo.isNeedCreate3rdWaybill = true
|
||||
if _, err = s.CreateWaybillOnProviders4SavedOrder(jxcontext.AdminCtx, savedOrderInfo, nil, savedOrderInfo.GetWaybillVendorIDs(), false, 1000, 1000, s.getMaxDeliveryFee(savedOrderInfo)); err == nil {
|
||||
if _, err = s.CreateWaybillOnProviders4SavedOrder(jxcontext.AdminCtx, savedOrderInfo, nil, savedOrderInfo.GetWaybillVendorIDs(), false, 1000, 1000, maxDeliveryFee); err == nil {
|
||||
savedOrderInfo.retryCount++
|
||||
}
|
||||
} else {
|
||||
@@ -1009,8 +1014,8 @@ func (s *DefScheduler) getWaybillTip(savedOrderInfo *WatchOrderInfo) (tipFee int
|
||||
if timeGap1 > 0 {
|
||||
timeGap := int64(timeGap1/(addWaybillTipGap*time.Minute)) + 1
|
||||
tipFee = timeGap * 100
|
||||
if tipFee > 600 {
|
||||
tipFee = 600
|
||||
if tipFee > maxWaybillTipMoney {
|
||||
tipFee = maxWaybillTipMoney
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1059,7 +1064,7 @@ func (s *DefScheduler) handleWaybillTip(savedOrderInfo *WatchOrderInfo) {
|
||||
partner.CurOrderManager.OnOrderMsg(order, vendorStatus, remark)
|
||||
}
|
||||
if savedOrderInfo.isNeedCreate3rdWaybill {
|
||||
s.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||
s.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/mobile"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/msg"
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
@@ -76,6 +77,7 @@ func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
|
||||
"storeMsgSendStatusName": model.StoreMsgSendStatusName,
|
||||
"shopChineseNames": model.ShopChineseNames,
|
||||
"printerVendorInfo": model.PrinterVendorInfo,
|
||||
"printerStatusName": partner.PrinterStatusName,
|
||||
"purchaseVendorInfo": model.PurchaseVendorInfo,
|
||||
"afsReasonTypeName": model.AfsReasonTypeName,
|
||||
"afsAppealTypeName": model.AfsAppealTypeName,
|
||||
@@ -84,6 +86,7 @@ func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
|
||||
"actCreateTypeName": model.ActCreateTypeName,
|
||||
"storeAuditStatusName": model.StoreAuditStatusName,
|
||||
"configTypeList": model.ConfigTypeList,
|
||||
"autoSaleAt": "20:45:00",
|
||||
},
|
||||
}
|
||||
Init()
|
||||
|
||||
@@ -26,36 +26,12 @@ const (
|
||||
CancelWaybillReasonOther = 10
|
||||
)
|
||||
|
||||
const (
|
||||
PrinterStatusUnknown = 0
|
||||
PrinterStatusOffline = 1
|
||||
PrinterStatusOnlineOK = 2
|
||||
PrinterStatusOnlineAbnormal = 3
|
||||
)
|
||||
|
||||
const (
|
||||
AfsApproveTypeRefund = 1 // 退款
|
||||
AfsApproveTypeReturnGoods = 2 // 退货
|
||||
AfsApproveTypeRefused = 3 // 驳回
|
||||
)
|
||||
|
||||
const (
|
||||
PrintResultSuccess = 0
|
||||
PrintResultNoPrinter = 1
|
||||
)
|
||||
|
||||
type PrinterStatus struct {
|
||||
PrintResult int `json:"printResult"` // 0:成功,1:没有配置网络打印机
|
||||
|
||||
// PrinterStatusUnknown = 0
|
||||
// PrinterStatusOffline = 1
|
||||
// PrinterStatusOnlineOK = 2
|
||||
// PrinterStatusOnlineAbnormal = 3
|
||||
PrinterStatus int `json:"printerStatus"`
|
||||
Printed int `json:"printed"` // 已经打印的单数
|
||||
Waiting int `json:"waiting"` // 等待打印的单数,超过1一般不太正常
|
||||
}
|
||||
|
||||
const (
|
||||
TimerTypeNoOverride = 0 // GetStatusActionConfig 返回表示不修改缺省配置
|
||||
TimerTypeByPass = 1
|
||||
|
||||
@@ -7,6 +7,34 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
)
|
||||
|
||||
const (
|
||||
PrinterStatusUnknown = 0
|
||||
PrinterStatusOffline = 1
|
||||
PrinterStatusOnlineOK = 2
|
||||
PrinterStatusOnlineAbnormal = 3
|
||||
)
|
||||
|
||||
const (
|
||||
PrintResultSuccess = 0 // 成功
|
||||
PrintResultNoPrinter = 1 // 没有配置网络打印机
|
||||
)
|
||||
|
||||
var (
|
||||
PrinterStatusName = map[int]string{
|
||||
PrinterStatusUnknown: "未知",
|
||||
PrinterStatusOffline: "离线",
|
||||
PrinterStatusOnlineOK: "正常",
|
||||
PrinterStatusOnlineAbnormal: "异常",
|
||||
}
|
||||
)
|
||||
|
||||
type PrinterStatus struct {
|
||||
PrintResult int `json:"printResult"`
|
||||
PrinterStatus int `json:"printerStatus"`
|
||||
Printed int `json:"printed"` // 已经打印的单数
|
||||
Waiting int `json:"waiting"` // 等待打印的单数,超过1一般不太正常
|
||||
}
|
||||
|
||||
type BindPrinterResult struct {
|
||||
PrinterSN string `json:"printerSN"`
|
||||
PrinterKey string `json:"printerKey"`
|
||||
|
||||
@@ -595,32 +595,11 @@ func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, skuID int, vendorSkuID
|
||||
return nil, err
|
||||
}
|
||||
if len(skuList) > 0 {
|
||||
jdSkuIDs := make([]int64, len(skuList))
|
||||
batchSkuNameList := make([]*partner.SkuNameInfo, len(skuList))
|
||||
for k, v := range skuList {
|
||||
batchSkuNameList[k] = vendorSku2Jx(v)
|
||||
jdSkuIDs[k] = v.SkuID
|
||||
}
|
||||
imgMap := make(map[int64]*jdapi.ImgHandleQueryResult)
|
||||
if imgList, err2 := api.JdAPI.QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{
|
||||
SkuIDs: jdSkuIDs,
|
||||
}); err2 == nil {
|
||||
for _, v := range imgList {
|
||||
if imgMap[v.SkuID] == nil || imgMap[v.SkuID].IsMain < v.IsMain || imgMap[v.SkuID].ImgType < v.ImgType {
|
||||
imgMap[v.SkuID] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, v := range batchSkuNameList {
|
||||
jdSkuID := utils.Str2Int64(v.SkuList[0].VendorSkuID)
|
||||
if imgInfo := imgMap[jdSkuID]; imgInfo != nil {
|
||||
v.PictureList = []string{imgInfo.SourceImgURL}
|
||||
} else {
|
||||
// if imgList, err2 := api.JdAPI.GetSkuPageImageInfo(jdSkuID); err2 == nil && len(imgList) > 0 {
|
||||
// v.PictureList = []string{imgList[0].Big}
|
||||
// }
|
||||
}
|
||||
}
|
||||
setSkuNameListPic(batchSkuNameList)
|
||||
skuNameList = append(skuNameList, batchSkuNameList...)
|
||||
}
|
||||
if len(skuList) < param.PageSize {
|
||||
@@ -631,6 +610,65 @@ func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, skuID int, vendorSkuID
|
||||
return skuNameList, err
|
||||
}
|
||||
|
||||
func setSkuNameListPic(skuNameList []*partner.SkuNameInfo) []*partner.SkuNameInfo {
|
||||
jdSkuIDs := make([]int64, len(skuNameList))
|
||||
for k, v := range skuNameList {
|
||||
jdSkuIDs[k] = utils.Str2Int64(v.SkuList[0].VendorSkuID)
|
||||
}
|
||||
|
||||
imgMap := make(map[int64]*jdapi.ImgHandleQueryResult)
|
||||
if imgList, err2 := api.JdAPI.QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{
|
||||
SkuIDs: jdSkuIDs,
|
||||
}); err2 == nil {
|
||||
for _, v := range imgList {
|
||||
if v.ImgType == jdapi.ImgTypeMain {
|
||||
imgResult := imgMap[v.SkuID]
|
||||
if imgResult == nil || imgResult.IsMain < v.IsMain {
|
||||
imgMap[v.SkuID] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 使用扒页面方式获取商品图片
|
||||
if false {
|
||||
var leftJdSkuIDs []int64
|
||||
for _, v := range jdSkuIDs {
|
||||
if imgMap[v] == nil {
|
||||
leftJdSkuIDs = append(leftJdSkuIDs, v)
|
||||
}
|
||||
}
|
||||
task := tasksch.NewParallelTask("jd setSkuNameListPic", nil, jxcontext.AdminCtx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
jdSkuID := batchItemList[0].(int64)
|
||||
imgList, err := api.JdAPI.GetSkuPageImageInfo(jdSkuID)
|
||||
if err == nil && len(imgList) > 0 {
|
||||
retVal = [][]string{
|
||||
[]string{utils.Int64ToStr(jdSkuID), imgList[0].Big},
|
||||
}
|
||||
}
|
||||
return retVal, err
|
||||
}, leftJdSkuIDs)
|
||||
task.Run()
|
||||
if resultList, err := task.GetResult(0); err == nil {
|
||||
for _, v := range resultList {
|
||||
strList := v.([]string)
|
||||
imgMap[utils.Str2Int64(strList[0])] = &jdapi.ImgHandleQueryResult{
|
||||
SourceImgURL: strList[1],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置商品图片
|
||||
for _, v := range skuNameList {
|
||||
if imgResult := imgMap[utils.Str2Int64(v.SkuList[0].VendorSkuID)]; imgResult != nil {
|
||||
v.PictureList = []string{imgResult.SourceImgURL}
|
||||
}
|
||||
}
|
||||
return skuNameList
|
||||
}
|
||||
|
||||
func vendorSku2Jx(vendorSku *jdapi.SkuMain) (skuName *partner.SkuNameInfo) {
|
||||
prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(vendorSku.SkuName)
|
||||
weight := int(vendorSku.Weight * 1000)
|
||||
|
||||
@@ -66,7 +66,7 @@ func TestGetVendorCategories(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetSkus(t *testing.T) {
|
||||
skuNameList, err := curPurchaseHandler.GetSkus(jxcontext.AdminCtx, 0, "", "")
|
||||
skuNameList, err := curPurchaseHandler.GetSkus(jxcontext.AdminCtx, 0, "2023747677", "")
|
||||
t.Log(utils.Format4Output(skuNameList, false))
|
||||
t.Log(len(skuNameList))
|
||||
if err != nil {
|
||||
|
||||
@@ -3,11 +3,10 @@ package jd
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/putils"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/putils"
|
||||
)
|
||||
|
||||
func TestGetStoreSkusBareInfo(t *testing.T) {
|
||||
|
||||
@@ -2,6 +2,9 @@ package mtwm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
@@ -21,6 +24,10 @@ const (
|
||||
VendorStorePrefix = "美好菜市"
|
||||
)
|
||||
|
||||
var (
|
||||
opTimeErrReg = regexp.MustCompile(`当前配送营业时间为:([\d:~,]*)`)
|
||||
)
|
||||
|
||||
type tEbaiStoreInfo struct {
|
||||
model.Store
|
||||
VendorStoreID string `orm:"column(vendor_store_id)"`
|
||||
@@ -186,10 +193,58 @@ func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, storeID int,
|
||||
return err
|
||||
}
|
||||
|
||||
func errOpStr2Int16(str string) []int16 {
|
||||
list := strings.Split(str, "~")
|
||||
if len(list) >= 2 {
|
||||
return []int16{jxutils.StrTime2JxOperationTime(list[0]+":00", 0), jxutils.StrTime2JxOperationTime(list[1]+":00", 2359)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getOpTimeListFromErr(err error) (opTimeList []int16) {
|
||||
if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == mtwmapi.ErrCodeOpFailed {
|
||||
if result := opTimeErrReg.FindStringSubmatch(errExt.ErrMsg()); len(result) >= 2 {
|
||||
timeStrList := strings.Split(result[1], ",")
|
||||
for _, v := range timeStrList {
|
||||
v = utils.TrimBlankChar(v)
|
||||
if len(v) == len("00:00~02:00") {
|
||||
opTimeList = append(opTimeList, errOpStr2Int16(v)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return opTimeList
|
||||
}
|
||||
|
||||
// 此函数只是简单实现,不支持区间切分,只做单一区间限制
|
||||
func constrainOpTimeList(opTimeList, validOpTimeList []int16) (newOpTimeList []int16) {
|
||||
for k := 0; k < len(opTimeList); k += 2 {
|
||||
beginTime := opTimeList[k]
|
||||
endTime := opTimeList[k+1]
|
||||
for k2 := 0; k2 < len(validOpTimeList); k2 += 2 {
|
||||
beginTime2 := validOpTimeList[k2]
|
||||
endTime2 := validOpTimeList[k2+1]
|
||||
if beginTime >= beginTime2 && beginTime <= endTime2 {
|
||||
newOpTimeList = append(newOpTimeList, beginTime)
|
||||
newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2))))
|
||||
} else if beginTime2 >= beginTime && beginTime2 <= endTime {
|
||||
newOpTimeList = append(newOpTimeList, beginTime2)
|
||||
newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2))))
|
||||
}
|
||||
}
|
||||
}
|
||||
return newOpTimeList
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, storeID int, vendorStoreID string, opTimeList []int16) (err error) {
|
||||
shippingTime := openTimeJX2Mtwm(opTimeList)
|
||||
if globals.EnableMtwmStoreWrite {
|
||||
err = api.MtwmAPI.PoiShipTimeUpdate(vendorStoreID, shippingTime)
|
||||
if err != nil {
|
||||
if validOpTimeList := getOpTimeListFromErr(err); len(validOpTimeList) > 0 {
|
||||
err = api.MtwmAPI.PoiShipTimeUpdate(vendorStoreID, openTimeJX2Mtwm(constrainOpTimeList(opTimeList, validOpTimeList)))
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func TestReadStore(t *testing.T) {
|
||||
store, err := new(PurchaseHandler).ReadStore(jxcontext.AdminCtx, "4351018")
|
||||
store, err := curPurchaseHandler.ReadStore(jxcontext.AdminCtx, "4351018")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -18,8 +18,21 @@ func TestReadStore(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUpdateStore(t *testing.T) {
|
||||
err := new(PurchaseHandler).UpdateStore(nil, 100002, "test")
|
||||
err := curPurchaseHandler.UpdateStore(nil, 100002, "test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConstrainOpTimeList(t *testing.T) {
|
||||
timeList := constrainOpTimeList([]int16{830, 1800}, []int16{
|
||||
0,
|
||||
200,
|
||||
930,
|
||||
1700,
|
||||
})
|
||||
t.Log(utils.Format4Output(timeList, false))
|
||||
if timeList[0] != 930 || timeList[1] != 1700 {
|
||||
t.Fatal("constrainOpTimeList failed")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user