Merge branch 'mark'

This commit is contained in:
gazebo
2019-11-14 11:23:36 +08:00
71 changed files with 1711 additions and 932 deletions

View File

@@ -52,6 +52,7 @@ type IUser interface {
GetMobile() string
GetEmail() string
GetName() string
GetAvatar() string
}
const (

View File

@@ -18,6 +18,7 @@ type UserBasic struct {
Mobile string `json:"mobile"`
Email string `json:"email"`
Name string `json:"name"`
Avatar string `json:"avatar"`
}
func (u *UserBasic) GetID() string {
@@ -39,6 +40,10 @@ func (u *UserBasic) GetName() string {
return u.Name
}
func (u *UserBasic) GetAvatar() string {
return u.Avatar
}
func (u *UserBasic) UpdateByIUser(user IUser) {
if user != nil {
u.UserID = user.GetID()
@@ -46,6 +51,7 @@ func (u *UserBasic) UpdateByIUser(user IUser) {
u.Mobile = user.GetMobile()
u.Email = user.GetEmail()
u.Name = user.GetName()
u.Avatar = user.GetAvatar()
}
}

View File

@@ -137,9 +137,11 @@ func (a *DefAuther) GenerateVerifyCode(keyID string) (verifyCode string) {
}
func (a *DefAuther) VerifyCode(keyID, verifyCode string) (isSame bool) {
savedVerifyCode := a.LoadVerifyCode(keyID)
if isSame = (verifyCode != "" && savedVerifyCode != "" && verifyCode == savedVerifyCode); isSame {
a.DeleteVerifyCode(keyID)
if keyID != "" {
savedVerifyCode := a.LoadVerifyCode(keyID)
if isSame = (verifyCode != "" && savedVerifyCode != "" && verifyCode == savedVerifyCode); isSame {
a.DeleteVerifyCode(keyID)
}
}
return isSame
}

View File

@@ -52,7 +52,8 @@ func (a *Auther) VerifySecret(state, code string) (authBindEx *auth2.AuthBindEx,
if err = err2; err == nil {
if authBindEx, err = a.UnionFindAuthBind(a.authType, []string{AuthTypeWeixin, AuthTypeMP, AuthTypeMini}, wxUserinfo.OpenID, wxUserinfo.UnionID, wxUserinfo); err == nil {
authBindEx.UserHint = &auth2.UserBasic{
Name: wxUserinfo.NickName,
Name: wxUserinfo.NickName,
Avatar: wxUserinfo.HeadImgURL,
}
}
}

View File

@@ -1,8 +1,8 @@
package weixin
import (
"encoding/base64"
"errors"
"fmt"
"strings"
"git.rosy.net.cn/baseapi/platformapi/weixinapi"
@@ -45,17 +45,34 @@ func (a *MiniAuther) VerifySecret(dummy, jsCode string) (authBindEx *auth2.AuthB
}
// 特殊接口
func (a *MiniAuther) DecryptData(authInfo *auth2.AuthInfo, encryptedData, iv string) (decryptedDataBase64 string, err error) {
globals.SugarLogger.Debugf("weixin mini DecryptData encryptedData:%s, iv:%s", encryptedData, iv)
if authInfo.AuthBindInfo.Type != AuthTypeMini {
return "", ErrAuthTypeShouldBeMini
func (a *MiniAuther) 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
if jsCode != "" {
sessionInfo, err := ProxySNSCode2Session(jsCode)
if err == nil {
if authBindEx, err := a.UnionFindAuthBind(AuthTypeMini, []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 != AuthTypeMini {
return "", ErrAuthTypeShouldBeMini
}
sessionKey = authInfo.AuthBindInfo.UserData.(string)
}
sessionKey := authInfo.AuthBindInfo.UserData.(string)
decryptedData, err := ProxySNSDecodeMiniProgramData(encryptedData, sessionKey, iv)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(decryptedData), nil
return string(decryptedData), nil
}
func (a *MiniAuther) GetUserType() (userType int8) {
@@ -76,6 +93,7 @@ func ProxySNSCode2Session(jsCode string) (sessionInfo *weixinapi.SessionInfo, er
}
func ProxySNSDecodeMiniProgramData(encryptedData, sessionKey, iv string) (decryptedData []byte, err error) {
globals.SugarLogger.Debugf("ProxySNSDecodeMiniProgramData, encryptedData:%s, sessionKey:%s, iv:%s", encryptedData, sessionKey, iv)
decryptedData, err = api.WeixinMiniAPI.SNSDecodeMiniProgramData(encryptedData, sessionKey, iv)
return decryptedData, err
}

View File

@@ -46,6 +46,7 @@ func onOrderMsg(msg *weimobapi.CallbackMsg) (response *weimobapi.CallbackRespons
func changeStoreSkusByOrder(order *weimobapi.OrderDetail) {
globals.SugarLogger.Debugf("changeStoreSkusByOrder order:%s", utils.Format4Output(order, true))
receiverMobile := order.DeliveryDetail.LogisticsDeliveryDetail.ReceiverMobile
ctx := jxcontext.NewWithUserName(nil, utils.LimitStringLen(utils.Int64ToStr(order.OrderNo), 32), nil, nil)
if storeList, err := GetStoreList4Mobile(dao.GetDB(), []string{receiverMobile}); err == nil {
if len(storeList) >= 1 {
var skuBindInfos []*cms.StoreSkuBindInfo
@@ -63,19 +64,41 @@ func changeStoreSkusByOrder(order *weimobapi.OrderDetail) {
IsSale: 1,
})
} else {
globals.SugarLogger.Infof("[运营],微商城订单:%s,商品:%s没有设置正确的SkuName编码或单价当前商家编码:%s市场价:%s", order.OrderNo, v.SkuNum, v.SkuCode, jxutils.IntPrice2StandardString(jxutils.StandardPrice2Int(unitPrice)))
globals.SugarLogger.Infof("[运营],微商城订单:%d,商品:%s没有设置正确的SkuName编码或单价当前商家编码:%s市场价:%s", order.OrderNo, v.SkuNum, v.SkuCode, jxutils.IntPrice2StandardString(jxutils.StandardPrice2Int(unitPrice)))
}
}
if len(skuBindInfos) > 0 {
cms.UpdateStoreSkus(jxcontext.NewWithUserName(nil, utils.LimitStringLen(utils.Int64ToStr(order.OrderNo), 32), nil, nil), storeID, skuBindInfos, true, true)
var nameIDs []int
for _, v := range skuBindInfos {
nameIDs = append(nameIDs, v.NameID)
}
if skuNamesInfo, err := cms.GetSkuNames(ctx, "", false, map[string]interface{}{
"nameIDs": nameIDs,
}, 0, 0); err == nil {
for _, skuName := range skuNamesInfo.SkuNames {
if skuName.Status != model.SkuStatusNormal {
cms.UpdateSkuName(ctx, skuName.ID, map[string]interface{}{
"status": model.SkuStatusNormal,
})
}
for _, sku := range skuName.Skus {
if sku.Status != model.SkuStatusNormal {
cms.UpdateSku(ctx, sku.ID, map[string]interface{}{
"status": model.SkuStatusNormal,
})
}
}
}
}
cms.UpdateStoreSkus(ctx, storeID, skuBindInfos, true, true)
} else {
globals.SugarLogger.Debugf("changeStoreSkusByOrder storeID:%d is empty", storeID)
globals.SugarLogger.Debugf("changeStoreSkusByOrder orderID:%d, storeID:%d is empty", order.OrderNo, storeID)
}
} else {
globals.SugarLogger.Infof("[运营],微商城订单:%s,手机:%s找不到唯一一个京西门店%d", order.OrderNo, receiverMobile, len(storeList))
globals.SugarLogger.Infof("[运营],微商城订单:%d,手机:%s找不到唯一一个京西门店%d", order.OrderNo, receiverMobile, len(storeList))
}
} else {
globals.SugarLogger.Warnf("changeStoreSkusByOrder receiverMobile:%s failed with err:%v", receiverMobile, err)
globals.SugarLogger.Warnf("changeStoreSkusByOrder orderNo:%d, receiverMobile:%s failed with err:%v", order.OrderNo, receiverMobile, err)
}
}

View File

@@ -1,14 +1,19 @@
package orderman
import (
"errors"
"fmt"
"math"
"strings"
"time"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
"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"
@@ -257,7 +262,7 @@ func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao
order.VendorStatus = orderStatus.VendorStatus
order.StatusTime = orderStatus.StatusTime
jxutils.RefreshOrderSkuRelated(order)
// jxutils.RefreshOrderSkuRelated(order)
}
}
}
@@ -344,7 +349,6 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
skumapper[v.VendorSkuID] = v
}
skuIDMap := make(map[int]int)
for _, v := range orderSkus {
v.VendorOrderID = order.VendorOrderID
v.VendorID = order.VendorID
@@ -364,33 +368,36 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
}
}
v.EarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, v.SalePrice, storePayPercentage)
if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 {
skuIDMap[skuID] = 1
}
}
updateSingleOrderEarningPrice(order, db)
}
return nil
}
if len(skuIDMap) > 0 {
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order.OrderCreatedAt, order.OrderCreatedAt)
if err != nil {
globals.SugarLogger.Errorf("updateOrderSkuOtherInfo can not get sku promotion info for error:%v", err)
return err
}
if actStoreSkuMap := jxutils.NewActStoreSkuMap(actStoreSkuList, false); actStoreSkuMap != nil {
for _, v := range orderSkus {
if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 {
if actStoreSku := actStoreSkuMap.GetActStoreSku(jxStoreID, skuID, order.VendorID); actStoreSku != nil {
v.EarningPrice = actStoreSku.EarningPrice
if true { //v.StoreSubName != "" { // 之前这里为什么要加判断?
v.StoreSubID = actStoreSku.ActID
}
func updateSingleOrderEarningPrice(order *model.GoodsOrder, db *dao.DaoDB) {
jxStoreID := jxutils.GetShowStoreIDFromOrder(order)
skuIDMap := make(map[int]int)
for _, v := range order.Skus {
skuIDMap[v.SkuID] = 1
}
if len(skuIDMap) > 0 {
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order.OrderCreatedAt, order.OrderCreatedAt)
if err != nil {
globals.SugarLogger.Errorf("updateOrderSkuOtherInfo can not get sku promotion info for error:%v", err)
}
if actStoreSkuMap := jxutils.NewActStoreSkuMap(actStoreSkuList, false); actStoreSkuMap != nil {
for _, v := range order.Skus {
if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 {
if actStoreSku := actStoreSkuMap.GetActStoreSku(jxStoreID, skuID, order.VendorID); actStoreSku != nil {
v.EarningPrice = actStoreSku.EarningPrice
if true { //v.StoreSubName != "" { // 之前这里为什么要加判断?
v.StoreSubID = actStoreSku.ActID
}
}
}
}
}
}
return nil
}
func (c *OrderManager) updateOrderOtherInfo(order *model.GoodsOrder, db *dao.DaoDB) (err error) {
@@ -413,22 +420,22 @@ func (c *OrderManager) updateOrderOtherInfo(order *model.GoodsOrder, db *dao.Dao
}
if err = c.updateOrderSkuOtherInfo(order, db, payPercentage); err == nil {
jxutils.RefreshOrderSkuRelated(order)
caculateOrderEarningPrice(order, payPercentage)
// caculateOrderEarningPrice(order, payPercentage)
}
return err
}
// 计算结算给门店的金额
func caculateOrderEarningPrice(order *model.GoodsOrder, storePayPercentage int) {
order.EarningPrice = 0
for _, v := range order.Skus {
skuEarningPrice := v.EarningPrice
if skuEarningPrice == 0 {
skuEarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, v.SalePrice, storePayPercentage)
}
order.EarningPrice += skuEarningPrice * int64(v.Count)
}
}
// func caculateOrderEarningPrice(order *model.GoodsOrder, storePayPercentage int) {
// order.EarningPrice = 0
// for _, v := range order.Skus {
// skuEarningPrice := v.EarningPrice
// if skuEarningPrice == 0 {
// skuEarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, v.SalePrice, storePayPercentage)
// }
// order.EarningPrice += skuEarningPrice * int64(v.Count)
// }
// }
func (c *OrderManager) addOrderStatus(orderStatus *model.OrderStatus, db *dao.DaoDB) (isDuplicated bool, order *model.GoodsOrder, err error) {
globals.SugarLogger.Debugf("addOrderStatus refOrderID:%s, orderID:%s", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID)
@@ -605,3 +612,107 @@ func (c *OrderManager) UpdateOrderFields(order *model.GoodsOrder, fieldList []st
}, "UpdateOrderFields orderID:%s failed with error:%v", order.VendorOrderID, err)
return err
}
func (c *OrderManager) RefreshHistoryOrdersEarningPrice(ctx *jxcontext.Context, vendorOrderID string, actID int, vendorIDs []int, storeID int, fromDate, toDate string, isAsync, isContinueWhenError bool) (hint string, err error) {
var (
orderList []*model.GoodsOrder
fromDateParam time.Time
toDateParam time.Time
beginAt time.Time
endAt time.Time
)
db := dao.GetDB()
if actID > 0 {
if fromDate != "" && toDate != "" {
fromDateParam = utils.Str2Time(fromDate)
toDateParam = utils.Str2Time(toDate)
actList, _ := dao.QueryActs(db, actID, 0, math.MaxInt32, 0, "", -1, nil, nil, nil, 0, 0, 0, time.Time{}, time.Time{}, time.Time{}, time.Time{})
if len(actList.Data) > 0 {
actBeginAt := actList.Data[0].BeginAt
actEndAt := actList.Data[0].EndAt
if fromDateParam.Sub(actBeginAt) > 0 && fromDateParam.Sub(actEndAt) > 0 {
return "", errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 [%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam))
}
if actBeginAt.Sub(toDateParam) > 0 && actEndAt.Sub(toDateParam) > 0 {
return "", errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 [%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam))
}
if fromDateParam.Sub(actBeginAt) > 0 {
beginAt = fromDateParam
if toDateParam.Sub(actEndAt) > 0 {
endAt = actEndAt
} else {
endAt = toDateParam
}
} else {
beginAt = actBeginAt
if toDateParam.Sub(actEndAt) > 0 {
endAt = actEndAt
} else {
endAt = toDateParam
}
}
orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, beginAt, endAt)
} else {
return "", errors.New(fmt.Sprintf("未查询到相关结算活动活动ID[%d]", actID))
}
} else if fromDate == "" && toDate == "" {
actList, _ := dao.QueryActs(db, actID, 0, math.MaxInt32, 0, "", -1, nil, nil, nil, 0, 0, 0, time.Time{}, time.Time{}, time.Time{}, time.Time{})
if len(actList.Data) > 0 {
orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, actList.Data[0].BeginAt, actList.Data[0].EndAt)
} else {
return "", errors.New(fmt.Sprintf("未查询到相关结算活动活动ID[%d]", actID))
}
} else {
return "", errors.New(fmt.Sprintf("间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate))
}
} else {
if fromDate != "" && toDate != "" {
fromDateParam = utils.Str2Time(fromDate)
toDateParam = utils.Str2Time(toDate)
//若未传入活动ID,且时间间隔大于10天则不允许查询
if math.Ceil(toDateParam.Sub(fromDateParam).Hours()/24) > 10 {
return "", errors.New(fmt.Sprintf("查询间隔时间不允许大于10天时间范围[%v] 至 [%v]", fromDate, toDate))
}
orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, fromDateParam, toDateParam)
} else {
return "", errors.New(fmt.Sprintf("若不按活动查询则间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate))
}
}
if len(orderList) <= 0 {
return "", errors.New(fmt.Sprintf("未查询到订单!,vendorOrderID : %s, actID : %d, 时间范围:[%v] 至 [%v]", vendorOrderID, actID, fromDate, toDate))
}
task := tasksch.NewParallelTask("刷新历史订单结算价", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
order := batchItemList[0].(*model.GoodsOrder)
db := dao.GetDB()
updateSingleOrderEarningPrice(order, db)
dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db)
if r != nil {
panic(r)
}
}
}()
for _, value := range order.Skus {
if _, err = dao.UpdateEntity(db, value, "EarningPrice", "StoreSubID"); err != nil {
return "", err
}
}
jxutils.RefreshOrderSkuRelated(order)
if _, err = dao.UpdateEntity(db, order, "EarningPrice"); err != nil {
return "", err
}
dao.Commit(db)
return retVal, err
}, orderList)
tasksch.HandleTask(task, nil, true).Run()
if !isAsync {
_, err = task.GetResult(0)
hint = "1"
} else {
hint = task.GetID()
}
return hint, err
}

View File

@@ -83,7 +83,7 @@ func (c *OrderManager) OnOrderComments(orderCommentList []*model.OrderComment) (
if dao.IsNoRowsError(err) {
err = nil
isNewComment = true
if orderComment.IsReplied == 0 && time.Now().Sub(orderComment.CommentCreatedAt) < MAX_REAPLY_TIME {
if orderComment.IsReplied == 0 && time.Now().Sub(orderComment.CommentCreatedAt) < time.Duration(orderComment.ModifyDuration)*time.Hour {
c.replyOrderComment(orderComment)
}
}
@@ -107,6 +107,10 @@ func (c *OrderManager) OnOrderComments(orderCommentList []*model.OrderComment) (
} else {
orderComment.ConsigneeMobile = order.ConsigneeMobile
}
} else {
if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, orderComment.VendorStoreID, orderComment.VendorID); err == nil {
orderComment.StoreID = storeDetail.ID
}
}
if orderComment.StoreID > 0 {
comment2.Jxstoreid = utils.Int2Str(orderComment.StoreID)

View File

@@ -1169,7 +1169,7 @@ func (c *OrderManager) AmendMissingOrders(ctx *jxcontext.Context, vendorIDs []in
if err = err2; err != nil && !isContinueWhenError {
return "", err
}
localOrders, err2 := dao.QueryOrders(db, vendorIDs, storeID, fromDate, toDate.Add(24*time.Hour-time.Second))
localOrders, err2 := dao.QueryOrders(db, "", 0, vendorIDs, storeID, fromDate, toDate.Add(24*time.Hour-time.Second))
if err = err2; err != nil {
return "", err
}

View File

@@ -4,14 +4,12 @@ import (
"fmt"
"git.rosy.net.cn/baseapi/utils/errlist"
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
"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/purchase/jd"
"git.rosy.net.cn/jx-callback/business/partner/purchase/jx"
"git.rosy.net.cn/jx-callback/globals"
)
@@ -30,18 +28,16 @@ func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order *
(excludeCourierVendorIDs == nil || excludeCourierVendorIDMap[storeCourier.VendorID] == 0) {
if handler := partner.GetDeliveryPlatformFromVendorID(storeCourier.VendorID); handler != nil && handler.Use4CreateWaybill {
courierVendorID := storeCourier.VendorID
if order.VendorID != model.VendorIDWSC || courierVendorID != model.VendorIDDada { // 达达作为微商城的自有配送,不参与配送竞争
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)
bills = append(bills, bill)
if createOnlyOne {
break
}
} else {
globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d failed with error:%v", order.VendorOrderID, userName, courierVendorID, err)
errList.AddErr(fmt.Errorf("平台:%s,%s", jxutils.GetVendorName(courierVendorID), err.Error()))
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)
bills = append(bills, bill)
if createOnlyOne {
break
}
} else {
globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d failed with error:%v", order.VendorOrderID, userName, courierVendorID, err)
errList.AddErr(fmt.Errorf("平台:%s,%s", jxutils.GetVendorName(courierVendorID), err.Error()))
}
}
}
@@ -67,9 +63,9 @@ func (c *BaseScheduler) SelfDeliveredAndUpdateStatus(ctx *jxcontext.Context, ven
globals.SugarLogger.Infof("SelfDeliveredAndUpdateStatus orderID:%s userName:%s", vendorOrderID, userName)
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
if err == nil {
if c.GetStoreDeliveryType(order, nil) == scheduler.StoreDeliveryTypeByStore {
if model.IsOrderDeliveryByStore(order) {
err = c.SelfDeliverDelivered(order, userName)
} else {
} else if model.IsOrderDeliveryByPlatform(order) {
err = c.Swtich2SelfDelivered(order, userName)
}
if err == nil {
@@ -93,7 +89,7 @@ func (c *BaseScheduler) PickupGoodsAndUpdateStatus(ctx *jxcontext.Context, vendo
globals.SugarLogger.Infof("PickupGoodsAndUpdateStatus orderID:%s userName:%s", vendorOrderID, userName)
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
if err == nil {
err = c.PickupGoods(order, c.GetStoreDeliveryType(order, nil) == scheduler.StoreDeliveryTypeByStore, userName)
err = c.PickupGoods(order, model.IsOrderDeliveryByStore(order), userName)
if err == nil {
order.Status = model.OrderStatusFinishedPickup
if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err == nil {
@@ -109,27 +105,6 @@ func (c *BaseScheduler) PickupGoodsAndUpdateStatus(ctx *jxcontext.Context, vendo
return err
}
func (c *BaseScheduler) GetStoreDeliveryType(order *model.GoodsOrder, storeMap *model.StoreMap) (deliveryType int) {
globals.SugarLogger.Debugf("GetStoreDeliveryType orderID:%s", order.VendorOrderID)
jxStoreID := jxutils.GetSaleStoreIDFromOrder(order)
if storeMap == nil {
storeMap, _ = dao.FakeGetStoreMapByStoreID(nil, jxStoreID, order.VendorID)
}
deliveryType = scheduler.StoreDeliveryTypeByPlatform // 缺省值
if storeMap != nil {
deliveryType = int(storeMap.DeliveryType)
// 微盟订单,要确认有绑达达,才能是非自送的
if order.VendorID == model.VendorIDWSC && deliveryType != scheduler.StoreDeliveryTypeByStore {
if courierMapList, _ := dao.GetOpenedStoreCouriersByStoreID(nil, jxStoreID, model.VendorIDDada); len(courierMapList) == 0 {
deliveryType = scheduler.StoreDeliveryTypeByStore
}
}
}
globals.SugarLogger.Debugf("GetStoreDeliveryType orderID:%s, deliveryType:%d", order.VendorOrderID, deliveryType)
return deliveryType
}
func (c *BaseScheduler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
if c.IsReallyCallPlatformAPI {
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).AdjustOrder(ctx, order, removedSkuList, reason)
@@ -257,8 +232,6 @@ func (c *BaseScheduler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID st
}
}
err = jd.CurPurchaseHandler.ConfirmSelfTake(ctx, vendorOrderID, selfTakeCode)
} else if vendorID == model.VendorIDJX {
err = jx.CurPurchaseHandler.ConfirmSelfTake(ctx, vendorOrderID, selfTakeCode)
} else {
err = fmt.Errorf("自提核销不支持%s平台订单", model.VendorChineseNames[vendorID])
}

View File

@@ -67,7 +67,6 @@ type WatchOrderInfo struct {
order *model.GoodsOrder // order里的信息是保持更新的
autoPickupTimeoutMinute int // 0表示禁用1表示用缺省值time2AutoPickupMin其它表示分钟数
storeDeliveryType int
isDeliveryCompetition bool
isNeedCreate3rdWaybill bool
@@ -107,7 +106,6 @@ type DefScheduler struct {
func NewWatchOrderInfo(order *model.GoodsOrder) (retVal *WatchOrderInfo) {
retVal = &WatchOrderInfo{
autoPickupTimeoutMinute: 1,
storeDeliveryType: scheduler.StoreDeliveryTypeCrowdSourcing,
waybills: map[int]*model.Waybill{},
}
retVal.SetOrder(order)
@@ -130,14 +128,12 @@ func (s *WatchOrderInfo) updateOrderStoreFeature(order *model.GoodsOrder) (err e
jxStoreID := jxutils.GetSaleStoreIDFromOrder(order)
if jxStoreID > 0 {
db := dao.GetDB()
storeMap, err2 := dao.FakeGetStoreMapByStoreID(db, jxStoreID, order.VendorID)
storeDetail, err2 := dao.GetStoreDetail(db, jxStoreID, order.VendorID)
if err = err2; err != nil {
return err
}
s.autoPickupTimeoutMinute = int(storeMap.AutoPickup)
s.storeDeliveryType = FixedScheduler.GetStoreDeliveryType(order, storeMap)
s.isDeliveryCompetition = storeMap.DeliveryCompetition != 0
globals.SugarLogger.Debugf("updateOrderStoreFeature orderID:%s, s.storeDeliveryType:%d", order.VendorOrderID, s.storeDeliveryType)
s.autoPickupTimeoutMinute = int(storeDetail.AutoPickup)
s.isDeliveryCompetition = storeDetail.DeliveryCompetition != 0
}
return err
}
@@ -229,7 +225,7 @@ func init() {
TimeoutGap: 0,
},
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore && savedOrderInfo.order.DeliveryType != model.OrderDeliveryTypeSelfTake { // 自配送商家使用
if model.IsOrderDeliveryByStore(savedOrderInfo.order) { // 自配送商家使用
// 启动抢单TIMER
sch.saveDeliveryFeeFromAndStartWatch(savedOrderInfo, savedOrderInfo.order.StatusTime)
return sch.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
@@ -237,7 +233,7 @@ func init() {
return nil
},
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
return savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore && savedOrderInfo.order.DeliveryType != model.OrderDeliveryTypeSelfTake
return model.IsOrderDeliveryByStore(savedOrderInfo.order)
},
},
},
@@ -251,7 +247,7 @@ func init() {
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
// 饿百转自送的时机不太清楚,暂时禁用超时转自送,在饿百运单取消时还是会自动创建
if savedOrderInfo.isDeliveryCompetition &&
savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore &&
model.IsOrderDeliveryByPlatform(savedOrderInfo.order) &&
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
savedOrderInfo.order.VendorID != model.VendorIDEBAI &&
savedOrderInfo.order.DeliveryType != model.OrderDeliveryTypeSelfTake { // 非自配送商家使用
@@ -261,7 +257,7 @@ func init() {
},
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
return savedOrderInfo.isDeliveryCompetition &&
savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore &&
model.IsOrderDeliveryByPlatform(savedOrderInfo.order) &&
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
savedOrderInfo.order.VendorID != model.VendorIDEBAI &&
savedOrderInfo.order.DeliveryType != model.OrderDeliveryTypeSelfTake
@@ -278,7 +274,7 @@ func init() {
if (order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) &&
savedOrderInfo.isDeliveryCompetition &&
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore &&
model.IsOrderDeliveryByPlatform(savedOrderInfo.order) &&
order.VendorID == model.VendorIDEBAI &&
savedOrderInfo.order.DeliveryType != model.OrderDeliveryTypeSelfTake { // 非自配送商家使用
return sch.createWaybillOn3rdProviders(savedOrderInfo, ebaiCancelWaybillMaxFee, nil)
@@ -290,7 +286,7 @@ func init() {
return (order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) &&
savedOrderInfo.isDeliveryCompetition &&
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore &&
model.IsOrderDeliveryByPlatform(savedOrderInfo.order) &&
order.VendorID == model.VendorIDEBAI &&
savedOrderInfo.order.DeliveryType != model.OrderDeliveryTypeSelfTake
},
@@ -471,14 +467,13 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
if model.IsWaybillPlatformOwn(bill) {
if bill.Status == model.WaybillStatusDelivering {
if bill.Status == model.WaybillStatusDelivering && order.Status < model.OrderStatusEndBegin {
// 强制将订单状态置为配送中?
order.Status = model.OrderStatusDelivering
partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
}
} else {
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore ||
model.IsSpecialOrderPlatformWaybill(bill) {
if model.IsOrderDeliveryByStore(savedOrderInfo.order) {
if err := s.SelfDeliverDelivering(savedOrderInfo.order, bill.CourierMobile); err != nil {
partner.CurOrderManager.OnOrderMsg(order, "自送出设置失败", err.Error())
}
@@ -495,9 +490,7 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
if isBillAlreadyCandidate && !s.isWaybillCourierSame(savedOrderInfo, bill) && !model.IsWaybillPlatformOwn(bill) {
s.notify3rdPartyWaybill(order, bill, isBillAlreadyCandidate)
}
flag2Clear := model.WaybillVendorID2Mask(bill.WaybillVendorID)
order.Flag &= ^model.OrderFlagMaskFailedGetGoods
order.DeliveryFlag &= ^flag2Clear
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
}
case model.WaybillStatusAcceptCanceled:
@@ -553,13 +546,11 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
if !isPending {
var err2 error
if !model.IsWaybillPlatformOwn(bill) {
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore {
if model.IsOrderDeliveryByStore(order) {
err2 = s.SelfDeliverDelivered(order, "")
} else {
} else if model.IsOrderDeliveryByPlatform(order) {
err2 = s.Swtich2SelfDelivered(order, "")
}
} else if model.IsSpecialOrderPlatformWaybill(bill) {
err2 = s.SelfDeliverDelivered(savedOrderInfo.order, "")
}
if err2 != nil {
partner.CurOrderManager.OnOrderMsg(order, "送达设置失败", err2.Error())
@@ -769,7 +760,7 @@ func (s *DefScheduler) resetTimer(savedOrderInfo *WatchOrderInfo, bill *model.Wa
statusTime = bill.StatusTime
}
globals.SugarLogger.Debugf("resetTimer, orderID:%s statusType:%d status:%d", order.VendorOrderID, statusType, status)
if isStatusNewer(savedOrderInfo.timerStatusType, savedOrderInfo.timerStatus, statusType, status) { // 新设置的TIMER不能覆盖状态在其后的TIMER如果状态回绕需要注意
if isStatusNewer(order.VendorID, savedOrderInfo.timerStatusType, savedOrderInfo.timerStatus, statusType, status) { // 新设置的TIMER不能覆盖状态在其后的TIMER如果状态回绕需要注意
config := s.mergeOrderStatusConfig(savedOrderInfo, statusTime, statusType, status)
if config == nil || config.TimerType != partner.TimerTypeByPass {
s.stopTimer(savedOrderInfo)
@@ -819,10 +810,13 @@ func (s *DefScheduler) resetTimer(savedOrderInfo *WatchOrderInfo, bill *model.Wa
}
}
func isStatusNewer(curStatusType, curStatus, statusType, status int) bool {
func isStatusNewer(vendorID int, curStatusType, curStatus, statusType, status int) bool {
// 拣货完成及之前的订单事件TIMER不能覆盖运单TIMER一般是消息错序引起的
if curStatusType == scheduler.TimerStatusTypeWaybill && statusType == scheduler.TimerStatusTypeOrder && status <= model.OrderStatusFinishedPickup {
return false
// 美团订单在接单后就会收到新运单事件因当前只支持一个TIMER暂时舍弃三方配送调度而要自动拣货调度
if vendorID != model.VendorIDMTWM {
if curStatusType == scheduler.TimerStatusTypeWaybill && statusType == scheduler.TimerStatusTypeOrder && status <= model.OrderStatusFinishedPickup {
return false
}
}
if curStatusType == scheduler.TimerStatusTypeWaybill {
return curStatus != status
@@ -990,8 +984,8 @@ func (s *DefScheduler) updateBillsInfo(savedOrderInfo *WatchOrderInfo, bill *mod
}
func (s *DefScheduler) autoPickupGood(savedOrderInfo *WatchOrderInfo) (err error) {
if err = s.PickupGoods(savedOrderInfo.order, savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore, ""); err == nil {
order := savedOrderInfo.order
order := savedOrderInfo.order
if err = s.PickupGoods(order, model.IsOrderDeliveryByStore(order), ""); err == nil {
order.DeliveryFlag |= model.OrderDeliveryFlagMaskAutoPickup
partner.CurOrderManager.UpdateOrderFields(order, []string{"DeliveryFlag"})
} else if err == scheduler.ErrOrderStatusAlreadySatisfyCurOperation {
@@ -1062,9 +1056,9 @@ func (s *DefScheduler) saveDeliveryFeeFromAndStartWatch(savedOrderInfo *WatchOrd
}
func (s *DefScheduler) watchOrderWaybills(savedOrderInfo *WatchOrderInfo) {
if savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore && savedOrderInfo.isDeliveryCompetition ||
savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore {
order2 := savedOrderInfo.order
order2 := savedOrderInfo.order
if model.IsOrderDeliveryByPlatform(order2) && savedOrderInfo.isDeliveryCompetition ||
model.IsOrderDeliveryByStore(order2) {
if order, err := partner.CurOrderManager.LoadOrder(order2.VendorOrderID, order2.VendorID); err == nil {
savedOrderInfo.SetOrder(order)
if isNeedWatch3rdWaybill(order) {

View File

@@ -33,7 +33,7 @@ func (s *DefScheduler) SelfDeliveringAndUpdateStatus(ctx *jxcontext.Context, ven
if err = s.isPossibleSwitch2SelfDelivery(order); err == nil {
err = s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, nil, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)
if err == nil {
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore {
if model.IsOrderDeliveryByStore(order) {
if order.Status < model.OrderStatusDelivering {
storeDetail, err2 := dao.GetStoreDetail(dao.GetDB(), order.StoreID, order.VendorID)
phone := userName
@@ -91,7 +91,7 @@ func (s *DefScheduler) canOrderCreateWaybillNormally(order *model.GoodsOrder) (e
}
func (s *DefScheduler) isPossibleSwitch2SelfDelivery(order *model.GoodsOrder) (err error) {
if scheduler.StoreDeliveryTypeByStore != s.GetStoreDeliveryType(order, nil) {
if model.IsOrderDeliveryByPlatform(order) {
if order.Status < model.OrderStatusFinishedPickup {
err = fmt.Errorf("拣货完成后才能转自配送")
} else if order.Status == model.OrderStatusFinishedPickup {

View File

@@ -72,6 +72,18 @@ func init() {
partner.InitActManager(FixedActManager)
}
func getVendorPriceFromStoreSkuBind(bind *model.StoreSkuBind, vendorID int) (vendorPrice int) {
switch vendorID {
case model.VendorIDJD:
vendorPrice = bind.JdPrice
case model.VendorIDMTWM:
vendorPrice = bind.MtwmPrice
case model.VendorIDEBAI:
vendorPrice = bind.EbaiPrice
}
return vendorPrice
}
func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Act, vendorIDs []int, actStoreSku []*ActStoreSkuParam) (validVendorIDs []int, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, err error) {
wholeValidVendorMap := make(map[int]int)
if len(actStoreSku) > 0 {
@@ -93,6 +105,7 @@ func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Ac
}
storeIDs := jxutils.IntMap2List(storeIDMap)
skuIDs := jxutils.IntMap2List(skuIDMap)
// 判断活动是否重叠的检查,当前忽略京东平台及所有结算信息
if !(len(vendorIDs) == 1 && vendorIDs[0] == model.VendorIDJD || act.Type == model.ActSkuFake) {
effectActStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, storeIDs, skuIDs, act.BeginAt, act.EndAt)
if err != nil {
@@ -119,59 +132,60 @@ func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Ac
for _, vendorID := range vendorIDs {
storeDetail, err2 := dao.GetStoreDetail(db, storeID, vendorID)
if err = err2; err == nil {
for _, v := range oneStoreSkuParam {
validVendorMap[vendorID] = 1
validSkuMap[v.SkuID] = 1
v.ActID = act.ID
actSkuMap := &model.ActStoreSkuMap{
ActID: act.ID,
StoreID: storeID,
SkuID: v.SkuID,
VendorID: vendorID,
}
v.OriginalPrice = actSkuMap.VendorPrice
storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]
if storeSkuInfo != nil {
jxPrice := storeSkuInfo.Price
pricePercentage := jxutils.GetPricePercentage(storeDetail.PricePercentagePackObj, jxPrice, int(storeDetail.PricePercentage))
actSkuMap.VendorPrice = int64(jxutils.CaculateSkuVendorPrice(jxPrice, pricePercentage))
v.OriginalPrice = int64(jxPrice)
}
var err2 error
if act.Type != model.ActSkuFake {
if storeSkuInfo == nil {
v.ErrMsg = fmt.Sprintf("门店:%d没有关注商品:%d", v.StoreID, v.SkuID)
wrongSkuList = append(wrongSkuList, v)
continue
if storeDetail.IsSync != 0 && storeDetail.Status != model.StoreStatusDisabled && storeDetail.VendorStatus != model.StoreStatusDisabled {
for _, v := range oneStoreSkuParam {
validVendorMap[vendorID] = 1
validSkuMap[v.SkuID] = 1
v.ActID = act.ID
actSkuMap := &model.ActStoreSkuMap{
ActID: act.ID,
StoreID: storeID,
SkuID: v.SkuID,
VendorID: vendorID,
}
actSkuMap.SyncStatus = model.SyncFlagNewMask
if v.ActPrice != 0 {
actSkuMap.ActualActPrice = v.ActPrice
} else {
percentage := act.PricePercentage
if v.PricePercentage != 0 {
percentage = v.PricePercentage
v.OriginalPrice = actSkuMap.VendorPrice
storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]
if storeSkuInfo != nil {
jxPrice := storeSkuInfo.Price
actSkuMap.VendorPrice = int64(getVendorPriceFromStoreSkuBind(storeSkuInfo, vendorID))
v.OriginalPrice = int64(jxPrice)
}
var err2 error
if act.Type != model.ActSkuFake { // 非结算,要计算实际活动价格
if storeSkuInfo == nil {
v.ErrMsg = fmt.Sprintf("门店:%d没有关注商品:%d", v.StoreID, v.SkuID)
wrongSkuList = append(wrongSkuList, v)
continue
}
actSkuMap.ActualActPrice = int64(jxutils.CaculateSkuVendorPrice(int(actSkuMap.VendorPrice), percentage))
if actSkuMap.ActualActPrice > 10 {
actSkuMap.ActualActPrice = int64(math.Round(float64(actSkuMap.ActualActPrice)/10) * 10)
actSkuMap.SyncStatus = model.SyncFlagNewMask
if v.ActPrice != 0 {
actSkuMap.ActualActPrice = v.ActPrice
} else {
percentage := act.PricePercentage
if v.PricePercentage != 0 {
percentage = v.PricePercentage
}
actSkuMap.ActualActPrice = int64(jxutils.CaculateSkuVendorPrice(int(actSkuMap.VendorPrice), percentage, 0))
if actSkuMap.ActualActPrice > 10 {
actSkuMap.ActualActPrice = int64(math.Floor(float64(actSkuMap.ActualActPrice)/10) * 10)
}
}
if actSkuMap.ActualActPrice <= 0 {
actSkuMap.ActualActPrice = 1
}
if err2 = checkDiscountValidation(act.Type, float64(actSkuMap.ActualActPrice)*100/float64(actSkuMap.VendorPrice)); err2 != nil {
v.ErrMsg = err2.Error()
v.ActualActPrice = actSkuMap.ActualActPrice
wrongSkuList = append(wrongSkuList, v)
}
}
if actSkuMap.ActualActPrice <= 0 {
actSkuMap.ActualActPrice = 1
}
if err2 = checkDiscountValidation(act.Type, int(actSkuMap.ActualActPrice*100/actSkuMap.VendorPrice)); err2 != nil {
v.ErrMsg = err2.Error()
v.ActualActPrice = actSkuMap.ActualActPrice
wrongSkuList = append(wrongSkuList, v)
if err2 == nil {
dao.WrapAddIDCULDEntity(actSkuMap, ctx.GetUserName())
actStoreSkuMapList = append(actStoreSkuMapList, actSkuMap)
}
}
if err2 == nil {
dao.WrapAddIDCULDEntity(actSkuMap, ctx.GetUserName())
actStoreSkuMapList = append(actStoreSkuMapList, actSkuMap)
}
wholeValidVendorMap[vendorID] = 1
}
wholeValidVendorMap[vendorID] = 1
} else if !dao.IsNoRowsError(err) {
return nil, nil, nil, err
} else {
@@ -268,26 +282,30 @@ func AddActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actSto
if err = addActStoreSkuBind(ctx, db, actStoreSkuList, actStoreSkuMapList); err != nil {
return err
}
for _, act := range actMap {
if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act),
map[string]interface{}{
model.FieldSyncStatus: act.SyncStatus | model.SyncFlagModifiedMask,
}, ctx.GetUserName(), nil); err != nil {
return err
if act.Type != model.ActSkuFake {
for _, act := range actMap {
if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act),
map[string]interface{}{
model.FieldSyncStatus: act.SyncStatus | model.SyncFlagModifiedMask,
}, ctx.GetUserName(), nil); err != nil {
return err
}
}
}
dao.Commit(db)
return err
}
func checkDiscountValidation(actType int, pricePercentage int) (err error) {
if actType == model.ActSkuDirectDown && (pricePercentage < minDiscount4SkuDirectDown || pricePercentage > 99) {
if pricePercentage < minDiscount4SkuDirectDown {
func checkDiscountValidation(actType int, pricePercentage float64) (err error) {
pricePercentageMin := int(math.Floor(pricePercentage))
pricePercentageMax := int(math.Ceil(pricePercentage))
if actType == model.ActSkuDirectDown && (pricePercentageMin < minDiscount4SkuDirectDown || pricePercentageMax > 99) {
if pricePercentageMin < minDiscount4SkuDirectDown {
err = fmt.Errorf("%s活动折扣必须大于:%d", model.ActTypeName[actType], minDiscount4SkuDirectDown)
} else if pricePercentage > 99 {
} else if pricePercentageMax > 99 {
err = fmt.Errorf("%s活动必须有折扣", model.ActTypeName[actType])
}
} else if actType == model.ActSkuSecKill && pricePercentage > maxDiscount4SkuSecKill {
} else if actType == model.ActSkuSecKill && pricePercentageMax > maxDiscount4SkuSecKill {
err = fmt.Errorf("%s活动折扣必须小于:%d", model.ActTypeName[actType], maxDiscount4SkuSecKill)
}
return err
@@ -308,7 +326,7 @@ func checkActValidation(act *model.Act, vendorIDs []int) (err error) {
if act.Type == model.ActSkuDirectDown || act.Type == model.ActSkuSecKill {
if act.PricePercentage == 0 {
errList.AddErr(fmt.Errorf("必须指定缺省活动折扣"))
} else if err = checkDiscountValidation(act.Type, act.PricePercentage); err != nil {
} else if err = checkDiscountValidation(act.Type, float64(act.PricePercentage)); err != nil {
errList.AddErr(err)
} else if act.Type == model.ActSkuSecKill && vendorIDMap[model.VendorIDMTWM] == 1 {
errList.AddErr(fmt.Errorf("%s平台不支持%s活动", model.VendorChineseNames[model.VendorIDMTWM], model.ActTypeName[model.ActSkuSecKill]))
@@ -501,6 +519,21 @@ func (a *ActManager) CreateActFromVendor(ctx *jxcontext.Context, act2 *model.Act
}
func createActFromVendor(ctx *jxcontext.Context, db *dao.DaoDB, act2 *model.Act2, actStoreSku []*model.ActStoreSku2) (actID int, err error) {
actMap := &model.ActMap{
VendorID: act2.VendorID,
VendorActID: act2.VendorActID,
SyncStatus: 0,
}
dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName())
if actMap.VendorActID != "" {
if err = dao.GetEntity(db, actMap, model.FieldVendorActID, model.FieldVendorID, model.FieldDeletedAt); err == nil {
return actMap.ActID, nil
} else if !dao.IsNoRowsError(err) {
return 0, err
}
err = nil
}
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
@@ -517,13 +550,7 @@ func createActFromVendor(ctx *jxcontext.Context, db *dao.DaoDB, act2 *model.Act2
return 0, err
}
actMap := &model.ActMap{
ActID: act.ID,
VendorID: act2.VendorID,
VendorActID: act2.VendorActID,
SyncStatus: 0,
}
dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName())
actMap.ActID = act.ID
err = dao.CreateEntity(db, actMap)
if err != nil {
dao.Rollback(db)
@@ -673,11 +700,13 @@ func DeleteActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, act
syncStatus = model.SyncFlagDeletedMask
}
syncStatus |= act.SyncStatus
if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act),
map[string]interface{}{
model.FieldSyncStatus: syncStatus,
}, ctx.GetUserName(), nil); err != nil {
return err
if act.Type != model.ActSkuFake {
if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act),
map[string]interface{}{
model.FieldSyncStatus: syncStatus,
}, ctx.GetUserName(), nil); err != nil {
return err
}
}
}
if isDeleteAll != isNeedCancelAct {

View File

@@ -15,10 +15,10 @@ import (
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/mobile"
"git.rosy.net.cn/jx-callback/business/authz/autils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"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/ddmsg"
"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"
@@ -97,6 +97,7 @@ func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
"configTypeName": model.ConfigTypeName,
"autoSaleAt": AutoSaleAtStr,
"userTypeName": model.UserTypeName,
"storePriceTypeName": model.StorePriceTypeName,
},
}
}
@@ -180,7 +181,7 @@ func SendMsg2Somebody(ctx *jxcontext.Context, mobileNum, verifyCode, msgType, ms
for _, v := range receiveMsgUsersMap[msgType] {
user, err2 := dao.GetUserByID(db, "name", v)
if err2 == nil {
msg.SendUserMessage(dingdingapi.MsgTyeText, user, msgType, msgContent)
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.GetID(), msgType, msgContent)
} else if err == nil {
err = err2
}
@@ -353,7 +354,11 @@ func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (hint s
vendorStoreMap[v.VendorID] = append(vendorStoreMap[v.VendorID], v.StoreID)
}
for vendorID, storeIDs := range vendorStoreMap {
dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, nil, model.SyncFlagPriceMask)
if vendorID != model.VendorIDJX {
dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, nil, model.SyncFlagPriceMask)
} else {
ReCalculateJxPrice(ctx, storeIDs)
}
}
// for _, v := range storeMapList {
// if _, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, &model.StoreSkuBind{}, nil, ctx.GetUserName(), map[string]interface{}{

View File

@@ -268,7 +268,6 @@ func DeleteCategoryMap(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int) (n
return dao.DeleteEntityLogically(db, catMap, map[string]interface{}{
model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask,
model.FieldMtwmSyncStatus: model.SyncFlagDeletedMask,
model.FieldWscSyncStatus: model.SyncFlagDeletedMask,
}, ctx.GetUserName(), map[string]interface{}{
model.FieldCategoryID: categoryID,
model.FieldDeletedAt: utils.DefaultTimeValue,
@@ -651,7 +650,8 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s
return outSkuNameExt, err
}
func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interface{}, userName string) (num int64, err error) {
func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interface{}) (num int64, err error) {
userName := ctx.GetUserName()
skuName := &model.SkuName{}
skuName.ID = nameID
db := dao.GetDB()
@@ -693,22 +693,10 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf
}
if globals.EnableStoreWrite {
if valid["img"] != nil {
// imgContent, imgMD5, err2 := jxutils.DownloadFileByURL(valid["img"].(string))
// if err = err2; err != nil {
// return 0, err
// }
// valid["ImgHashCode"] = imgMD5
// imgHintMap, err := UploadImg2Platforms(ctx, nil, valid["img"].(string), imgContent, "")
// if err != nil {
// return 0, err
// }
// // valid["ImgWeimob"] = imgHintMap[model.VendorIDWSC]
// valid["ImgEbai"] = imgHintMap[model.VendorIDEBAI]
dataRes, err2 := datares.TryRegisterDataResource(ctx, skuName.Name, valid["img"].(string), model.ImgTypeMain, false)
if err = err2; err != nil {
return 0, err
}
// valid["ImgHashCode"] = dataRes.HashCode
valid["ImgEbai"] = dataRes.EbaiURL
}
if valid["img2"] != nil {
@@ -865,7 +853,8 @@ func AddSku(ctx *jxcontext.Context, nameID int, sku *model.Sku, userName string)
return outSkuNameExt, err
}
func UpdateSku(ctx *jxcontext.Context, skuID int, payload map[string]interface{}, userName string) (num int64, err error) {
func UpdateSku(ctx *jxcontext.Context, skuID int, payload map[string]interface{}) (num int64, err error) {
userName := ctx.GetUserName()
sku := &model.Sku{}
sku.ID = skuID
db := dao.GetDB()
@@ -996,7 +985,6 @@ func DeleteStoreSku(ctx *jxcontext.Context, db *dao.DaoDB, nameID, skuID int) (n
storeSkuBind := &model.StoreSkuBind{}
_, err = dao.DeleteEntityLogically(db, storeSkuBind, map[string]interface{}{
model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
model.FieldWscSyncStatus: model.SyncFlagDeletedMask,
model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask,
}, ctx.GetUserName(), map[string]interface{}{
model.FieldSkuID: v.ID,

View File

@@ -19,6 +19,7 @@ import (
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/baseapi/utils/errlist"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/msg"
@@ -66,6 +67,11 @@ type Store4User struct {
OriginalName string `orm:"-" json:"originalName"`
Name string `orm:"size(255)" json:"name"`
OpenTime1 int16 `json:"openTime1"` // 930就表示9点半用两个的原因是为了支持中午休息1与2的时间段不能交叉为0表示没有
CloseTime1 int16 `json:"closeTime1"` // 格式同上
OpenTime2 int16 `json:"openTime2"` // 格式同上
CloseTime2 int16 `json:"closeTime2"` // 格式同上
Status int `json:"status"`
CityCode int `orm:"default(0);null" json:"cityCode"` // todo ?
DistrictCode int `orm:"default(0);null" json:"districtCode"` // todo ?
Address string `orm:"size(255)" json:"address"`
@@ -202,7 +208,9 @@ func getStoresSql(ctx *jxcontext.Context, keyword string, params map[string]inte
sqlVendorStoreCond += " AND ( 1 = 0"
}
}
sqlFrom += "\nLEFT JOIN " + tableName + " " + tableAlias + " ON " + tableAlias + ".vendor_id = ? AND " + tableAlias + ".store_id = t1.id AND " + tableAlias + ".deleted_at = ?"
sqlFrom += "\nLEFT JOIN " + tableName + " " + tableAlias + " ON " + tableAlias + ".vendor_id = ? AND " +
tableAlias + ".store_id = t1.id AND " + tableAlias + ".deleted_at = ? AND " +
tableAlias + ".is_sync <> 0 "
sqlFromParams = append(sqlFromParams, vendor, utils.DefaultTimeValue)
if cond == 1 {
sqlVendorStoreCond += " " + mapCond + " " + tableAlias + ".id IS NOT NULL"
@@ -251,7 +259,7 @@ func getStoresSql(ctx *jxcontext.Context, keyword string, params map[string]inte
if params["storeID"] != nil || params["storeIDs"] != nil {
var storeIDs []int
if params["storeIDs"] != nil {
if err = jxutils.Strings2Objs(utils.Interface2String("storeIDs"), &storeIDs); err != nil {
if err = jxutils.Strings2Objs(utils.Interface2String(params["storeIDs"]), &storeIDs); err != nil {
return "", nil, "", nil, err
}
}
@@ -310,7 +318,7 @@ func getStoresSql(ctx *jxcontext.Context, keyword string, params map[string]inte
return sql, sqlParams, sqlFrom, sqlFromParams, nil
}
func setStoreMapInfo(ctx *jxcontext.Context, db *dao.DaoDB, storesInfo *StoresInfo, storeIDs []int) (err error) {
func setStoreMapInfo(ctx *jxcontext.Context, db *dao.DaoDB, storesInfo *StoresInfo, storeIDs []int, briefLevel int) (err error) {
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll, model.StoreIsSyncAll, "")
if err != nil {
return err
@@ -330,6 +338,14 @@ func setStoreMapInfo(ctx *jxcontext.Context, db *dao.DaoDB, storesInfo *StoresIn
}
for _, v := range storesInfo.Stores {
if briefLevel > 0 {
v.DeliveryRange = ""
v.IDCardFront = ""
v.IDCardBack = ""
v.IDCardHand = ""
v.Licence = ""
v.Licence2Image = ""
}
for _, v2 := range storeMapMap[v.ID] {
v.StoreMaps = append(v.StoreMaps, utils.Struct2FlatMap(v2))
}
@@ -342,6 +358,7 @@ func setStoreMapInfo(ctx *jxcontext.Context, db *dao.DaoDB, storesInfo *StoresIn
// todo 门店绑定信息可以考虑以数组形式返回,而不是现在这样
func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interface{}, offset, pageSize int, orderTimeFrom, orderTimeTo time.Time, orderCountFrom, orderCountTo int) (retVal *StoresInfo, err error) {
briefLevel := int(utils.ForceInterface2Int64(params["briefLevel"]))
sql, sqlParams, _, _, err := getStoresSql(ctx, keyword, params, orderTimeFrom, orderTimeTo)
if err != nil {
@@ -447,7 +464,7 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa
}
if len(retVal.Stores) > 0 {
setStoreMapInfo(ctx, db, retVal, storeIDs)
setStoreMapInfo(ctx, db, retVal, storeIDs, briefLevel)
retVal.MapCenterLng, retVal.MapCenterLat = getMapCenter(retVal.Stores)
}
return retVal, err
@@ -759,6 +776,7 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa
} else {
dao.Commit(db)
}
notifyStoreOperatorChanged(store, valid["operatorPhone"])
}
} else {
globals.SugarLogger.Debugf("UpdateStore track:%s, store:%s", ctx.GetTrackInfo(), utils.Format4Output(store, true))
@@ -766,6 +784,21 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa
return num, err
}
func notifyStoreOperatorChanged(store *model.Store, newOperator2 interface{}) {
if store.OperatorPhone != "" && newOperator2 != nil {
db := dao.GetDB()
if user, err := dao.GetUserByID(db, "mobile", store.OperatorPhone); err == nil {
curUserName := ""
if newOperator := utils.Interface2String(newOperator2); newOperator != "" {
if curUser, err := dao.GetUserByID(db, "mobile", newOperator); err == nil {
curUserName = curUser.GetName()
}
}
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.GetID(), "门店运营变更", fmt.Sprintf("门店:%d-%s,原运营:%s,变更为:%s", store.ID, store.Name, user.GetName(), curUserName))
}
}
}
func SetStoreStatus(ctx *jxcontext.Context, storeID, status int) (err error) {
payload := map[string]interface{}{
"status": status,
@@ -1095,7 +1128,7 @@ func TmpGetJxBadCommentsNo(ctx *jxcontext.Context, storeID int) (count int, err
return count, err
}
func TmpGetJxBadCommentsByStoreId(ctx *jxcontext.Context, storeIDs []int, offset, pageSize, commentType int, fromTime, toTime time.Time) (retVal map[string]interface{}, err error) {
func TmpGetJxBadCommentsByStoreId(ctx *jxcontext.Context, keyword string, storeIDs []int, offset, pageSize, commentType int, fromTime, toTime time.Time) (retVal map[string]interface{}, err error) {
db := dao.GetDB()
sql := `
SELECT SQL_CALC_FOUND_ROWS
@@ -1108,6 +1141,13 @@ func TmpGetJxBadCommentsByStoreId(ctx *jxcontext.Context, storeIDs []int, offset
WHERE 1 = 1
`
sqlParams := []interface{}{}
if keyword != "" {
keywordLike := "%" + keyword + "%"
sql += `
AND (t1.order_id LIKE ? OR t1.jxstoreid LIKE ? OR t1.userphone LIKE ? OR t1.scorecontent LIKE ? OR t1.vendertags LIKE ? OR t1.updated_scorecontent LIKE ?
OR t1.updated_vendertags LIKE ? OR t2.name LIKE ?)`
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike)
}
if len(storeIDs) > 0 {
sql += " AND t1.jxstoreid IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")"
sqlParams = append(sqlParams, storeIDs)
@@ -1494,7 +1534,7 @@ func GetStoresVendorSnapshot(ctx *jxcontext.Context, parentTask tasksch.ITask, v
task := tasksch.NewParallelTask("GetStoresVendorSnapshot", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
storeMap := batchItemList[0].(*model.StoreMap)
if storeMap.VendorID != model.VendorIDWSC {
if model.IsVendorRemote(storeMap.VendorID) {
if handler := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID); handler != nil {
store, err2 := handler.ReadStore(ctx, storeMap.VendorStoreID)
if err = err2; err == nil {
@@ -2076,21 +2116,8 @@ func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, needWalkDi
if err = dao.GetRows(dao.GetDB(), &storeList1, sql, sqlParams...); err == nil {
var storeList2 []*Store4User
for _, v := range storeList1 {
isStoreOK := false
v.FloatLng = jxutils.IntCoordinate2Standard(v.Lng)
v.FloatLat = jxutils.IntCoordinate2Standard(v.Lat)
if v.DeliveryRangeType == model.DeliveryRangeTypeRadius {
maxDistance := int(utils.Str2Int64WithDefault(v.DeliveryRange, 0))
v.Distance = int(jxutils.EarthDistance(lng, lat, v.FloatLng, v.FloatLat) * 1000)
isStoreOK = v.Distance <= maxDistance
} else {
points := jxutils.CoordinateStr2Points(v.DeliveryRange)
if utils.IsPointInPolygon(lng, lat, points) {
v.Distance = int(jxutils.EarthDistance(lng, lat, v.FloatLng, v.FloatLat) * 1000)
isStoreOK = true
}
}
if isStoreOK {
if distance := jxutils.Point2StoreDistance(lng, lat, v.Lng, v.Lat, v.DeliveryRangeType, v.DeliveryRange); distance > 0 {
v.Distance = distance
storeList2 = append(storeList2, v)
}
}

View File

@@ -54,24 +54,28 @@ type StoreSkuExt struct {
StoreSkuStatus int `json:"storeSkuStatus"`
EbaiID string `orm:"column(ebai_id);index" json:"ebaiID"`
MtwmID string `orm:"column(mtwm_id)" json:"mtwmID"` // 这个也不是必须的只是为了DAO取数据语句一致
WscID string `orm:"column(wsc_id);index" json:"wscID"` // 表示微盟skuId
WscID2 string `orm:"column(wsc_id2);index" json:"wscID2"` // 表示微盟goodsId
MtwmID string `orm:"column(mtwm_id)" json:"mtwmID"` // 这个也不是必须的只是为了DAO取数据语句一致
// WscID string `orm:"column(wsc_id);index" json:"wscID"` // 表示微盟skuId
// WscID2 string `orm:"column(wsc_id2);index" json:"wscID2"` // 表示微盟goodsId
JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"`
EbaiSyncStatus int8 `orm:"default(2)" json:"ebaiSyncStatus"`
MtwmSyncStatus int8 `orm:"default(2)" json:"mtwmSyncStatus"`
WscSyncStatus int8 `orm:"default(2)" json:"wscSyncStatus"`
// WscSyncStatus int8 `orm:"default(2)" json:"wscSyncStatus"`
JdPrice int `json:"jdPrice"`
EbaiPrice int `json:"ebaiPrice"`
MtwmPrice int `json:"mtwmPrice"`
WscPrice int `json:"wscPrice"`
JxPrice int `json:"jxPrice"`
AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"`
ActPrice int `json:"actPrice"`
EarningPrice int `json:"earningPrice"`
ActPrice int `json:"actPrice"`
ActID int `orm:"column(act_id)" json:"actID"`
EarningPrice int `json:"earningPrice"`
EarningActID int `orm:"column(earning_act_id)" json:"earningActID"`
RealEarningPrice int `json:"realEarningPrice"`
Count int `json:"count"`
@@ -198,7 +202,8 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool
sql += `
JOIN (
SELECT t2.store_id, t2.sku_id,
MIN(IF(t3.actual_act_price = 0, NULL, t3.actual_act_price)) actual_act_price, MIN(IF(t2.earning_price = 0, NULL, t2.earning_price)) earning_price /*non-zero min value*/
MIN(IF(t3.actual_act_price <= 0, NULL, t3.actual_act_price)) actual_act_price, /*non-zero min value*/
MIN(IF(t2.earning_price <= 0, NULL, t2.earning_price)) earning_price /*non-zero min value*/
FROM act t1
JOIN act_store_sku t2 ON t2.act_id = t1.id AND t2.deleted_at = ?
JOIN act_store_sku_map t3 ON t3.bind_id = t2.id AND t3.act_id = t1.id AND (t3.sync_status & ? = 0 OR t1.type = ?)
@@ -441,9 +446,9 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo
t2.comment, t2.category_id sku_category_id, t2.status sku_status,
t4.created_at bind_created_at, t4.updated_at bind_updated_at, t4.last_operator bind_last_operator, t4.deleted_at bind_deleted_at,
t4.sub_store_id, t4.price bind_price, IF(t4.unit_price IS NOT NULL, t4.unit_price, t1.price) unit_price, t4.status store_sku_status, t4.auto_sale_at,
t4.ebai_id, t4.mtwm_id, t4.wsc_id, t4.wsc_id2,
t4.jd_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status, t4.wsc_sync_status,
t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.wsc_price
t4.ebai_id, t4.mtwm_id,
t4.jd_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status,
t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price
` + sql
var tmpList []*tGetStoresSkusInfo
beginTime := time.Now()
@@ -486,8 +491,12 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo
if true { //!(offset == 0 && pageSize == model.UnlimitedPageSize) {
storeIDs, skuIDs = GetStoreAndSkuIDsFromInfo(skuNamesInfo)
}
actVendorID := -1
if params["actVendorID"] != nil {
actVendorID = int(utils.Interface2Int64WithDefault(params["actVendorID"], -1))
}
beginTime := time.Now()
err = updateActPrice4StoreSkuNameNew(db, storeIDs, skuIDs, skuNamesInfo)
err = updateActPrice4StoreSkuNameNew(db, storeIDs, skuIDs, skuNamesInfo, actVendorID)
globals.SugarLogger.Debugf("GetStoresSkusNew updateActPrice4StoreSkuName:%v", time.Now().Sub(beginTime))
if !isFocus {
err = updateUnitPrice4StoreSkuNameNew(db, skuNamesInfo)
@@ -534,11 +543,15 @@ func updateUnitPrice4StoreSkuNameNew(db *dao.DaoDB, skuNamesInfo *StoreSkuNamesI
}
// skuIDs为空会导致性能极低所以要skuIDs必须有值
func updateActPrice4StoreSkuNameNew(db *dao.DaoDB, storeIDs, skuIDs []int, skuNamesInfo *StoreSkuNamesInfo) (err error) {
func updateActPrice4StoreSkuNameNew(db *dao.DaoDB, storeIDs, skuIDs []int, skuNamesInfo *StoreSkuNamesInfo, actVendorID int) (err error) {
if len(skuIDs) == 0 {
return nil
}
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, nil, storeIDs, skuIDs, time.Now(), time.Now())
var vendorIDs []int
if actVendorID >= 0 {
vendorIDs = []int{actVendorID}
}
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, storeIDs, skuIDs, time.Now(), time.Now())
if err != nil {
globals.SugarLogger.Errorf("updateActPrice4StoreSkuNameNew can not get sku promotion info for error:%v", err)
return err
@@ -551,9 +564,11 @@ func updateActPrice4StoreSkuNameNew(db *dao.DaoDB, storeIDs, skuIDs []int, skuNa
for _, v := range skuName.Skus2 {
if actStoreSku := actStoreSkuMap4Act.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil {
v.ActPrice = int(actStoreSku.ActualActPrice)
v.ActID = actStoreSku.ActID
}
if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil {
v.EarningPrice = int(actStoreSku.EarningPrice)
v.EarningActID = actStoreSku.ActID
}
v.RealEarningPrice = v.EarningPrice
@@ -924,6 +939,12 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
}
}()
for _, storeID := range storeIDs {
// todo 可以考虑在需要更新价格再获取
storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDJX)
if err != nil {
dao.Rollback(db)
return nil, err
}
for _, skuBindInfo := range skuBindInfos {
// 关注且没有给价时需要尝试从store_sku_bind中得到已有的单价
needGetExistingUnitPrice := skuBindInfo.UnitPrice == 0 && skuBindInfo.IsFocus == 1
@@ -988,7 +1009,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
for _, v := range allBinds {
var num int64
inSkuBind := inSkuBinsMap[v.RealSkuID]
isCanChangePrice := (isUserCanDirectChangePrice || v.ChangePriceType != model.StoreChangePriceTypeBossDisabled)
isCanChangePrice := (isUserCanDirectChangePrice || jxutils.TranslateStorePriceType(v.ChangePriceType) != model.StoreChangePriceTypeBossDisabled)
// globals.SugarLogger.Debug(utils.Format4Output(inSkuBind, false))
var skuBind *model.StoreSkuBind
if v.ID == 0 {
@@ -1001,6 +1022,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
Price: jxutils.CaculateSkuPrice(unitPrice, v.SpecQuality, v.SpecUnit, v.SkuNameUnit),
Status: model.StoreSkuBindStatusDontSale, // 缺省不可售?
}
skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price)
if tmpStatus := getSkuSaleStatus(inSkuBind, skuBindInfo); tmpStatus != model.StoreSkuBindStatusNA {
skuBind.Status = tmpStatus
}
@@ -1022,7 +1044,6 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask,
model.FieldMtwmSyncStatus: model.SyncFlagDeletedMask,
model.FieldWscSyncStatus: model.SyncFlagDeletedMask,
}, userName, nil); err != nil {
dao.Rollback(db)
return nil, err
@@ -1049,9 +1070,11 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
if skuBindInfo.UnitPrice != 0 && isCanChangePrice { // 这里是否需要加此条件限制
skuBind.UnitPrice = unitPrice
skuBind.Price = jxutils.CaculateSkuPrice(unitPrice, v.SpecQuality, v.SpecUnit, v.SkuNameUnit)
skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price)
setStoreSkuBindStatus(skuBind, model.SyncFlagPriceMask)
updateFieldMap["UnitPrice"] = 1
updateFieldMap["Price"] = 1
updateFieldMap["JxPrice"] = 1
}
// todo 这里应该是不需处理这个信息的吧?
// if inSkuBind != nil && inSkuBind.EbaiID != 0 {
@@ -1066,7 +1089,6 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
updateFieldMap[model.FieldJdSyncStatus] = 1
updateFieldMap[model.FieldEbaiSyncStatus] = 1
updateFieldMap[model.FieldMtwmSyncStatus] = 1
updateFieldMap[model.FieldWscSyncStatus] = 1
updateFieldMap[model.FieldUpdatedAt] = 1
updateFieldMap[model.FieldLastOperator] = 1
@@ -1160,7 +1182,6 @@ func updateStoreSkusSaleWithoutSync(ctx *jxcontext.Context, storeID int, skuBind
model.FieldJdSyncStatus: skuBind.JdSyncStatus | model.SyncFlagSaleMask,
model.FieldEbaiSyncStatus: skuBind.EbaiSyncStatus | model.SyncFlagSaleMask,
model.FieldMtwmSyncStatus: skuBind.MtwmSyncStatus | model.SyncFlagSaleMask,
model.FieldWscSyncStatus: skuBind.WscSyncStatus | model.SyncFlagSaleMask,
}
if utils.IsTimeZero(autoSaleTime) || skuBind.Status == model.SkuStatusNormal {
kvs["AutoSaleAt"] = utils.DefaultTimeValue
@@ -1270,9 +1291,9 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
SET t1.last_operator = ?,
t1.updated_at = ?,
t1.price = t1.price * ? / 100,
t1.jx_price = t1.jx_price * ? / 100,
t1.unit_price = t1.unit_price * ? / 100,
t1.jd_sync_status = t1.jd_sync_status | ?,
t1.wsc_sync_status = t1.wsc_sync_status | ?,
t1.mtwm_sync_status = t1.mtwm_sync_status | ?,
t1.ebai_sync_status = t1.ebai_sync_status | ?
WHERE t1.store_id = ? AND t1.deleted_at = ?
@@ -1285,7 +1306,7 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
now,
pricePercentage,
pricePercentage,
model.SyncFlagPriceMask,
pricePercentage,
model.SyncFlagPriceMask,
model.SyncFlagPriceMask,
model.SyncFlagPriceMask,
@@ -1312,14 +1333,14 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
JOIN sku t2 ON t1.sku_id = t2.id/* AND t2.deleted_at = ?*/
JOIN sku_name t3 ON t2.name_id = t3.id/* AND t2.deleted_at = ?*/
LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t2.deleted_at = ?
SET t1.deleted_at = ?,
t1.updated_at = ?,
t1.last_operator = ?,
t1.status = ?,
t1.jd_sync_status = IF((t1.jd_sync_status & ?) <> 0, 0, ?),
t1.wsc_sync_status = IF((t1.wsc_sync_status & ?) <> 0, 0, ?),
t1.mtwm_sync_status = IF((t1.mtwm_sync_status & ?) <> 0, 0, ?),
t1.ebai_sync_status = IF((t1.ebai_sync_status & ?) <> 0, 0, ?)
SET
t1.deleted_at = ?,
t1.updated_at = ?,
t1.last_operator = ?,
t1.status = ?,
t1.jd_sync_status = IF((t1.jd_sync_status & ?) <> 0, 0, ?),
t1.mtwm_sync_status = IF((t1.mtwm_sync_status & ?) <> 0, 0, ?),
t1.ebai_sync_status = IF((t1.ebai_sync_status & ?) <> 0, 0, ?)
WHERE t1.store_id = ? AND t1.deleted_at = ? AND t0.id IS NULL
`
sqlDeleteParams := []interface{}{
@@ -1338,8 +1359,6 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
model.SyncFlagDeletedMask,
model.SyncFlagNewMask,
model.SyncFlagDeletedMask,
model.SyncFlagNewMask,
model.SyncFlagDeletedMask,
toStoreID,
utils.DefaultTimeValue,
}
@@ -1364,14 +1383,15 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
JOIN sku t2 ON t1.sku_id = t2.id/* AND t2.deleted_at = ?*/
JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ?
SET t1.last_operator = ?,
SET
t1.last_operator = ?,
t1.updated_at = ?,
t1.sub_store_id = 0,
t1.price = IF(t0.price * ? / 100 > 0, t0.price * ? / 100, 1),
t1.jx_price = IF(t0.jx_price * ? / 100 > 0, t0.jx_price * ? / 100, 1),
t1.unit_price = IF(t0.unit_price * ? / 100 > 0, t0.unit_price * ? / 100, 1),
t1.status = IF(? = 0, t1.status, t0.status),
t1.jd_sync_status = t1.jd_sync_status | ?,
t1.wsc_sync_status = t1.wsc_sync_status | ?,
t1.mtwm_sync_status = t1.mtwm_sync_status | ?,
t1.ebai_sync_status = t1.ebai_sync_status | ?
WHERE t1.store_id = ? AND t1.deleted_at = ? AND t0.id IS NOT NULL
@@ -1388,11 +1408,12 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
pricePercentage,
pricePercentage,
pricePercentage,
pricePercentage,
pricePercentage,
isModifyStatus,
syncStatus,
syncStatus,
syncStatus,
syncStatus,
toStoreID,
utils.DefaultTimeValue,
}
@@ -1407,11 +1428,12 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
// 添加toStore中不存在但fromStore存在的
sql = `
INSERT INTO store_sku_bind(created_at, updated_at, last_operator, deleted_at, store_id, sku_id, sub_store_id, price, unit_price, status,
jd_sync_status, wsc_sync_status, ebai_sync_status, mtwm_sync_status)
INSERT INTO store_sku_bind(created_at, updated_at, last_operator, deleted_at, store_id, sku_id, sub_store_id, price, jx_price, unit_price, status,
jd_sync_status, ebai_sync_status, mtwm_sync_status)
SELECT ?, ?, ?, ?, ?,
t1.sku_id, 0, IF(t1.price * ? / 100 > 0, t1.price * ? / 100, 1), IF(t1.unit_price * ? / 100 > 0, t1.unit_price * ? / 100, 1),
IF(? = 0, ?, t1.status), ?, ?, ?, ?
t1.sku_id, 0,
IF(t1.price * ? / 100 > 0, t1.price * ? / 100, 1), IF(t1.jx_price * ? / 100 > 0, t1.jx_price * ? / 100, 1), IF(t1.unit_price * ? / 100 > 0, t1.unit_price * ? / 100, 1),
IF(? = 0, ?, t1.status), ?, ?, ?
FROM store_sku_bind t1
JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ?
JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ?
@@ -1425,12 +1447,13 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
pricePercentage,
pricePercentage,
pricePercentage,
pricePercentage,
pricePercentage,
isModifyStatus,
model.SkuStatusDontSale,
model.SyncFlagNewMask,
model.SyncFlagNewMask,
model.SyncFlagNewMask,
model.SyncFlagNewMask,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
@@ -1459,7 +1482,7 @@ func shouldPendingStorePriceChange(ctx *jxcontext.Context, storeID int, skuBindI
if err = dao.GetEntity(db, store); err != nil {
return false, err
}
return store.ChangePriceType == model.StoreChangePriceTypeNeedApprove, nil
return jxutils.TranslateStorePriceType(store.ChangePriceType) == model.StoreChangePriceTypeNeedApprove, nil
}
}
return false, nil
@@ -1798,7 +1821,6 @@ func setStoreSkuBindStatus(skuBind *model.StoreSkuBind, status int8) {
skuBind.JdSyncStatus |= status
skuBind.EbaiSyncStatus |= status
skuBind.MtwmSyncStatus |= status
skuBind.WscSyncStatus |= status
}
func checkStoreExisting(db *dao.DaoDB, storeID int) (err error) {
@@ -1900,10 +1922,10 @@ func RefreshStoresSkuByVendor(ctx *jxcontext.Context, storeIDs []int, vendorID i
}
}
for _, v := range storeSkuList {
pricePercentage := jxutils.GetPricePercentageByVendorPrice(storeMap[v.StoreID].PricePercentagePackObj, v.Price, int(storeMap[v.StoreID].PricePercentage))
pricePercentage, priceAdd := jxutils.GetPricePercentageByVendorPrice(storeMap[v.StoreID].PricePercentagePackObj, v.Price, int(storeMap[v.StoreID].PricePercentage))
skuName := skuNameMap[skuMap[v.SkuID].NameID]
v.Price = jxutils.CaculateSkuPriceFromVendor(v.Price, pricePercentage)
v.UnitPrice = jxutils.CaculateSkuPriceFromVendor(skuName.Price, pricePercentage)
v.Price = jxutils.CaculateSkuPriceFromVendor(v.Price, pricePercentage, priceAdd)
v.UnitPrice = jxutils.CaculateSkuPriceFromVendor(skuName.Price, pricePercentage, priceAdd)
dao.WrapAddIDCULDEntity(v, ctx.GetUserName())
setStoreSkuBindStatus(v, model.SyncFlagNewMask)
v.JdSyncStatus = 0
@@ -2057,3 +2079,22 @@ func AutoSaleStoreSku(ctx *jxcontext.Context, storeIDs []int, isNeedSync bool) (
}
return err
}
func ReCalculateJxPrice(ctx *jxcontext.Context, storeIDs []int) (err error) {
db := dao.GetDB()
for _, storeID := range storeIDs {
if storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX); err == nil {
if storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, nil); err == nil {
for _, skuBind := range storeSkuList {
skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price)
dao.UpdateEntity(db, skuBind)
}
} else {
return err
}
} else {
return err
}
}
return err
}

View File

@@ -542,15 +542,14 @@ func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int,
storeID := jxStoreInfoListValue.ID
storeIDStr := utils.Int2Str(storeID)
storeName := jxStoreInfoListValue.Name
jxSkuInfoDataSingle := &StoreSkuNamesInfo{}
jxSkuInfoDataMulti := &StoreSkuNamesInfo{}
if jxStoreInfoListValue.StoreMaps != nil {
var filterJxSkuInfoMapSingle map[int]*StoreSkuNameExt
var filterJxSkuInfoMapMulti map[int]*StoreSkuNameExt
for _, vendorListValue := range jxStoreInfoListValue.StoreMaps {
vendorID := int(utils.MustInterface2Int64(vendorListValue["vendorID"]))
//京西的门店商品只取一次
flag := false
jxSkuInfoDataSingle := &StoreSkuNamesInfo{}
jxSkuInfoDataMulti := &StoreSkuNamesInfo{}
var flag = false
if partner.IsMultiStore(vendorID) {
if flag == false {
jxSkuInfoDataMulti, _ = GetStoreSkus(ctx, storeID, filterJxDepotUnSaleSkuIds, true, "", true, false, map[string]interface{}{}, 0, -1)

View File

@@ -213,8 +213,7 @@ func storeSkuSyncInfo2Bare(inSku *dao.StoreSkuSyncInfo) (outSku *partner.StoreSk
func calVendorPrice4StoreSku(inSku *dao.StoreSkuSyncInfo, pricePercentagePack model.PricePercentagePack, pricePercentage int) (outSku *dao.StoreSkuSyncInfo) {
if inSku.VendorPrice <= 0 { // 避免重新计算
pricePercentage = jxutils.GetPricePercentage(pricePercentagePack, int(inSku.Price), pricePercentage)
inSku.VendorPrice = int64(jxutils.CaculateSkuVendorPrice(int(inSku.Price), pricePercentage))
inSku.VendorPrice = int64(jxutils.CaculatePriceByPricePack(pricePercentagePack, pricePercentage, int(inSku.Price)))
if inSku.VendorPrice <= 0 {
inSku.VendorPrice = 1 // 最少1分钱
}
@@ -348,7 +347,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))
if singleStoreHandler == nil {
sku.StoreSkuSyncStatus |= model.SyncFlagSaleMask | model.SyncFlagPriceMask
bareSku = storeSkuSyncInfo2Bare(calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage)))
bareSku = storeSkuSyncInfo2Bare(sku)
stockList = append(stockList, bareSku)
priceList = append(priceList, bareSku)
if sku.MergedStatus == model.SkuStatusNormal {
@@ -447,6 +446,8 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
}
if err == nil {
successList = batchedStoreSkuList
} else {
offlineList = append(offlineList, batchedStoreSkuList...)
}
if len(successList) > 0 {
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagDeletedMask)
@@ -665,7 +666,10 @@ func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, v
case 1:
if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(sku2Delete) > 0 {
_, err = putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
_, err = handler.DeleteStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList)
if _, err = handler.DeleteStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList); err != nil {
// 如果删除失败尝试设置不可售假定删除批处理SIZE小于等于设置门店商品可售批处理SIZE
handler.UpdateStoreSkusStatus(ctx, storeID, vendorStoreID, batchedStoreSkuList, model.SkuStatusDontSale)
}
return nil, 0, err
}, ctx, task, sku2Delete, handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus), isContinueWhenError)
}

View File

@@ -136,11 +136,14 @@ func RegisterUserWithMobile(ctx *jxcontext.Context, user *model.User, mobileVeri
user.Type = model.UserTypeConsumer
if inAuthInfo.AuthBindInfo.Type == dingding.AuthTypeStaff {
user.Type |= model.UserTypeOperator
} else {
} else if user.Mobile != nil {
user.Type |= model.UserTypeStoreBoss
}
createName += "," + inAuthInfo.GetAuthID()
authType = inAuthInfo.GetAuthType()
if user.Avatar == "" {
user.Avatar = inAuthInfo.GetAvatar()
}
}
if err = CreateUser(user, utils.LimitUTF8StringLen(createName, 32)); err == nil {
userProvider.UpdateLastLogin(user.GetID(), authType, ctx.GetRealRemoteIP())
@@ -637,7 +640,7 @@ func UpdateMyDeliveryAddress(ctx *jxcontext.Context, addressID int, payload map[
}
func QueryUserDeliveryAddress(ctx *jxcontext.Context, userIDs []string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
addressList, totalCount, err := dao.QueryUserDeliveryAddress(dao.GetDB(), userIDs, offset, pageSize)
addressList, totalCount, err := dao.QueryUserDeliveryAddress(dao.GetDB(), 0, userIDs, offset, pageSize)
if err == nil {
pagedInfo = &model.PagedInfo{
TotalCount: totalCount,
@@ -649,7 +652,7 @@ func QueryUserDeliveryAddress(ctx *jxcontext.Context, userIDs []string, offset,
func QueryMyDeliveryAddress(ctx *jxcontext.Context) (addressList []*dao.UserDeliveryAddressEx, err error) {
_, userID := ctx.GetMobileAndUserID()
addressList, _, err = dao.QueryUserDeliveryAddress(dao.GetDB(), []string{userID}, 0, model.UnlimitedPageSize)
addressList, _, err = dao.QueryUserDeliveryAddress(dao.GetDB(), 0, []string{userID}, 0, model.UnlimitedPageSize)
return addressList, err
}
@@ -702,3 +705,11 @@ func LoadUserCart(ctx *jxcontext.Context, userID string, storeIDs []int) (cartIt
err = dao.GetRows(dao.GetDB(), &cartItems, sql, userID, storeIDs)
return cartItems, err
}
func GetSelfInfo(ctx *jxcontext.Context) (user *model.User, err error) {
tokenInfo, err := auth2.GetTokenInfo(ctx.GetToken())
if err == nil {
user, err = dao.GetUserByID(dao.GetDB(), "user_id", tokenInfo.GetID())
}
return user, err
}

View File

@@ -220,17 +220,20 @@ func GetAllStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeList
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
storeInfo := batchItemList[0].(*cms.StoreExt)
storeID := storeInfo.ID
jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, false,map[string]interface{}{}, 0, -1)
jxSkuPriceMapData := make(map[int]int)
for _, value := range jxSkuInfoData.SkuNames {
for _, skuInfo := range value.Skus2 {
saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus)
if saleStatus == model.SkuStatusNormal {
jxSkuPriceMapData[skuInfo.SkuID] = skuInfo.BindPrice
if jxSkuInfoData, err2 := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, false, map[string]interface{}{}, 0, -1); jxSkuInfoData != nil {
jxSkuPriceMapData := make(map[int]int)
for _, value := range jxSkuInfoData.SkuNames {
for _, skuInfo := range value.Skus2 {
saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus)
if saleStatus == model.SkuStatusNormal {
jxSkuPriceMapData[skuInfo.SkuID] = skuInfo.BindPrice
}
}
}
allStoreSkusWrapper.SetData(storeID, jxSkuPriceMapData)
} else {
globals.SugarLogger.Warnf("store_score.GetAllStoreSkus %d return empty, err:%v", storeID, err2)
}
allStoreSkusWrapper.SetData(storeID, jxSkuPriceMapData)
return retVal, err
}
taskParallel := tasksch.NewParallelTask("得到所有门店商品", tasksch.NewParallelConfig().SetParallelCount(ParallelCount), ctx, taskFunc, storeList)

View File

@@ -577,7 +577,7 @@ func DeleteWrongSpu(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (
mapData := map[string]interface{}{
"name": skuNameList[step].Name,
}
_, err = cms.UpdateSkuName(ctx, skuNameList[step].ID, mapData, ctx.GetUserName())
_, err = cms.UpdateSkuName(ctx, skuNameList[step].ID, mapData)
if err != nil {
globals.SugarLogger.Debugf("DeleteWrongSpu failed nameid:%d, name:%s, with error:%v", skuNameList[step].ID, skuNameList[step].Name, err)
}

View File

@@ -0,0 +1,125 @@
package yonghui
import (
"fmt"
"mime/multipart"
"unicode"
"git.rosy.net.cn/baseapi/platformapi/jdapi"
"git.rosy.net.cn/baseapi/platformapi/weimobapi"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"github.com/360EntSecGroup-Skylar/excelize"
)
var (
sheetNames = []string{"蔬菜", "水果", "肉禽", "净配", "水产", "干货", "MINI肉禽价格"}
)
//sheet1 蔬菜
var (
sheet1SkuIdCol = 0
sheet1SkuPriceCol = 14
sheet1OrgSkuIdCol = 5
sheet1OrgSkuPriceCol = 8
)
func SendFilesToStores(ctx *jxcontext.Context, files []*multipart.FileHeader) (hint string, err error) {
var (
// skuId string
// skuPrice string
skuMap = make(map[string]string)
)
param := &weimobapi.QueryGoodsListParam{
PageNum: 1,
PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds,
}
// if len(files) == 0 {
// return "", errors.New("没有文件上传!")
// }
xlsx, err := excelize.OpenFile("111.xlsx")
if err != nil {
fmt.Println(err)
return
}
for _, v := range sheetNames {
// goodsParam := &weimobapi.GoodsParameter{}
rows, _ := xlsx.GetRows(v)
switch v {
case "蔬菜":
for _, row := range rows {
for k, _ := range row {
if k == sheet1SkuIdCol {
}
// if !IsChineseChar(colCell) {
// }
}
fmt.Println()
}
}
}
// xlFile, err := xlsx.OpenFile("111.xlsx")
// if err != nil {
// errors.New(err.Error())
// }
// excelize
// for _, sheet := range xlFile.Sheets {
// if sheet.Name == "蔬菜" {
// for j := 0; j < len(sheet.Rows); j++ {
// cells := sheet.Rows[j].Cells
// for i := 0; i < len(cells); i++ {
// cell := cells[i]
// if i == 0 {
// if _, err := strconv.Atoi(cell.String()); err != nil || cell.String() == "" {
// continue
// }
// skuId = cell.String()
// }
// if i == 14 {
// skuPrice = cell.String()
// }
// skuMap[skuId] = skuPrice
// }
// }
// }
// }
for k, v := range skuMap {
fmt.Println(k)
fmt.Println(v)
}
GetWeiMoGoodsList(param)
return "", err
}
func GetWeiMoGoodsList(param *weimobapi.QueryGoodsListParam) {
// for {
// skuList, _, err2 := getAPI("").QuerySkuInfos(param)
// if err = err2; err != nil {
// return nil, err
// }
// if len(skuList) > 0 {
// batchSkuNameList := make([]*partner.SkuNameInfo, len(skuList))
// for k, v := range skuList {
// batchSkuNameList[k] = vendorSku2Jx(v)
// }
// setSkuNameListPic(batchSkuNameList)
// skuNameList = append(skuNameList, batchSkuNameList...)
// }
// if len(skuList) < param.PageSize {
// break
// }
// param.PageNum++
// }
}
func IsChineseChar(str string) bool {
for _, r := range str {
if unicode.Is(unicode.Scripts["Han"], r) {
return true
}
}
return false
}

View File

@@ -80,18 +80,12 @@ func getJxStoreIDFromOrder(order *model.GoodsOrder) (retVal int) {
// 此函数得到的是order的销售门店京西ID与GetJxStoreIDFromOrder的区别是order.StoreID的解释不同参考其它相关资料
func GetSaleStoreIDFromOrder(order *model.GoodsOrder) (retVal int) {
if order.VendorID != model.VendorIDWSC {
return getJxStoreIDFromOrder(order)
}
return order.StoreID
return getJxStoreIDFromOrder(order)
}
// 此函数得到的是order的商品的展示门店京西ID与GetJxStoreIDFromOrder的区别是order.StoreID的解释不同参考其它相关资料
func GetShowStoreIDFromOrder(order *model.GoodsOrder) (retVal int) {
if order.VendorID != model.VendorIDWSC {
return getJxStoreIDFromOrder(order)
}
return order.JxStoreID
return getJxStoreIDFromOrder(order)
}
func GetSkuIDFromOrderSku(sku *model.OrderSku) (skuID int) {
@@ -241,7 +235,7 @@ func IntCoordinate2MarsStandard(gpsLng, gpsLat int, coordinateType int) (marsLng
case model.CoordinateTypeGPS:
coordSys = autonavi.CoordSysGPS
case model.CoordinateTypeMars:
coordSys = autonavi.CoordSysAutonavi
return marsLng, marsLat, nil
case model.CoordinateTypeBaiDu:
coordSys = autonavi.CoordSysBaidu
case model.CoordinateTypeMapbar:
@@ -526,6 +520,7 @@ func RefreshOrderSkuRelated(order *model.GoodsOrder) *model.GoodsOrder {
order.VendorPrice = 0
order.ShopPrice = 0
order.Weight = 0
order.EarningPrice = 0
for _, sku := range order.Skus {
if sku.SkuID > math.MaxInt32 {
sku.SkuID = 0
@@ -538,6 +533,7 @@ func RefreshOrderSkuRelated(order *model.GoodsOrder) *model.GoodsOrder {
order.SalePrice += sku.SalePrice * int64(sku.Count)
order.VendorPrice += sku.VendorPrice * int64(sku.Count)
order.ShopPrice += sku.ShopPrice * int64(sku.Count)
order.EarningPrice += sku.EarningPrice * int64(sku.Count)
order.Weight += sku.Weight * sku.Count
}
return order
@@ -783,3 +779,29 @@ func GetOneEmailFromStr(str string) (email string) {
}
return email
}
// 计算一个坐标点距离一个门店的距离单位为米如果不在有效范围内则返回0
func Point2StoreDistance(lng, lat float64, intStoreLng, intStoreLat int, deliveryRangeType int8, deliveryRange string) (distance int) {
storeLng := IntCoordinate2Standard(intStoreLng)
storeLat := IntCoordinate2Standard(intStoreLat)
if deliveryRangeType == model.DeliveryRangeTypeRadius {
maxDistance := int(utils.Str2Int64WithDefault(deliveryRange, 0))
distance = int(EarthDistance(lng, lat, storeLng, storeLat) * 1000)
if distance > maxDistance {
distance = 0
}
} else {
points := CoordinateStr2Points(deliveryRange)
if utils.IsPointInPolygon(lng, lat, points) {
distance = int(EarthDistance(lng, lat, storeLng, storeLat) * 1000)
}
}
return distance
}
func TranslateStorePriceType(storePriceType int8) int8 {
if storePriceType == model.StoreChangePriceTypeManagedStore {
storePriceType = model.StoreChangePriceTypeBossDisabled
}
return storePriceType
}

View File

@@ -245,60 +245,80 @@ func CaculateUnitPrice(skuPrice int, specQuality float32, specUnit string, skuNa
return unitPrice
}
func CaculateSkuVendorPrice(price, percentage int) (vendorPrice int) {
if percentage <= 10 || percentage >= 400 {
percentage = 100
func ConstrainPricePercentage(percentage int) int {
if percentage <= model.MinVendorPricePercentage || percentage >= model.MaxVendorPricePercentage {
percentage = model.DefVendorPricePercentage
}
vendorPrice = int(math.Round(float64(price*percentage) / 100))
return percentage
}
func CaculateSkuVendorPrice(price, percentage, priceAdd int) (vendorPrice int) {
percentage = ConstrainPricePercentage(percentage)
vendorPrice = int(math.Round(float64(price*percentage)/100)) + priceAdd
if vendorPrice < 1 {
vendorPrice = 1
}
return vendorPrice
}
func CaculateSkuPriceFromVendor(vendorPrice, percentage int) (price int) {
if percentage <= 10 || percentage >= 400 {
percentage = 100
}
price = int(math.Round(float64(vendorPrice) * 100 / float64(percentage)))
func CaculateSkuPriceFromVendor(vendorPrice, percentage, priceAdd int) (price int) {
percentage = ConstrainPricePercentage(percentage)
price = int(math.Round(float64(vendorPrice-priceAdd) * 100 / float64(percentage)))
if price < 0 {
price = 0
}
return price
}
func GetPricePercentage(l model.PricePercentagePack, price int, defPricePercentage int) (pricePercentage int) {
func GetPricePercentage(l model.PricePercentagePack, price int, defPricePercentage int) (pricePercentage, priceAdd int) {
pricePercentage = defPricePercentage
if len(l) > 0 {
var lastItem *model.PricePercentageItem
for _, v := range l {
if v.BeginPrice > price {
itemLen := len(l)
if itemLen > 0 {
low := 0
high := itemLen - 1
mid := 0
for low <= high {
mid = low + (high-low)/2
if mid == 0 || mid == itemLen-1 {
break
}
lastItem = v
}
if lastItem != nil {
pricePercentage = lastItem.PricePercentage
if price >= l[mid].BeginPrice {
if price < l[mid+1].BeginPrice {
break
} else {
low = mid + 1
}
} else {
high = mid - 1
}
}
pricePercentage = l[mid].PricePercentage
priceAdd = l[mid].PriceAdd
}
return pricePercentage
return pricePercentage, priceAdd
}
func GetPricePercentageByVendorPrice(l model.PricePercentagePack, vendorPrice int, defPricePercentage int) (pricePercentage int) {
func GetPricePercentageByVendorPrice(l model.PricePercentagePack, vendorPrice int, defPricePercentage int) (pricePercentage, priceAdd int) {
pricePercentage = defPricePercentage
if len(l) > 0 {
var lastItem *model.PricePercentageItem
for _, v := range l {
if CaculateSkuVendorPrice(v.BeginPrice, v.PricePercentage) > vendorPrice {
if CaculateSkuVendorPrice(v.BeginPrice, v.PricePercentage, v.PriceAdd) > vendorPrice {
break
}
lastItem = v
}
if lastItem != nil {
pricePercentage = lastItem.PricePercentage
priceAdd = lastItem.PriceAdd
}
}
return pricePercentage
return pricePercentage, priceAdd
}
func CaculatePriceByPricePack(l model.PricePercentagePack, defPricePercentage, price int) (outPrice int) {
pricePercentage, priceAdd := GetPricePercentage(l, price, defPricePercentage)
return CaculateSkuVendorPrice(price, pricePercentage, priceAdd)
}
func IsSkuSpecial(specQuality float32, specUnit string) bool {

View File

@@ -164,3 +164,47 @@ func TestCaculateSkuPrice(t *testing.T) {
}
}
}
func TestGetPricePercentage(t *testing.T) {
type tTestInfo struct {
DesiredPrice int
UnitPrice int
SpecQuality float32
SpecUnit string
Unit string
}
l := []*model.PricePercentageItem{
&model.PricePercentageItem{
BeginPrice: 0,
PricePercentage: 0,
PriceAdd: 0,
},
&model.PricePercentageItem{
BeginPrice: 10,
PricePercentage: 10,
PriceAdd: 1,
},
&model.PricePercentageItem{
BeginPrice: 20,
PricePercentage: 20,
PriceAdd: 2,
},
&model.PricePercentageItem{
BeginPrice: 30,
PricePercentage: 30,
PriceAdd: 3,
},
}
for _, v := range [][]int{
[]int{0, 0, 0, 0},
[]int{30, 3, 40, 0},
[]int{20, 2, 25, 0},
[]int{10, 1, 10, 0},
} {
pricePercentage, priceAdd := GetPricePercentage(l, v[2], v[3])
if pricePercentage != v[0] || priceAdd != v[1] {
t.Errorf("price:%d, defPricePercentage:%d, expected pricePercentage:%d, priceAdd:%d, actual pricePercentage:%d, priceAdd:%d",
v[2], v[3], v[0], v[1], pricePercentage, priceAdd)
}
}
}

View File

@@ -14,8 +14,6 @@ import (
"git.rosy.net.cn/jx-callback/globals"
)
const weixinTemplateID4StoreStatusChanged = "Fl0vOnBKTQqRFx3-shGKxdCnxMdQXNeODzgkuwd7oxw"
// todo msgType不依赖于钉钉
func SendUserMessage(msgType string, user *model.User, title, content string) (err error) {
userID := user.GetID()

View File

@@ -417,7 +417,7 @@ func PushJDBadCommentToWeiXin(comment *legacymodel.JxBadComments, isBadComment b
orderInfo = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[int(utils.Str2Int64WithDefault(comment.OrderFlag, 0))], order.OrderSeq, comment.OrderId)
consigneeName = order.ConsigneeName
} else {
orderInfo = fmt.Sprintf("%s订单, %s", model.VendorChineseNames[int(utils.Str2Int64WithDefault(comment.OrderFlag, 0))], comment.OrderId)
orderInfo = fmt.Sprintf("%s订单, %s", model.VendorChineseNames[int(utils.Str2Int64WithDefault(comment.OrderFlag, 0))] /*comment.OrderId*/, "")
}
data := map[string]interface{}{
"first": map[string]interface{}{

View File

@@ -27,7 +27,8 @@ var (
VendorIDMTWM: "美好菜市",
VendorIDELM: "好菜鲜生",
VendorIDEBAI: "好菜鲜生",
VendorIDWSC: "京西菜市",
VendorIDJX: "京西商城",
VendorIDWSC: "微盟微商城",
}
OrderStatusName = map[int]string{
@@ -268,7 +269,8 @@ const (
OrderFlagMaskCallPMCourier = 64 // 取货失败后召唤平台配送
OrderFlagMaskSetDelivered = 128 // 设置送达
OrderFlagMaskFake = 256 // 假订单,即刷单用的
OrderFlagMaskFake = 256 // 假订单,即刷单用的
OrderFlagMaskTempJX = 512 // 临时京西订单
)
const (
@@ -305,6 +307,14 @@ const (
AfsTypeFullRefund = 2 // 全额退款
)
const (
DefaultEarningPricePercentage = 70 // 门店缺省结算百分比
MinVendorPricePercentage = 10
DefVendorPricePercentage = 100 // 平台缺省调价比例
MaxVendorPricePercentage = 400
)
func IsPurchaseVendorExist(vendorID int) bool {
_, ok := VendorNames[vendorID]
return ok && vendorID >= VendorIDPurchaseBegin && vendorID <= VendorIDPurchaseEnd
@@ -340,8 +350,8 @@ func IsOrderImportantStatus(status int) bool {
return IsOrderMainStatus(status) || IsOrderLockStatus(status) || IsOrderUnlockStatus(status)
}
func IsSpecialVendorID(vendorID int) bool {
return vendorID == VendorIDWSC || vendorID == VendorIDJX
func IsVendorRemote(vendorID int) bool {
return vendorID >= VendorIDJD && vendorID <= VendorIDEBAI
}
func WaybillVendorID2Mask(vendorID int) (mask int8) {
@@ -356,7 +366,3 @@ func WaybillVendorID2Mask(vendorID int) (mask int8) {
func IsAfsOrderFinalStatus(status int) bool {
return status >= AfsOrderStatusFinished && status <= AfsOrderStatusFailed
}
const (
DefaultEarningPricePercentage = 70 // 门店缺省结算百分比
)

View File

@@ -36,30 +36,139 @@ type OrderSkuWithActualPayPrice struct {
PayPercentage int `json:"payPercentage"`
}
func QueryOrders(db *DaoDB, vendorIDs []int, storeID int, orderCreatedAtBegin, orderCreatedAtEnd time.Time) (orderList []*model.GoodsOrder, err error) {
type tGoodsAndOrder struct {
model.GoodsOrder
OrderSkuID int64 `orm:"column(order_sku_id)" json:"orderSkuID"`
StoreSubID int `orm:"column(store_sub_id)" json:"storeSubID"` // 当前这个字段被当成结算活动ID用
StoreSubName string `orm:"size(64)" json:"storeSubName"` // 当前这个字段被用作vendorActType
Count int `json:"count"`
VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"`
SkuID int `orm:"column(sku_id)" json:"skuID"` // 外部系统里记录的 jxskuid
JxSkuID int `orm:"column(jx_sku_id)" json:"jxSkuID"` // 根据VendorSkuID在本地系统里查询出来的 jxskuid
SkuName string `orm:"size(255)" json:"skuName"`
SkuShopPrice int64 `json:"shopPrice"` // 京西价
SkuVendorPrice int64 `json:"vendorPrice"` // 平台价
SkuSalePrice int64 `json:"salePrice"` // 售卖价
SkuEarningPrice int64 `json:"earningPrice"` // 活动商品设置结算给门店老板的钱如果结算活动ID为0是按结算比例算的否则就是结算表中的值
Weight int `json:"weight"` // 单位为克
SkuType int `json:"skuType"` // 当前如果为gift就为1否则缺省为0
PromotionType int `json:"promotionType"` // todo 当前是用于记录京东的PromotionType(生成jxorder用),没有做转换
}
//actID指结算活动的id
func QueryOrders(db *DaoDB, vendorOrderID string, actID int, vendorIDs []int, storeID int, fromDate, toDate time.Time) (orderList []*model.GoodsOrder, err error) {
sqlParams := []interface{}{}
var (
orderNewList []*tGoodsAndOrder
orderNewMap map[string][]*model.OrderSku
)
sql := `
SELECT t1.*
FROM goods_order t1
WHERE t1.order_created_at >= ?`
sqlParams := []interface{}{
orderCreatedAtBegin,
SELECT a.*,
b.id order_sku_id, b.store_sub_id, b.store_sub_name, b.count, b.vendor_sku_id, b.sku_id, b.jx_sku_id, b.sku_name, b.shop_price sku_shop_price,
b.vendor_price sku_vendor_price, b.sale_price sku_sale_price, b.earning_price sku_earning_price, b.weight, b.sku_type, b.promotion_type
FROM goods_order a
JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id
`
if actID > 0 {
sql += `
JOIN ( SELECT t4.vendor_order_id, t4.vendor_id
FROM act t1
JOIN act_store_sku t2 ON t2.act_id = t1.id
JOIN order_sku t3 ON t3.sku_id = t2.sku_id
JOIN goods_order t4 ON t4.vendor_order_id = t3.vendor_order_id
AND t4.vendor_id = t3.vendor_id
AND t2.store_id = IF(t4.jx_store_id <> 0, t4.jx_store_id, t4.store_id)
AND t4.order_created_at BETWEEN t1.begin_at AND t1.end_at
WHERE t1.status = 1
AND t1.type = ?
AND t1.id = ?
GROUP BY 1,2
)s ON s.vendor_order_id = a.vendor_order_id AND s.vendor_id = a.vendor_id
`
sqlParams = append(sqlParams, model.ActSkuFake, actID)
}
sql += `
WHERE 1=1
`
if vendorOrderID != "" {
sql += " AND a.vendor_order_id = ?"
sqlParams = append(sqlParams, vendorOrderID)
}
if len(vendorIDs) > 0 {
sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
sql += " AND a.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
sqlParams = append(sqlParams, vendorIDs)
}
if storeID > 0 {
sql += " AND IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id) = ?"
sql += " AND IF(a.jx_store_id <> 0, a.jx_store_id, a.store_id) = ?"
sqlParams = append(sqlParams, storeID)
}
if !utils.IsTimeZero(orderCreatedAtEnd) {
sql += " AND t1.order_created_at <= ?"
sqlParams = append(sqlParams, orderCreatedAtEnd)
if !utils.IsTimeZero(fromDate) && !utils.IsTimeZero(toDate) {
sql += " AND a.order_created_at BETWEEN ? and ?"
sqlParams = append(sqlParams, fromDate, toDate)
}
// sql += " ORDER BY t1.order_created_at DESC, t1.id DESC;"
return orderList, GetRows(db, &orderList, sql, sqlParams...)
err = GetRows(db, &orderNewList, sql, sqlParams...)
if len(orderNewList) > 0 {
orderNewMap = make(map[string][]*model.OrderSku)
for _, v := range orderNewList {
if orderNewMap[v.VendorOrderID] == nil {
orderList = append(orderList, &v.GoodsOrder)
}
orderNewMap[v.VendorOrderID] = append(orderNewMap[v.VendorOrderID], &model.OrderSku{
ID: v.OrderSkuID,
VendorOrderID: v.VendorOrderID,
VendorID: v.VendorID,
StoreSubID: v.StoreSubID,
StoreSubName: v.StoreSubName,
Count: v.Count,
VendorSkuID: v.VendorSkuID,
SkuID: v.SkuID,
JxSkuID: v.JxSkuID,
SkuName: v.SkuName,
ShopPrice: v.SkuShopPrice,
VendorPrice: v.SkuVendorPrice,
SalePrice: v.SkuSalePrice,
EarningPrice: v.SkuEarningPrice,
Weight: v.Weight,
SkuType: v.SkuType,
PromotionType: v.PromotionType,
})
}
for _, v := range orderList {
v.Skus = orderNewMap[v.VendorOrderID]
}
}
return orderList, err
}
// func QueryOrders(db *DaoDB, vendorOrderID string, vendorIDs []int, storeID int, orderCreatedAtBegin, orderCreatedAtEnd time.Time) (orderList []*model.GoodsOrder, err error) {
// sql := `
// SELECT t1.*
// FROM goods_order t1
// WHERE t1.order_created_at >= ?`
// sqlParams := []interface{}{
// orderCreatedAtBegin,
// }
// if vendorOrderID != "" {
// sql += " AND t1.vendor_order_id = ?"
// sqlParams = append(sqlParams, vendorOrderID)
// }
// if len(vendorIDs) > 0 {
// sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
// sqlParams = append(sqlParams, vendorIDs)
// }
// if storeID > 0 {
// sql += " AND IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id) = ?"
// sqlParams = append(sqlParams, storeID)
// }
// if !utils.IsTimeZero(orderCreatedAtEnd) {
// sql += " AND t1.order_created_at <= ?"
// sqlParams = append(sqlParams, orderCreatedAtEnd)
// }
// // sql += " ORDER BY t1.order_created_at DESC, t1.id DESC;"
// return orderList, GetRows(db, &orderList, sql, sqlParams...)
// }
func GetStoreOrderAfterTime(db *DaoDB, storeID int, orderTime time.Time, lastOrderSeqID int64) (orderList []*model.GoodsOrderExt, err error) {
sql := `
SELECT t1.*,

View File

@@ -158,7 +158,7 @@ func GetStoreListByMobileOrStoreIDs(db *DaoDB, mobile string, shortRoleNameList
return storeList, err
}
func QueryUserDeliveryAddress(db *DaoDB, userIDs []string, offset, pageSize int) (addressList []*UserDeliveryAddressEx, totalCount int, err error) {
func QueryUserDeliveryAddress(db *DaoDB, addressID int64, userIDs []string, offset, pageSize int) (addressList []*UserDeliveryAddressEx, totalCount int, err error) {
sql := `
SELECT SQL_CALC_FOUND_ROWS
t1.*,
@@ -174,6 +174,10 @@ func QueryUserDeliveryAddress(db *DaoDB, userIDs []string, offset, pageSize int)
sqlParams := []interface{}{
utils.DefaultTimeValue,
}
if addressID > 0 {
sql += " AND t1.id = ? "
sqlParams = append(sqlParams, addressID)
}
if len(userIDs) > 0 {
sql += " AND t1.user_id IN (" + GenQuestionMarks(len(userIDs)) + ")"
sqlParams = append(sqlParams, userIDs)

View File

@@ -25,7 +25,7 @@ type FoodRecipeItemChoiceExt struct {
Comment string `json:"-"`
}
func QueryFoodRecipes(db *DaoDB, keyword string, recipeID int, authorID, userID string, offset, pageSize int) (recipeList []*FoodRecipeWithAction, totalCount int, err error) {
func QueryFoodRecipes(db *DaoDB, keyword string, recipeID int, authorID, userID string, skuIDs []int, offset, pageSize int) (recipeList []*FoodRecipeWithAction, totalCount int, err error) {
var sql string
var sqlParams []interface{}
if userID != "" {
@@ -64,6 +64,14 @@ func QueryFoodRecipes(db *DaoDB, keyword string, recipeID int, authorID, userID
sql += " AND t1.author_id = ?"
sqlParams = append(sqlParams, authorID)
}
if len(skuIDs) > 0 {
sql += ` AND (
SELECT COUNT(*)
FROM food_recipe_item_choice t11
WHERE t11.recipe_id = t1.id AND t11.sku_id IN (` + GenQuestionMarks(len(skuIDs)) + `)
) > 0`
sqlParams = append(sqlParams, skuIDs)
}
offset = FormalizePageOffset(offset)
pageSize = FormalizePageSize(pageSize)
sql += `
@@ -80,7 +88,7 @@ func QueryFoodRecipes(db *DaoDB, keyword string, recipeID int, authorID, userID
}
func GetRecommendFoodRecipes(db *DaoDB, keyword, userID string, offset, pageSize int) (recipeList []*model.FoodRecipe, totalCount int, err error) {
list, totalCount, err := QueryFoodRecipes(db, keyword, 0, userID, "", offset, pageSize)
list, totalCount, err := QueryFoodRecipes(db, keyword, 0, userID, "", nil, offset, pageSize)
if err == nil {
recipeList = FoodRecipeWithActionList2Recipe(list)
}

View File

@@ -6,8 +6,6 @@ import (
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/globals"
"github.com/astaxie/beego/orm"
)
// 带购物平台信息的
@@ -97,13 +95,15 @@ func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (sto
sql += " AND t2.vendor_store_id = ?"
sqlParams = append(sqlParams, vendorStoreID)
}
storeDetail = &StoreDetail{}
if err = GetRow(db, storeDetail, sql, sqlParams...); err == nil {
if err = GetRow(db, &storeDetail, sql, sqlParams...); err == nil {
storeDetail.PricePercentagePackObj = PricePercentagePack2Obj(storeDetail.PricePercentagePackStr)
storeDetail.FreightDeductionPackObj = FreightDeductionPack2Obj(storeDetail.FreightDeductionPackStr)
if vendorID == model.VendorIDJX {
if storeDetail.VendorStoreID == "" {
storeDetail.VendorStatus = storeDetail.Status
storeDetail.PricePercentage = 100
storeDetail.PricePercentage = model.DefVendorPricePercentage
storeDetail.AutoPickup = 1
storeDetail.DeliveryType = model.StoreDeliveryTypeByStore
storeDetail.DeliveryCompetition = 1
}
return storeDetail, nil
}
@@ -124,67 +124,6 @@ func GetStoreDetailByVendorStoreID(db *DaoDB, vendorStoreID string, vendorID int
return storeDetail, err
}
func GetPossibleStoresByPlaceName(db *DaoDB, cityName, provinceName string) (storeList []*StoreDetail, err error) {
sqlList := []string{
`
SELECT t1.*, t5.vendor_store_id
FROM store t1
JOIN place t2 ON t2.code = t1.city_code AND t2.name = ?
LEFT JOIN store_map t5 ON t1.id = t5.store_id AND t5.vendor_id = ? AND t5.deleted_at = ?
WHERE t1.status = ? AND (SELECT COUNT(*) FROM store_map t10 WHERE t10.store_id = t1.id AND t10.deleted_at = ? AND t10.status <> ?) > 0
`,
`
SELECT t1.*, t5.vendor_store_id
FROM store t1
JOIN place t2 ON t2.code = t1.city_code
JOIN place t3 ON t3.code = t2.parent_code AND t3.name = ?
LEFT JOIN store_map t5 ON t1.id = t5.store_id AND t5.vendor_id = ? AND t5.deleted_at = ?
WHERE t1.status = ? AND (SELECT COUNT(*) FROM store_map t10 WHERE t10.store_id = t1.id AND t10.deleted_at = ? AND t10.status <> ?) > 0
`,
`
SELECT t1.*, t5.vendor_store_id
FROM store t1
LEFT JOIN store_map t5 ON t1.id = t5.store_id AND t5.vendor_id = ? AND t5.deleted_at = ?
WHERE t1.status = ? AND (SELECT COUNT(*) FROM store_map t10 WHERE t10.store_id = t1.id AND t10.deleted_at = ? AND t10.status <> ?) > 0
`,
}
sqlParamsList := [][]interface{}{
[]interface{}{
cityName,
model.VendorIDWSC,
utils.DefaultTimeValue,
model.StoreStatusOpened,
utils.DefaultTimeValue,
model.StoreStatusDisabled,
},
[]interface{}{
provinceName,
model.VendorIDWSC,
utils.DefaultTimeValue,
model.StoreStatusOpened,
utils.DefaultTimeValue,
model.StoreStatusDisabled,
},
[]interface{}{
model.VendorIDWSC,
utils.DefaultTimeValue,
model.StoreStatusOpened,
utils.DefaultTimeValue,
model.StoreStatusDisabled,
},
}
for k := range sqlList {
if err = GetRows(db, &storeList, sqlList[k], sqlParamsList[k]); err != nil {
return nil, err
}
if len(storeList) > 0 {
return storeList, nil
}
}
// 正常是不应该达到这里的
return storeList, err
}
// 这个返回的地点信息是城市
func GetStoreDetail2(db *DaoDB, storeID int, vendorStoreID string, vendorID int) (storeDetail *StoreDetail2, err error) {
sql := `
@@ -244,10 +183,12 @@ func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs []int, status, isSync int,
sql := `
SELECT t1.*
FROM store_map t1
JOIN store t2 ON t2.id = t1.store_id AND t2.deleted_at = ?
WHERE t1.deleted_at = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
utils.DefaultTimeValue,
}
if len(vendorIDs) > 0 {
sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
@@ -354,15 +295,31 @@ func GetRebindPrinterStoreList(db *DaoDB) (storeList []*model.Store, err error)
return storeList, err
}
// 容错用
type tPricePercentageItemFloat struct {
BeginPrice float64 `json:"beginPrice"` // 起始价格区间(包括)
PricePercentage float64 `json:"pricePercentage"` // 调价比例
PriceAdd float64 `json:"priceAdd"` // 调价额定值
}
func PricePercentagePack2Obj(packStr string) (obj model.PricePercentagePack) {
if packStr != "" {
if err := utils.UnmarshalUseNumber([]byte(packStr), &obj); err == nil {
for _, v := range obj {
if v.PricePercentage >= 500 || v.PricePercentage <= 80 {
return nil
var floatObj []*tPricePercentageItemFloat
if err := utils.UnmarshalUseNumber([]byte(packStr), &floatObj); err == nil {
if len(floatObj) > 0 {
obj = make(model.PricePercentagePack, len(floatObj))
for k, v := range floatObj {
if v.PricePercentage >= 500 || v.PricePercentage <= 80 {
return nil
}
obj[k] = &model.PricePercentageItem{
BeginPrice: int(v.BeginPrice),
PricePercentage: int(v.PricePercentage),
PriceAdd: int(v.PriceAdd),
}
}
sort.Sort(obj)
}
sort.Sort(obj)
}
}
return obj
@@ -374,7 +331,6 @@ func AddStoreCategoryMap(db *DaoDB, storeID, categoryID int, vendorID int, vendo
CategoryID: categoryID,
MtwmSyncStatus: model.SyncFlagNewMask,
EbaiSyncStatus: model.SyncFlagNewMask,
WscSyncStatus: model.SyncFlagNewMask,
}
storeCat.DeletedAt = utils.DefaultTimeValue
if err = GetEntity(db, storeCat, model.FieldStoreID, model.FieldCategoryID, model.FieldDeletedAt); err != nil && !IsNoRowsError(err) {
@@ -383,15 +339,9 @@ func AddStoreCategoryMap(db *DaoDB, storeID, categoryID int, vendorID int, vendo
if vendorID == model.VendorIDMTWM {
storeCat.MtwmID = vendorCategoryID
storeCat.MtwmSyncStatus = status
} else if vendorID == model.VendorIDEBAI || vendorID == model.VendorIDWSC {
intVendorCategoryID := utils.Str2Int64WithDefault(vendorCategoryID, 0)
if vendorID == model.VendorIDEBAI {
storeCat.EbaiID = intVendorCategoryID
storeCat.EbaiSyncStatus = status
} else {
storeCat.WscID = intVendorCategoryID
storeCat.WscSyncStatus = status
}
} else if vendorID == model.VendorIDEBAI {
storeCat.EbaiID = utils.Str2Int64WithDefault(vendorCategoryID, 0)
storeCat.EbaiSyncStatus = status
} else {
panic("unsupported vendor")
}
@@ -407,49 +357,6 @@ func AddStoreCategoryMap(db *DaoDB, storeID, categoryID int, vendorID int, vendo
return err
}
func GetStoreMapByStoreID(db *DaoDB, storeID, vendorID int) (storeMap *model.StoreMap, err error) {
if db == nil {
db = GetDB()
}
storeMap = &model.StoreMap{
StoreID: storeID,
VendorID: vendorID,
}
storeMap.DeletedAt = utils.DefaultTimeValue
if err = GetEntity(db, storeMap, model.FieldStoreID, model.FieldVendorID, model.FieldDeletedAt); err != nil {
if err != orm.ErrNoRows {
globals.SugarLogger.Warnf("GetStoreMapByStoreID storeID:%d, vendorID:%d read storeMap failed with error:%v", storeID, vendorID, err)
}
return nil, err
}
return storeMap, nil
}
func FakeGetStoreMapByStoreID(db *DaoDB, storeID, vendorID int) (storeMap *model.StoreMap, err error) {
vendorID2 := vendorID
if model.IsSpecialVendorID(vendorID) {
vendorID2 = model.VendorIDJD // 微商城与京西的属性以京东属性为准(以免再绑定)
}
if storeMap, err = GetStoreMapByStoreID(db, storeID, vendorID2); model.IsSpecialVendorID(vendorID) && IsNoRowsError(err) {
err = nil
storeMap = &model.StoreMap{
StoreID: storeID,
VendorID: vendorID2,
Status: model.StoreStatusOpened,
PricePercentage: 100,
AutoPickup: 1,
DeliveryType: model.StoreDeliveryTypeByStore,
// DeliveryFee
DeliveryCompetition: 1,
IsSync: 1,
}
}
if storeMap != nil && vendorID == model.VendorIDJX {
storeMap.DeliveryType = model.StoreDeliveryTypeByStore
}
return storeMap, err
}
func GetOpenedStoreCouriersByStoreID(db *DaoDB, storeID, vendorID int) (storeMaps []*model.StoreCourierMap, err error) {
if db == nil {
db = GetDB()

View File

@@ -213,14 +213,10 @@ func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty boo
if !isSingleStorePF {
tableName = "t2"
}
vendorSkuNameField := "0"
if vendorID == model.VendorIDWSC {
vendorSkuNameField = "t1.wsc_id2"
}
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
sql := `
SELECT t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, %s.%s_id vendor_sku_id,
t1.%s_sync_status store_sku_sync_status, %s vendor_name_id, t1.store_id, t1.deleted_at bind_deleted_at,
t1.%s_sync_status store_sku_sync_status, t1.store_id, t1.deleted_at bind_deleted_at,
t2.*,
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc,
IF(t11.%s <> '', t11.%s, t3.img) img,
@@ -228,7 +224,7 @@ func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty boo
t13.%s desc_img,
t4.%s_category_id vendor_vendor_cat_id`
fmtParams := []interface{}{
tableName, fieldPrefix, fieldPrefix, vendorSkuNameField,
tableName, fieldPrefix, fieldPrefix,
GetDataResFieldName(vendorID), GetDataResFieldName(vendorID),
GetDataResFieldName(vendorID), GetDataResFieldName(vendorID),
GetDataResFieldName(vendorID),

View File

@@ -17,7 +17,7 @@ const (
// FieldElmSyncStatus = "ElmSyncStatus"
FieldEbaiSyncStatus = "EbaiSyncStatus"
FieldMtwmSyncStatus = "MtwmSyncStatus"
FieldWscSyncStatus = "WscSyncStatus"
// FieldWscSyncStatus = "WscSyncStatus"
FieldVendorID = "VendorID"
FieldStoreID = "StoreID"
@@ -31,8 +31,8 @@ const (
// FieldElmID = "ElmID"
FieldEbaiID = "EbaiID"
FieldMtwmID = "MtwmID"
FieldWscID = "WscID"
FieldWscID2 = "WscID2"
// FieldWscID = "WscID"
// FieldWscID2 = "WscID2"
FieldSkuID = "SkuID"
FieldLevel = "Level"

View File

@@ -245,7 +245,7 @@ type OrderComment struct {
UserCommentID string `orm:"column(user_comment_id);size(48)" json:"userCommentID"`
IsReplied int8
Status int8
ModifyDuration int8 // 改评价的小时数
ModifyDuration int16 // 改评价的小时数
TagList string
Score int8
@@ -263,12 +263,7 @@ type OrderComment struct {
// 判断是否是购买平台自有物流
// 对于京东,饿百来说,就是其自有的物流,对于微商城来说,是达达
func IsWaybillPlatformOwn(bill *Waybill) bool {
return bill.OrderVendorID == bill.WaybillVendorID || IsSpecialOrderPlatformWaybill(bill)
}
// 是否是特殊物流
func IsSpecialOrderPlatformWaybill(bill *Waybill) bool {
return (bill.OrderVendorID == VendorIDWSC && bill.WaybillVendorID == VendorIDDada)
return bill.OrderVendorID == bill.WaybillVendorID
}
// 订单是否已经有了有效运单
@@ -280,3 +275,23 @@ func IsOrderHaveWaybill(order *GoodsOrder) bool {
func IsOrderHaveOwnWaybill(order *GoodsOrder) bool {
return order.VendorID == order.WaybillVendorID && order.VendorWaybillID != ""
}
// 订单的初始配送方式是否是门店自配送
func IsOrderDeliveryByStore(order *GoodsOrder) bool {
return order.DeliveryType == OrderDeliveryTypeStoreSelf
}
// 订单的初始配送方式是否是平台负责配送
func IsOrderDeliveryByPlatform(order *GoodsOrder) bool {
return order.DeliveryType == OrderDeliveryTypePlatform
}
func IsOrderJXTemp(order *GoodsOrder) bool {
// return order.Flag&OrderFlagMaskTempJX != 0
return true
}
func IsAfsOrderJXTemp(order *AfsOrder) bool {
// return order.Flag&OrderFlagMaskTempJX != 0
return true
}

View File

@@ -74,7 +74,6 @@ var (
"长条",
"鲜活宰杀",
"惠",
"鱼腥草",
"冰冻",
"思念",
"散装",

View File

@@ -43,9 +43,10 @@ const (
)
const (
StoreChangePriceTypeDirect = 0
StoreChangePriceTypeNeedApprove = 1
StoreChangePriceTypeBossDisabled = 2
StoreChangePriceTypeDirect = 0 // 普通门店
StoreChangePriceTypeNeedApprove = 1 // 改价需要审核,暂时没用
StoreChangePriceTypeBossDisabled = 2 // 完全禁止改价
StoreChangePriceTypeManagedStore = 3 // 直营门店,禁止改价
)
var (
@@ -234,6 +235,11 @@ var (
StoreAuditStatusOnline: "上线",
StoreAuditStatusRejected: "拒绝",
}
StorePriceTypeName = map[int]string{
StoreChangePriceTypeDirect: "可直接改价",
StoreChangePriceTypeBossDisabled: "禁止改价",
StoreChangePriceTypeManagedStore: "直营门店",
}
)
type Store struct {
@@ -258,12 +264,13 @@ type Store struct {
AutoEnableAt *time.Time `orm:"type(datetime);null" json:"autoEnableAt"` // 自动营业时间(临时休息用)
ChangePriceType int8 `json:"changePriceType"` // 修改价格类型,即是否需要审核
SMSNotify int8 `orm:"column(sms_notify);" json:"smsNotify"` // 是否通过短信接收订单消息
PrinterDisabled int8 `orm:"default(0)" json:"printerDisabled"` // 是否禁用网络打印机
PrinterFontSize int8 `orm:"default(0)" json:"printerFontSize"` // 打印字体-10正常1
PrinterVendorID int `orm:"column(printer_vendor_id);" json:"printerVendorID"`
PrinterSN string `orm:"size(32);column(printer_sn);index" json:"printerSN"`
PrinterKey string `orm:"size(64)" json:"printerKey"`
PrinterBindInfo string `orm:"size(1024)" json:"-"`
PrinterDisabled int8 `orm:"default(0)" json:"printerDisabled"` // 是否禁用网络打印机
PrinterFontSize int8 `orm:"default(0)" json:"printerFontSize"` // 打印字体-10正常1
PrinterVendorID int `orm:"column(printer_vendor_id);" json:"printerVendorID"`
PrinterSN string `orm:"size(32);column(printer_sn);index" json:"printerSN"`
PrinterKey string `orm:"size(64)" json:"printerKey"`
PrinterBindInfo string `orm:"size(1024)" json:"-"`
IDCardFront string `orm:"size(255);column(id_card_front)" json:"idCardFront"`
IDCardBack string `orm:"size(255);column(id_card_back)" json:"idCardBack"`
@@ -465,6 +472,7 @@ func (v *VendorStoreSnapshot) CompareOperationTime(s2 *VendorStoreSnapshot) int
type PricePercentageItem struct {
BeginPrice int `json:"beginPrice"` // 起始价格区间(包括)
PricePercentage int `json:"pricePercentage"` // 调价比例
PriceAdd int `json:"priceAdd"` // 调价额定值
}
type PricePercentagePack []*PricePercentageItem

View File

@@ -45,13 +45,13 @@ type StoreSkuCategoryMap struct {
// ElmID int64 `orm:"column(elm_id);index"`
EbaiID int64 `orm:"column(ebai_id);index"`
MtwmID string `orm:"column(mtwm_id);index;size(16)"` // 美团外卖没有ID保存名字
WscID int64 `orm:"column(wsc_id);index"`
MtwmID string `orm:"column(mtwm_id);index;size(16)"`
// WscID int64 `orm:"column(wsc_id);index"`
// ElmSyncStatus int8 `orm:"default(2)"`
EbaiSyncStatus int8 `orm:"default(2)"`
MtwmSyncStatus int8 `orm:"default(2)"`
WscSyncStatus int8 `orm:"default(2)"`
// WscSyncStatus int8 `orm:"default(2)"`
}
func (*StoreSkuCategoryMap) TableUnique() [][]string {
@@ -95,20 +95,21 @@ type StoreSkuBind struct {
// ElmID int64 `orm:"column(elm_id);index"`
EbaiID int64 `orm:"column(ebai_id);index"`
MtwmID int64 `orm:"column(mtwm_id)"` // 这个也不是必须的只是为了DAO取数据语句一致
WscID int64 `orm:"column(wsc_id);index"` // 表示微盟skuId
WscID2 int64 `orm:"column(wsc_id2);index"` // 表示微盟goodsId
MtwmID int64 `orm:"column(mtwm_id)"`
// WscID int64 `orm:"column(wsc_id);index"` // 表示微盟skuId
// WscID2 int64 `orm:"column(wsc_id2);index"` // 表示微盟goodsId
// ElmSyncStatus int8 `orm:"default(2)"`
JdSyncStatus int8 `orm:"default(2)"`
EbaiSyncStatus int8 `orm:"default(2)"`
MtwmSyncStatus int8 `orm:"default(2)"`
WscSyncStatus int8 `orm:"default(2)"`
// WscSyncStatus int8 `orm:"default(2)"`
JdPrice int `json:"jdPrice"`
EbaiPrice int `json:"ebaiPrice"`
MtwmPrice int `json:"mtwmPrice"`
WscPrice int `json:"wscPrice"`
JxPrice int `json:"jxPrice"`
// WscPrice int `json:"wscPrice"`
AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"`
}

View File

@@ -35,6 +35,7 @@ type User struct {
Name string `orm:"size(48);index" json:"name" compact:"name"` // 外部显示标识(当前可以重复)
Mobile *string `orm:"size(32);null" json:"mobile" compact:"mobile"`
Email *string `orm:"size(32);null" json:"email" compact:"email"`
Avatar string `orm:"size(255)" json:"avatar" compact:"avatar"` // 头像
Status int8 `json:"status" compact:"status"`
Type int8 `json:"type" compact:"type"` // 用户类型
@@ -80,6 +81,10 @@ func (user *User) GetName() string {
return user.Name
}
func (user *User) GetAvatar() string {
return user.Avatar
}
type StoreBoss struct {
ModelIDCULD
UserID string `orm:"size(48);column(user_id);unique" json:"userID"` // 内部唯一标识

View File

@@ -34,12 +34,11 @@ func CallCreateWaybillPolicy(deliveryFee, maxDeliveryFee int64, order *model.Goo
return err
}
func CalculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db *dao.DaoDB) (deliveryFee, addFee int64, err error) {
globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s", order.VendorOrderID)
func CalculateDeliveryFee(db *dao.DaoDB, jxStoreID int, hint string, consigneeLng, consigneeLat, coordinateType, weight int, billTime time.Time) (deliveryFee, addFee int64, err error) {
globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s", hint)
if db == nil {
db = dao.GetDB()
}
jxStoreID := jxutils.GetSaleStoreIDFromOrder(order)
var lng, lat float64
priceInfo := &struct {
CityPrice int64
@@ -63,21 +62,21 @@ func CalculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db *
deliveryFee = priceInfo.CityPrice
}
if deliveryFee == 0 {
globals.SugarLogger.Warnf("CalculateOrderDeliveryFee 查不到美团配送价格 orderID:%s", order.VendorOrderID)
globals.SugarLogger.Warnf("CalculateOrderDeliveryFee 查不到美团配送价格 orderID:%s", hint)
deliveryFee = 650
}
if lng == 0 || lat == 0 {
globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,门店:%d没有坐标信息", order.VendorOrderID, jxutils.GetSaleStoreIDFromOrder(order))
return 0, 0, fmt.Errorf("找不到门店:%d的坐标", jxutils.GetSaleStoreIDFromOrder(order))
globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,门店:%d没有坐标信息", hint, jxStoreID)
return 0, 0, fmt.Errorf("找不到门店:%d的坐标", jxStoreID)
}
lng2, lat2, _ := jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
lng2, lat2, _ := jxutils.IntCoordinate2MarsStandard(consigneeLng, consigneeLat, coordinateType)
var distanceAddFee, weightAddFee, timeAddFee int64
// 距离加价
distance := jxutils.WalkingDistance(lng, lat, lng2, lat2)
if distance > warningDistance {
globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,距离%.3fkm太远,请检查门店坐标信息", order.VendorOrderID, distance)
globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,距离%.3fkm太远,请检查门店坐标信息", hint, distance)
}
distanceAddFee = int64(jxutils.CalcStageValue([][]float64{
[]float64{
@@ -95,8 +94,8 @@ func CalculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db *
}, distance))
// 重量加价
if order.Weight > warningWeight {
globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,重量:%dg太重,请检查商品属性", order.VendorOrderID, order.Weight)
if weight > warningWeight {
globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,重量:%dg太重,请检查商品属性", hint, weight)
}
weightAddFee = int64(jxutils.CalcStageValue([][]float64{
[]float64{
@@ -111,7 +110,7 @@ func CalculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db *
5,
50,
},
}, float64(order.Weight)/1000))
}, float64(weight)/1000))
// 其它加价
hour, min, sec := billTime.Clock()
@@ -123,10 +122,15 @@ func CalculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db *
timeAddFee = jxutils.StandardPrice2Int(3)
}
addFee = distanceAddFee + weightAddFee + timeAddFee
globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s, deliveryFee:%d addFee:%d, distance:%.3fkm distanceAddFee:%d, weight:%dg weightAddFee:%d, time:%s timeAddFee:%d", order.VendorOrderID, deliveryFee, addFee, distance, distanceAddFee, order.Weight, weightAddFee, utils.Time2TimeStr(billTime), timeAddFee)
globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s, deliveryFee:%d addFee:%d, distance:%.3fkm distanceAddFee:%d, weight:%dg weightAddFee:%d, time:%s timeAddFee:%d",
hint, deliveryFee, addFee, distance, distanceAddFee, weight, weightAddFee, utils.Time2TimeStr(billTime), timeAddFee)
return deliveryFee + addFee, addFee, nil
}
func CalculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db *dao.DaoDB) (deliveryFee, addFee int64, err error) {
return CalculateDeliveryFee(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorOrderID, order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType, order.Weight, billTime)
}
func CalculateBillDeliveryFee(bill *model.Waybill) (deliveryFee, addFee int64) {
order, err := partner.CurOrderManager.LoadOrder(bill.VendorOrderID, bill.OrderVendorID)
if err != nil {

View File

@@ -22,11 +22,9 @@ const (
)
func (c *PurchaseHandler) StartRefreshComment() {
if globals.ReallyCallPlatformAPI {
utils.AfterFuncWithRecover(5*time.Second, func() {
c.refreshCommentOnce()
})
}
utils.AfterFuncWithRecover(5*time.Second, func() {
c.refreshCommentOnce()
})
}
func (c *PurchaseHandler) refreshCommentOnce() {

View File

@@ -158,9 +158,7 @@ func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, v
if globals.EnableEbaiStoreWrite {
opResult, err2 := api.EbaiAPI.SkuDelete(ctx.GetTrackInfo(), utils.Int2Str(storeID), partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDIntList(), nil)
if err = err2; err2 != nil && opResult != nil {
if len(storeSkuList) == 1 && len(storeSkuList) == len(opResult.FailedList) { // 饿百现在删除不存在错在上层通过IsErrSkuNotExist很难准备判断暂时这里直接处理
err = nil
} else {
if len(storeSkuList) > len(opResult.FailedList) {
successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult))
}
}

View File

@@ -0,0 +1,133 @@
package localjx
import (
"fmt"
"time"
"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"
)
type JxSkuInfo struct {
SkuID int `json:"skuID"`
Count int `json:"count"`
Price int64 `json:"price,omitempty"` // 原价
SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
}
type JxOrderInfo struct {
Skus []*JxSkuInfo `json:"skus"`
ExpectedDeliveredTime *time.Time `orm:"type(datetime)" json:"expectedDeliveredTime"` // 预期送达时间
TotalPrice int64 `json:"totalPrice"` // 单位为分 订单总价
FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费
OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
}
func PreCreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, ExpectedDeliveredTime *time.Time) (outJxOrder *JxOrderInfo, err error) {
return outJxOrder, err
}
func formalizeSkus(skus []*JxSkuInfo) (outSkus []*JxSkuInfo) {
skuMap := make(map[int]int)
for _, v := range skus {
skuMap[v.SkuID] += v.Count
}
for skuID, skuCount := range skuMap {
outSkus = append(outSkus, &JxSkuInfo{
SkuID: skuID,
Count: skuCount,
})
}
return outSkus
}
func isTimeInOpTime(openTime1, closeTime1, openTime2, closeTime2 int16, time2Check time.Time) bool {
timeStrList := []string{
jxutils.OperationTime2StrWithSecond(openTime1),
jxutils.OperationTime2StrWithSecond(closeTime1),
}
if openTime1 > 0 {
timeStrList = append(timeStrList,
jxutils.OperationTime2StrWithSecond(openTime2),
jxutils.OperationTime2StrWithSecond(closeTime2),
)
}
checkTimeStr := utils.Time2TimeStr(time2Check)
for i := 0; i < len(timeStrList); i += 2 {
if checkTimeStr >= timeStrList[i] && checkTimeStr <= timeStrList[i+1] {
return true
}
}
return false
}
func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, storeID int, addressID int64, ExpectedDeliveredTime *time.Time) (outJxOrder *JxOrderInfo, err error) {
db := dao.GetDB()
// 配送范围检查
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX)
if err != nil {
return nil, err
}
addressList, _, err := dao.QueryUserDeliveryAddress(db, addressID, []string{ctx.GetUserID()}, 0, 0)
if err != nil {
return nil, err
}
if len(addressList) == 0 {
return nil, fmt.Errorf("地址ID不正确")
}
deliveryAddress := addressList[0]
if distance := jxutils.Point2StoreDistance(deliveryAddress.Lng, deliveryAddress.Lat, storeDetail.Lng, storeDetail.Lat, storeDetail.DeliveryRangeType, storeDetail.DeliveryRange); distance == 0 {
return nil, fmt.Errorf("送货地址:%s不在门店%s的配送范围", deliveryAddress.DetailAddress, storeDetail.Name)
}
// 营业状态及时间检查
if storeDetail.Status == model.StoreStatusDisabled {
return nil, fmt.Errorf("门店:%s状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
}
checkTime := time.Now()
if ExpectedDeliveredTime == nil {
if storeDetail.Status != model.StoreStatusOpened {
return nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
}
} else {
checkTime = *ExpectedDeliveredTime
}
if !isTimeInOpTime(storeDetail.OpenTime1, storeDetail.CloseTime1, storeDetail.OpenTime2, storeDetail.CloseTime2, checkTime) {
return nil, fmt.Errorf("门店:%s不在营业时间范围", storeDetail.Name)
}
skus := formalizeSkus(jxOrder.Skus)
var skuIDs []int
for _, v := range skus {
skuIDs = append(skuIDs, v.SkuID)
}
storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, skuIDs)
if err != nil {
return nil, err
}
storeSkuMap := make(map[int]*model.StoreSkuBind)
for _, v := range storeSkuList {
storeSkuMap[v.SkuID] = v
}
outJxOrder = &JxOrderInfo{}
for _, v := range skus {
outJxOrder.Skus = append(outJxOrder.Skus, &JxSkuInfo{
SkuID: v.SkuID,
Count: v.Count,
Price: v.Price,
SalePrice: v.SalePrice,
})
outJxOrder.TotalPrice += int64(v.Count) * v.SalePrice
}
return outJxOrder, err
}

View File

@@ -3,77 +3,13 @@ package jx
import (
"time"
"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"
"git.rosy.net.cn/jx-callback/business/partner/purchase/jx/phpjx"
)
type Data4Neworder struct {
model.GoodsOrder
Skus []*model.OrderSku `json:"skus"`
}
func (c *PurchaseHandler) OnOrderMsg(msg *CallbackMsg) (retVal, errCode string, err error) {
jxutils.CallMsgHandler(func() {
retVal, errCode, err = c.onOrderMsg(msg)
}, jxutils.ComposeUniversalOrderID(msg.ThingID, c.GetVendorID()))
return retVal, errCode, err
}
func (c *PurchaseHandler) onOrderMsg(msg *CallbackMsg) (retVal, errCode string, err error) {
subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0))
if subMsgType == model.OrderStatusNew || subMsgType == model.OrderStatusAdjust {
var order *Data4Neworder
if err = utils.UnmarshalUseNumber([]byte(msg.Data), &order); err == nil {
if order.VendorStatus == "" {
order.VendorStatus = utils.Int2Str(order.Status)
}
retVal, errCode, err = c.onOrderNew(msg, subMsgType, order)
}
} else {
status := c.callbackMsg2Status(msg)
err = partner.CurOrderManager.OnOrderStatusChanged(status)
}
return retVal, errCode, err
}
func (c *PurchaseHandler) callbackMsg2Status(msg *CallbackMsg) *model.OrderStatus {
orderStatus := &model.OrderStatus{
VendorOrderID: msg.ThingID,
VendorID: model.VendorIDJX,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: msg.ThingID,
RefVendorID: model.VendorIDJX,
VendorStatus: msg.SubMsgType,
Status: int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)),
StatusTime: utils.Timestamp2Time(msg.Timestamp),
Remark: "",
}
return orderStatus
}
func (c *PurchaseHandler) onOrderNew(msg *CallbackMsg, subMsgType int, order *Data4Neworder) (retVal, errCode string, err error) {
globals.SugarLogger.Debugf("onOrderNew orderID:%s", msg.ThingID)
order.StoreID = int(utils.Str2Int64WithDefault(order.VendorStoreID, 0))
order.GoodsOrder.Skus = order.Skus
order.VendorID = model.VendorIDJX
for _, v := range order.GoodsOrder.Skus {
v.SkuID = int(utils.Str2Int64WithDefault(v.VendorSkuID, 0))
}
jxutils.RefreshOrderSkuRelated(&order.GoodsOrder)
orderStatus := model.Order2Status(&order.GoodsOrder)
if subMsgType == model.OrderStatusNew {
err = partner.CurOrderManager.OnOrderNew(&order.GoodsOrder, orderStatus)
} else if subMsgType == model.OrderStatusAdjust {
err = partner.CurOrderManager.OnOrderAdjust(&order.GoodsOrder, orderStatus)
}
return retVal, errCode, err
}
func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
return order
}
@@ -89,12 +25,16 @@ func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptI
} else {
status = model.OrderStatusCanceled
}
err = c.notifyOrderStatusChanged(order, status)
if model.IsOrderJXTemp(order) {
err = phpjx.NotifyOrderStatusChanged(order, status)
}
return err
}
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
err = c.notifyOrderStatusChanged(order, model.OrderStatusFinishedPickup)
if model.IsOrderJXTemp(order) {
err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusFinishedPickup)
}
return err
}
@@ -119,13 +59,16 @@ func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName
}
func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
err = c.notifyOrderStatusChanged(order, model.OrderStatusDelivering)
if model.IsOrderJXTemp(order) {
err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusDelivering)
}
return err
}
// 京东送达接口都是一样的
func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
err = c.notifyOrderStatusChanged(order, model.OrderStatusFinished)
if model.IsOrderJXTemp(order) {
err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusFinished)
}
return err
}
@@ -138,7 +81,9 @@ func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *mod
}
func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
err = c.notifyOrderStatusChanged(order, model.OrderStatusCanceled)
if model.IsOrderJXTemp(order) {
err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusCanceled)
}
return err
}
@@ -161,16 +106,9 @@ func (c *PurchaseHandler) AddWaybillTip(ctx *jxcontext.Context, order *model.Goo
func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID, selfTakeCode string) (err error) {
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJX)
if err == nil {
err = c.notifyOrderStatusChanged(order, model.OrderStatusFinished)
}
return err
}
func (c *PurchaseHandler) notifyOrderStatusChanged(order *model.GoodsOrder, status int) (err error) {
orderMsg := *order
orderMsg.Status = status
if err = jxAPI.NotifyOrderStatusChanged(&orderMsg); err == nil {
c.postFakeMsg(orderMsg.VendorOrderID, orderMsg.Status)
if model.IsOrderJXTemp(order) {
err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusFinished)
}
}
return err
}

View File

@@ -2,134 +2,13 @@ package jx
import (
"fmt"
"time"
"git.rosy.net.cn/baseapi/platformapi/jdapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/business/partner/purchase/jx/phpjx"
)
type Data4AfsOrderSku struct {
VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"` // 平台skuid
PromotionType int `json:"promotionType"` // 商品级别促销类型 (1、无优惠;2、秒杀(已经下线);3、单品直降;4、限时抢购;1202、加价购;1203、满赠(标识商品);6、买赠(买A送B标识B);9999、表示一个普通商品参与捆绑促销设置的捆绑类型;9998、表示一个商品参与了捆绑促销并且还参与了其他促销类型;9997、表示一个商品参与了捆绑促销但是金额拆分不尽,9996:组合购,8001:轻松购会员价,8:第二件N折,9:拼团促销)
Name string `orm:"size(255)" json:"name"` // 商品名
SalePrice int64 `json:"salePrice"` // 售卖价
Count int `json:"count"` // 订单下单数量
}
type Data4AfsOrder struct {
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID
AfsOrderID string `orm:"column(afs_order_id);size(48)" json:"afsOrderID"` // 售后订单ID
AfsCreatedAt time.Time `orm:"type(datetime);null;index" json:"afsCreatedAt"` // 售后单生成时间
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid
VendorStatus string `orm:"size(255)" json:"vendorStatus"`
VendorReasonType string `orm:"size(255)" json:"vendorReasonType"` // 原始售后原因
ReasonDesc string `orm:"size(1024)" json:"reasonDesc"` // 售后原因描述
ReasonImgList string `orm:"size(1024)" json:"reasonImgList"` // 售后描述图片
VendorAppealType string `orm:"size(255)" json:"vendorAppealType"` // 原始售后方式
Skus []*Data4AfsOrderSku
}
func (c *PurchaseHandler) OnAfsOrderMsg(msg *CallbackMsg) (err error) {
jxutils.CallMsgHandlerAsync(func() {
err = c.onAfsOrderMsg(msg)
}, jxutils.ComposeUniversalOrderID(msg.ThingID, c.GetVendorID()))
return err
}
func (c *PurchaseHandler) buildAfsOrder(msg *CallbackMsg) (outAfsOrder *model.AfsOrder, err error) {
var afsOrder *Data4AfsOrder
if err = utils.UnmarshalUseNumber([]byte(msg.Data), &afsOrder); err == nil {
outAfsOrder = &model.AfsOrder{
VendorID: model.VendorIDJX,
AfsOrderID: afsOrder.AfsOrderID,
VendorOrderID: afsOrder.VendorOrderID,
VendorStoreID: afsOrder.VendorStoreID,
StoreID: int(utils.Str2Int64WithDefault(afsOrder.VendorStoreID, 0)),
AfsCreatedAt: afsOrder.AfsCreatedAt,
VendorStatus: afsOrder.VendorStatus,
VendorReasonType: afsOrder.VendorReasonType,
ReasonType: int8(utils.Str2Int64WithDefault(afsOrder.VendorReasonType, 0)),
ReasonDesc: utils.LimitUTF8StringLen(afsOrder.ReasonDesc, 1024),
ReasonImgList: afsOrder.ReasonImgList,
VendorAppealType: afsOrder.VendorAppealType,
AppealType: int8(utils.Str2Int64WithDefault(afsOrder.VendorAppealType, 0)),
}
outAfsOrder.Status = int(utils.Str2Int64WithDefault(afsOrder.VendorStatus, 0))
for _, x := range afsOrder.Skus {
orderSku := &model.OrderSkuFinancial{
Count: x.Count,
VendorSkuID: x.VendorSkuID,
SkuID: int(utils.Str2Int64WithDefault(x.VendorSkuID, 0)),
Name: x.Name,
}
if x.PromotionType != 0 && x.PromotionType != jdapi.PromotionTypeNormal {
orderSku.StoreSubName = utils.Int2Str(x.PromotionType)
}
outAfsOrder.Skus = append(outAfsOrder.Skus, orderSku)
}
}
return outAfsOrder, err
}
func (c *PurchaseHandler) callbackAfsMsg2Status(msg *CallbackMsg) *model.OrderStatus {
orderStatus := &model.OrderStatus{
VendorOrderID: msg.ThingID2, // 是售后单ID不是订单ID订单ID在RefVendorOrderID中
VendorID: model.VendorIDJX,
OrderType: model.OrderTypeAfsOrder,
RefVendorOrderID: msg.ThingID,
RefVendorID: model.VendorIDJX,
VendorStatus: msg.SubMsgType,
Status: int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)),
StatusTime: utils.Timestamp2Time(msg.Timestamp),
Remark: "",
}
return orderStatus
}
func (c *PurchaseHandler) onAfsOrderMsg(msg *CallbackMsg) (err error) {
subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0))
status := c.callbackAfsMsg2Status(msg)
if subMsgType == model.AfsOrderStatusWait4Approve || subMsgType == model.AfsOrderStatusNew {
afsOrder, err2 := c.buildAfsOrder(msg)
if err = err2; err == nil {
err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, status)
}
} else {
err = partner.CurOrderManager.OnOrderStatusChanged(status)
}
return err
}
func (p *PurchaseHandler) postFakeAfsMsg(orderNo, afsOrderID string, status int) {
msg := &CallbackMsg{
AppKey: appKey,
MsgType: MsgTypeAfsOrder,
SubMsgType: utils.Int2Str(status),
ThingID: orderNo,
ThingID2: afsOrderID,
Timestamp: time.Now().Unix(),
}
utils.CallFuncAsync(func() {
OnCallbackMsg(msg)
})
}
func (c *PurchaseHandler) notifyAfsOrderStatusChanged(order *model.AfsOrder, status int) (err error) {
orderMsg := *order
orderMsg.Status = status
if err = jxAPI.NotifyAfsOrderStatusChanged(&orderMsg); err == nil {
c.postFakeAfsMsg(orderMsg.VendorOrderID, orderMsg.AfsOrderID, orderMsg.Status)
}
return err
}
// 审核售后单申请
func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) {
var status int
@@ -138,7 +17,10 @@ func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *mod
} else {
status = model.AfsOrderStatusFinished
}
return c.notifyAfsOrderStatusChanged(order, status)
if model.IsAfsOrderJXTemp(order) {
err = phpjx.NotifyAfsOrderStatusChanged(order, status)
}
return err
}
// 确认收到退货

View File

@@ -1,4 +1,4 @@
package jx
package phpjx
import (
"fmt"
@@ -34,14 +34,14 @@ func OnCallbackMsg(msg *CallbackMsg) (retVal, errCode string, err error) {
return retVal, errCode, fmt.Errorf("无效的AppKey:%s", msg.AppKey)
}
if msg.MsgType == MsgTypeOrder {
retVal, errCode, err = CurPurchaseHandler.OnOrderMsg(msg)
retVal, errCode, err = OnOrderMsg(msg)
} else if msg.MsgType == MsgTypeAfsOrder {
err = CurPurchaseHandler.OnAfsOrderMsg(msg)
err = OnAfsOrderMsg(msg)
}
return retVal, errCode, err
}
func (p *PurchaseHandler) postFakeMsg(orderNo string, status int) {
func postFakeMsg(orderNo string, status int) {
msg := &CallbackMsg{
AppKey: appKey,
MsgType: MsgTypeOrder,

View File

@@ -1,4 +1,4 @@
package jx
package phpjx
import (
"testing"
@@ -33,7 +33,7 @@ func TestBuildNewJxOrder(t *testing.T) {
msg := &CallbackMsg{
AppKey: appKey,
MsgType: MsgTypeOrder,
SubMsgType: SubMsgTypeOrderNew,
SubMsgType: utils.Int2Str(model.OrderStatusNew),
ThingID: order.VendorOrderID,
Data: utils.Format4Output(order2, true),
}

View File

@@ -1,4 +1,4 @@
package jx
package phpjx
import (
"fmt"

View File

@@ -1,4 +1,4 @@
package jx
package phpjx
import (
"git.rosy.net.cn/jx-callback/business/model"
@@ -42,3 +42,4 @@ func (a *API) NotifyAfsOrderStatusChanged(afsOrder *model.AfsOrder) (err error)
}
return err
}

View File

@@ -1,4 +1,4 @@
package jx
package phpjx
import (
"testing"

View File

@@ -0,0 +1,82 @@
package phpjx
import (
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
)
func NotifyOrderStatusChanged(order *model.GoodsOrder, status int) (err error) {
orderMsg := *order
orderMsg.Status = status
if err = jxAPI.NotifyOrderStatusChanged(&orderMsg); err == nil {
postFakeMsg(orderMsg.VendorOrderID, orderMsg.Status)
}
return err
}
type Data4Neworder struct {
model.GoodsOrder
Skus []*model.OrderSku `json:"skus"`
}
func OnOrderMsg(msg *CallbackMsg) (retVal, errCode string, err error) {
jxutils.CallMsgHandler(func() {
retVal, errCode, err = onOrderMsg(msg)
}, jxutils.ComposeUniversalOrderID(msg.ThingID, model.VendorIDJX))
return retVal, errCode, err
}
func onOrderMsg(msg *CallbackMsg) (retVal, errCode string, err error) {
subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0))
if subMsgType == model.OrderStatusNew || subMsgType == model.OrderStatusAdjust {
var order *Data4Neworder
if err = utils.UnmarshalUseNumber([]byte(msg.Data), &order); err == nil {
if order.VendorStatus == "" {
order.VendorStatus = utils.Int2Str(order.Status)
}
retVal, errCode, err = onOrderNew(msg, subMsgType, order)
}
} else {
status := callbackMsg2Status(msg)
err = partner.CurOrderManager.OnOrderStatusChanged(status)
}
return retVal, errCode, err
}
func callbackMsg2Status(msg *CallbackMsg) *model.OrderStatus {
orderStatus := &model.OrderStatus{
VendorOrderID: msg.ThingID,
VendorID: model.VendorIDJX,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: msg.ThingID,
RefVendorID: model.VendorIDJX,
VendorStatus: msg.SubMsgType,
Status: int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)),
StatusTime: utils.Timestamp2Time(msg.Timestamp),
Remark: "",
}
return orderStatus
}
func onOrderNew(msg *CallbackMsg, subMsgType int, order *Data4Neworder) (retVal, errCode string, err error) {
globals.SugarLogger.Debugf("onOrderNew orderID:%s", msg.ThingID)
order.StoreID = int(utils.Str2Int64WithDefault(order.VendorStoreID, 0))
order.DeliveryType = model.OrderDeliveryTypeStoreSelf
order.GoodsOrder.Skus = order.Skus
order.VendorID = model.VendorIDJX
order.Flag = model.OrderFlagMaskTempJX
for _, v := range order.GoodsOrder.Skus {
v.SkuID = int(utils.Str2Int64WithDefault(v.VendorSkuID, 0))
}
jxutils.RefreshOrderSkuRelated(&order.GoodsOrder)
orderStatus := model.Order2Status(&order.GoodsOrder)
if subMsgType == model.OrderStatusNew {
err = partner.CurOrderManager.OnOrderNew(&order.GoodsOrder, orderStatus)
} else if subMsgType == model.OrderStatusAdjust {
err = partner.CurOrderManager.OnOrderAdjust(&order.GoodsOrder, orderStatus)
}
return retVal, errCode, err
}

View File

@@ -0,0 +1,130 @@
package phpjx
import (
"time"
"git.rosy.net.cn/baseapi/platformapi/jdapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/partner"
)
type Data4AfsOrderSku struct {
VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"` // 平台skuid
PromotionType int `json:"promotionType"` // 商品级别促销类型 (1、无优惠;2、秒杀(已经下线);3、单品直降;4、限时抢购;1202、加价购;1203、满赠(标识商品);6、买赠(买A送B标识B);9999、表示一个普通商品参与捆绑促销设置的捆绑类型;9998、表示一个商品参与了捆绑促销并且还参与了其他促销类型;9997、表示一个商品参与了捆绑促销但是金额拆分不尽,9996:组合购,8001:轻松购会员价,8:第二件N折,9:拼团促销)
Name string `orm:"size(255)" json:"name"` // 商品名
SalePrice int64 `json:"salePrice"` // 售卖价
Count int `json:"count"` // 订单下单数量
}
type Data4AfsOrder struct {
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID
AfsOrderID string `orm:"column(afs_order_id);size(48)" json:"afsOrderID"` // 售后订单ID
AfsCreatedAt time.Time `orm:"type(datetime);null;index" json:"afsCreatedAt"` // 售后单生成时间
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid
VendorStatus string `orm:"size(255)" json:"vendorStatus"`
VendorReasonType string `orm:"size(255)" json:"vendorReasonType"` // 原始售后原因
ReasonDesc string `orm:"size(1024)" json:"reasonDesc"` // 售后原因描述
ReasonImgList string `orm:"size(1024)" json:"reasonImgList"` // 售后描述图片
VendorAppealType string `orm:"size(255)" json:"vendorAppealType"` // 原始售后方式
Skus []*Data4AfsOrderSku
}
func OnAfsOrderMsg(msg *CallbackMsg) (err error) {
jxutils.CallMsgHandlerAsync(func() {
err = onAfsOrderMsg(msg)
}, jxutils.ComposeUniversalOrderID(msg.ThingID, model.VendorIDJX))
return err
}
func buildAfsOrder(msg *CallbackMsg) (outAfsOrder *model.AfsOrder, err error) {
var afsOrder *Data4AfsOrder
if err = utils.UnmarshalUseNumber([]byte(msg.Data), &afsOrder); err == nil {
outAfsOrder = &model.AfsOrder{
VendorID: model.VendorIDJX,
AfsOrderID: afsOrder.AfsOrderID,
VendorOrderID: afsOrder.VendorOrderID,
VendorStoreID: afsOrder.VendorStoreID,
StoreID: int(utils.Str2Int64WithDefault(afsOrder.VendorStoreID, 0)),
AfsCreatedAt: afsOrder.AfsCreatedAt,
VendorStatus: afsOrder.VendorStatus,
VendorReasonType: afsOrder.VendorReasonType,
ReasonType: int8(utils.Str2Int64WithDefault(afsOrder.VendorReasonType, 0)),
ReasonDesc: utils.LimitUTF8StringLen(afsOrder.ReasonDesc, 1024),
ReasonImgList: afsOrder.ReasonImgList,
VendorAppealType: afsOrder.VendorAppealType,
AppealType: int8(utils.Str2Int64WithDefault(afsOrder.VendorAppealType, 0)),
Flag: model.OrderFlagMaskTempJX,
}
outAfsOrder.Status = int(utils.Str2Int64WithDefault(afsOrder.VendorStatus, 0))
for _, x := range afsOrder.Skus {
orderSku := &model.OrderSkuFinancial{
Count: x.Count,
VendorSkuID: x.VendorSkuID,
SkuID: int(utils.Str2Int64WithDefault(x.VendorSkuID, 0)),
Name: x.Name,
}
if x.PromotionType != 0 && x.PromotionType != jdapi.PromotionTypeNormal {
orderSku.StoreSubName = utils.Int2Str(x.PromotionType)
}
outAfsOrder.Skus = append(outAfsOrder.Skus, orderSku)
}
}
return outAfsOrder, err
}
func callbackAfsMsg2Status(msg *CallbackMsg) *model.OrderStatus {
orderStatus := &model.OrderStatus{
VendorOrderID: msg.ThingID2, // 是售后单ID不是订单ID订单ID在RefVendorOrderID中
VendorID: model.VendorIDJX,
OrderType: model.OrderTypeAfsOrder,
RefVendorOrderID: msg.ThingID,
RefVendorID: model.VendorIDJX,
VendorStatus: msg.SubMsgType,
Status: int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)),
StatusTime: utils.Timestamp2Time(msg.Timestamp),
Remark: "",
}
return orderStatus
}
func onAfsOrderMsg(msg *CallbackMsg) (err error) {
subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0))
status := callbackAfsMsg2Status(msg)
if subMsgType == model.AfsOrderStatusWait4Approve || subMsgType == model.AfsOrderStatusNew {
afsOrder, err2 := buildAfsOrder(msg)
if err = err2; err == nil {
err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, status)
}
} else {
err = partner.CurOrderManager.OnOrderStatusChanged(status)
}
return err
}
func postFakeAfsMsg(orderNo, afsOrderID string, status int) {
msg := &CallbackMsg{
AppKey: appKey,
MsgType: MsgTypeAfsOrder,
SubMsgType: utils.Int2Str(status),
ThingID: orderNo,
ThingID2: afsOrderID,
Timestamp: time.Now().Unix(),
}
utils.CallFuncAsync(func() {
OnCallbackMsg(msg)
})
}
func NotifyAfsOrderStatusChanged(order *model.AfsOrder, status int) (err error) {
orderMsg := *order
orderMsg.Status = status
if err = jxAPI.NotifyAfsOrderStatusChanged(&orderMsg); err == nil {
postFakeAfsMsg(orderMsg.VendorOrderID, orderMsg.AfsOrderID, orderMsg.Status)
}
return err
}

View File

@@ -11,7 +11,6 @@ import (
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
"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"
@@ -23,9 +22,9 @@ import (
)
const (
FakeMsgTypeOrderReceived = "orderReceived"
FakeMsgTypeOrderDelivering = "orderDelivering"
FakeMsgType = "fakeMsgType"
fakeFinishedPickup = "fake_finished_pickup"
fakeUserApplyCancel = "fake_user_apply_cancel"
fakeMerchantAgreeApplyCancel = "fake_merchant_agree_apply_cancel"
fakeRefuseUserApplyCancel = "fake_refuse_user_apply_cancel"
@@ -38,11 +37,11 @@ const (
)
const (
// pickupOrderDelay = 260 * time.Second
pickupOrderDelay = 1 * time.Second
// pickupOrderDelay = 260 * time.Second
// pickupOrderDelay = 1 * time.Second
callDeliveryDelay = 10 * time.Minute
callDeliveryDelayGap = 30
// callDeliveryDelay = 10 * time.Minute
// callDeliveryDelayGap = 30
)
var (
@@ -53,13 +52,16 @@ var (
VendorStatus2StatusMap = map[string]int{
mtwmapi.OrderStatusUserCommitted: model.OrderStatusUnknown,
mtwmapi.OrderStatusNew: model.OrderStatusNew,
mtwmapi.OrderStatusReceived: model.OrderStatusAccepted,
mtwmapi.OrderStatusAccepted: model.OrderStatusFinishedPickup,
mtwmapi.OrderStatusDelivering: model.OrderStatusDelivering,
mtwmapi.OrderStatusDelivered: model.OrderStatusUnknown, // 以mtwmapi.OrderStatusFinished为结束状态这个当成一个中间状态且很少看到这个状态
mtwmapi.OrderStatusFinished: model.OrderStatusFinished,
mtwmapi.OrderStatusCanceled: model.OrderStatusCanceled,
// mtwmapi.OrderStatusReceived: model.OrderStatusAccepted,
// mtwmapi.OrderStatusAccepted: model.OrderStatusFinishedPickup,
mtwmapi.OrderStatusAccepted: model.OrderStatusAccepted,
mtwmapi.OrderStatusDelivering: model.OrderStatusDelivering,
mtwmapi.OrderStatusDelivered: model.OrderStatusUnknown, // 以mtwmapi.OrderStatusFinished为结束状态这个当成一个中间状态且很少看到这个状态
mtwmapi.OrderStatusFinished: model.OrderStatusFinished,
mtwmapi.OrderStatusCanceled: model.OrderStatusCanceled,
fakeFinishedPickup: model.OrderStatusFinishedPickup,
fakeOrderAdjustFinished: model.OrderStatusAdjust,
fakeRefuseUserApplyCancel: model.OrderStatusUnlocked,
fakeUserApplyCancel: model.OrderStatusApplyCancel,
@@ -142,9 +144,10 @@ func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
if openUID > 0 {
order.VendorUserID = utils.Int64ToStr(openUID)
}
if utils.IsTimeZero(order.PickDeadline) && !utils.IsTimeZero(order.StatusTime) {
order.PickDeadline = order.StatusTime.Add(pickupOrderDelay) // 美团外卖要求在5分钟内拣货不然订单会被取消
}
// 不设置最晚拣货时间,以缺省值为准
// if utils.IsTimeZero(order.PickDeadline) && !utils.IsTimeZero(order.StatusTime) {
// order.PickDeadline = order.StatusTime.Add(pickupOrderDelay) // 美团外卖要求在5分钟内拣货不然订单会被取消
// }
order.Status = p.getStatusFromVendorStatus(order.VendorStatus)
if utils.IsTimeZero(order.ExpectedDeliveredTime) {
order.BusinessType = model.BusinessTypeImmediate
@@ -347,7 +350,7 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *mtwmapi.CallbackMsg) (orderSta
case mtwmapi.MsgTypeOrderCanceled:
vendorStatus = mtwmapi.OrderStatusCanceled
remark = msg.FormData.Get("reason")
case mtwmapi.MsgTypeNewOrder, FakeMsgTypeOrderReceived, mtwmapi.MsgTypeOrderAccepted, FakeMsgTypeOrderDelivering, mtwmapi.MsgTypeOrderFinished:
case FakeMsgType, mtwmapi.MsgTypeNewOrder, mtwmapi.MsgTypeOrderAccepted, mtwmapi.MsgTypeOrderFinished:
vendorStatus = msg.FormData.Get("status")
statusTime = utils.Str2Int64(msg.FormData.Get("utime"))
case mtwmapi.MsgTypeOrderRefund, mtwmapi.MsgTypeOrderPartialRefund:
@@ -414,11 +417,15 @@ func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptI
globals.SugarLogger.Debugf("mtwm AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt)
if isAcceptIt {
if globals.EnableMtwmStoreWrite {
err = api.MtwmAPI.OrderReceived(utils.Str2Int64(order.VendorOrderID))
}
if err == nil {
c.postFakeMsg(order.VendorOrderID, FakeMsgTypeOrderReceived, mtwmapi.OrderStatusReceived)
// err = api.MtwmAPI.OrderReceived(utils.Str2Int64(order.VendorOrderID))
err = api.MtwmAPI.OrderConfirm(utils.Str2Int64(order.VendorOrderID))
if err != nil {
globals.SugarLogger.Warnf("mtwm AcceptOrRefuseOrder orderID:%s failed with err:%v", order.VendorOrderID, err)
}
}
// if err == nil {
// c.postFakeMsg(order.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusReceived)
// }
} else {
if globals.EnableMtwmStoreWrite {
err = c.CancelOrder(jxcontext.AdminCtx, order, "bu")
@@ -429,10 +436,14 @@ func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptI
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
globals.SugarLogger.Debugf("mtwm PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery)
if globals.EnableMtwmStoreWrite {
err = api.MtwmAPI.OrderConfirm(utils.Str2Int64(order.VendorOrderID))
} else {
c.postFakeMsg(order.VendorOrderID, mtwmapi.MsgTypeOrderAccepted, mtwmapi.OrderStatusAccepted)
if !isSelfDelivery {
if globals.EnableMtwmStoreWrite {
// err = api.MtwmAPI.OrderConfirm(utils.Str2Int64(order.VendorOrderID))
err = api.MtwmAPI.PreparationMealComplete(utils.Str2Int64(order.VendorOrderID))
}
}
if err == nil {
c.postFakeMsg(order.VendorOrderID, FakeMsgType, fakeFinishedPickup)
}
return err
}
@@ -495,19 +506,19 @@ func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *mode
return mobile, err
}
func (c *PurchaseHandler) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *partner.StatusActionParams) {
if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusAccepted {
params = &partner.StatusActionParams{ // PickDeadline没有设置时才有效美团外卖要求在5分钟内拣货不然订单会被取消
Timeout: pickupOrderDelay,
}
} else if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusFinishedPickup {
params = &partner.StatusActionParams{ // 立即达订单有效,自配送延时召唤配送
Timeout: callDeliveryDelay,
TimeoutGap: callDeliveryDelayGap,
}
}
return params
}
// func (c *PurchaseHandler) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *partner.StatusActionParams) {
// if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusAccepted {
// params = &partner.StatusActionParams{ // PickDeadline没有设置时才有效美团外卖要求在5分钟内拣货不然订单会被取消
// Timeout: pickupOrderDelay,
// }
// } else if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusFinishedPickup {
// params = &partner.StatusActionParams{ // 立即达订单有效,自配送延时召唤配送
// Timeout: callDeliveryDelay,
// TimeoutGap: callDeliveryDelayGap,
// }
// }
// return params
// }
func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
if globals.EnableMtwmStoreWrite {

View File

@@ -1,11 +1,13 @@
package mtwm
import (
"strings"
"time"
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
@@ -16,17 +18,15 @@ import (
)
const (
RefreshCommentTime = 36 * time.Hour
RefreshCommentTime = 7 * 24 * time.Hour // 此值必须大于24小时
RefreshCommentTimeInterval = 60 * time.Minute
BAD_COMMENTS_MAX_MODIFY_TIME = 24 // 小时
BAD_COMMENTS_MAX_MODIFY_TIME = 24 * 6 // 小时
)
func (c *PurchaseHandler) StartRefreshComment() {
if globals.ReallyCallPlatformAPI {
utils.AfterFuncWithRecover(5*time.Second, func() {
c.refreshCommentOnce()
})
}
utils.AfterFuncWithRecover(5*time.Second, func() {
c.refreshCommentOnce()
})
}
func (c *PurchaseHandler) refreshCommentOnce() {
@@ -36,43 +36,75 @@ func (c *PurchaseHandler) refreshCommentOnce() {
})
}
func formalizeTagList(mtwmTagList string) (outTagList string) {
if mtwmTagList != "" {
outTagList = string(utils.Format4Output(strings.Split(mtwmTagList, ","), true))
}
return outTagList
}
func (c *PurchaseHandler) RefreshComment(fromTime, toTime time.Time) (err error) {
if globals.EnableMtwmStoreWrite {
storeMapList, err2 := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDMTWM}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "")
if err = err2; err != nil {
return err
}
task := tasksch.NewParallelTask("mtwm RefreshComment", nil, jxcontext.AdminCtx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
storeMap := batchItemList[0].(*model.StoreMap)
startDateStr := time.Now().Format("20060102")
endDateStr := time.Now().Add(-RefreshCommentTime).Format("20060102")
commentList, err2 := api.MtwmAPI.CommentQuery(storeMap.VendorStoreID, startDateStr, endDateStr, 0, 0, mtwmapi.CommentReplyStatusAll)
if err = err2; err != nil {
return nil, err
}
return commentList, nil
}, storeMapList)
task.Run()
resultList, err2 := task.GetResult(0)
if err = err2; err != nil {
return err
}
var orderCommentList []*model.OrderComment
for _, result := range resultList {
mtwmComment := result.(*mtwmapi.OrderComment)
orderComment := &model.OrderComment{
VendorID: model.VendorIDMTWM,
TagList: mtwmComment.CommentLables,
Score: int8(mtwmComment.FoodCommentScore),
storeMapList, err2 := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDMTWM}, nil, model.StoreStatusAll, model.StoreIsSyncYes, "")
if err = err2; err != nil {
return err
}
task := tasksch.NewParallelTask("mtwm RefreshComment", nil, jxcontext.AdminCtx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
storeMap := batchItemList[0].(*model.StoreMap)
endDateStr := time.Now().Add(-24 * time.Hour).Format("20060102")
startDateStr := time.Now().Add(-RefreshCommentTime).Format("20060102")
commentList, err2 := api.MtwmAPI.CommentQuery(storeMap.VendorStoreID, startDateStr, endDateStr, 0, 0, mtwmapi.CommentReplyStatusAll)
var orderCommentList []*model.OrderComment
if err = err2; err != nil {
return nil, err
}
orderCommentList = append(orderCommentList, orderComment)
}
for _, mtwmComment := range commentList {
createdTime, err := utils.TryStr2Time(mtwmComment.CommentTime)
if err == nil {
orderComment := &model.OrderComment{
VendorOrderID: utils.Int64ToStr(mtwmComment.CommentID), // 美团评价不能得到订单号以评价ID代替
VendorID: model.VendorIDMTWM,
UserCommentID: utils.Int64ToStr(mtwmComment.CommentID),
VendorStoreID: storeMap.VendorStoreID,
TagList: formalizeTagList(mtwmComment.CommentLables),
Score: int8(mtwmComment.FoodCommentScore),
ModifyDuration: BAD_COMMENTS_MAX_MODIFY_TIME,
OriginalMsg: string(utils.MustMarshal(mtwmComment)),
IsReplied: int8(mtwmComment.ReplyStatus),
}
if orderComment.IsReplied == 0 {
orderComment.Content = mtwmComment.CommentContent
orderComment.CommentCreatedAt = createdTime
} else {
orderComment.Content = mtwmComment.AddComment
if updatedTime, err := utils.TryStr2Time(mtwmComment.CommentTime); err == nil {
orderComment.CommentCreatedAt = updatedTime
}
}
orderCommentList = append(orderCommentList, orderComment)
}
}
return orderCommentList, nil
}, storeMapList)
task.Run()
resultList, err2 := task.GetResult(0)
if err = err2; err != nil {
return err
}
var orderCommentList []*model.OrderComment
for _, result := range resultList {
orderComment := result.(*model.OrderComment)
orderCommentList = append(orderCommentList, orderComment)
}
if len(orderCommentList) > 0 {
err = partner.CurOrderManager.OnOrderComments(orderCommentList)
}
return err
}
func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, orderComment *model.OrderComment, replyComment string) (err error) {
globals.SugarLogger.Debugf("mtwm ReplyOrderComment, orderComment:%s, replyComment:%s", utils.Format4Output(orderComment, true), replyComment)
if globals.EnableMtwmStoreWrite {
err = api.MtwmAPI.CommentAddReply(orderComment.VendorStoreID, utils.Str2Int64(orderComment.UserCommentID), replyComment)
}

View File

@@ -36,7 +36,7 @@ func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) {
case partner.FuncUpdateStoreSkusStock, partner.FuncUpdateStoreSkusStatus, partner.FuncUpdateStoreSkusPrice:
batchSize = mtwmapi.MaxStoreSkuBatchSize
case partner.FuncDeleteStoreSkus:
batchSize = 1 // 可考虑用批量操作
batchSize = mtwmapi.MaxBatchDeleteSize
case partner.FuncCreateStoreSkus:
batchSize = 1 // 可考虑用批量操作
case partner.FuncUpdateStoreSkus:
@@ -284,7 +284,7 @@ func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, v
err = api.MtwmAPI.RetailDelete(ctx.GetTrackInfo(), vendorStoreID, storeSkuList[0].VendorSkuID)
} else {
// todo 部分失败
err = api.MtwmAPI.RetailCatSkuBatchDelete(ctx.GetTrackInfo(), vendorStoreID, nil, nil, partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDList())
err = api.MtwmAPI.RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, nil, nil, partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDList())
}
}
return nil, err
@@ -403,7 +403,7 @@ func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTas
func vendorSku2Jx(appFood *mtwmapi.AppFood) (skuName *partner.SkuNameInfo) {
prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(appFood.Name)
vendorSku := appFood.SkuList[0]
weight := vendorSku.Weight
weight := int(utils.Str2Int64WithDefault(vendorSku.Weight, 0))
if weight <= 0 {
weight = jxutils.FormatSkuWeight(specQuality, specUnit)
}

View File

@@ -1,9 +1,6 @@
package mtwm
import (
"net/url"
"time"
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
@@ -33,17 +30,7 @@ func (c *PurchaseHandler) onWaybillMsg(msg *mtwmapi.CallbackMsg) (response *mtwm
waybill := c.callbackMsg2Waybill(msg)
err := partner.CurOrderManager.OnWaybillStatusChanged(waybill)
if err == nil && waybill.Status == model.WaybillStatusDelivering {
msg := &mtwmapi.CallbackMsg{
Cmd: FakeMsgTypeOrderDelivering,
FormData: url.Values{},
}
msg.FormData.Set("timestamp", utils.Int64ToStr(time.Now().Unix()))
msg.FormData.Set("utime", msg.FormData.Get("timestamp"))
msg.FormData.Set(mtwmapi.KeyOrderID, waybill.VendorOrderID)
msg.FormData.Set("status", mtwmapi.OrderStatusDelivering)
utils.CallFuncAsync(func() {
c.onOrderMsg(msg)
})
c.postFakeMsg(waybill.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusDelivering)
}
return mtwmapi.Err2CallbackResponse(err, "")
}

View File

@@ -2,7 +2,6 @@ package wsc
import (
"errors"
"sort"
"time"
"git.rosy.net.cn/baseapi/platformapi/weimobapi"
@@ -263,75 +262,7 @@ func (p *PurchaseHandler) postFakeMsg(orderNo int64, fakeStatus string) {
}
func (p *PurchaseHandler) arrangeSaleStore(order *model.GoodsOrder, cityName, provinceName string) {
globals.SugarLogger.Debugf("arrangeSaleStore orderID:%s cityName:%s, provinceName:%s", order.VendorOrderID, cityName, provinceName)
const (
maxTryStoreWhenArrange = 5
)
db := dao.GetDB()
var selectedStore *model.Store
if true {
if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, model.VendorIDWSC); err == nil {
selectedStore = &storeDetail.Store
}
} else {
storeList, err := dao.GetPossibleStoresByPlaceName(db, cityName, provinceName)
if err != nil {
globals.SugarLogger.Errorf("arrangeSaleStore failed with error:%v", err)
}
globals.SugarLogger.Debugf("arrangeSaleStore possible stores orderID:%s", order.VendorOrderID)
for _, store := range storeList {
globals.SugarLogger.Debugf("orderID:%s %s:%d", order.VendorOrderID, store.Name, store.ID)
}
if len(storeList) > 0 {
distanceList := make(utils.SortList, 0)
userLng := jxutils.IntCoordinate2Standard(order.ConsigneeLng)
userLat := jxutils.IntCoordinate2Standard(order.ConsigneeLat)
for k, store := range storeList {
// 展示门店自身不参与派单
if store.VendorStoreID != order.VendorStoreID {
sortItem := &utils.SortItem{
CompareValue: int64(jxutils.EarthDistance(userLng, userLat, jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat)) * 1000),
Index: k,
}
distanceList = append(distanceList, sortItem)
}
}
sort.Sort(distanceList)
globals.SugarLogger.Debugf("arrangeSaleStore distance list orderID:%s", order.VendorOrderID)
for _, dist := range distanceList {
globals.SugarLogger.Debugf("orderID:%s %s:%d, distance:%d", order.VendorOrderID, storeList[dist.Index].Name, storeList[dist.Index].ID, dist.CompareValue)
}
if len(distanceList) > maxTryStoreWhenArrange {
distanceList = distanceList[:maxTryStoreWhenArrange]
}
for _, v := range distanceList {
selectedStore = &storeList[v.Index].Store
if selectedStore.DeliveryRangeType == model.DeliveryRangeTypeRadius {
distance := v.CompareValue
if distance < utils.Str2Int64(selectedStore.DeliveryRange) {
break
} else {
globals.SugarLogger.Debugf("arrangeSaleStore orderID:%s distance:%d, deliveryRange:%d", order.VendorOrderID, distance, utils.Str2Int64(selectedStore.DeliveryRange))
}
} else {
points := jxutils.CoordinateStr2Points(selectedStore.DeliveryRange)
if utils.IsPointInPolygon(userLng, userLat, points) {
break
} else {
globals.SugarLogger.Debugf("arrangeSaleStore orderID:%s userLng:%f, userLat:%f, deliveryRange:%s", order.VendorOrderID, userLng, userLat, selectedStore.DeliveryRange)
}
}
selectedStore = nil
}
}
}
if selectedStore != nil {
order.StoreID = selectedStore.ID
order.StoreName = selectedStore.Name
globals.SugarLogger.Debugf("arrangeSaleStore orderID:%s arranged to store:%d", order.VendorOrderID, selectedStore.ID)
} else {
globals.SugarLogger.Errorf("arrangeSaleStore orderID:%s 找不到门店", order.VendorOrderID)
}
}
func (p *PurchaseHandler) setStoreOrderSeq(order *model.GoodsOrder) {

View File

@@ -200,9 +200,9 @@ func tryRegisterDataRes4Recipe(ctx *jxcontext.Context, name, mainImg string, ste
return errList.GetErrListAsOne()
}
func QueryFoodRecipes(ctx *jxcontext.Context, keyword, authorID string, offset, pageSize int) (recipeInfo *model.PagedInfo, err error) {
func QueryFoodRecipes(ctx *jxcontext.Context, keyword, authorID string, skuIDs []int, offset, pageSize int) (recipeInfo *model.PagedInfo, err error) {
_, userID := ctx.GetMobileAndUserID()
recipeList, totalCount, err := dao.QueryFoodRecipes(dao.GetDB(), keyword, 0, authorID, userID, offset, pageSize)
recipeList, totalCount, err := dao.QueryFoodRecipes(dao.GetDB(), keyword, 0, authorID, userID, skuIDs, offset, pageSize)
if err == nil {
recipeInfo = &model.PagedInfo{
TotalCount: totalCount,
@@ -227,7 +227,7 @@ func GetRecommendFoodRecipes(ctx *jxcontext.Context, keyword string, offset, pag
func GetRecipeDetail(ctx *jxcontext.Context, recipeID int) (recipeDetail *FoodRecipeDetail, err error) {
_, userID := ctx.GetMobileAndUserID()
db := dao.GetDB()
recipeList, _, err := dao.QueryFoodRecipes(db, "", recipeID, "", userID, 0, 0)
recipeList, _, err := dao.QueryFoodRecipes(db, "", recipeID, "", userID, nil, 0, 0)
if err != nil {
return nil, err
}
@@ -275,7 +275,7 @@ func VoteFoodRecipe(ctx *jxcontext.Context, recipeID, voteType int) (err error)
}
db := dao.GetDB()
recipeList, _, err := dao.QueryFoodRecipes(db, "", recipeID, "", userID, 0, 0)
recipeList, _, err := dao.QueryFoodRecipes(db, "", recipeID, "", userID, nil, 0, 0)
if err != nil {
return err
}

View File

@@ -18,7 +18,6 @@ type CmsController struct {
// @Title 得到地点(省,城市,区)信息
// @Description 得到地点(省,城市,区)信息。
// @Param token header string true "认证token"
// @Param keyword query string false "查询关键字(可以为空,为空表示不限制)"
// @Param parentCode query int false "上级地点code这个指的是国家标准CODE中国为100000北京为110000北京市为110100不是数据库中的ID"
// @Param level query int false "地点级别省为1市为2区为3注意直辖市也要分省与市级"
@@ -222,10 +221,10 @@ func (c *CmsController) FakeNewOrder() {
// @Title 发送消息给相关人员
// @Description 发送消息给相关人员
// @Param mobile formData string true "手机号"
// @Param verifyCode formData string false "验证码"
// @Param msgType formData string true "消息类型"
// @Param msgContent formData string true "消息内容"
// @Param mobile formData string false "手机号"
// @Param verifyCode formData string false "验证码"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SendMsg2Somebody [post]

View File

@@ -72,9 +72,9 @@ func (c *FoodRecipeController) UpdateFoodRecipe() {
// @Title 查询菜谱列表
// @Description 查询菜谱列表
// @Param token header string true "认证token"
// @Param keyword query string false "关键字"
// @Param authorID query string false "创建者ID"
// @Param skuIDs query string false "skuID列表"
// @Param offset query int false "菜谱列表起始序号以0开始缺省为0"
// @Param pageSize query int false "菜谱列表页大小缺省为50-1表示全部"
// @Success 200 {object} controllers.CallResult
@@ -82,14 +82,16 @@ func (c *FoodRecipeController) UpdateFoodRecipe() {
// @router /QueryFoodRecipes [get]
func (c *FoodRecipeController) QueryFoodRecipes() {
c.callQueryFoodRecipes(func(params *tFoodrecipeQueryFoodRecipesParams) (retVal interface{}, errCode string, err error) {
retVal, err = userstore.QueryFoodRecipes(params.Ctx, params.Keyword, params.AuthorID, params.Offset, params.PageSize)
var skuIDs []int
if err = jxutils.Strings2Objs(params.SkuIDs, &skuIDs); err == nil {
retVal, err = userstore.QueryFoodRecipes(params.Ctx, params.Keyword, params.AuthorID, skuIDs, params.Offset, params.PageSize)
}
return retVal, "", err
})
}
// @Title 得到我的推荐菜谱列表
// @Description 得到我的推荐菜谱列表
// @Param token header string true "认证token"
// @Param keyword query string false "关键字"
// @Param offset query int false "菜谱列表起始序号以0开始缺省为0"
// @Param pageSize query int false "菜谱列表页大小缺省为50-1表示全部"
@@ -105,7 +107,6 @@ func (c *FoodRecipeController) GetRecommendFoodRecipes() {
// @Title 得到菜谱详情
// @Description 得到菜谱详情
// @Param token header string true "认证token"
// @Param recipeID query int true "菜谱ID"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult

View File

@@ -31,7 +31,6 @@ func (c *SkuController) GetVendorCategories() {
// @Title 得到商品类别
// @Description 得到商品类别区别于厂商家SKU类别
// @Param token header string true "认证token"
// @Param parentID query int false "父ID-1表示所有缺省为-1"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
@@ -152,7 +151,7 @@ func (c *SkuController) SyncCategory() {
// @Param isBySku query bool false "是否将sku拆开缺省为false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetSkuNames [get]
// @router /GetSkuNames [get,post]
func (c *SkuController) GetSkuNames() {
c.callGetSkuNames(func(params *tSkuGetSkuNamesParams) (retVal interface{}, errCode string, err error) {
retVal, err = cms.GetSkuNames(params.Ctx, params.Keyword, params.IsBySku, params.MapData, params.Offset, params.PageSize)
@@ -191,7 +190,7 @@ func (c *SkuController) UpdateSkuName() {
// dummySkuName := &model.SkuName{}
payload := make(map[string]interface{})
if err = utils.UnmarshalUseNumber([]byte(params.Payload), &payload); err == nil {
retVal, err = cms.UpdateSkuName(params.Ctx, params.NameID, payload, params.Ctx.GetUserName())
retVal, err = cms.UpdateSkuName(params.Ctx, params.NameID, payload)
}
return retVal, "", err
})
@@ -241,7 +240,7 @@ func (c *SkuController) UpdateSku() {
c.callUpdateSku(func(params *tSkuUpdateSkuParams) (retVal interface{}, errCode string, err error) {
payload := make(map[string]interface{})
if err = utils.UnmarshalUseNumber([]byte(params.Payload), &payload); err == nil {
retVal, err = cms.UpdateSku(params.Ctx, params.SkuID, payload, params.Ctx.GetUserName())
retVal, err = cms.UpdateSku(params.Ctx, params.SkuID, payload)
}
return retVal, "", err
})

View File

@@ -39,6 +39,7 @@ type StoreController struct {
// @Param orderTimeTo query string false "订单创建结束时间"
// @Param orderCountFrom query int false "订单量起始"
// @Param orderCountTo query int false "订单量结束"
// @Param briefLevel query int false "返回信息精简模式"
// @Param offset query int false "门店列表起始序号以0开始缺省为0"
// @Param pageSize query int false "门店列表页大小缺省为50-1表示全部"
// @Success 200 {object} controllers.CallResult
@@ -236,7 +237,7 @@ func (c *StoreController) TmpGetJxBadCommentsByStoreId() {
if err = err2; err == nil {
pageSize := jxutils.FormalizePageSize(params.Size)
offset := (params.Page - 1) * pageSize
retVal, err = cms.TmpGetJxBadCommentsByStoreId(params.Ctx, []int{params.JxStoreId}, offset, pageSize, params.Type, timeList[0], timeList[1])
retVal, err = cms.TmpGetJxBadCommentsByStoreId(params.Ctx, "", []int{params.JxStoreId}, offset, pageSize, params.Type, timeList[0], timeList[1])
}
return retVal, "", err
})
@@ -246,11 +247,12 @@ func (c *StoreController) TmpGetJxBadCommentsByStoreId() {
// @Description 得到门店评价列表(多店)
// @Param token header string true "认证token"
// @Param type query int true "评论类型0差评1所有2已解决"
// @Param keyword query string false "关键字"
// @Param storeIDs query string false "门店I列表"
// @Param offset query int false "起始页从1开始"
// @Param pageSize query int false "页大小(-1表示无限大"
// @Param fromTime query string false "创建起始时间"
// @Param toTime query string false "创建结束时间"
// @Param offset query int false "起始页从1开始"
// @Param pageSize query int false "页大小(-1表示无限大"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /TmpGetJxBadComments [get]
@@ -260,7 +262,7 @@ func (c *StoreController) TmpGetJxBadComments() {
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs); err == nil {
timeList, err2 := jxutils.BatchStr2Time(params.FromTime, params.ToTime)
if err = err2; err == nil {
retVal, err = cms.TmpGetJxBadCommentsByStoreId(params.Ctx, storeIDs, params.Offset, params.PageSize, params.Type, timeList[0], timeList[1])
retVal, err = cms.TmpGetJxBadCommentsByStoreId(params.Ctx, params.Keyword, storeIDs, params.Offset, params.PageSize, params.Type, timeList[0], timeList[1])
}
}
return retVal, "", err
@@ -532,7 +534,6 @@ func (c *StoreController) SyncStoresCourierInfo() {
// @Title 根据位置得到推荐门店列表
// @Description 根据位置得到推荐门店列表
// @Param token header string true "认证token"
// @Param lng query float64 true "经度"
// @Param lat query float64 true "纬度"
// @Param needWalkDistance query bool false "是否需要返回步行距离(且以步行距离排序)"

View File

@@ -40,6 +40,7 @@ type StoreSkuController struct {
// @Param pageSize query int false "门店列表页大小缺省为50-1表示全部"
// @Param isBySku query bool false "是否按SKU分拆"
// @Param isAct query bool false "是否活动商品(包括正常活动与补贴)"
// @Param actVendorID query int false "要得到哪个平台的活动信息(缺省不限制,非零最小值)"
// @Param jdSyncStatus query int false "京东同步标识"
// @Param ebaiSyncStatus query int false "饿百同步标识"
// @Param mtwmSyncStatus query int false "美团外卖同步标识"
@@ -58,7 +59,6 @@ func (c *StoreSkuController) GetStoreSkus() {
// @Title 得到商家商品信息
// @Description 得到商家商品信息,如下条件之间是与的关系。对于没有认领的商品,按城市限制。但对于已经认领的商品就不限制了,因为已经在平台上可售,可以操作(改价等等)
// @Param token header string true "认证token"
// @Param storeIDs query string false "门店ID"
// @Param isFocus query bool true "是否已关注(认领)"
// @Param keyword query string false "查询关键字(可以为空,为空表示不限制)"
@@ -80,6 +80,7 @@ func (c *StoreSkuController) GetStoreSkus() {
// @Param pageSize query int false "门店列表页大小缺省为50-1表示全部"
// @Param isBySku query bool false "是否按SKU分拆"
// @Param isAct query bool false "是否活动商品(包括正常活动与补贴)"
// @Param actVendorID query int false "要得到哪个平台的活动信息(缺省不限制,非零最小值)"
// @Param jdSyncStatus query int false "京东同步标识"
// @Param ebaiSyncStatus query int false "饿百同步标识"
// @Param mtwmSyncStatus query int false "美团外卖同步标识"

View File

@@ -1,13 +1,16 @@
package controllers
import (
"git.rosy.net.cn/baseapi/platformapi/weixinapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/auth2"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
"git.rosy.net.cn/jx-callback/business/authz"
"git.rosy.net.cn/jx-callback/business/authz/autils"
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"github.com/astaxie/beego"
)
@@ -361,3 +364,50 @@ func (c *User2Controller) SaveMyCart() {
return retVal, "", err
})
}
// @Title 得到用户自己的信息
// @Description 得到用户自己的信息
// @Param token header string true "认证token"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetSelfInfo [get]
func (c *User2Controller) GetSelfInfo() {
c.callGetSelfInfo(func(params *tUser2GetSelfInfoParams) (retVal interface{}, errCode string, err error) {
retVal, err = cms.GetSelfInfo(params.Ctx)
return retVal, "", err
})
}
// @Title 根据小程序jsCode修改用户信息
// @Description 根据小程序jsCode修改用户信息
// @Param token header string true "认证token"
// @Param jsCode query string true "小程序jsCode"
// @Param data query string true "加密数据"
// @Param iv query string true "iv"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /UpdateUserByMiniInfo [put]
func (c *Auth2Controller) UpdateUserByMiniInfo() {
c.callUpdateUserByMiniInfo(func(params *tAuth2UpdateUserByMiniInfoParams) (retVal interface{}, errCode string, err error) {
authInfo, err := params.Ctx.GetV2AuthInfo()
if err == nil {
decryptedDataBase64, err2 := weixin.AutherObjMini.DecryptData(authInfo, GetComposedCode(&c.Controller, params.JsCode), params.Data, params.Iv)
if err = err2; err == nil {
var userInfo *weixinapi.MiniUserInfo
if err = utils.UnmarshalUseNumber([]byte(decryptedDataBase64), &userInfo); err == nil {
retVal = userInfo
if user := params.Ctx.GetFullUser(); user != nil {
if userInfo.AvatarURL != "" {
user.Avatar = userInfo.AvatarURL
}
if userInfo.PurePhoneNumber != "" {
user.Mobile = utils.String2Pointer(userInfo.PurePhoneNumber)
}
dao.UpdateEntity(dao.GetDB(), user)
}
}
}
}
return retVal, "", err
})
}

View File

@@ -741,6 +741,30 @@ func (c *OrderController) AmendMissingOrders() {
})
}
// @Title 同步刷新历史订单的结算价按订单
// @Description 同步刷新历史订单的结算价按订单
// @Param token header string true "认证token"
// @Param fromTime formData string false "订单起始时间 (yyyy-mm-dd hh:ms:ss)"
// @Param toTime formData string false "订单结束时间 (yyyy-mm-dd hh:ms:ss)"
// @Param vendorOrderID formData string false "订单号"
// @Param vendorIDs formData string false "平台ID列表[0,1,3]"
// @Param actID formData int false "活动ID"
// @Param storeID formData int false "门店ID"
// @Param isAsync formData bool false "是否异步操作"
// @Param isContinueWhenError formData bool false "单个失败是否继续缺省true"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /RefreshHistoryOrdersEarningPrice [post]
func (c *OrderController) RefreshHistoryOrdersEarningPrice() {
c.callRefreshHistoryOrdersEarningPrice(func(params *tOrderRefreshHistoryOrdersEarningPriceParams) (retVal interface{}, errCode string, err error) {
var vendorIDList []int
if err = jxutils.Strings2Objs(params.VendorIDs, &vendorIDList); err == nil {
retVal, err = orderman.FixedOrderManager.RefreshHistoryOrdersEarningPrice(params.Ctx, params.VendorOrderID, params.ActID, vendorIDList, params.StoreID, params.FromTime, params.ToTime, params.IsAsync, params.IsContinueWhenError)
}
return retVal, "", err
})
}
// @Title 商家主动发起部分退款售后
// @Description 商家主动发起部分退款售后
// @Param token header string true "认证token"

View File

@@ -1,7 +1,7 @@
package controllers
import (
"git.rosy.net.cn/jx-callback/business/partner/purchase/jx"
"git.rosy.net.cn/jx-callback/business/partner/purchase/jx/phpjx"
"github.com/astaxie/beego"
)
@@ -21,7 +21,7 @@ type JxShopController struct {
// @router /JxMsg [post]
func (c *JxShopController) JxMsg(msgType string) {
c.callJxMsg(func(params *tJxshopJxMsgParams) (retVal interface{}, errCode string, err error) {
retVal, errCode, err = jx.OnCallbackMsg(&jx.CallbackMsg{
retVal, errCode, err = phpjx.OnCallbackMsg(&phpjx.CallbackMsg{
AppKey: params.AppKey,
MsgType: params.MsgType,
SubMsgType: params.SubMsgType,

27
controllers/yonghui.go Normal file
View File

@@ -0,0 +1,27 @@
package controllers
import (
"git.rosy.net.cn/jx-callback/business/jxstore/yonghui"
"github.com/astaxie/beego"
)
//读取永辉excelAPI
type YongHuiController struct {
beego.Controller
}
// @Title 读取永辉excel文件
// @Description 读取永辉excel文件
// @Param token header string true "认证token"
// @Param isAsync query bool false "是否异步,缺省是同步"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /LoadExcelByYongHui [post]
func (c *YongHuiController) LoadExcelByYongHui() {
c.callLoadExcelByYongHui(func(params *tYonghuiLoadExcelByYongHuiParams) (retVal interface{}, errCode string, err error) {
r := c.Ctx.Request
files := r.MultipartForm.File["userfiles"]
retVal, err = yonghui.SendFilesToStores(params.Ctx, files)
return retVal, "", err
})
}

View File

@@ -21,6 +21,7 @@ import (
"git.rosy.net.cn/jx-callback/business/jxstore/misc"
"git.rosy.net.cn/jx-callback/business/jxutils/tasks"
"git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
"git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"git.rosy.net.cn/jx-callback/globals/api2"
@@ -32,7 +33,7 @@ import (
_ "git.rosy.net.cn/jx-callback/business/partner/printer/zhongwu"
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm"
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jx"
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc"
@@ -66,6 +67,7 @@ func Init() {
if globals.IsProductEnv() {
ebai.CurPurchaseHandler.StartRefreshComment()
mtwm.CurPurchaseHandler.StartRefreshComment()
}
misc.Init()
}

View File

@@ -169,6 +169,15 @@ func init() {
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:Auth2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:Auth2Controller"],
beego.ControllerComments{
Method: "UpdateUserByMiniInfo",
Router: `/UpdateUserByMiniInfo`,
AllowHTTPMethods: []string{"put"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:Auth2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:Auth2Controller"],
beego.ControllerComments{
Method: "WeixinMPOAuth2",
@@ -918,6 +927,15 @@ func init() {
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"],
beego.ControllerComments{
Method: "RefreshHistoryOrdersEarningPrice",
Router: `/RefreshHistoryOrdersEarningPrice`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"],
beego.ControllerComments{
Method: "RefreshOrderFinancial",
@@ -1084,7 +1102,7 @@ func init() {
beego.ControllerComments{
Method: "GetSkuNames",
Router: `/GetSkuNames`,
AllowHTTPMethods: []string{"get"},
AllowHTTPMethods: []string{"get","post"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
@@ -1890,6 +1908,15 @@ func init() {
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"],
beego.ControllerComments{
Method: "GetSelfInfo",
Router: `/GetSelfInfo`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"],
beego.ControllerComments{
Method: "GetStoreRoleList",
@@ -1971,4 +1998,13 @@ func init() {
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"],
beego.ControllerComments{
Method: "LoadExcelByYongHui",
Router: `/LoadExcelByYongHui`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
}

View File

@@ -126,6 +126,11 @@ func init() {
&controllers.ReportController{},
),
),
beego.NSNamespace("/yonghui",
beego.NSInclude(
&controllers.YongHuiController{},
),
),
)
beego.AddNamespace(ns)