- make defsch.time2Schedule3rdCarrier configable.
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
||||
_ "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" // 导入缺省订单调度器
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
|
||||
@@ -4,12 +4,14 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/basesch"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/configindb"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
@@ -22,7 +24,7 @@ import (
|
||||
|
||||
const (
|
||||
time2Delivered = 1 * time.Hour // 正常从下单到送达的时间。
|
||||
time2Schedule3rdCarrier = 20 * time.Minute // 京东要求5分钟后才能转自送,保险起见,设置为5分半钟
|
||||
time2Schedule3rdCarrier = 20 // 京东要求5分钟后才能转自送,保险起见,设置为5分半钟
|
||||
// time2Schedule3rdCarrierGap4OrderStatus = 3 * time.Minute // 京东要求是运单状态为待抢单且超时5分钟,但为了防止没有运单事件,所以就拣货完成事件开始算,添加3分钟
|
||||
time2AutoPickupMin = 15 * time.Minute
|
||||
time2AutoPickupGap = 5 * 60 //随机5分钟
|
||||
@@ -35,6 +37,8 @@ const (
|
||||
maxWaybillRetryCount = 3
|
||||
|
||||
orderMapStoreMaxTime = 4 * 24 * time.Hour // cache最长存储时间
|
||||
|
||||
time2Schedule3rdCarrierKey = "waitminute4mt"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -73,6 +77,7 @@ type StatusActionConfig struct {
|
||||
// 重要:此调度器要求同一定单的处理逻辑必须是序列化了的,不然会有并发问题
|
||||
type DefScheduler struct {
|
||||
basesch.BaseScheduler
|
||||
locker sync.RWMutex
|
||||
defWorkflowConfig []map[int]*StatusActionConfig
|
||||
orderMap jxutils.SyncMapWithTimeout
|
||||
}
|
||||
@@ -237,7 +242,7 @@ func init() {
|
||||
map[int]*StatusActionConfig{
|
||||
model.WaybillStatusNew: &StatusActionConfig{
|
||||
TimerType: scheduler.TimerTypeBaseStatusTime,
|
||||
Timeout: time2Schedule3rdCarrier,
|
||||
Timeout: time2Schedule3rdCarrier * time.Minute,
|
||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo) (err error) {
|
||||
if savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore { // 非自配置商家使用
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||
@@ -249,6 +254,15 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func Init() {
|
||||
configindb.WatchConfigChange(time2Schedule3rdCarrierKey, OnDefSchConfChanged)
|
||||
if configTime, err := configindb.GetConfig(time2Schedule3rdCarrierKey, utils.Int2Str(time2Schedule3rdCarrier)); err == nil {
|
||||
OnDefSchConfChanged(time2Schedule3rdCarrierKey, configTime)
|
||||
} else {
|
||||
globals.SugarLogger.Errorf("defsch Init, error:%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 以下是订单
|
||||
func (s *DefScheduler) OnOrderNew(order *model.GoodsOrder, isPending bool) (err error) {
|
||||
globals.SugarLogger.Debugf("OnOrderNew orderID:%s", order.VendorOrderID)
|
||||
@@ -752,6 +766,10 @@ func (s *DefScheduler) handleAutoAcceptOrder(orderID string, vendorID int, userM
|
||||
|
||||
func (s *DefScheduler) mergeOrderStatusConfig(statusType, status int, purchaseVendorID int) (retVal *StatusActionConfig) {
|
||||
vendorTimeout := partner.GetPurchasePlatformFromVendorID(purchaseVendorID).GetStatusActionTimeout(statusType, status)
|
||||
s.locker.RLock()
|
||||
defer func() {
|
||||
s.locker.RUnlock()
|
||||
}()
|
||||
defConfig := s.defWorkflowConfig[statusType][status]
|
||||
if defConfig == nil {
|
||||
return nil
|
||||
@@ -809,3 +827,18 @@ func (s *DefScheduler) ProxyCancelWaybill(order *model.GoodsOrder, bill *model.W
|
||||
globals.SugarLogger.Debugf("ProxyCancelWaybill orderID:%s stop schedule, bypass CancelWaybill", order.VendorOrderID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func OnDefSchConfChanged(key, value string) {
|
||||
if key == time2Schedule3rdCarrierKey {
|
||||
waitMinutes := int(utils.Str2Int64WithDefault(value, time2Schedule3rdCarrier))
|
||||
if waitMinutes >= 0 {
|
||||
FixedScheduler.locker.Lock()
|
||||
defer func() {
|
||||
FixedScheduler.locker.Unlock()
|
||||
}()
|
||||
conf := FixedScheduler.defWorkflowConfig[1][model.WaybillStatusNew]
|
||||
conf.Timeout = time.Duration(waitMinutes) * time.Minute
|
||||
globals.SugarLogger.Debugf("defsch wait miniutes 4 3rd delivery changed to:%d", waitMinutes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
82
business/jxutils/configindb/configindb.go
Normal file
82
business/jxutils/configindb/configindb.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package configindb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
"git.rosy.net.cn/jx-callback/business/model/legacymodel"
|
||||
)
|
||||
|
||||
type ConfigNotifier func(key, value string)
|
||||
|
||||
var (
|
||||
legalUsers = map[string]int{
|
||||
"zhaominfu": 1,
|
||||
"shifeng@2018": 1,
|
||||
"zhouyang_2018": 1,
|
||||
"xujianhua": 1,
|
||||
}
|
||||
configNotifierMap = sync.Map{}
|
||||
)
|
||||
|
||||
func ListConfig(key string) (configList []*legacymodel.Config, err error) {
|
||||
sql := `
|
||||
SELECT *
|
||||
FROM config
|
||||
`
|
||||
sqlParams := []interface{}{}
|
||||
if key != "" {
|
||||
sql += " WHERE thirdparty = ?"
|
||||
sqlParams = append(sqlParams, key)
|
||||
}
|
||||
db := dao.GetDB()
|
||||
if err = dao.GetRows(db, &configList, sql, sqlParams...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return configList, nil
|
||||
}
|
||||
|
||||
func GetConfig(key, defValue string) (value string, err error) {
|
||||
configList, err := ListConfig(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(configList) == 0 {
|
||||
return defValue, nil
|
||||
}
|
||||
return configList[0].Token, nil
|
||||
}
|
||||
|
||||
func SetConfig(ctx *jxcontext.Context, key, value string) (num int64, err error) {
|
||||
userName := ctx.GetUserName()
|
||||
if legalUsers[userName] != 1 {
|
||||
return 0, fmt.Errorf("%s不具有此功能操作权限", userName)
|
||||
}
|
||||
sql := `
|
||||
UPDATE config
|
||||
SET token = ?,
|
||||
date = NOW(),
|
||||
last_operator = ?
|
||||
WHERE thirdparty = ?
|
||||
`
|
||||
db := dao.GetDB()
|
||||
num, err = dao.ExecuteSQL(db, sql, value, userName, key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if num == 0 {
|
||||
return 0, fmt.Errorf("没有%s这个配置项", key)
|
||||
}
|
||||
if v, ok := configNotifierMap.Load(key); ok {
|
||||
if notifier, ok := v.(ConfigNotifier); ok {
|
||||
notifier(key, value)
|
||||
}
|
||||
}
|
||||
return num, nil
|
||||
}
|
||||
|
||||
func WatchConfigChange(key string, configNotifier ConfigNotifier) {
|
||||
configNotifierMap.Store(key, configNotifier)
|
||||
}
|
||||
@@ -2,7 +2,8 @@ package legacymodel
|
||||
|
||||
type Config struct {
|
||||
Id int
|
||||
Thirdparty string `orm:"size(20);unique"`
|
||||
Token string `orm:"size(300)"`
|
||||
Date string `orm:"size(30)"`
|
||||
Thirdparty string `orm:"size(20);unique" json:"key"`
|
||||
Token string `orm:"size(300)" json:"value"`
|
||||
Date string `orm:"size(30)" json:"date"`
|
||||
LastOperator string `orm:"size(32)" json:"lastOperator"` // 最后操作员
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package controllers
|
||||
import (
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/configindb"
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
@@ -103,3 +104,32 @@ func (c *CmsController) GetCoordinateDistrictCode() {
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 得到配置参数
|
||||
// @Description 得到配置参数
|
||||
// @Param token header string true "认证token"
|
||||
// @Param key query string true "参数名"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetConfig [get]
|
||||
func (c *CmsController) GetConfig() {
|
||||
c.callGetConfig(func(params *tCmsGetConfigParams) (retVal interface{}, errCode string, err error) {
|
||||
retVal, err = configindb.GetConfig(params.Key, "")
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 设置配置参数
|
||||
// @Description 设置配置参数
|
||||
// @Param token header string true "认证token"
|
||||
// @Param key query string true "参数名"
|
||||
// @Param value query string true "参数值"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /SetConfig [put]
|
||||
func (c *CmsController) SetConfig() {
|
||||
c.callSetConfig(func(params *tCmsSetConfigParams) (retVal interface{}, errCode string, err error) {
|
||||
retVal, err = configindb.SetConfig(params.Ctx, params.Key, params.Value)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
2
main.go
2
main.go
@@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" // 导入缺省订单调度器
|
||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
||||
"git.rosy.net.cn/jx-callback/business/jxstore/promotion"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasks"
|
||||
@@ -28,6 +29,7 @@ var (
|
||||
func Init() {
|
||||
// globals.Init()
|
||||
beegodb.Init()
|
||||
defsch.Init()
|
||||
api.Init()
|
||||
cms.InitServiceInfo(Version, BuildDate, GitCommit)
|
||||
if globals.EnableStore {
|
||||
|
||||
@@ -55,6 +55,14 @@ func init() {
|
||||
MethodParams: param.Make(),
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
|
||||
beego.ControllerComments{
|
||||
Method: "GetConfig",
|
||||
Router: `/GetConfig`,
|
||||
AllowHTTPMethods: []string{"get"},
|
||||
MethodParams: param.Make(),
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
|
||||
beego.ControllerComments{
|
||||
Method: "GetCoordinateDistrictCode",
|
||||
@@ -87,6 +95,14 @@ func init() {
|
||||
MethodParams: param.Make(),
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
|
||||
beego.ControllerComments{
|
||||
Method: "SetConfig",
|
||||
Router: `/SetConfig`,
|
||||
AllowHTTPMethods: []string{"put"},
|
||||
MethodParams: param.Make(),
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"],
|
||||
beego.ControllerComments{
|
||||
Method: "UpdatePlace",
|
||||
|
||||
Reference in New Issue
Block a user