Merge remote-tracking branch 'origin/mark' into don

This commit is contained in:
Rosy-zhudan
2019-08-02 15:36:57 +08:00
9 changed files with 183 additions and 66 deletions

View File

@@ -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)
}
}
}

View File

@@ -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()

View File

@@ -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

View File

@@ -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"`

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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")
}
}