同步错误
This commit is contained in:
@@ -31,29 +31,6 @@ type tStoreSkuBindAndVendorSkuID struct {
|
||||
func init() {
|
||||
}
|
||||
|
||||
func (c *OrderManager) LoadPendingOrders() []*model.GoodsOrder {
|
||||
db := orm.NewOrm()
|
||||
var orders []*model.GoodsOrder
|
||||
tillTime := time.Now().Add(-pendingOrderGapMax)
|
||||
_, err := db.Raw(`
|
||||
SELECT *
|
||||
FROM goods_order
|
||||
WHERE order_created_at >= ?
|
||||
AND status < ?
|
||||
`, tillTime, model.OrderStatusEndBegin).QueryRows(&orders)
|
||||
if err != nil {
|
||||
globals.SugarLogger.Warnf("LoadPendingOrders load pending orders error:%v", err)
|
||||
return nil
|
||||
}
|
||||
for _, order := range orders {
|
||||
utils.CallFuncLogError(func() error {
|
||||
_, err = db.QueryTable("order_sku").Filter("vendor_order_id", order.VendorOrderID).Filter("vendor_id", order.VendorID).All(&order.Skus)
|
||||
return err
|
||||
}, "LoadPendingOrders order:%v", order)
|
||||
}
|
||||
return orders
|
||||
}
|
||||
|
||||
// msgVendorStatus的意思是事件本身的类型,类似有时收到NewOrder事件去取,订单状态不一定就是New的
|
||||
// OnOrderAdjust也类似,而OrderStatus要记录的是消息,所以添加这个
|
||||
func (c *OrderManager) OnOrderNew(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) {
|
||||
@@ -97,6 +74,7 @@ func (c *OrderManager) OnOrderNew(order *model.GoodsOrder, orderStatus *model.Or
|
||||
|
||||
// todo 调整单的处理可能还需要再细化一点,当前只是简单的删除重建
|
||||
func (c *OrderManager) OnOrderAdjust(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) {
|
||||
globals.SugarLogger.Debugf("OnOrderAdjust orderID:%s, status:%d", order.VendorOrderID, order.Status)
|
||||
if order.ConsigneeMobile2 == "" && jxutils.IsStringLikeMobile(order.ConsigneeMobile) {
|
||||
order.ConsigneeMobile2 = order.ConsigneeMobile
|
||||
}
|
||||
@@ -185,6 +163,33 @@ func (c *OrderManager) OnOrderStatusChanged(vendorOrgCode string, orderStatus *m
|
||||
isDuplicated, order, err := c.addOrderStatus(orderStatus, db)
|
||||
if err == nil {
|
||||
dao.Commit(db)
|
||||
if orderStatus.Status == model.OrderStatusWaybillTipChanged {
|
||||
if order, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == nil {
|
||||
if handler := partner.GetWaybillTipUpdater(orderStatus.RefVendorID); handler != nil {
|
||||
tipFee, err2 := handler.GetWaybillTip(jxcontext.AdminCtx, vendorOrgCode, order.VendorStoreID, orderStatus.RefVendorOrderID, orderStatus.VendorOrderID, "")
|
||||
if err2 == nil {
|
||||
order.WaybillTipMoney = tipFee
|
||||
c.UpdateOrderFields(order, []string{"WaybillTipMoney"})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if orderStatus.Status == model.OrderStatusFinished {
|
||||
if order, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == nil {
|
||||
// 当前只针对三方运单更新配送费信息
|
||||
if order.WaybillVendorID >= 0 && order.VendorWaybillID != "" && order.WaybillVendorID != order.VendorID {
|
||||
if waybill, err2 := c.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID); err2 == nil {
|
||||
if handler := partner.GetWaybillTipUpdater(waybill.WaybillVendorID); handler != nil {
|
||||
tipFee, err2 := handler.GetWaybillTip(jxcontext.AdminCtx, waybill.VendorOrgCode, "", order.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2)
|
||||
if err2 == nil && waybill.TipFee != tipFee {
|
||||
waybill.ActualFee += tipFee - waybill.TipFee
|
||||
waybill.TipFee = tipFee
|
||||
dao.UpdateEntity(db, waybill, "TipFee", "ActualFee")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !isDuplicated {
|
||||
if order != nil {
|
||||
order.Skus = c.loadOrderSku(db, order.VendorOrderID, order.VendorID)
|
||||
@@ -234,7 +239,7 @@ func setFakeOrderFlag(db *dao.DaoDB, order *model.GoodsOrder) {
|
||||
}
|
||||
|
||||
func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao.DaoDB) (isDuplicated bool, err error) {
|
||||
globals.SugarLogger.Debugf("SaveOrder orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
|
||||
globals.SugarLogger.Debugf("SaveOrder orderID:%s, VendorStoreID:%s, status:%d", order.VendorOrderID, order.VendorStoreID, order.Status)
|
||||
// 忽略查找JX信息错误
|
||||
c.updateOrderOtherInfo(order, db)
|
||||
order.ID = 0
|
||||
@@ -259,7 +264,7 @@ func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao
|
||||
if dao.GetRow(db, orderStatus, `
|
||||
SELECT *
|
||||
FROM order_status
|
||||
WHERE order_type = ? AND vendor_order_id = ? AND vendor_id = ?
|
||||
WHERE order_type = ? AND vendor_order_id = ? AND vendor_id = ? AND status > 0
|
||||
ORDER BY status_time DESC
|
||||
LIMIT 1
|
||||
`, model.OrderTypeOrder, order.VendorOrderID, order.VendorID) == nil {
|
||||
@@ -394,7 +399,7 @@ func updateSingleOrderEarningPrice(order *model.GoodsOrder, db *dao.DaoDB) {
|
||||
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)
|
||||
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, model.ActTypeAll, []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)
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ func (c *OrderManager) updateAfsOrderSkuOtherInfo(db *dao.DaoDB, order *model.Af
|
||||
var actStoreSkuMap *jxutils.ActStoreSkuMap
|
||||
if len(skuIDMap) > 0 {
|
||||
if order2, err2 := c.LoadOrder(order.VendorOrderID, order.VendorID); err2 == nil {
|
||||
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order2.OrderCreatedAt, order2.OrderCreatedAt)
|
||||
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, model.ActTypeAll, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order2.OrderCreatedAt, order2.OrderCreatedAt)
|
||||
if err != nil {
|
||||
globals.SugarLogger.Errorf("updateAfsOrderSkuOtherInfo can not get sku promotion info for error:%v", err)
|
||||
return err
|
||||
|
||||
@@ -85,7 +85,10 @@ func (c *OrderManager) OnOrderComments(orderCommentList []*model.OrderComment) (
|
||||
isNewComment = true
|
||||
if orderComment.IsReplied == 0 && time.Now().Sub(orderComment.CommentCreatedAt) < time.Duration(orderComment.ModifyDuration)*time.Hour {
|
||||
if storeDetail, err2 := dao.GetStoreDetail(db, orderComment.StoreID, orderComment.VendorID); err2 == nil {
|
||||
c.replyOrderComment(storeDetail.VendorOrgCode, orderComment)
|
||||
if storeDetail.AutoReplyType == model.AutoReplyAll ||
|
||||
orderComment.Score > JX_BAD_COMMENTS_MAX_LEVEL && storeDetail.AutoReplyType == model.AutoReplyGoodComment {
|
||||
c.replyOrderComment(storeDetail.VendorOrgCode, orderComment)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,8 +115,11 @@ func (c *OrderManager) GetStatusDuplicatedCount(status *model.OrderStatus) (dupl
|
||||
|
||||
// todo 最好还是改成全事件回放算了
|
||||
func LoadPendingOrders() {
|
||||
orders := FixedOrderManager.LoadPendingOrders()
|
||||
globals.SugarLogger.Infof("LoadPendingOrders orders count:%d", len(orders))
|
||||
orders, err := dao.LoadPendingOrders(dao.GetDB(), time.Now().Add(-pendingOrderGapMax), model.OrderStatusEndBegin)
|
||||
globals.SugarLogger.Infof("LoadPendingOrders orders count:%d, err:%v", len(orders), err)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ordersCount := len(orders)
|
||||
if ordersCount > 0 {
|
||||
|
||||
@@ -23,6 +23,9 @@ import (
|
||||
const (
|
||||
maxLastHours = 7 * 24 // 最多只能查询7天内的订单数据
|
||||
defLastHours = 2 * 24 // 缺省是两天内的订单
|
||||
|
||||
orderSubTimeImmediatelyArrive = 8
|
||||
orderSubTimeDelayArrive = 5
|
||||
)
|
||||
|
||||
type tWaybillExt struct {
|
||||
@@ -96,8 +99,7 @@ func (c *OrderManager) GetOrderSkuInfo(ctx *jxcontext.Context, vendorOrderID str
|
||||
t1.sku_name,
|
||||
IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price,
|
||||
t1.sale_price,
|
||||
t1.earning_price,
|
||||
CAST(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, ?) / 100) AS SIGNED) real_earning_price,
|
||||
CAST(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, ?) / 100) AS SIGNED) earning_price,
|
||||
t1.weight,
|
||||
t1.sku_type,
|
||||
t1.promotion_type,
|
||||
@@ -159,7 +161,7 @@ func (c *OrderManager) GetOrderInfo(ctx *jxcontext.Context, vendorOrderID string
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (c *OrderManager) GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded bool) (bills []*model.Waybill, err error) {
|
||||
func (c *OrderManager) GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded, isGetPos bool) (bills []*model.WaybillExt, err error) {
|
||||
globals.SugarLogger.Debugf("GetOrderWaybillInfo orderID:%s", vendorOrderID)
|
||||
db := dao.GetDB()
|
||||
sql := `
|
||||
@@ -176,7 +178,26 @@ func (c *OrderManager) GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID
|
||||
sqlParams = append(sqlParams, model.OrderStatusEndBegin)
|
||||
}
|
||||
err = dao.GetRows(db, &bills, sql, sqlParams...)
|
||||
globals.SugarLogger.Infof("GetOrderWaybillInfo orderID:%s failed with error:%v", vendorOrderID, err)
|
||||
if err == nil && isGetPos {
|
||||
var taskBills []*model.WaybillExt
|
||||
for _, v := range bills {
|
||||
if v.Status >= model.WaybillStatusAccepted && v.Status <= model.WaybillStatusDelivering {
|
||||
if handler := partner.GetRidderPositionGetter(v.WaybillVendorID); handler != nil {
|
||||
taskBills = append(taskBills, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(taskBills) > 0 {
|
||||
task := tasksch.NewParallelTask("GetOrderWaybillInfo", nil, ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
waybill := batchItemList[0].(*model.WaybillExt)
|
||||
waybill.Lng, waybill.Lat, err = partner.GetRidderPositionGetter(waybill.WaybillVendorID).GetRidderPosition(ctx, waybill.VendorOrderID, waybill.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2)
|
||||
return nil, err
|
||||
}, taskBills)
|
||||
tasksch.HandleTask(task, nil, false).Run()
|
||||
task.GetResult(0)
|
||||
}
|
||||
}
|
||||
return bills, err
|
||||
}
|
||||
|
||||
@@ -937,6 +958,7 @@ func (c *OrderManager) AmendMissingOrders(ctx *jxcontext.Context, vendorIDs []in
|
||||
}
|
||||
if len(dateVendorList) > 0 {
|
||||
var missingOrderList []*tOrderVendorPair
|
||||
var updateOrderStatusList []*model.GoodsOrder
|
||||
db := dao.GetDB()
|
||||
vendorStoreIDMap := make(map[int]string)
|
||||
if storeID > 0 {
|
||||
@@ -987,8 +1009,21 @@ func (c *OrderManager) AmendMissingOrders(ctx *jxcontext.Context, vendorIDs []in
|
||||
|
||||
for _, v := range orderList {
|
||||
pair := v.(*tOrderVendorPair)
|
||||
if localOrderMap[jxutils.ComposeUniversalOrderID(pair.VendorOrderID, pair.VendorID)] == nil {
|
||||
goodsOrder := localOrderMap[jxutils.ComposeUniversalOrderID(pair.VendorOrderID, pair.VendorID)]
|
||||
if goodsOrder == nil {
|
||||
missingOrderList = append(missingOrderList, pair)
|
||||
} else {
|
||||
if !model.IsOrderFinalStatus(goodsOrder.Status) {
|
||||
if goodsOrder.BusinessType == model.BusinessTypeImmediate {
|
||||
if time.Now().Sub(goodsOrder.CreatedAt).Hours() >= orderSubTimeImmediatelyArrive {
|
||||
updateOrderStatusList = append(updateOrderStatusList, goodsOrder)
|
||||
}
|
||||
} else {
|
||||
if time.Now().Sub(goodsOrder.ExpectedDeliveredTime).Hours() >= orderSubTimeDelayArrive {
|
||||
updateOrderStatusList = append(updateOrderStatusList, goodsOrder)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
@@ -1008,9 +1043,26 @@ func (c *OrderManager) AmendMissingOrders(ctx *jxcontext.Context, vendorIDs []in
|
||||
}, missingOrderList)
|
||||
tasksch.HandleTask(task2, task, true).Run()
|
||||
result, err = task2.GetResult(0)
|
||||
case 2:
|
||||
task3 := tasksch.NewParallelTask("AmendMissingOrders UpdateOrders", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
goodsOrder := batchItemList[0].(*model.GoodsOrder)
|
||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(goodsOrder.VendorID); handler != nil {
|
||||
status, err2 := handler.GetOrderStatus(goodsOrder.VendorOrgCode, goodsOrder.VendorOrderID)
|
||||
if err = err2; err == nil {
|
||||
if model.IsOrderFinalStatus(status) {
|
||||
goodsOrder.Status = status
|
||||
_, err = dao.UpdateEntity(db, goodsOrder, "Status")
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal, err
|
||||
}, updateOrderStatusList)
|
||||
tasksch.HandleTask(task3, task, true).Run()
|
||||
_, err = task3.GetResult(0)
|
||||
}
|
||||
return result, err
|
||||
}, 2)
|
||||
}, 3)
|
||||
tasksch.HandleTask(task, nil, true).Run()
|
||||
if !isAsync {
|
||||
result, err2 := task.GetResult(0)
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
package orderman
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/dadaapi"
|
||||
|
||||
"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/globals"
|
||||
@@ -19,6 +25,17 @@ var (
|
||||
model.WaybillStatusRefuseFailedGetGoods: model.OrderStatusRefuseFailedGetGoods,
|
||||
model.WaybillStatusDeliverFailed: model.OrderStatusDeliverFailed,
|
||||
}
|
||||
complaintReasonsMap = map[int]string{
|
||||
1: "骑手态度恶劣",
|
||||
2: "骑手接单后未取货",
|
||||
3: "骑手取货太慢",
|
||||
4: "骑手送货太慢",
|
||||
5: "货品未送达",
|
||||
6: "货品有损坏",
|
||||
7: "骑手违规收取顾客其他费用",
|
||||
69: "骑手恶意取消订单",
|
||||
71: "骑手提前点击取货/送达",
|
||||
}
|
||||
)
|
||||
|
||||
func (w *OrderManager) LoadPendingWaybills() []*model.Waybill {
|
||||
@@ -85,6 +102,9 @@ func (w *OrderManager) onWaybillNew(bill2 *model.Waybill, db *dao.DaoDB) (isDupl
|
||||
|
||||
func (w *OrderManager) OnWaybillStatusChanged(bill *model.Waybill) (err error) {
|
||||
var isDuplicated bool
|
||||
if bill.ActualFee == 0 {
|
||||
bill.ActualFee = bill.DesiredFee + bill.TipFee
|
||||
}
|
||||
bill.CourierMobile = jxutils.FormalizeMobile(bill.CourierMobile)
|
||||
db := dao.GetDB()
|
||||
dao.Begin(db)
|
||||
@@ -220,3 +240,26 @@ func (c *OrderManager) LoadWaybill(vendorWaybillID string, waybillVendorID int)
|
||||
}
|
||||
return bill, err
|
||||
}
|
||||
|
||||
func GetComplaintReasons() (complaintReasonList []*dadaapi.ComplaintReason) {
|
||||
for k, v := range complaintReasonsMap {
|
||||
complaintReason := &dadaapi.ComplaintReason{
|
||||
ID: k,
|
||||
Reason: v,
|
||||
}
|
||||
complaintReasonList = append(complaintReasonList, complaintReason)
|
||||
}
|
||||
return complaintReasonList
|
||||
}
|
||||
|
||||
func ComplaintRider(ctx *jxcontext.Context, vendorOrderID string, vendorID, waybillVendorID, complaintID int) (err error) {
|
||||
db := dao.GetDB()
|
||||
p := partner.GetDeliveryPlatformFromVendorID(waybillVendorID).Handler
|
||||
wayBillList, err := dao.GetWayBillByOrderID(db, model.OrderStatusFinished, vendorID, waybillVendorID, vendorOrderID)
|
||||
if err == nil && len(wayBillList) > 0 {
|
||||
err = p.ComplaintRider(wayBillList[0], complaintID, complaintReasonsMap[complaintID])
|
||||
} else {
|
||||
return fmt.Errorf("未查询到到相关订单,订单状态要求必须是完成!订单号:[%v] ,厂商:[%v],运送厂商:[%v]", vendorOrderID, vendorID, waybillVendorID)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -37,8 +37,14 @@ func (c *BaseScheduler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool
|
||||
globals.SugarLogger.Infof("PickupGoods orderID:%s", order.VendorOrderID)
|
||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusAccepted {
|
||||
if c.IsReallyCallPlatformAPI {
|
||||
err = utils.CallFuncLogErrorWithInfo(func() error {
|
||||
return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).PickupGoods(order, isSelfDelivery, userName)
|
||||
handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID)
|
||||
err = utils.CallFuncLogErrorWithInfo(func() (err error) {
|
||||
if err = handler.PickupGoods(order, isSelfDelivery, userName); err != nil {
|
||||
if status, err2 := handler.GetOrderStatus(order.VendorOrgCode, order.VendorOrderID); err2 == nil && status >= model.OrderStatusFinished {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}, "PickupGoods orderID:%s", order.VendorOrderID)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -236,6 +236,69 @@ func (c *BaseScheduler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID st
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *BaseScheduler) SetOrderWaybillTip(ctx *jxcontext.Context, vendorOrderID string, vendorID int, tipFee int64) (err error) {
|
||||
order, err2 := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
||||
if err = err2; err == nil {
|
||||
err = c.SetOrderWaybillTipByOrder(ctx, order, tipFee)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func isWaybillCanAddTip(waybill *model.Waybill) (isCan bool) {
|
||||
isCan = waybill.Status >= model.WaybillStatusNew && waybill.Status < model.WaybillStatusAccepted && partner.GetWaybillTipUpdater(waybill.WaybillVendorID) != nil
|
||||
return isCan
|
||||
}
|
||||
|
||||
func (c *BaseScheduler) SetOrderWaybillTipByOrder(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee int64) (err error) {
|
||||
roundTipFee := tipFee / 100 * 100
|
||||
if roundTipFee != tipFee {
|
||||
return fmt.Errorf("小费必须是1元的整数倍")
|
||||
}
|
||||
if order.WaybillTipMoney >= tipFee {
|
||||
return fmt.Errorf("当前小费已经是%s元,想要设置%s元", jxutils.IntPrice2StandardString(order.WaybillTipMoney), jxutils.IntPrice2StandardString(tipFee))
|
||||
}
|
||||
|
||||
db := dao.GetDB()
|
||||
storeDetail, err2 := dao.GetStoreDetail(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorID)
|
||||
if err = err2; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 如果平台支持设置配送小费,必须要成功设置
|
||||
if handler := partner.GetWaybillTipUpdater(order.VendorID); handler != nil {
|
||||
if err = handler.UpdateWaybillTip(ctx, order.VendorOrgCode, order.VendorStoreID, order.VendorOrderID, "", "", utils.Int2Str(storeDetail.CityCode), tipFee); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
order.WaybillTipMoney = tipFee
|
||||
partner.CurOrderManager.UpdateOrderFields(order, []string{"WaybillTipMoney"})
|
||||
|
||||
waybills, err := dao.GetWayBillByOrderID(db, 0, order.VendorID, 0, order.VendorOrderID)
|
||||
if err == nil {
|
||||
var waybills2 []*model.Waybill
|
||||
for _, v := range waybills {
|
||||
// 必须是三方配送
|
||||
if !model.IsWaybillPlatformOwn(v) && isWaybillCanAddTip(v) {
|
||||
waybills2 = append(waybills2, v)
|
||||
}
|
||||
}
|
||||
if len(waybills2) > 0 {
|
||||
task := tasksch.NewParallelTask("SetOrderWaybillTipByOrder", nil, ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
waybill := batchItemList[0].(*model.Waybill)
|
||||
handler := partner.GetWaybillTipUpdater(waybill.WaybillVendorID)
|
||||
if err == nil {
|
||||
err = handler.UpdateWaybillTip(ctx, waybill.VendorOrgCode, storeDetail.VendorStoreID, waybill.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2, utils.Int2Str(storeDetail.CityCode), tipFee)
|
||||
}
|
||||
return nil, err
|
||||
}, waybills2)
|
||||
tasksch.HandleTask(task, nil, false).Run()
|
||||
_, err = task.GetResult(0)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *BaseScheduler) confirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) {
|
||||
globals.SugarLogger.Debugf("confirmSelfTake orderID:%s, selfTakeCode:%s", order.VendorOrderID, selfTakeCode)
|
||||
if order.VendorID == model.VendorIDJD {
|
||||
|
||||
@@ -6,11 +6,14 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"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/netprinter"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/smsmsg"
|
||||
"git.rosy.net.cn/jx-callback/business/msghub"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/basesch"
|
||||
@@ -157,6 +160,7 @@ func (s *WatchOrderInfo) updateOrderStoreFeature(order *model.GoodsOrder) (err e
|
||||
s.autoPickupTimeoutMinute = int(storeDetail.AutoPickup)
|
||||
s.isDeliveryCompetition = storeDetail.DeliveryCompetition != 0
|
||||
}
|
||||
globals.SugarLogger.Debugf("updateOrderStoreFeature2 orderID:%s, isDeliveryCompetition:%t", order.VendorOrderID, s.isDeliveryCompetition)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -175,7 +179,7 @@ func (w *WatchOrderInfo) StopTimer(statusType, vendorID, status int) {
|
||||
for _, timerInfo := range w.timerList {
|
||||
if (statusType == -1 || statusType == timerInfo.statusType) &&
|
||||
(vendorID == -1 || vendorID == timerInfo.vendorID) &&
|
||||
(status == -1 || status <= timerInfo.status) {
|
||||
(status == -1 || status >= timerInfo.status) {
|
||||
if timerInfo.timer != nil {
|
||||
timerInfo.timer.Stop()
|
||||
timerInfo.timer = nil
|
||||
@@ -187,6 +191,10 @@ func (w *WatchOrderInfo) StopTimer(statusType, vendorID, status int) {
|
||||
w.timerList = newTimerList
|
||||
}
|
||||
|
||||
func (w *WatchOrderInfo) AddTimer(timerInfo *tTimerInfo) {
|
||||
w.timerList = append(w.timerList, timerInfo)
|
||||
}
|
||||
|
||||
func (w *WatchOrderInfo) GetCreateWaybillTimeout() (timeoutSecond int) {
|
||||
// if w.timerStatusType == scheduler.TimerStatusTypeWaybill && w.timerStatus == model.WaybillStatusNew {
|
||||
// timeoutSecond = int(w.timerTime.Sub(time.Now()) / time.Second)
|
||||
@@ -267,7 +275,7 @@ func init() {
|
||||
return nil
|
||||
},
|
||||
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||
return savedOrderInfo.autoPickupTimeoutMinute > 0
|
||||
return savedOrderInfo.autoPickupTimeoutMinute > 0 && savedOrderInfo.order.Status < model.OrderStatusFinishedPickup
|
||||
},
|
||||
},
|
||||
model.OrderStatusFinishedPickup: &StatusActionConfig{
|
||||
@@ -304,7 +312,6 @@ func init() {
|
||||
order.VendorID == bill.WaybillVendorID &&
|
||||
savedOrderInfo.isDeliveryCompetition &&
|
||||
model.IsOrderDeliveryByPlatform(order) &&
|
||||
order.DeliveryType != model.OrderDeliveryTypeSelfTake &&
|
||||
isOrderCanSwitch2SelfDeliver(order) &&
|
||||
(order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin)
|
||||
},
|
||||
@@ -325,9 +332,8 @@ func init() {
|
||||
order.VendorID == bill.WaybillVendorID &&
|
||||
savedOrderInfo.isDeliveryCompetition &&
|
||||
model.IsOrderDeliveryByPlatform(order) &&
|
||||
order.DeliveryType != model.OrderDeliveryTypeSelfTake &&
|
||||
isOrderCanSwitch2SelfDeliver(order) &&
|
||||
(order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin)
|
||||
(order.Status >= model.OrderStatusAccepted && order.Status < model.OrderStatusEndBegin) // 运单与订单时间有错序的情况,放开订单条件至OrderStatusAccepted
|
||||
},
|
||||
},
|
||||
//*/
|
||||
@@ -453,24 +459,35 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
|
||||
if !isPending {
|
||||
if order.Status > model.OrderStatusEndBegin {
|
||||
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||
} else if model.IsOrderHaveWaybill(order) {
|
||||
globals.SugarLogger.Debugf("OnWaybillStatusChanged multiple waybill created, bill:%v", bill)
|
||||
if model.IsWaybillPlatformOwn(bill) { // 是购物平台运单
|
||||
if !model.IsOrderHaveOwnWaybill(order) { // 既有运单不是购物平台运单
|
||||
globals.SugarLogger.Infof("OnWaybillStatusChanged bill:%v purchase platform bill came later than others, strange!!!", bill)
|
||||
oldBill := savedOrderInfo.waybills[order.WaybillVendorID]
|
||||
if oldBill != nil {
|
||||
s.ProxyCancelWaybill(order, oldBill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||
} else {
|
||||
globals.SugarLogger.Warnf("OnWaybillStatusChanged bill:%v, oldBill is null, strange!!!", bill)
|
||||
} else {
|
||||
needAddTip := order.WaybillTipMoney > 0 && !model.IsWaybillPlatformOwn(bill)
|
||||
if model.IsOrderHaveWaybill(order) {
|
||||
globals.SugarLogger.Debugf("OnWaybillStatusChanged multiple waybill created, bill:%v", bill)
|
||||
if model.IsWaybillPlatformOwn(bill) { // 是购物平台运单
|
||||
if !model.IsOrderHaveOwnWaybill(order) { // 既有运单不是购物平台运单
|
||||
globals.SugarLogger.Infof("OnWaybillStatusChanged bill:%v purchase platform bill came later than others, strange!!!", bill)
|
||||
oldBill := savedOrderInfo.waybills[order.WaybillVendorID]
|
||||
if oldBill != nil {
|
||||
s.ProxyCancelWaybill(order, oldBill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||
} else {
|
||||
globals.SugarLogger.Warnf("OnWaybillStatusChanged bill:%v, oldBill is null, strange!!!", bill)
|
||||
}
|
||||
}
|
||||
s.updateOrderByBill(order, nil, false)
|
||||
if time.Now().Sub(order.OrderCreatedAt) < 2*time.Minute { // 京东一些门店设置成了接单即拣货完成,这种情况下自动调用拣货完成
|
||||
s.autoPickupGood(savedOrderInfo)
|
||||
}
|
||||
} else {
|
||||
needAddTip = false
|
||||
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||
}
|
||||
}
|
||||
if needAddTip {
|
||||
if handler := partner.GetWaybillTipUpdater(bill.WaybillVendorID); handler != nil {
|
||||
if storeDetail, err2 := dao.GetStoreDetail(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), order.VendorID); err2 == nil {
|
||||
handler.UpdateWaybillTip(jxcontext.AdminCtx, order.VendorOrgCode, order.VendorStoreID, order.VendorOrderID, bill.VendorWaybillID, bill.VendorWaybillID2, utils.Int2Str(storeDetail.CityCode), order.WaybillTipMoney)
|
||||
}
|
||||
}
|
||||
s.updateOrderByBill(order, nil, false)
|
||||
if time.Now().Sub(order.OrderCreatedAt) < 2*time.Minute { // 京东一些门店设置成了接单即拣货完成,这种情况下自动调用拣货完成
|
||||
s.autoPickupGood(savedOrderInfo)
|
||||
}
|
||||
} else {
|
||||
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||
}
|
||||
}
|
||||
flag2Clear := model.WaybillVendorID2Mask(bill.WaybillVendorID)
|
||||
@@ -840,6 +857,7 @@ func (s *DefScheduler) resetTimer(savedOrderInfo *WatchOrderInfo, bill *model.Wa
|
||||
ts.StopTimer(statusType, vendorID, status)
|
||||
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
||||
})
|
||||
savedOrderInfo.AddTimer(timerInfo)
|
||||
}
|
||||
globals.SugarLogger.Debugf("resetTimer, orderID:%s, statusType:%d, status:%d, timeout:%v", order.VendorOrderID, statusType, status, timeout)
|
||||
} else {
|
||||
@@ -1184,29 +1202,41 @@ func (s *DefScheduler) watchOrderWaybills(savedOrderInfo *WatchOrderInfo) {
|
||||
savedOrderInfo.SetOrder(order)
|
||||
if isNeedWatch3rdWaybill(order) {
|
||||
if isNeedWatchWaybillTip(order) {
|
||||
// tipFee := getWaybillTip(order)
|
||||
// if tipFee > order.WaybillTipMoney {
|
||||
// vendorStatus := fmt.Sprintf("应设置小费:%s", jxutils.IntPrice2StandardCurrencyString(tipFee))
|
||||
// remark := ""
|
||||
// if false {
|
||||
// err = s.SetOrderWaybillTipByOrder(jxcontext.AdminCtx, order, tipFee)
|
||||
// if err == nil {
|
||||
// vendorStatus += "成功"
|
||||
// } else {
|
||||
// vendorStatus += "失败"
|
||||
// remark = fmt.Sprint(err)
|
||||
// }
|
||||
// } else {
|
||||
// vendorStatus += "空操作"
|
||||
// }
|
||||
// partner.CurOrderManager.OnOrderMsg(order, vendorStatus, remark)
|
||||
// }
|
||||
if handler, ok := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).(partner.IAddWaybillTip); ok && handler != nil {
|
||||
var remark string
|
||||
tipFee := getWaybillTip(order)
|
||||
vendorStatus := fmt.Sprintf("设置小费:%s", jxutils.IntPrice2StandardCurrencyString(tipFee))
|
||||
if curTipFee, err := handler.GetWaybillTip(jxcontext.AdminCtx, order); err == nil {
|
||||
tipFee2Add := tipFee - curTipFee
|
||||
vendorStatus += fmt.Sprintf(", 本次添加:%s", jxutils.IntPrice2StandardCurrencyString(tipFee2Add))
|
||||
if false { //tipFee2Add > 0 {
|
||||
err := handler.AddWaybillTip(jxcontext.AdminCtx, order, tipFee2Add)
|
||||
if err == nil {
|
||||
vendorStatus += "成功"
|
||||
order.WaybillTipMoney += tipFee2Add
|
||||
partner.CurOrderManager.UpdateOrderFields(order, []string{"WaybillTipMoney"})
|
||||
} else {
|
||||
vendorStatus += "失败"
|
||||
remark = fmt.Sprint(err)
|
||||
}
|
||||
tipFee2Add := tipFee - order.WaybillTipMoney
|
||||
vendorStatus += fmt.Sprintf(", 本次添加:%s", jxutils.IntPrice2StandardCurrencyString(tipFee2Add))
|
||||
if false { //tipFee2Add > 0 {
|
||||
err := handler.UpdateWaybillTip(jxcontext.AdminCtx, order.VendorOrgCode, order.VendorStoreID, order.VendorOrderID, order.VendorOrderID, "", "", tipFee)
|
||||
if err == nil {
|
||||
vendorStatus += "成功"
|
||||
order.WaybillTipMoney = tipFee
|
||||
partner.CurOrderManager.UpdateOrderFields(order, []string{"WaybillTipMoney"})
|
||||
} else {
|
||||
vendorStatus += "空操作"
|
||||
vendorStatus += "失败"
|
||||
remark = fmt.Sprint(err)
|
||||
}
|
||||
} else {
|
||||
vendorStatus += "失败"
|
||||
remark = fmt.Sprint(err)
|
||||
vendorStatus += "空操作"
|
||||
}
|
||||
partner.CurOrderManager.OnOrderMsg(order, vendorStatus, remark)
|
||||
}
|
||||
@@ -1251,18 +1281,35 @@ func OnDefSchConfChanged(key, value string) {
|
||||
}
|
||||
}
|
||||
|
||||
func setFakeActualPayPrice(order *model.GoodsOrder) (newOrder *model.GoodsOrder) {
|
||||
orderCopy := *order
|
||||
storeDetail, err := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, order.VendorID)
|
||||
if err == nil {
|
||||
if storeDetail.PayPercentage < 50 {
|
||||
orderCopy.ActualPayPrice = order.TotalShopMoney * (100 - int64(storeDetail.PayPercentage/2)) * 100
|
||||
} else {
|
||||
orderCopy.ActualPayPrice = order.EarningPrice
|
||||
}
|
||||
}
|
||||
newOrder = &orderCopy
|
||||
return newOrder
|
||||
}
|
||||
|
||||
func (s *DefScheduler) notifyNewOrder(order *model.GoodsOrder) {
|
||||
if order.Flag&model.OrderFlagMaskFake == 0 {
|
||||
utils.CallFuncAsync(func() {
|
||||
order = setFakeActualPayPrice(order)
|
||||
netprinter.PrintOrderByOrder(jxcontext.AdminCtx, order)
|
||||
weixinmsg.NotifyNewOrder(order)
|
||||
smsmsg.NotifyNewOrder(order)
|
||||
OrderProfitWarning(order)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DefScheduler) notifyUserApplyCancel(order *model.GoodsOrder, cancelReason string) {
|
||||
utils.CallFuncAsync(func() {
|
||||
order = setFakeActualPayPrice(order)
|
||||
weixinmsg.NotifyUserApplyCancel(order, cancelReason)
|
||||
})
|
||||
}
|
||||
@@ -1270,6 +1317,7 @@ func (s *DefScheduler) notifyUserApplyCancel(order *model.GoodsOrder, cancelReas
|
||||
func (s *DefScheduler) notifyOrderCanceled(order *model.GoodsOrder) {
|
||||
if order.Flag&model.OrderFlagMaskFake == 0 {
|
||||
utils.CallFuncAsync(func() {
|
||||
order = setFakeActualPayPrice(order)
|
||||
weixinmsg.NotifyOrderCanceled(order)
|
||||
smsmsg.NotifyOrderCanceled(order)
|
||||
})
|
||||
@@ -1291,3 +1339,46 @@ func isOrderCanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool) {
|
||||
}
|
||||
return isCan
|
||||
}
|
||||
|
||||
//订单预计利润若低于0,则向门店运营负责人发送钉钉消息
|
||||
func OrderProfitWarning(order *model.GoodsOrder) {
|
||||
var (
|
||||
operatorName string
|
||||
operatorPhone string
|
||||
noticeMsg string
|
||||
profit float64
|
||||
storeID int
|
||||
)
|
||||
db := dao.GetDB()
|
||||
if order == nil {
|
||||
return
|
||||
}
|
||||
if order.TotalShopMoney == 0 {
|
||||
globals.SugarLogger.Debugf("OrderProfitWarning TotalShopMoney=0 orderID:%s", order.VendorOrderID)
|
||||
return
|
||||
}
|
||||
storeID = jxutils.GetShowStoreIDFromOrder(order)
|
||||
storeDetail, err := dao.GetStoreDetail(db, storeID, order.VendorID)
|
||||
if storeDetail != nil && err == nil {
|
||||
payPercentage := storeDetail.PayPercentage
|
||||
if payPercentage >= 50 {
|
||||
profit = utils.Str2Float64(utils.Int64ToStr(order.TotalShopMoney-order.EarningPrice-order.DistanceFreightMoney-order.WaybillTipMoney)) / 100
|
||||
} else {
|
||||
profit = utils.Str2Float64(utils.Int64ToStr(order.TotalShopMoney*int64(payPercentage)/200)) / 100
|
||||
}
|
||||
if profit < 0 {
|
||||
if storeDetail.OperatorPhone != "" {
|
||||
operatorName = storeDetail.OperatorName
|
||||
operatorPhone = storeDetail.OperatorPhone
|
||||
} else if storeDetail.OperatorPhone2 != "" {
|
||||
operatorName = storeDetail.OperatorName2
|
||||
operatorPhone = storeDetail.OperatorPhone2
|
||||
}
|
||||
noticeMsg = fmt.Sprintf("利润 :[%v],运营负责人:[%v],门店ID:[%v],平台门店ID[%v],门店名:[%v],订单号(点击进入详情):%v", profit, operatorName, order.StoreID, order.VendorStoreID, order.StoreName, globals.BackstageHost+"/#/ordermanager/"+order.VendorOrderID)
|
||||
user, err := dao.GetUserByID(db, "mobile", operatorPhone)
|
||||
if user != nil && err == nil {
|
||||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "警告!此订单利润低于0", noticeMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,13 +214,13 @@ func (s *DefScheduler) QueryOrderWaybillFeeInfoEx(ctx *jxcontext.Context, vendor
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
waybillList, err := partner.CurOrderManager.GetOrderWaybillInfo(ctx, vendorOrderID, vendorID, true)
|
||||
waybillList, err := partner.CurOrderManager.GetOrderWaybillInfo(ctx, vendorOrderID, vendorID, true, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
waybillMap := make(map[int]*model.Waybill)
|
||||
for _, bill := range waybillList {
|
||||
waybillMap[bill.WaybillVendorID] = bill
|
||||
waybillMap[bill.WaybillVendorID] = &bill.Waybill
|
||||
}
|
||||
deliveryFeeMap = make(map[int]*partner.WaybillFeeInfo)
|
||||
|
||||
@@ -238,7 +238,7 @@ func (s *DefScheduler) QueryOrderWaybillFeeInfoEx(ctx *jxcontext.Context, vendor
|
||||
if storeCourier.Status != model.StoreStatusOpened {
|
||||
feeInfo = &partner.WaybillFeeInfo{
|
||||
ErrCode: partner.WaybillFeeErrCodeCourierNotOpen,
|
||||
ErrStr: fmt.Sprintf("%d配送门店没有启用", storeCourier.VendorID),
|
||||
ErrStr: fmt.Sprintf("暂未开通,联系运营"),
|
||||
}
|
||||
} else {
|
||||
if handler := partner.GetDeliveryPlatformFromVendorID(storeCourier.VendorID); handler != nil {
|
||||
|
||||
@@ -113,7 +113,7 @@ func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Ac
|
||||
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)
|
||||
effectActStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, act.Type, storeIDs, skuIDs, act.BeginAt, act.EndAt)
|
||||
if err != nil {
|
||||
globals.SugarLogger.Errorf("GetEffectiveActStoreSkuInfo can not get sku promotion info for error:%v", err)
|
||||
return nil, nil, nil, err
|
||||
@@ -138,62 +138,64 @@ 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 {
|
||||
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,
|
||||
}
|
||||
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
|
||||
if storeDetail.IsSync != 0 {
|
||||
if act.Type == model.ActSkuFake ||
|
||||
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,
|
||||
}
|
||||
if !(vendorID == model.VendorIDJX || act.Type == model.ActSkuFake) {
|
||||
actSkuMap.SyncStatus = model.SyncFlagNewMask
|
||||
storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]
|
||||
if storeSkuInfo != nil {
|
||||
jxPrice := storeSkuInfo.Price
|
||||
actSkuMap.VendorPrice = int64(getVendorPriceFromStoreSkuBind(storeSkuInfo, vendorID))
|
||||
v.OriginalPrice = int64(jxPrice)
|
||||
}
|
||||
if v.ActPrice != 0 {
|
||||
actSkuMap.ActualActPrice = v.ActPrice
|
||||
} else {
|
||||
percentage := act.PricePercentage
|
||||
if v.PricePercentage != 0 {
|
||||
percentage = v.PricePercentage
|
||||
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, 0))
|
||||
if actSkuMap.ActualActPrice > 10 {
|
||||
actSkuMap.ActualActPrice = int64(math.Floor(float64(actSkuMap.ActualActPrice)/10) * 10)
|
||||
if !(vendorID == model.VendorIDJX || act.Type == model.ActSkuFake) {
|
||||
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(vendorIDs, act.Type, float64(actSkuMap.ActualActPrice)*100/float64(actSkuMap.VendorPrice)); err2 != nil {
|
||||
v.ErrMsg = err2.Error()
|
||||
v.ActualActPrice = actSkuMap.ActualActPrice
|
||||
v.VendorPrice = actSkuMap.VendorPrice
|
||||
wrongSkuList = append(wrongSkuList, v)
|
||||
}
|
||||
}
|
||||
if actSkuMap.ActualActPrice <= 0 {
|
||||
actSkuMap.ActualActPrice = 1
|
||||
}
|
||||
if err2 = checkDiscountValidation(vendorIDs, act.Type, float64(actSkuMap.ActualActPrice)*100/float64(actSkuMap.VendorPrice)); err2 != nil {
|
||||
v.ErrMsg = err2.Error()
|
||||
v.ActualActPrice = actSkuMap.ActualActPrice
|
||||
v.VendorPrice = actSkuMap.VendorPrice
|
||||
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
|
||||
@@ -318,8 +320,12 @@ func checkDiscountValidation(vendorIDs []int, actType int, pricePercentage float
|
||||
} else if len(vendorIDs) > 0 && vendorIDs[0] == model.VendorIDMTWM && pricePercentageMin < minDiscount4SkuDirectDownMTWM {
|
||||
err = fmt.Errorf("美团平台%s活动折扣必须大于:%d", model.ActTypeName[actType], minDiscount4SkuDirectDownMTWM)
|
||||
}
|
||||
} else if actType == model.ActSkuSecKill && pricePercentageMax > maxDiscount4SkuSecKill {
|
||||
err = fmt.Errorf("%s活动折扣必须小于:%d", model.ActTypeName[actType], maxDiscount4SkuSecKill)
|
||||
} else if actType == model.ActSkuSecKill {
|
||||
if len(vendorIDs) > 0 && vendorIDs[0] == model.VendorIDMTWM && pricePercentageMax > minDiscount4SkuDirectDownMTWM {
|
||||
err = fmt.Errorf("美团平台%s活动折扣必须小于:%d", model.ActTypeName[actType], minDiscount4SkuDirectDownMTWM)
|
||||
} else if pricePercentageMax > maxDiscount4SkuSecKill {
|
||||
err = fmt.Errorf("%s活动折扣必须小于:%d", model.ActTypeName[actType], maxDiscount4SkuSecKill)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -341,8 +347,6 @@ func checkActValidation(act *model.Act, vendorIDs []int) (err error) {
|
||||
errList.AddErr(fmt.Errorf("必须指定缺省活动折扣"))
|
||||
} else if err = checkDiscountValidation(vendorIDs, 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]))
|
||||
}
|
||||
} else if act.Type == model.ActSkuFake {
|
||||
|
||||
@@ -611,7 +615,7 @@ func GetActStoreSkuInfo(ctx *jxcontext.Context, actID int, vendorIDs []int, keyw
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range actStoreSkuList {
|
||||
v.SkuName = jxutils.ComposeSkuName(v.Prefix, v.SkuNameName, v.Comment, v.Unit, v.SpecQuality, v.SpecUnit, 0)
|
||||
v.SkuName = jxutils.ComposeSkuName(v.Prefix, v.SkuNameName, v.Comment, v.Unit, v.SpecQuality, v.SpecUnit, 0, v.ExPrefix, v.ExPrefixBegin, v.ExPrefixEnd)
|
||||
}
|
||||
if pageSize > 0 && pageSize != model.UnlimitedPageSize {
|
||||
pagedInfo := &model.PagedInfo{
|
||||
@@ -760,7 +764,7 @@ func SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, actID int, vendor
|
||||
if vendorIDs == nil {
|
||||
vendorIDs = partner.GetVendorIDsFromActMap(actMap)
|
||||
}
|
||||
if len(vendorIDs) == 0 || actMap[vendorIDs[0]].Type == model.ActSkuFake {
|
||||
if len(vendorIDs) == 0 || vendorIDs[0] == model.VendorIDJX || actMap[vendorIDs[0]].Type == model.ActSkuFake {
|
||||
return "", nil
|
||||
}
|
||||
task := tasksch.NewParallelTask("SyncAct", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
||||
@@ -888,16 +892,15 @@ func RefreshPageActs(ctx *jxcontext.Context, vendorIDs []int, createdFrom time.T
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func DeleteSkusFromAct(ctx *jxcontext.Context, vendorID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
func DeleteSkusFromAct(ctx *jxcontext.Context, vendorID int, actTypes, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
db := dao.GetDB()
|
||||
actMap := make(map[int]*model.Act)
|
||||
for _, skuID := range skuIDs {
|
||||
pagedInfo, err2 := dao.QueryActs(db, 0, 0, -1, -1, "", vendorID, []int{model.ActStatusCreated}, []int{model.ActSkuDirectDown, model.ActSkuSecKill}, nil, 0, skuID, 0,
|
||||
pagedInfo, err2 := dao.QueryActs(db, 0, 0, -1, -1, "", vendorID, []int{model.ActStatusCreated}, actTypes, nil, 0, skuID, 0,
|
||||
utils.DefaultTimeValue, utils.DefaultTimeValue, time.Now().Add(-24*30*3*time.Hour), utils.DefaultTimeValue)
|
||||
if err = err2; err != nil {
|
||||
return "", err
|
||||
}
|
||||
// globals.SugarLogger.Debug(utils.Format4Output(pagedInfo, false))
|
||||
for _, v := range pagedInfo.Data {
|
||||
actMap[v.Act.ID] = &v.Act
|
||||
}
|
||||
@@ -951,7 +954,7 @@ func DeleteSkusFromAct(ctx *jxcontext.Context, vendorID int, skuIDs []int, isAsy
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, storeSkuList []*ActStoreSkuParam, isAsync bool) (hint string, err error) {
|
||||
func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, storeSkuList []*ActStoreSkuParam, lockTime time.Time, isAsync bool) (hint string, err error) {
|
||||
var wrongSkuList []*ActStoreSkuParam
|
||||
var storeSkuBindList []*model.StoreSkuBind
|
||||
|
||||
@@ -985,13 +988,15 @@ func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, s
|
||||
}
|
||||
}
|
||||
if storeSkuBind != nil {
|
||||
dao.SetStoreSkuBindVendorPrice(storeSkuBind, vendorID, vendorPrice)
|
||||
dao.SetStoreSkuBindVendorPrice(storeSkuBind, vendorID, vendorPrice, lockTime)
|
||||
if vendorID != model.VendorIDJX {
|
||||
dao.SetStoreSkuBindSyncStatus(storeSkuBind, vendorID, dao.GetStoreSkuBindSyncStatus(storeSkuBind, vendorID)|model.SyncFlagPriceMask)
|
||||
}
|
||||
storeSkuBind.LastOperator = ctx.GetUserName()
|
||||
storeSkuBindList = append(storeSkuBindList, storeSkuBind)
|
||||
}
|
||||
} else if dao.IsNoRowsError(err) { // 忽略不存在错
|
||||
err = nil
|
||||
} else {
|
||||
errList.AddErr(fmt.Errorf("获取门店:%d商品:%d出错:%s", v.StoreID, v.SkuID, err))
|
||||
}
|
||||
|
||||
@@ -100,6 +100,8 @@ func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
|
||||
"storePriceTypeName": model.StorePriceTypeName,
|
||||
"payStatusName": model.PayStatusName,
|
||||
"refundStatusName": model.RefundStatusName,
|
||||
"autoReplyTypeName": model.AutoReplyTypeName,
|
||||
"complaintReasons": model.ComplaintReasons,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,12 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/globals/api"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/baseapi/utils/errlist"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
@@ -54,7 +60,7 @@ func GetVendorCategories(ctx *jxcontext.Context, vendorID int, parentID string)
|
||||
// parentID 为-1表示所有
|
||||
func GetCategories(ctx *jxcontext.Context, parentID int) (catList []*dao.SkuCategoryWithVendor, err error) {
|
||||
db := dao.GetDB()
|
||||
cats, err := dao.GetCategories(db, parentID, nil)
|
||||
cats, err := dao.GetCategories(db, parentID, 0, nil)
|
||||
if err == nil {
|
||||
var ids []int
|
||||
for _, v := range cats {
|
||||
@@ -516,7 +522,10 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma
|
||||
t1.status,
|
||||
t1.is_spu,
|
||||
t1.desc_img,
|
||||
t1.upc`
|
||||
t1.upc,
|
||||
t1.ex_prefix,
|
||||
t1.ex_prefix_begin,
|
||||
t1.ex_prefix_end`
|
||||
if isBySku {
|
||||
sql += `,
|
||||
t2.id`
|
||||
@@ -545,6 +554,9 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma
|
||||
t1.upc,
|
||||
t1.jd_id,
|
||||
t1.jd_sync_status,
|
||||
t1.ex_prefix,
|
||||
t1.ex_prefix_begin,
|
||||
t1.ex_prefix_end,
|
||||
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"id":', t2.id, ',"comment":"', t2.comment, '","status":', t2.status,
|
||||
',"createdAt":"', CONCAT(REPLACE(t2.created_at," ","T"),"+08:00"), '","updatedAt":"', CONCAT(REPLACE(t2.updated_at," ","T"),"+08:00"),
|
||||
'","lastOperator":"', t2.last_operator, '","specQuality":', t2.spec_quality, ',"specUnit":"', t2.spec_unit,
|
||||
@@ -575,6 +587,7 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma
|
||||
|
||||
var skuIDs []int
|
||||
for _, skuName := range skuNamesInfo.SkuNames {
|
||||
skuName.FullName = jxutils.ComposeSkuName(skuName.Prefix, skuName.Name, "", "", 0, "", 0, skuName.ExPrefix, skuName.ExPrefixBegin, skuName.ExPrefixEnd)
|
||||
if skuName.SkusStr != "" {
|
||||
if err = utils.UnmarshalUseNumber([]byte(skuName.SkusStr), &skuName.Skus); err != nil {
|
||||
dao.Rollback(db)
|
||||
@@ -646,17 +659,14 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s
|
||||
if hasSensitiveWord, err := CheckHasSensitiveWord(skuNameExt.Name); hasSensitiveWord {
|
||||
return nil, err
|
||||
}
|
||||
upc := utils.Pointer2String(skuNameExt.Upc)
|
||||
if upc == "" {
|
||||
skuNameExt.Upc = nil
|
||||
} else if !jxutils.IsUpcValid(upc) {
|
||||
return nil, fmt.Errorf("upc:%s不合法,请仔细检查", upc)
|
||||
}
|
||||
|
||||
db := dao.GetDB()
|
||||
if skuNameExt.Upc != "" {
|
||||
err = dao.GetEntity(db, &skuNameExt.SkuName, "Upc")
|
||||
if err == nil {
|
||||
return nil, fmt.Errorf("UPC:%s重复", skuNameExt.Upc)
|
||||
} else if !dao.IsNoRowsError(err) {
|
||||
return nil, err
|
||||
}
|
||||
err = nil
|
||||
}
|
||||
skuNameExt.SkuName.Status = model.SkuStatusNormal
|
||||
if skuNameExt.IsSpu == 1 {
|
||||
return nil, fmt.Errorf("不允许创建多规格商品")
|
||||
@@ -776,19 +786,14 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf
|
||||
valid = utils.RemoveGeneralMapKeys(valid, model.FieldSpecQuality, model.FieldSpecUnit)
|
||||
_, hasPlaces := payload["places"]
|
||||
if len(valid) > 0 || hasPlaces {
|
||||
globals.SugarLogger.Debugf("UpdateSkuName valid:%s", utils.Format4Output(valid, false))
|
||||
if upc, _ := valid["upc"].(string); upc != "" {
|
||||
skuName := &model.SkuName{
|
||||
Upc: upc,
|
||||
if valid["Upc"] != nil {
|
||||
if upc, _ := valid["Upc"].(string); upc == "" {
|
||||
valid["Upc"] = nil
|
||||
} else if !jxutils.IsUpcValid(upc) {
|
||||
return 0, fmt.Errorf("upc:%s不合法,请仔细检查", upc)
|
||||
}
|
||||
err = dao.GetEntity(db, skuName, "Upc")
|
||||
if err == nil {
|
||||
return 0, fmt.Errorf("UPC:%s重复", upc)
|
||||
} else if !dao.IsNoRowsError(err) {
|
||||
return 0, err
|
||||
}
|
||||
err = nil
|
||||
}
|
||||
globals.SugarLogger.Debugf("UpdateSkuName valid:%s", utils.Format4Output(valid, false))
|
||||
for _, imgName := range []string{"img", "img2"} {
|
||||
if valid[imgName] != nil {
|
||||
if imgStr := utils.Interface2String(valid[imgName]); imgStr != "" {
|
||||
@@ -846,7 +851,6 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
skuList, err2 := dao.GetSkus(db, nil, []int{nameID}, nil, nil)
|
||||
if err = err2; err == nil {
|
||||
for _, v := range skuList {
|
||||
@@ -865,7 +869,6 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
skuIDs, err2 := dao.GetSkuIDByNames(db, []int{nameID})
|
||||
if err = err2; err != nil {
|
||||
dao.Rollback(db)
|
||||
@@ -1289,3 +1292,146 @@ func SortCategorySkus(ctx *jxcontext.Context, catID int, skuIDList []int) (err e
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func GetJdUpcCodeByName(ctx *jxcontext.Context, name, upcCode string) (productInfos []*jdapi.ProductInfo, err error) {
|
||||
var (
|
||||
pageNo = 5
|
||||
pageSize = 30
|
||||
pageNoList []int
|
||||
)
|
||||
if name == "" && upcCode == "" {
|
||||
return nil, fmt.Errorf("至少输入一个条件查询,商品名或者upc码!")
|
||||
}
|
||||
for i := 1; i < pageNo+1; i++ {
|
||||
pageNoList = append(pageNoList, i)
|
||||
}
|
||||
task := tasksch.NewParallelTask("获取京东商品", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
pageNum := batchItemList[0].(int)
|
||||
productInfo, err := api.JdAPI.GetJdUpcCodeByName(name, upcCode, pageNum, pageSize)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
for _, v := range productInfo {
|
||||
_, name, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.OriginalName)
|
||||
v.Name = name
|
||||
v.SpecQuality = specQuality
|
||||
v.SpecUnit = specUnit
|
||||
}
|
||||
retVal = productInfo
|
||||
return retVal, err
|
||||
}, pageNoList)
|
||||
tasksch.HandleTask(task, nil, true).Run()
|
||||
productInfoInterface, err := task.GetResult(0)
|
||||
for _, v := range productInfoInterface {
|
||||
productInfos = append(productInfos, v.(*jdapi.ProductInfo))
|
||||
}
|
||||
return productInfos, err
|
||||
}
|
||||
|
||||
func UpdateSkuNamesExPrefix(ctx *jxcontext.Context, nameIDs []int, exPrefix, fromTime, toTime string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
var (
|
||||
fromTimeP time.Time
|
||||
toTimeP time.Time
|
||||
db = dao.GetDB()
|
||||
)
|
||||
if fromTime != "" {
|
||||
fromTimeP = utils.Time2Date(utils.Str2Time(fromTime))
|
||||
}
|
||||
if toTime != "" {
|
||||
toTimeP = utils.Time2Date(utils.Str2Time(toTime))
|
||||
}
|
||||
if toTimeP.Before(fromTimeP) {
|
||||
return "", fmt.Errorf("结束时间不可以小于开始时间!开始时间:[%v],结束时间:[%v]", fromTimeP, toTimeP)
|
||||
}
|
||||
task := tasksch.NewParallelTask("批量设置商品前缀", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
step := batchItemList[0].(int)
|
||||
now := utils.Time2Date(time.Now())
|
||||
switch step {
|
||||
case 0:
|
||||
task := tasksch.NewParallelTask("批量设置商品前缀", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
nameID := batchItemList[0].(int)
|
||||
payload := map[string]interface{}{
|
||||
"exPrefix": exPrefix,
|
||||
"exPrefixBegin": fromTimeP,
|
||||
"exPrefixEnd": toTimeP,
|
||||
}
|
||||
if now.Sub(toTimeP) <= 0 && now.Sub(fromTimeP) >= 0 {
|
||||
_, err = UpdateSkuName(ctx, nameID, payload)
|
||||
} else if now.Sub(fromTimeP) > 0 && now.Sub(toTimeP) > 0 {
|
||||
payload["exPrefixBegin"] = nil
|
||||
payload["exPrefixEnd"] = nil
|
||||
_, err = UpdateSkuName(ctx, nameID, payload)
|
||||
} else {
|
||||
skuList, err := dao.GetSkus(db, nil, []int{nameID}, nil, nil)
|
||||
if err == nil && len(skuList) > 0 {
|
||||
if skuList[0].ExPrefixBegin != nil {
|
||||
_, err = UpdateSkuName(ctx, nameID, payload)
|
||||
CurVendorSync.SyncStoresSkus2(ctx, db, partner.GetSingleStoreVendorIDs(), nil, false, []int{skuList[0].ID}, nil, model.SyncFlagModifiedMask, true, true)
|
||||
} else {
|
||||
skuName := &model.SkuName{
|
||||
ExPrefix: exPrefix,
|
||||
ExPrefixBegin: &fromTimeP,
|
||||
ExPrefixEnd: &toTimeP,
|
||||
}
|
||||
skuName.ID = nameID
|
||||
skuName.LastOperator = ctx.GetLoginID()
|
||||
skuName.UpdatedAt = time.Now()
|
||||
dao.Begin(db)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
dao.Rollback(db)
|
||||
panic(r)
|
||||
}
|
||||
}()
|
||||
_, err = dao.UpdateEntity(db, skuName, "ExPrefix", "ExPrefixBegin", "ExPrefixEnd", "LastOperator", "UpdatedAt")
|
||||
dao.Commit(db)
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal, err
|
||||
}, nameIDs)
|
||||
tasksch.HandleTask(task, nil, true).Run()
|
||||
_, err = task.GetResult(0)
|
||||
case 1:
|
||||
if (now.Sub(toTimeP) <= 0 && now.Sub(fromTimeP) >= 0) || (now.Sub(fromTimeP) > 0 && now.Sub(toTimeP) > 0) {
|
||||
var skuIDs []int
|
||||
skuList, err2 := dao.GetSkus(db, nil, nameIDs, nil, nil)
|
||||
if err = err2; err == nil {
|
||||
if len(skuList) > 0 {
|
||||
for _, v := range skuList {
|
||||
skuIDs = append(skuIDs, v.ID)
|
||||
}
|
||||
CurVendorSync.SyncStoresSkus2(ctx, db, partner.GetSingleStoreVendorIDs(), nil, false, skuIDs, nil, model.SyncFlagModifiedMask, true, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal, err
|
||||
}, []int{0, 1})
|
||||
tasksch.HandleTask(task, nil, true).Run()
|
||||
if !isAsync {
|
||||
_, err = task.GetResult(0)
|
||||
hint = "1"
|
||||
} else {
|
||||
hint = task.GetID()
|
||||
}
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func SetSingleStoreSkuSyncModifyStatus(db *dao.DaoDB, vendorIDs []int) (err error) {
|
||||
_, err = dao.UpdateStoreSkuBindSyncStatusForExPrefix(db, vendorIDs)
|
||||
return err
|
||||
}
|
||||
|
||||
func SetMultiStoreSkuSyncModifyStatus(db *dao.DaoDB, vendorIDs []int) (err error) {
|
||||
_, err = dao.UpdateSkuSyncStatusForExPrefix(db, vendorIDs)
|
||||
return err
|
||||
}
|
||||
|
||||
func DeleteSkuNameExPrefixOverdue(db *dao.DaoDB) (err error) {
|
||||
_, err = dao.DeleteSkuNameExPrefixOverdue(db)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/360EntSecGroup-Skylar/excelize"
|
||||
|
||||
@@ -145,6 +146,11 @@ type VendorStoreExcel struct {
|
||||
OperatorName2 string `json:"运营负责人2"`
|
||||
}
|
||||
|
||||
type JdStoreLevelExt struct {
|
||||
Level string `json:"level`
|
||||
PageNo int `json:"pageNo"`
|
||||
}
|
||||
|
||||
var (
|
||||
ErrMissingInput = errors.New("没有有效的输入参数")
|
||||
ErrCanNotFindVendor = errors.New("vendorID参数不合法")
|
||||
@@ -167,6 +173,7 @@ var (
|
||||
"deliveryRangeType": 1,
|
||||
"deliveryRange": 1,
|
||||
"status": 1,
|
||||
"promoteInfo": 1,
|
||||
}
|
||||
|
||||
WatchVendorStoreTimeList = []string{
|
||||
@@ -204,6 +211,7 @@ var (
|
||||
"18328080405": "18328080405", //肖娜娜的手机
|
||||
"13350726500": "13350726500", //谭翔心
|
||||
"15928865396": "15928865396", //何佳梦
|
||||
"18048531223": "18048531223", //石老板
|
||||
}
|
||||
)
|
||||
|
||||
@@ -830,6 +838,10 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa
|
||||
}
|
||||
}
|
||||
|
||||
if valid["promoteInfo"] != nil {
|
||||
valid["promoteInfo"] = strings.ReplaceAll(valid["promoteInfo"].(string), "{phone}", store.Tel1)
|
||||
}
|
||||
|
||||
for k, _ := range valid {
|
||||
if roleMap[k] != "" {
|
||||
if authInfo, err := ctx.GetV2AuthInfo(); err == nil {
|
||||
@@ -1042,6 +1054,7 @@ func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, vendorID int, vend
|
||||
userName := ctx.GetUserName()
|
||||
storeMap.StoreID = storeID
|
||||
storeMap.VendorID = vendorID
|
||||
storeMap.VendorOrgCode = vendorOrgCode
|
||||
storeMap.Status = model.StoreStatusOpened
|
||||
storeMap.DeliveryType = model.StoreDeliveryTypeByStore
|
||||
storeMap.SyncStatus = 0
|
||||
@@ -1137,6 +1150,12 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor
|
||||
if valid["status"] != nil {
|
||||
syncStatus |= model.SyncFlagStoreStatus
|
||||
}
|
||||
if vendorStoreName, ok := valid["vendorStoreName"].(string); ok {
|
||||
if utf8.RuneCountInString(vendorStoreName) > jdapi.MaxStoreNameLen && vendorID == model.VendorIDJD {
|
||||
return 0, fmt.Errorf("门店名称不允许超过13位!")
|
||||
}
|
||||
syncStatus |= model.SyncFlagStoreName
|
||||
}
|
||||
for _, v := range [][]string{
|
||||
[]string{
|
||||
"pricePercentagePack",
|
||||
@@ -1177,7 +1196,7 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor
|
||||
panic(r)
|
||||
}
|
||||
}()
|
||||
if valid["status"] != nil { // 对于store vendor map,只有Status改变才需要同步到厂商
|
||||
if valid["status"] != nil || valid["vendorStoreName"] != nil { // 对于store vendor map,只有Status改变才需要同步到厂商
|
||||
num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, storeMap, valid, userName, map[string]interface{}{
|
||||
model.FieldStoreID: storeID,
|
||||
model.FieldVendorID: vendorID,
|
||||
@@ -1210,7 +1229,7 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor
|
||||
}
|
||||
}
|
||||
dao.Commit(db)
|
||||
if vendorID != model.VendorIDJX && (valid["status"] != nil || valid["freightDeductionPack"] != nil) {
|
||||
if vendorID != model.VendorIDJX && (valid["status"] != nil || valid["freightDeductionPack"] != nil || valid["vendorStoreName"] != nil) {
|
||||
_, err = CurVendorSync.SyncStore(ctx, db, vendorID, storeID, false, userName)
|
||||
}
|
||||
}
|
||||
@@ -2529,13 +2548,13 @@ func StoreStatus2Chinese(status int) (str string) {
|
||||
}
|
||||
}
|
||||
|
||||
func GetStorePriceScore(ctx *jxcontext.Context, storeIDs []int, fromScore, toScore, sort int, snapDate string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
||||
func GetStorePriceScore(ctx *jxcontext.Context, storeIDs, vendorIDs []int, fromScore, toScore, sort int, snapDate string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
||||
var snapDateParam time.Time
|
||||
db := dao.GetDB()
|
||||
if snapDate != "" {
|
||||
snapDateParam = utils.Str2Time(snapDate)
|
||||
}
|
||||
storePriceScore, totalCount, err := dao.GetStorePriceScore(db, storeIDs, fromScore, toScore, sort, snapDateParam, offset, pageSize)
|
||||
storePriceScore, totalCount, err := dao.GetStorePriceScore(db, storeIDs, vendorIDs, fromScore, toScore, sort, snapDateParam, offset, pageSize)
|
||||
pagedInfo = &model.PagedInfo{
|
||||
Data: storePriceScore,
|
||||
TotalCount: totalCount,
|
||||
@@ -2543,14 +2562,10 @@ func GetStorePriceScore(ctx *jxcontext.Context, storeIDs []int, fromScore, toSco
|
||||
return pagedInfo, err
|
||||
}
|
||||
|
||||
func CreateStorePriceScore(ctx *jxcontext.Context, forRefresh bool) (err error) {
|
||||
func CreateStorePriceScore(ctx *jxcontext.Context) (err error) {
|
||||
db := dao.GetDB()
|
||||
var snapshotAt time.Time
|
||||
if forRefresh {
|
||||
snapshotAt = utils.Time2Date(time.Now().AddDate(0, 0, -1))
|
||||
} else {
|
||||
snapshotAt = utils.Time2Date(time.Now())
|
||||
}
|
||||
snapshotAt = utils.Time2Date(time.Now().AddDate(0, 0, -1))
|
||||
storePriceScoreSnapshot, err := dao.GetStorePriceScoreSnapshot(db, snapshotAt)
|
||||
if len(storePriceScoreSnapshot) > 0 {
|
||||
dao.Begin(db)
|
||||
@@ -2574,6 +2589,51 @@ func CreateStorePriceScore(ctx *jxcontext.Context, forRefresh bool) (err error)
|
||||
}
|
||||
}
|
||||
dao.Commit(db)
|
||||
globals.SugarLogger.Debugf("CreateStorePriceScore")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func RefreshJdLevel(ctx *jxcontext.Context) (err error) {
|
||||
db := dao.GetDB()
|
||||
storeMapList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, model.StoreStatusOpened, -1, "")
|
||||
if len(storeMapList) > 0 {
|
||||
dao.Begin(db)
|
||||
defer func() {
|
||||
if r := recover(); r != nil || err != nil {
|
||||
dao.Rollback(db)
|
||||
if r != nil {
|
||||
panic(r)
|
||||
}
|
||||
}
|
||||
}()
|
||||
task := tasksch.NewParallelTask("更新京东门店等级", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
v := batchItemList[0].(*model.StoreMap)
|
||||
var (
|
||||
pageLimit = 5
|
||||
pageNo = 1
|
||||
level string
|
||||
)
|
||||
for ; pageNo < pageLimit+1; pageNo++ {
|
||||
level, err = jd.GetAPI(v.VendorOrgCode).GetJdStoreLevel(v.VendorOrgCode, v.VendorStoreID, pageNo)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
if level != "" {
|
||||
break
|
||||
}
|
||||
if pageNo == pageLimit {
|
||||
level = ""
|
||||
}
|
||||
}
|
||||
v.JdStoreLevel = level
|
||||
_, err = dao.UpdateEntity(db, v, "JdStoreLevel")
|
||||
return retVal, err
|
||||
}, storeMapList)
|
||||
tasksch.HandleTask(task, nil, true).Run()
|
||||
_, err = task.GetResult(0)
|
||||
dao.Commit(db)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
||||
"git.rosy.net.cn/jx-callback/globals/api/apimanager"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
|
||||
@@ -42,6 +43,13 @@ const (
|
||||
CopyStoreSkuModeUpdatePrice = "updatePrice" // 增量复制价格
|
||||
)
|
||||
|
||||
//通用写入Excel
|
||||
type ExcelParam struct {
|
||||
DataList interface{}
|
||||
SheetName string
|
||||
TitleList []string
|
||||
}
|
||||
|
||||
// UpdateStoreSku用,API调用时
|
||||
type StoreSkuBindSkuInfo struct {
|
||||
SkuID int `json:"skuID"`
|
||||
@@ -117,6 +125,14 @@ type SheetParam struct {
|
||||
SkuRow int
|
||||
}
|
||||
|
||||
type DataVendorStoreSkuPrice struct {
|
||||
StoreID string `json:"门店ID"`
|
||||
StoreName string `json:"门店名"`
|
||||
SkuID int `json:"商品ID"`
|
||||
SkuName string `json:"商品名"`
|
||||
VendorPrice string `json:"平台价"`
|
||||
}
|
||||
|
||||
type DataSuccess struct {
|
||||
NameID int `json:"商品NameID"`
|
||||
Name string `json:"商品名称"`
|
||||
@@ -139,7 +155,7 @@ type DataLock struct {
|
||||
}
|
||||
|
||||
const (
|
||||
maxStoreNameBind = 3000 // 最大门店SkuName bind个数
|
||||
maxStoreNameBind = 10000 // 最大门店SkuName bind个数
|
||||
maxStoreNameBind2 = 10000 // 最大门店乘SkuName个数
|
||||
|
||||
AutoSaleAtStr = "22:00:00"
|
||||
@@ -151,7 +167,14 @@ var (
|
||||
"18180948107": 1, // 徐
|
||||
// "13684045763": 1, // 周
|
||||
}
|
||||
dataLock DataLock
|
||||
dataLock DataLock
|
||||
titleListVendorStoreSkuPrice = []string{
|
||||
"门店ID",
|
||||
"门店名",
|
||||
"商品ID",
|
||||
"商品名",
|
||||
"平台价",
|
||||
}
|
||||
titleListSuccess = []string{
|
||||
"商品NameID",
|
||||
"商品名称",
|
||||
@@ -319,6 +342,12 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool
|
||||
sqlParams = append(sqlParams, skuID)
|
||||
}
|
||||
}
|
||||
if lockTimeStr, ok := params["lockTime"].(string); ok && lockTimeStr != "" {
|
||||
if timeList, err2 := jxutils.BatchStr2Time(lockTimeStr); err2 == nil {
|
||||
sql += " AND (t4.jd_lock_time > ? OR t4.mtwm_lock_time > ? OR t4.ebai_lock_time > ? OR t4.jx_lock_time > ?)"
|
||||
sqlParams = append(sqlParams, timeList[0], timeList[0], timeList[0], timeList[0])
|
||||
}
|
||||
}
|
||||
if isFocus {
|
||||
if params["fromStatus"] != nil {
|
||||
fromStatus := params["fromStatus"].(int)
|
||||
@@ -451,6 +480,7 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo
|
||||
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,
|
||||
t4.jd_lock_time, t4.ebai_lock_time, t4.mtwm_lock_time, t4.jx_lock_time,
|
||||
t4.status_sale_begin, t4.status_sale_end
|
||||
`, jdVendorIDField) + sql
|
||||
var tmpList []*tGetStoresSkusInfo
|
||||
@@ -862,9 +892,9 @@ func uniqueStoreNameBind(skuBindInfos []*StoreSkuBindInfo) (outSkuBindInfos []*S
|
||||
}
|
||||
|
||||
func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isScale bool) (needSyncSkus []int, err error) {
|
||||
if len(storeIDs)*len(skuBindInfos) > maxStoreNameBind2 {
|
||||
return nil, fmt.Errorf("门店商品信息大于%d", maxStoreNameBind2)
|
||||
}
|
||||
// if len(storeIDs)*len(skuBindInfos) > maxStoreNameBind2 {
|
||||
// return nil, fmt.Errorf("门店商品信息大于%d", maxStoreNameBind2)
|
||||
// }
|
||||
|
||||
storeIDs = uniqueStoreIDs(storeIDs)
|
||||
skuBindInfos = uniqueStoreNameBind(skuBindInfos)
|
||||
@@ -991,11 +1021,24 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
|
||||
setStoreSkuBindStatus(skuBind, model.SyncFlagNewMask)
|
||||
dao.WrapAddIDCULDEntity(skuBind, userName)
|
||||
globals.SugarLogger.Debug(utils.Format4Output(skuBind, false))
|
||||
if err = dao.CreateEntity(db, skuBind); err != nil {
|
||||
dao.Rollback(db)
|
||||
return nil, err
|
||||
if deletedSku := dao.GetDeletedStoreSkuBind(db, skuBind.StoreID, skuBind.SkuID); deletedSku == nil {
|
||||
if err = dao.CreateEntity(db, skuBind); err != nil {
|
||||
dao.Rollback(db)
|
||||
return nil, err
|
||||
}
|
||||
num = 1
|
||||
} else {
|
||||
// 需要处理,在删除某个门店商品,同步失败的情况下,又把商品重新关注。
|
||||
// 所以统一处理成恢复删除的记录,这样避免问题
|
||||
skuBind.ID = deletedSku.ID
|
||||
// vendorSkuID的赋值意义不大
|
||||
skuBind.MtwmID = deletedSku.MtwmID
|
||||
skuBind.EbaiID = deletedSku.EbaiID
|
||||
if num, err = dao.UpdateEntity(db, skuBind); err != nil {
|
||||
dao.Rollback(db)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
num = 1
|
||||
}
|
||||
} else {
|
||||
skuBind = &v.StoreSkuBind
|
||||
@@ -1090,12 +1133,13 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
|
||||
return skuIDs, err
|
||||
}
|
||||
|
||||
func getSkuSaleStatus(inSkuBind *StoreSkuBindSkuInfo, skuBindInfo *StoreSkuBindInfo) int {
|
||||
func getSkuSaleStatus(inSkuBind *StoreSkuBindSkuInfo, skuNameBindInfo *StoreSkuBindInfo) int {
|
||||
tempSale := 0
|
||||
if inSkuBind != nil {
|
||||
tempSale = inSkuBind.IsSale
|
||||
} else {
|
||||
tempSale = skuBindInfo.IsSale
|
||||
}
|
||||
if tempSale == 0 {
|
||||
tempSale = skuNameBindInfo.IsSale
|
||||
}
|
||||
if tempSale == -1 {
|
||||
return model.StoreSkuBindStatusDontSale
|
||||
@@ -2139,12 +2183,118 @@ func GetTopSkusByStoreIDs(ctx *jxcontext.Context, storeIDs []int) (storeSkuNameE
|
||||
return storeSkuNameExt, err
|
||||
}
|
||||
|
||||
func GetTopCategorysByStoreIDs(ctx *jxcontext.Context, storeIDs []int) (skuCategory []*model.SkuCategory, err error) {
|
||||
func GetTopSkusByCityCode(ctx *jxcontext.Context, cityCode, storeID int) (skuNameAndPlaceList []*dao.SkuNameAndPlace, err error) {
|
||||
db := dao.GetDB()
|
||||
orderCreate := time.Now().AddDate(0, -1, 0)
|
||||
skuNameAndPlace, err := dao.GetTopSkusByCityCode(db, cityCode, orderCreate)
|
||||
if storeID > 0 {
|
||||
var skuNameList []*model.SkuName
|
||||
//未关注,不可售的商品nameID列表
|
||||
sql := `
|
||||
SELECT DISTINCT b.name_id id,1 brand_id
|
||||
FROM store_sku_bind a
|
||||
JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ?
|
||||
WHERE a.deleted_at = ?
|
||||
AND a.store_id = ?
|
||||
AND a.status <> ?
|
||||
AND b.name_id NOT IN(SELECT DISTINCT b.name_id
|
||||
FROM store_sku_bind a
|
||||
JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ?
|
||||
WHERE a.deleted_at = ?
|
||||
AND a.store_id = ?
|
||||
AND a.status = ?)
|
||||
UNION
|
||||
SELECT DISTINCT a.name_id id,0 brand_id
|
||||
FROM sku a
|
||||
LEFT JOIN (SELECT DISTINCT b.name_id
|
||||
FROM store_sku_bind a
|
||||
JOIN sku b ON a.sku_id = b.id
|
||||
WHERE a.deleted_at = ?
|
||||
AND store_id = ?)b ON a.name_id = b.name_id
|
||||
WHERE a.status = ?
|
||||
AND a.deleted_at = ?
|
||||
AND b.name_id IS NULL
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
utils.DefaultTimeValue,
|
||||
utils.DefaultTimeValue,
|
||||
storeID,
|
||||
model.StoreSkuBindStatusNormal,
|
||||
utils.DefaultTimeValue,
|
||||
utils.DefaultTimeValue,
|
||||
storeID,
|
||||
model.StoreSkuBindStatusNormal,
|
||||
utils.DefaultTimeValue,
|
||||
storeID,
|
||||
model.StoreSkuBindStatusNormal,
|
||||
utils.DefaultTimeValue,
|
||||
}
|
||||
err = dao.GetRows(db, &skuNameList, sql, sqlParams...)
|
||||
var skuNameMap = make(map[int]*model.SkuName)
|
||||
for _, v := range skuNameList {
|
||||
skuNameMap[v.ID] = v
|
||||
}
|
||||
for _, v := range skuNameAndPlace {
|
||||
if skuNameMap[v.ID] != nil {
|
||||
midPrice, _ := dao.GetMidPriceByNameID(db, cityCode, v.ID, utils.Time2Date(time.Now().AddDate(0, 0, -1)))
|
||||
if midPrice != 0 {
|
||||
v.Price = midPrice
|
||||
}
|
||||
v.Type = skuNameMap[v.ID].BrandID
|
||||
skuNameAndPlaceList = append(skuNameAndPlaceList, v)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
skuNameAndPlaceList = append(skuNameAndPlaceList, skuNameAndPlace...)
|
||||
}
|
||||
i := 1
|
||||
for _, v := range skuNameAndPlaceList {
|
||||
v.Sequence = i
|
||||
i++
|
||||
}
|
||||
if len(skuNameAndPlaceList) <= 100 {
|
||||
return skuNameAndPlaceList, err
|
||||
} else {
|
||||
return skuNameAndPlaceList[0:100], err
|
||||
}
|
||||
}
|
||||
|
||||
func GetTopCategoriesByStoreIDs(ctx *jxcontext.Context, storeIDs []int) (skuCategory []*model.SkuCategory, err error) {
|
||||
var (
|
||||
skuCategory2 []*model.SkuCategory
|
||||
skuCategoryMap = make(map[int]*model.SkuCategory)
|
||||
limit = 10
|
||||
)
|
||||
if len(storeIDs) == 0 {
|
||||
return skuCategory, err
|
||||
}
|
||||
db := dao.GetDB()
|
||||
skuCategory, err = dao.GetTopCategorysByStoreIDs(db, storeIDs)
|
||||
skuCategory, err = dao.GetTopCategoriesByStoreIDs(db, storeIDs, limit)
|
||||
//若大于等于10个就不用做下面的操作
|
||||
if len(skuCategory) >= limit {
|
||||
return skuCategory, err
|
||||
}
|
||||
if len(skuCategory) > 0 {
|
||||
for _, v := range skuCategory {
|
||||
skuCategoryMap[v.ID] = v
|
||||
}
|
||||
}
|
||||
//推荐分类,若不满10个,则填满10个
|
||||
if (len(skuCategory) < limit && len(skuCategory) > 0) || len(skuCategory) == 0 {
|
||||
skuCategory2, err = dao.GetCategories(db, -1, 1, nil)
|
||||
if len(skuCategory2) > 0 {
|
||||
for _, v := range skuCategory2 {
|
||||
if skuCategoryMap[v.ID] == nil {
|
||||
if !strings.Contains(v.Name, "赠品") {
|
||||
skuCategory = append(skuCategory, v)
|
||||
}
|
||||
}
|
||||
if len(skuCategory) >= limit {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2155,7 +2305,7 @@ func RefershStoreSkusMidPrice(ctx *jxcontext.Context, storeIDs []int) (err error
|
||||
db := dao.GetDB()
|
||||
_, err = dao.RefershStoreSkusMidPrice(db, storeIDs)
|
||||
if err == nil {
|
||||
CreateStorePriceScore(ctx, true)
|
||||
CreateStorePriceScore(ctx)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -2443,3 +2593,319 @@ func IsChineseChar(str string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func GetStoreCategories(ctx *jxcontext.Context, storeID, parentID int) (catList []*model.SkuCategory, err error) {
|
||||
return dao.GetStoreSkuCategories(dao.GetDB(), storeID, parentID)
|
||||
}
|
||||
|
||||
func GetVendorStoreSkuPrice(ctx *jxcontext.Context, vendorIDs []int, skuID int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
var (
|
||||
storeSkuListJD []DataVendorStoreSkuPrice
|
||||
storeSkuListMT []DataVendorStoreSkuPrice
|
||||
storeSkuListEB []DataVendorStoreSkuPrice
|
||||
excelParamList []ExcelParam
|
||||
)
|
||||
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||
switch step {
|
||||
case 0:
|
||||
for _, v := range vendorIDs {
|
||||
vendorID := v
|
||||
handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler)
|
||||
handlerStore := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IStoreHandler)
|
||||
for _, v := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) {
|
||||
vendorStoreIDs, err2 := handlerStore.GetAllStoresVendorID(ctx, v)
|
||||
err = err2
|
||||
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
vendorStoreID := batchItemList[0].(string)
|
||||
var (
|
||||
inStoreSkuList []*partner.StoreSkuInfo
|
||||
storeDetail *dao.StoreDetail
|
||||
inStoreSku = &partner.StoreSkuInfo{}
|
||||
outStoreSkuList []*partner.StoreSkuInfo
|
||||
)
|
||||
db := dao.GetDB()
|
||||
skuNameList, err := dao.GetSkus(db, []int{skuID}, nil, nil, nil)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
if partner.IsMultiStore(vendorID) {
|
||||
multiHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler)
|
||||
storeDetail, err = multiHandler.ReadStore(ctx, v, vendorStoreID)
|
||||
if len(skuNameList) > 0 {
|
||||
inStoreSku.VendorSkuID = utils.Int64ToStr(skuNameList[0].JdID)
|
||||
}
|
||||
} else {
|
||||
singleHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreHandler)
|
||||
storeDetail, err = singleHandler.ReadStore(ctx, v, vendorStoreID)
|
||||
inStoreSku.SkuID = skuID
|
||||
}
|
||||
inStoreSkuList = append(inStoreSkuList, inStoreSku)
|
||||
storeDetail2, err := dao.GetStoreDetailByVendorStoreID(db, vendorStoreID, vendorID)
|
||||
if storeDetail2 != nil {
|
||||
outStoreSkuList, err = handler.GetStoreSkusBareInfo(ctx, v, task, storeDetail2.ID, vendorStoreID, inStoreSkuList)
|
||||
} else {
|
||||
outStoreSkuList, err = handler.GetStoreSkusBareInfo(ctx, v, task, 0, vendorStoreID, inStoreSkuList)
|
||||
}
|
||||
if storeDetail != nil {
|
||||
if len(outStoreSkuList) == 0 {
|
||||
data := DataVendorStoreSkuPrice{
|
||||
StoreID: vendorStoreID,
|
||||
StoreName: storeDetail.Name,
|
||||
SkuID: skuID,
|
||||
SkuName: skuNameList[0].Name,
|
||||
VendorPrice: "",
|
||||
}
|
||||
retVal = []DataVendorStoreSkuPrice{data}
|
||||
} else {
|
||||
data := DataVendorStoreSkuPrice{
|
||||
StoreID: vendorStoreID,
|
||||
StoreName: storeDetail.Name,
|
||||
SkuID: skuID,
|
||||
SkuName: skuNameList[0].Name,
|
||||
VendorPrice: utils.Float64ToStr(utils.Str2Float64(utils.Int64ToStr(outStoreSkuList[0].VendorPrice)) / 100),
|
||||
}
|
||||
retVal = []DataVendorStoreSkuPrice{data}
|
||||
}
|
||||
}
|
||||
return retVal, err
|
||||
}
|
||||
taskParallel := tasksch.NewParallelTask("获取各平台所有门店某商品价格", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, vendorStoreIDs)
|
||||
tasksch.HandleTask(taskParallel, task, true).Run()
|
||||
storeSkuList, _ := taskParallel.GetResult(0)
|
||||
for _, v := range storeSkuList {
|
||||
if vendorID == model.VendorIDJD {
|
||||
storeSkuListJD = append(storeSkuListJD, v.(DataVendorStoreSkuPrice))
|
||||
}
|
||||
if vendorID == model.VendorIDEBAI {
|
||||
storeSkuListEB = append(storeSkuListEB, v.(DataVendorStoreSkuPrice))
|
||||
}
|
||||
if vendorID == model.VendorIDMTWM {
|
||||
storeSkuListMT = append(storeSkuListMT, v.(DataVendorStoreSkuPrice))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
excelParam1 := ExcelParam{
|
||||
DataList: storeSkuListJD,
|
||||
TitleList: titleListVendorStoreSkuPrice,
|
||||
SheetName: "京东平台",
|
||||
}
|
||||
excelParam2 := ExcelParam{
|
||||
DataList: storeSkuListEB,
|
||||
TitleList: titleListVendorStoreSkuPrice,
|
||||
SheetName: "饿百平台",
|
||||
}
|
||||
excelParam3 := ExcelParam{
|
||||
DataList: storeSkuListMT,
|
||||
TitleList: titleListVendorStoreSkuPrice,
|
||||
SheetName: "美团平台",
|
||||
}
|
||||
excelParamList = append(excelParamList, excelParam1, excelParam2, excelParam3)
|
||||
case 1:
|
||||
WriteToExcelNormal(task, "各平台"+utils.Int2Str(skuID)+"商品所有门店价格", excelParamList)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
taskSeq := tasksch.NewSeqTask2("获取各平台所有门店某商品价格-序列任务", ctx, isContinueWhenError, taskSeqFunc, 2)
|
||||
tasksch.HandleTask(taskSeq, nil, true).Run()
|
||||
if !isAsync {
|
||||
_, err = taskSeq.GetResult(0)
|
||||
hint = "1"
|
||||
} else {
|
||||
hint = taskSeq.GetID()
|
||||
}
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func WriteToExcelNormal(task *tasksch.SeqTask, fileName string, excelParam []ExcelParam) (err error) {
|
||||
var sheetList []*excel.Obj2ExcelSheetConfig
|
||||
for _, v := range excelParam {
|
||||
if v.DataList != nil {
|
||||
excelConf := &excel.Obj2ExcelSheetConfig{
|
||||
Title: v.SheetName,
|
||||
Data: v.DataList,
|
||||
CaptionList: v.TitleList,
|
||||
}
|
||||
sheetList = append(sheetList, excelConf)
|
||||
}
|
||||
}
|
||||
downloadURL, fileNameResult, err := jxutils.UploadExeclAndPushMsg(sheetList, fileName)
|
||||
if err != nil {
|
||||
baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", fileNameResult, err)
|
||||
} else {
|
||||
noticeMsg := fmt.Sprintf("[详情点我]path=%s \n", downloadURL)
|
||||
task.SetNoticeMsg(noticeMsg)
|
||||
baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL:%s", fileNameResult, downloadURL)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func FocusStoreSkusByExcel(ctx *jxcontext.Context, files []*multipart.FileHeader, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
if len(files) == 0 {
|
||||
return "", errors.New("没有文件上传!")
|
||||
}
|
||||
fileHeader := files[0]
|
||||
file, err := fileHeader.Open()
|
||||
hint, err = FocusStoreSkusByExcelBin(ctx, file, isAsync, isContinueWhenError)
|
||||
file.Close()
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func FocusStoreSkusByExcelBin(ctx *jxcontext.Context, reader io.Reader, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
var (
|
||||
skuMap = make(map[int]int)
|
||||
skuNameMap = make(map[int]int)
|
||||
skuBindInfos []*StoreSkuBindInfo
|
||||
db = dao.GetDB()
|
||||
storeIDs []int
|
||||
skuIDs []int
|
||||
)
|
||||
sheetParam := &SheetParam{
|
||||
OutSkuIDCol: 1,
|
||||
SkuPriceCol: 3,
|
||||
SkuRow: 1,
|
||||
}
|
||||
// xlsx, err := excelize.OpenFile("111.xlsx")
|
||||
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||
switch step {
|
||||
case 0:
|
||||
xlsx, err := excelize.OpenReader(reader)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
rows, _ := xlsx.GetRows(xlsx.GetSheetName(1))
|
||||
for rowNum, row := range rows {
|
||||
if rowNum < sheetParam.SkuRow {
|
||||
continue
|
||||
}
|
||||
GetCellForFocusStoreSkus(db, rowNum, row, sheetParam, skuMap)
|
||||
}
|
||||
case 1:
|
||||
for k, _ := range skuMap {
|
||||
skuIDs = append(skuIDs, k)
|
||||
}
|
||||
skuList, err := dao.GetSkus(db, skuIDs, nil, nil, nil)
|
||||
if err != nil && len(skuList) == 0 {
|
||||
return result, err
|
||||
}
|
||||
for _, v := range skuList {
|
||||
var (
|
||||
price int
|
||||
specQuality float64
|
||||
)
|
||||
if v.Unit == model.SpecialUnit {
|
||||
if v.SpecUnit == model.SpecUnitNames[1] || v.SpecUnit == model.SpecUnitNames[2] {
|
||||
specQuality = float64(v.SpecQuality) * 1000
|
||||
} else {
|
||||
specQuality = float64(v.SpecQuality)
|
||||
}
|
||||
price = int(utils.Float64TwoInt64(utils.Int2Float64(model.SpecialSpecQuality) / specQuality * utils.Int2Float64(skuMap[v.ID])))
|
||||
} else {
|
||||
price = skuMap[v.ID]
|
||||
}
|
||||
if skuNameMap[v.NameID] < price {
|
||||
skuNameMap[v.NameID] = price
|
||||
}
|
||||
}
|
||||
for k, v := range skuNameMap {
|
||||
skuBindInfo := &StoreSkuBindInfo{
|
||||
NameID: k,
|
||||
UnitPrice: v,
|
||||
IsFocus: 1,
|
||||
IsSale: 1,
|
||||
}
|
||||
skuBindInfos = append(skuBindInfos, skuBindInfo)
|
||||
}
|
||||
storeList, err := dao.GetStoreList(db, nil, nil, "")
|
||||
for _, v := range storeList {
|
||||
storeIDs = append(storeIDs, v.ID)
|
||||
}
|
||||
case 2:
|
||||
UpdateStoresSkus(ctx, storeIDs, skuBindInfos, false, isAsync, isContinueWhenError)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
taskSeq := tasksch.NewSeqTask2("根据Excel中skuID批量关注商品", ctx, isContinueWhenError, taskSeqFunc, 3)
|
||||
tasksch.HandleTask(taskSeq, nil, true).Run()
|
||||
if !isAsync {
|
||||
_, err = taskSeq.GetResult(0)
|
||||
hint = "1"
|
||||
} else {
|
||||
hint = taskSeq.GetID()
|
||||
}
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func GetCellForFocusStoreSkus(db *dao.DaoDB, rowNum int, row []string, sheetParam *SheetParam, skuMap map[int]int) {
|
||||
var (
|
||||
skuID int
|
||||
price int
|
||||
)
|
||||
for k, cell := range row {
|
||||
if k == sheetParam.OutSkuIDCol {
|
||||
skuID = int(utils.Str2Int64(cell))
|
||||
}
|
||||
if k == sheetParam.SkuPriceCol {
|
||||
price = int(utils.Float64TwoInt64(utils.Str2Float64(cell) * 100))
|
||||
}
|
||||
}
|
||||
skuMap[skuID] = price
|
||||
}
|
||||
|
||||
func FocusStoreSkusBySku(ctx *jxcontext.Context, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
var (
|
||||
skuBindInfos []*StoreSkuBindInfo
|
||||
skuNameMap = make(map[int][]*StoreSkuBindSkuInfo)
|
||||
storeIDs []int
|
||||
)
|
||||
db := dao.GetDB()
|
||||
skuList, err := dao.GetSkus(db, skuIDs, nil, nil, nil)
|
||||
storeList, err := dao.GetStoreList(db, nil, nil, "")
|
||||
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||
switch step {
|
||||
case 0:
|
||||
for _, v := range storeList {
|
||||
storeIDs = append(storeIDs, v.ID)
|
||||
}
|
||||
for _, v := range skuList {
|
||||
skuNameMap[v.NameID] = append(skuNameMap[v.NameID], &StoreSkuBindSkuInfo{
|
||||
SkuID: v.ID,
|
||||
IsSale: 1,
|
||||
})
|
||||
}
|
||||
case 1:
|
||||
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
store := batchItemList[0].(*model.Store)
|
||||
for k, v := range skuNameMap {
|
||||
midPrice, _ := dao.GetMidPriceByNameID(db, store.CityCode, k, utils.Time2Date(time.Now().AddDate(0, 0, -1)))
|
||||
skuBindInfo := &StoreSkuBindInfo{
|
||||
NameID: k,
|
||||
UnitPrice: midPrice,
|
||||
IsFocus: 1,
|
||||
Skus: v,
|
||||
}
|
||||
retVal = []*StoreSkuBindInfo{skuBindInfo}
|
||||
}
|
||||
return retVal, err
|
||||
}
|
||||
taskParallel := tasksch.NewParallelTask("根据skuID部分关注商品", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeList)
|
||||
tasksch.HandleTask(taskParallel, task, true).Run()
|
||||
result1, _ := taskParallel.GetResult(0)
|
||||
for _, v := range result1 {
|
||||
skuBindInfos = append(skuBindInfos, v.(*StoreSkuBindInfo))
|
||||
}
|
||||
case 2:
|
||||
UpdateStoresSkus(ctx, storeIDs, skuBindInfos, false, isAsync, isContinueWhenError)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
taskSeq := tasksch.NewSeqTask2("根据skuID批量部分关注商品", ctx, isContinueWhenError, taskSeqFunc, 3)
|
||||
tasksch.HandleTask(taskSeq, nil, true).Run()
|
||||
if !isAsync {
|
||||
_, err = taskSeq.GetResult(0)
|
||||
hint = "1"
|
||||
} else {
|
||||
hint = taskSeq.GetID()
|
||||
}
|
||||
return hint, err
|
||||
}
|
||||
|
||||
@@ -340,10 +340,10 @@ func CompareJxAndVendor(vendorID int, storeIDStr, vendorStoreID, storeName strin
|
||||
//多规格商品不用比较数量单位
|
||||
if jxSkuInfo.IsSpu == 0 {
|
||||
//jxSkuDetailName : 前缀 ([荐]) + 分类名(xxx水饺) + 数量单位(约..g/份) + 注释 (补充..)
|
||||
jxSkuDetailName = jxutils.ComposeSkuName(jxSkuInfo.SkuName.Prefix, jxSkuInfo.SkuName.Name, jxSkuInfo.Skus[0].Comment, jxSkuInfo.SkuName.Unit, jxSkuInfo.Skus[0].SkuSpecQuality, jxSkuInfo.Skus[0].SkuSpecUnit, 0)
|
||||
jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.SkuName.Prefix, jxSkuInfo.SkuName.Name, jxSkuInfo.Skus[0].Comment, jxSkuInfo.SkuName.Unit, jxSkuInfo.Skus[0].SkuSpecQuality, jxSkuInfo.Skus[0].SkuSpecUnit, 0)
|
||||
} else {
|
||||
//jxSkuDetailName : 前缀 ([荐]) + 分类名(xxx水饺) + 数量单位(约..g/份) + 注释 (补充..)
|
||||
jxSkuDetailName = jxutils.ComposeSkuName(jxSkuInfo.SkuName.Prefix, jxSkuInfo.SkuName.Name, jxSkuInfo.Skus[0].Comment, "", jxSkuInfo.Skus[0].SkuSpecQuality, "", 0)
|
||||
jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.SkuName.Prefix, jxSkuInfo.SkuName.Name, jxSkuInfo.Skus[0].Comment, "", jxSkuInfo.Skus[0].SkuSpecQuality, "", 0)
|
||||
}
|
||||
|
||||
//jxSkuSaleStatus : 商品状态 ,skustatus 优先级高于 StoreSkuStatus
|
||||
@@ -462,9 +462,9 @@ func CompareJxAndMultiVenderDepot(ctx *jxcontext.Context, vendorMap map[int]bool
|
||||
var jxSkuDetailName string
|
||||
//多规格商品不用比较数量单位
|
||||
if jxSkuInfo.IsSpu == 0 {
|
||||
jxSkuDetailName = jxutils.ComposeSkuName(jxSkuInfo.Prefix, jxSkuInfo.Name, jxSkuInfo.Comment, jxSkuInfo.Unit, jxSkuInfo.SpecQuality, jxSkuInfo.SpecUnit, 0)
|
||||
jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.Prefix, jxSkuInfo.Name, jxSkuInfo.Comment, jxSkuInfo.Unit, jxSkuInfo.SpecQuality, jxSkuInfo.SpecUnit, 0)
|
||||
} else {
|
||||
jxSkuDetailName = jxutils.ComposeSkuName(jxSkuInfo.Prefix, jxSkuInfo.Name, jxSkuInfo.Comment, "", jxSkuInfo.SpecQuality, "", 0)
|
||||
jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.Prefix, jxSkuInfo.Name, jxSkuInfo.Comment, "", jxSkuInfo.SpecQuality, "", 0)
|
||||
}
|
||||
|
||||
vendorSkuInfoMap := filterVendorSkuInfoMap[skuid]
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"git.rosy.net.cn/jx-callback/globals/refutil"
|
||||
)
|
||||
|
||||
type SyncErrResult struct {
|
||||
@@ -80,36 +79,36 @@ var (
|
||||
syncErrResultLock SyncErrResultLock
|
||||
)
|
||||
|
||||
func (p *MultiStoreHandlerWrapper) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||
if jxutils.IsEmptyID(cat.JdID) {
|
||||
return nil
|
||||
}
|
||||
return p.IMultipleStoresHandler.DeleteCategory(db, cat, userName)
|
||||
}
|
||||
// func (p *MultiStoreHandlerWrapper) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||
// if jxutils.IsEmptyID(cat.JdID) {
|
||||
// return nil
|
||||
// }
|
||||
// return p.IMultipleStoresHandler.DeleteCategory(db, cat, userName)
|
||||
// }
|
||||
|
||||
func (p *MultiStoreHandlerWrapper) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||
if jxutils.IsEmptyID(cat.JdID) {
|
||||
globals.SugarLogger.Warnf("UpdateCategory fakeid cat:%s should not get here", utils.Format4Output(cat, true))
|
||||
return nil
|
||||
}
|
||||
return p.IMultipleStoresHandler.UpdateCategory(db, cat, userName)
|
||||
}
|
||||
// func (p *MultiStoreHandlerWrapper) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||
// if jxutils.IsEmptyID(cat.JdID) {
|
||||
// globals.SugarLogger.Warnf("UpdateCategory fakeid cat:%s should not get here", utils.Format4Output(cat, true))
|
||||
// return nil
|
||||
// }
|
||||
// return p.IMultipleStoresHandler.UpdateCategory(db, cat, userName)
|
||||
// }
|
||||
|
||||
func (p *MultiStoreHandlerWrapper) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
globals.SugarLogger.Debugf("wrapper DeleteSku, sku:%s", utils.Format4Output(sku, false))
|
||||
if jxutils.IsEmptyID(sku.JdID) {
|
||||
return nil
|
||||
}
|
||||
return p.IMultipleStoresHandler.DeleteSku(db, sku, userName)
|
||||
}
|
||||
// func (p *MultiStoreHandlerWrapper) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
// globals.SugarLogger.Debugf("wrapper DeleteSku, sku:%s", utils.Format4Output(sku, false))
|
||||
// if jxutils.IsEmptyID(sku.JdID) {
|
||||
// return nil
|
||||
// }
|
||||
// return p.IMultipleStoresHandler.DeleteSku(db, sku, userName)
|
||||
// }
|
||||
|
||||
func (p *MultiStoreHandlerWrapper) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
if jxutils.IsEmptyID(sku.JdID) {
|
||||
globals.SugarLogger.Warnf("UpdateSku fakeid sku:%s should not get here", utils.Format4Output(sku, true))
|
||||
return nil
|
||||
}
|
||||
return p.IMultipleStoresHandler.UpdateSku(db, sku, userName)
|
||||
}
|
||||
// func (p *MultiStoreHandlerWrapper) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
// if jxutils.IsEmptyID(sku.JdID) {
|
||||
// globals.SugarLogger.Warnf("UpdateSku fakeid sku:%s should not get here", utils.Format4Output(sku, true))
|
||||
// return nil
|
||||
// }
|
||||
// return p.IMultipleStoresHandler.UpdateSku(db, sku, userName)
|
||||
// }
|
||||
|
||||
func (v *VendorSync) GetStoreHandler(vendorID int) partner.IPurchasePlatformHandler {
|
||||
return partner.GetPurchasePlatformFromVendorID(vendorID)
|
||||
@@ -129,95 +128,95 @@ func (v *VendorSync) GetSingleStoreHandler(vendorID int) partner.ISingleStoreHan
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *VendorSync) syncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, db *dao.DaoDB, cats []*model.SkuCategory, userName string) (err error) {
|
||||
multiStoresHandler := v.GetMultiStoreHandler(vendorID)
|
||||
syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[vendorID])
|
||||
task := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[vendorID]), nil, ctx,
|
||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
cat := batchItemList[0].(*model.SkuCategory)
|
||||
updateFields := []string{syncStatusFieldName}
|
||||
syncStatus := refutil.GetObjFieldByName(cat, syncStatusFieldName).(int8)
|
||||
if (syncStatus & model.SyncFlagDeletedMask) != 0 { //删除
|
||||
if (syncStatus & model.SyncFlagNewMask) == 0 {
|
||||
err = multiStoresHandler.DeleteCategory(db, cat, userName)
|
||||
}
|
||||
} else if (syncStatus & model.SyncFlagNewMask) != 0 { // 新增
|
||||
err = multiStoresHandler.CreateCategory(db, cat, userName)
|
||||
updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()]))
|
||||
} else if (syncStatus & model.SyncFlagModifiedMask) != 0 { // 修改
|
||||
err = multiStoresHandler.UpdateCategory(db, cat, userName)
|
||||
if intErr, ok := err.(*utils.ErrorWithCode); ok && intErr.IntCode() == -3 {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
refutil.SetObjFieldByName(cat, syncStatusFieldName, int8(0))
|
||||
_, err = dao.UpdateEntity(db, cat, updateFields...)
|
||||
}
|
||||
return nil, err
|
||||
}, cats)
|
||||
tasksch.HandleTask(task, parentTask, false).Run()
|
||||
_, err = task.GetResult(0)
|
||||
return err
|
||||
}
|
||||
// func (v *VendorSync) syncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, db *dao.DaoDB, cats []*model.SkuCategory, userName string) (err error) {
|
||||
// multiStoresHandler := v.GetMultiStoreHandler(vendorID)
|
||||
// syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[vendorID])
|
||||
// task := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[vendorID]), nil, ctx,
|
||||
// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
// cat := batchItemList[0].(*model.SkuCategory)
|
||||
// updateFields := []string{syncStatusFieldName}
|
||||
// syncStatus := refutil.GetObjFieldByName(cat, syncStatusFieldName).(int8)
|
||||
// if (syncStatus & model.SyncFlagDeletedMask) != 0 { //删除
|
||||
// if (syncStatus & model.SyncFlagNewMask) == 0 {
|
||||
// err = multiStoresHandler.DeleteCategory(db, cat, userName)
|
||||
// }
|
||||
// } else if (syncStatus & model.SyncFlagNewMask) != 0 { // 新增
|
||||
// err = multiStoresHandler.CreateCategory(db, cat, userName)
|
||||
// updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()]))
|
||||
// } else if (syncStatus & model.SyncFlagModifiedMask) != 0 { // 修改
|
||||
// err = multiStoresHandler.UpdateCategory(db, cat, userName)
|
||||
// if intErr, ok := err.(*utils.ErrorWithCode); ok && intErr.IntCode() == -3 {
|
||||
// err = nil
|
||||
// }
|
||||
// }
|
||||
// if err == nil {
|
||||
// refutil.SetObjFieldByName(cat, syncStatusFieldName, int8(0))
|
||||
// _, err = dao.UpdateEntity(db, cat, updateFields...)
|
||||
// }
|
||||
// return nil, err
|
||||
// }, cats)
|
||||
// tasksch.HandleTask(task, parentTask, false).Run()
|
||||
// _, err = task.GetResult(0)
|
||||
// return err
|
||||
// }
|
||||
|
||||
func (v *VendorSync) SyncCategory(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) {
|
||||
if !globals.IsUseThingMap {
|
||||
return v.oldSyncCategory(ctx, db, categoryID, isAsync, userName)
|
||||
}
|
||||
// if !globals.IsUseThingMap {
|
||||
// return v.oldSyncCategory(ctx, db, categoryID, isAsync, userName)
|
||||
// }
|
||||
return SyncCategories(ctx, nil, nil, nil, []int{categoryID}, isAsync)
|
||||
}
|
||||
|
||||
func (v *VendorSync) oldSyncCategory(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) {
|
||||
globals.SugarLogger.Debug("SyncCategory")
|
||||
hint, err = v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步分类信息:%d", categoryID), isAsync, false,
|
||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
vendorInfo := batchItemList[0].(*MultiStoreVendorInfo)
|
||||
var cats []*model.SkuCategory
|
||||
cond := make(map[string]interface{})
|
||||
if categoryID > 0 {
|
||||
cond[model.FieldID] = categoryID
|
||||
} else {
|
||||
cond[model.FieldLevel] = 1
|
||||
}
|
||||
err := dao.GetEntitiesByKV(db, &cats, cond, true)
|
||||
if err == nil {
|
||||
err = v.syncCategories(ctx, t, vendorInfo.VendorID, db, cats, userName)
|
||||
}
|
||||
if err != nil || categoryID > 0 {
|
||||
return nil, err
|
||||
}
|
||||
cond[model.FieldLevel] = 2
|
||||
err = dao.GetEntitiesByKV(db, &cats, cond, true)
|
||||
if err == nil {
|
||||
err = v.syncCategories(ctx, t, vendorInfo.VendorID, db, cats, userName)
|
||||
}
|
||||
return nil, err
|
||||
})
|
||||
return "", err
|
||||
}
|
||||
// func (v *VendorSync) oldSyncCategory(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) {
|
||||
// globals.SugarLogger.Debug("SyncCategory")
|
||||
// hint, err = v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步分类信息:%d", categoryID), isAsync, false,
|
||||
// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
// vendorInfo := batchItemList[0].(*MultiStoreVendorInfo)
|
||||
// var cats []*model.SkuCategory
|
||||
// cond := make(map[string]interface{})
|
||||
// if categoryID > 0 {
|
||||
// cond[model.FieldID] = categoryID
|
||||
// } else {
|
||||
// cond[model.FieldLevel] = 1
|
||||
// }
|
||||
// err := dao.GetEntitiesByKV(db, &cats, cond, true)
|
||||
// if err == nil {
|
||||
// err = v.syncCategories(ctx, t, vendorInfo.VendorID, db, cats, userName)
|
||||
// }
|
||||
// if err != nil || categoryID > 0 {
|
||||
// return nil, err
|
||||
// }
|
||||
// cond[model.FieldLevel] = 2
|
||||
// err = dao.GetEntitiesByKV(db, &cats, cond, true)
|
||||
// if err == nil {
|
||||
// err = v.syncCategories(ctx, t, vendorInfo.VendorID, db, cats, userName)
|
||||
// }
|
||||
// return nil, err
|
||||
// })
|
||||
// return "", err
|
||||
// }
|
||||
|
||||
func (v *VendorSync) SyncReorderCategories(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) {
|
||||
if !globals.IsUseThingMap {
|
||||
return v.oldSyncReorderCategories(ctx, db, categoryID, isAsync, userName)
|
||||
}
|
||||
// if !globals.IsUseThingMap {
|
||||
// return v.oldSyncReorderCategories(ctx, db, categoryID, isAsync, userName)
|
||||
// }
|
||||
return SyncReorderCategories(ctx, -1, isAsync)
|
||||
}
|
||||
|
||||
func (v *VendorSync) oldSyncReorderCategories(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) {
|
||||
hint, err = v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("分类重排序:%d", categoryID), isAsync, false, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
vendorInfo := batchItemList[0].(*MultiStoreVendorInfo)
|
||||
multiStoresHandler := v.GetMultiStoreHandler(vendorInfo.VendorID)
|
||||
err2 := multiStoresHandler.ReorderCategories(db, categoryID, userName)
|
||||
if err2 == nil {
|
||||
cat := &model.SkuCategory{}
|
||||
_, err2 = dao.UpdateEntityByKV(db, cat, utils.Params2Map(dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()]), 0), utils.Params2Map(model.FieldParentID, categoryID))
|
||||
return nil, err2
|
||||
}
|
||||
return nil, err2
|
||||
})
|
||||
return "", err
|
||||
}
|
||||
// func (v *VendorSync) oldSyncReorderCategories(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) {
|
||||
// hint, err = v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("分类重排序:%d", categoryID), isAsync, false, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
// vendorInfo := batchItemList[0].(*MultiStoreVendorInfo)
|
||||
// multiStoresHandler := v.GetMultiStoreHandler(vendorInfo.VendorID)
|
||||
// err2 := multiStoresHandler.ReorderCategories(db, categoryID, userName)
|
||||
// if err2 == nil {
|
||||
// cat := &model.SkuCategory{}
|
||||
// _, err2 = dao.UpdateEntityByKV(db, cat, utils.Params2Map(dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()]), 0), utils.Params2Map(model.FieldParentID, categoryID))
|
||||
// return nil, err2
|
||||
// }
|
||||
// return nil, err2
|
||||
// })
|
||||
// return "", err
|
||||
// }
|
||||
|
||||
func (v *VendorSync) SyncStore(ctx *jxcontext.Context, db *dao.DaoDB, vendorID, storeID int, isAsync bool, userName string) (hint string, err error) {
|
||||
globals.SugarLogger.Debugf("SyncStore, storeID:%d", storeID)
|
||||
@@ -281,109 +280,109 @@ func (v *VendorSync) SyncSku(ctx *jxcontext.Context, db *dao.DaoDB, nameID, skuI
|
||||
}
|
||||
|
||||
func (v *VendorSync) SyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []int, skuIDs []int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) {
|
||||
if !globals.IsUseThingMap {
|
||||
return v.oldSyncSkus(ctx, db, nameIDs, skuIDs, isAsync, isContinueWhenError, userName)
|
||||
}
|
||||
// if !globals.IsUseThingMap {
|
||||
// return v.oldSyncSkus(ctx, db, nameIDs, skuIDs, isAsync, isContinueWhenError, userName)
|
||||
// }
|
||||
return SyncSkus(ctx, nil, nil, nil, nameIDs, skuIDs, isAsync)
|
||||
}
|
||||
|
||||
func (v *VendorSync) oldSyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []int, skuIDs []int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) {
|
||||
globals.SugarLogger.Debugf("SyncSku trackInfo:%s, nameIDs:%v, skuIDs:%v, userName:%s", ctx.GetTrackInfo(), nameIDs, skuIDs, userName)
|
||||
isManagedIt := !(len(nameIDs) > 0 && len(nameIDs) <= 2 || len(skuIDs) > 0 && len(skuIDs) < 8)
|
||||
return v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步商品信息, nameIDs:%v, skuIDs:%v", nameIDs, skuIDs), isAsync, isManagedIt,
|
||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
var resultList []interface{}
|
||||
vendorInfo := batchItemList[0].(*MultiStoreVendorInfo)
|
||||
multiStoresHandler := v.GetMultiStoreHandler(vendorInfo.VendorID)
|
||||
syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()])
|
||||
dbField := dao.ConvertDBFieldPrefix(model.VendorNames[multiStoresHandler.GetVendorID()])
|
||||
skuMap := make(map[int]bool)
|
||||
sql := fmt.Sprintf(`
|
||||
SELECT DISTINCT t2.*
|
||||
FROM sku t1
|
||||
JOIN sku_name t2 ON t2.id = t1.name_id
|
||||
WHERE t1.%s_sync_status <> 0
|
||||
`, dbField)
|
||||
sqlParams := []interface{}{}
|
||||
if len(nameIDs) > 0 {
|
||||
sql += " AND t1.name_id IN (" + dao.GenQuestionMarks(len(nameIDs)) + ")"
|
||||
sqlParams = append(sqlParams, nameIDs)
|
||||
}
|
||||
if len(skuIDs) > 0 {
|
||||
sql += " AND t1.id IN(" + dao.GenQuestionMarks(len(skuIDs)) + ")"
|
||||
sqlParams = append(sqlParams, skuIDs)
|
||||
// func (v *VendorSync) oldSyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []int, skuIDs []int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) {
|
||||
// globals.SugarLogger.Debugf("SyncSku trackInfo:%s, nameIDs:%v, skuIDs:%v, userName:%s", ctx.GetTrackInfo(), nameIDs, skuIDs, userName)
|
||||
// isManagedIt := !(len(nameIDs) > 0 && len(nameIDs) <= 2 || len(skuIDs) > 0 && len(skuIDs) < 8)
|
||||
// return v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步商品信息, nameIDs:%v, skuIDs:%v", nameIDs, skuIDs), isAsync, isManagedIt,
|
||||
// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
// var resultList []interface{}
|
||||
// vendorInfo := batchItemList[0].(*MultiStoreVendorInfo)
|
||||
// multiStoresHandler := v.GetMultiStoreHandler(vendorInfo.VendorID)
|
||||
// syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()])
|
||||
// dbField := dao.ConvertDBFieldPrefix(model.VendorNames[multiStoresHandler.GetVendorID()])
|
||||
// skuMap := make(map[int]bool)
|
||||
// sql := fmt.Sprintf(`
|
||||
// SELECT DISTINCT t2.*
|
||||
// FROM sku t1
|
||||
// JOIN sku_name t2 ON t2.id = t1.name_id
|
||||
// WHERE t1.%s_sync_status <> 0
|
||||
// `, dbField)
|
||||
// sqlParams := []interface{}{}
|
||||
// if len(nameIDs) > 0 {
|
||||
// sql += " AND t1.name_id IN (" + dao.GenQuestionMarks(len(nameIDs)) + ")"
|
||||
// sqlParams = append(sqlParams, nameIDs)
|
||||
// }
|
||||
// if len(skuIDs) > 0 {
|
||||
// sql += " AND t1.id IN(" + dao.GenQuestionMarks(len(skuIDs)) + ")"
|
||||
// sqlParams = append(sqlParams, skuIDs)
|
||||
|
||||
}
|
||||
for _, v := range skuIDs {
|
||||
skuMap[v] = true
|
||||
}
|
||||
sql += " ORDER BY t2.id"
|
||||
// }
|
||||
// for _, v := range skuIDs {
|
||||
// skuMap[v] = true
|
||||
// }
|
||||
// sql += " ORDER BY t2.id"
|
||||
|
||||
var skuNameList []*model.SkuName
|
||||
err := dao.GetRows(db, &skuNameList, sql, sqlParams...)
|
||||
if err == nil && len(skuNameList) > 0 {
|
||||
// todo 同一skuName下的sku顺序处理的原因是京东SPU特殊类型必须要序列化同步才能正常处理, db可能会有多线程问题
|
||||
task := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[vendorInfo.VendorID]), tasksch.NewParallelConfig().SetParallelCount(10).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
var resultList []interface{}
|
||||
skuName := batchItemList[0].(*model.SkuName)
|
||||
var skuList []*model.Sku
|
||||
if err = dao.GetRows(db, &skuList, fmt.Sprintf(`
|
||||
SELECT *
|
||||
FROM sku
|
||||
WHERE name_id = ? AND %s_sync_status <> 0
|
||||
ORDER BY IF(spec_unit IN('kg', 'L'), 1000, 1) * spec_quality
|
||||
`, dbField), skuName.ID); err == nil && len(skuList) > 0 {
|
||||
for _, sku := range skuList {
|
||||
syncStatus := refutil.GetObjFieldByName(sku, syncStatusFieldName).(int8)
|
||||
globals.SugarLogger.Debugf("SyncSku trackInfo2:%s, skuID:%d, syncStatus:%d", ctx.GetTrackInfo(), sku.ID, syncStatus)
|
||||
if (len(skuIDs) == 0 || skuMap[sku.ID]) && (syncStatus != 0) {
|
||||
updateFields := []string{syncStatusFieldName}
|
||||
if syncStatus&model.SyncFlagDeletedMask != 0 { // 删除
|
||||
if syncStatus&model.SyncFlagNewMask == 0 {
|
||||
err = multiStoresHandler.DeleteSku(db, sku, userName)
|
||||
}
|
||||
} else if syncStatus&model.SyncFlagNewMask != 0 { // 新增
|
||||
if err = multiStoresHandler.CreateSku(db, sku, userName); err == nil {
|
||||
var tmpStruct struct {
|
||||
MaxIndex int
|
||||
}
|
||||
// todo hard code 得到京东spu中sku的顺序(以方便以后修改销售属性),这个必须要每次重新从数据库取
|
||||
if dao.GetRow(db, &tmpStruct, "SELECT MAX(sku_index) max_index FROM sku WHERE name_id = ? AND jd_id > 0 AND jd_id < 4024012631406 ", sku.NameID) == nil {
|
||||
sku.SkuIndex = tmpStruct.MaxIndex + 1
|
||||
updateFields = append(updateFields, "SkuIndex")
|
||||
}
|
||||
updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()]))
|
||||
}
|
||||
} else if syncStatus&model.SyncFlagModifiedMask != 0 { // 修改
|
||||
err = multiStoresHandler.UpdateSku(db, sku, userName)
|
||||
}
|
||||
if err == nil {
|
||||
refutil.SetObjFieldByName(sku, syncStatusFieldName, int8(0))
|
||||
if _, err = dao.UpdateEntity(db, sku, updateFields...); err != nil {
|
||||
break
|
||||
} else {
|
||||
resultList = append(resultList, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
refutil.SetObjFieldByName(skuName, syncStatusFieldName, int8(0))
|
||||
_, err = dao.UpdateEntity(db, skuName, syncStatusFieldName)
|
||||
}
|
||||
return resultList, err
|
||||
}, skuNameList)
|
||||
t.AddChild(task).Run()
|
||||
result, err2 := task.GetResult(0)
|
||||
if err = err2; err == nil {
|
||||
resultList = append(resultList, result...)
|
||||
}
|
||||
}
|
||||
return resultList, err
|
||||
})
|
||||
}
|
||||
// var skuNameList []*model.SkuName
|
||||
// err := dao.GetRows(db, &skuNameList, sql, sqlParams...)
|
||||
// if err == nil && len(skuNameList) > 0 {
|
||||
// // todo 同一skuName下的sku顺序处理的原因是京东SPU特殊类型必须要序列化同步才能正常处理, db可能会有多线程问题
|
||||
// task := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[vendorInfo.VendorID]), tasksch.NewParallelConfig().SetParallelCount(10).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||
// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
// var resultList []interface{}
|
||||
// skuName := batchItemList[0].(*model.SkuName)
|
||||
// var skuList []*model.Sku
|
||||
// if err = dao.GetRows(db, &skuList, fmt.Sprintf(`
|
||||
// SELECT *
|
||||
// FROM sku
|
||||
// WHERE name_id = ? AND %s_sync_status <> 0
|
||||
// ORDER BY IF(spec_unit IN('kg', 'L'), 1000, 1) * spec_quality
|
||||
// `, dbField), skuName.ID); err == nil && len(skuList) > 0 {
|
||||
// for _, sku := range skuList {
|
||||
// syncStatus := refutil.GetObjFieldByName(sku, syncStatusFieldName).(int8)
|
||||
// globals.SugarLogger.Debugf("SyncSku trackInfo2:%s, skuID:%d, syncStatus:%d", ctx.GetTrackInfo(), sku.ID, syncStatus)
|
||||
// if (len(skuIDs) == 0 || skuMap[sku.ID]) && (syncStatus != 0) {
|
||||
// updateFields := []string{syncStatusFieldName}
|
||||
// if syncStatus&model.SyncFlagDeletedMask != 0 { // 删除
|
||||
// if syncStatus&model.SyncFlagNewMask == 0 {
|
||||
// err = multiStoresHandler.DeleteSku(db, sku, userName)
|
||||
// }
|
||||
// } else if syncStatus&model.SyncFlagNewMask != 0 { // 新增
|
||||
// if err = multiStoresHandler.CreateSku(db, sku, userName); err == nil {
|
||||
// var tmpStruct struct {
|
||||
// MaxIndex int
|
||||
// }
|
||||
// // todo hard code 得到京东spu中sku的顺序(以方便以后修改销售属性),这个必须要每次重新从数据库取
|
||||
// if dao.GetRow(db, &tmpStruct, "SELECT MAX(sku_index) max_index FROM sku WHERE name_id = ? AND jd_id > 0 AND jd_id < 4024012631406 ", sku.NameID) == nil {
|
||||
// sku.SkuIndex = tmpStruct.MaxIndex + 1
|
||||
// updateFields = append(updateFields, "SkuIndex")
|
||||
// }
|
||||
// updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()]))
|
||||
// }
|
||||
// } else if syncStatus&model.SyncFlagModifiedMask != 0 { // 修改
|
||||
// err = multiStoresHandler.UpdateSku(db, sku, userName)
|
||||
// }
|
||||
// if err == nil {
|
||||
// refutil.SetObjFieldByName(sku, syncStatusFieldName, int8(0))
|
||||
// if _, err = dao.UpdateEntity(db, sku, updateFields...); err != nil {
|
||||
// break
|
||||
// } else {
|
||||
// resultList = append(resultList, 1)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if err == nil {
|
||||
// refutil.SetObjFieldByName(skuName, syncStatusFieldName, int8(0))
|
||||
// _, err = dao.UpdateEntity(db, skuName, syncStatusFieldName)
|
||||
// }
|
||||
// return resultList, err
|
||||
// }, skuNameList)
|
||||
// t.AddChild(task).Run()
|
||||
// result, err2 := task.GetResult(0)
|
||||
// if err = err2; err == nil {
|
||||
// resultList = append(resultList, result...)
|
||||
// }
|
||||
// }
|
||||
// return resultList, err
|
||||
// })
|
||||
// }
|
||||
|
||||
func (v *VendorSync) SyncStoresCategory(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
globals.SugarLogger.Debug("SyncStoresCategory")
|
||||
@@ -572,6 +571,29 @@ func (v *VendorSync) AddCreateFlagForJxStoreSku(ctx *jxcontext.Context, vendorID
|
||||
return hint, makeSyncError(err)
|
||||
}
|
||||
|
||||
func (v *VendorSync) AmendAndPruneStoreStuff(ctx *jxcontext.Context, vendorIDs []int, storeIDs []int, isAsync, isContinueWhenError bool, optType int, isForceUpdate bool) (hint string, err error) {
|
||||
globals.SugarLogger.Debug("AmendAndPruneStoreStuff")
|
||||
hint, err = v.LoopStoresMap(ctx, dao.GetDB(), fmt.Sprintf("处理京西平台商家分类与商品差异:%v", storeIDs), isAsync, true, vendorIDs, storeIDs,
|
||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
||||
if len(loopMapInfo.StoreMapList) > 1 {
|
||||
loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]),
|
||||
tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
storeMap := batchItemList[0].(*model.StoreMap)
|
||||
_, err = amendAndPruneStoreStuff(ctx, task, loopMapInfo.VendorID, storeMap.StoreID, storeMap.VendorStoreID, false, isContinueWhenError, optType, isForceUpdate)
|
||||
return nil, err
|
||||
}, loopMapInfo.StoreMapList)
|
||||
t.AddChild(loopStoreTask).Run()
|
||||
_, err = loopStoreTask.GetResult(0)
|
||||
} else {
|
||||
_, err = amendAndPruneStoreStuff(ctx, t, loopMapInfo.VendorID, loopMapInfo.StoreMapList[0].StoreID, loopMapInfo.StoreMapList[0].VendorStoreID, false, isContinueWhenError, optType, isForceUpdate)
|
||||
}
|
||||
return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
||||
}, isContinueWhenError)
|
||||
return hint, makeSyncError(err)
|
||||
}
|
||||
|
||||
func (v *VendorSync) LoopStoresMap2(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync, isManageIt bool, vendorIDs []int, storeIDs []int, handler tasksch.WorkFunc, isContinueWhenError bool) (task tasksch.ITask, hint string, err error) {
|
||||
var storeMapList []*model.StoreMap
|
||||
if storeMapList, err = dao.GetStoresMapList(db, vendorIDs, storeIDs, model.StoreStatusAll, model.StoreIsSyncYes, ""); err != nil {
|
||||
@@ -722,7 +744,7 @@ func (v *VendorSync) ChangeStoreSkuSaleStatus(ctx *jxcontext.Context, storeID in
|
||||
skuIDs = append(skuIDs, v.SkuID)
|
||||
}
|
||||
vendorIDs := partner.GetPurchasePlatformVendorIDs()
|
||||
dao.UpdateStoreSkuBindSyncStatus(db, vendorIDs, storeID)
|
||||
dao.UpdateStoreSkuBindSyncStatusForSaleStatus(db, vendorIDs, storeID)
|
||||
v.SyncStoresSkus(ctx, db, vendorIDs, storeIDs, skuIDs, false, isAsync, isContinueWhenError)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func getMultiStoreVendorInfoList() (list []*MultiStoreVendorInfo) {
|
||||
func syncCategories(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, catList []*dao.SkuStoreCatInfo, isAsync bool) (hint string, err error) {
|
||||
if len(catList) > 0 {
|
||||
// todo 按vendorID orgCode合并操作
|
||||
task := tasksch.NewParallelTask(fmt.Sprintf("同步分类2:%D", len(catList)), tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
||||
task := tasksch.NewParallelTask(fmt.Sprintf("同步分类2:%d", len(catList)), tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
catVendorInfo := batchItemList[0].(*dao.SkuStoreCatInfo)
|
||||
if catVendorInfo.Level != 1 && catVendorInfo.ParentVendorCatID == "" {
|
||||
@@ -84,10 +84,11 @@ func syncCategories(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.IT
|
||||
}
|
||||
|
||||
func SyncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, catIDs []int, isAsync bool) (hint string, err error) {
|
||||
globals.SugarLogger.Debugf("SyncCategories catIDs:%v", catIDs)
|
||||
globals.SugarLogger.Debugf("SyncCategories vendorIDs:%v, appOrgCodes:%v, catIDs:%v", vendorIDs, appOrgCodes, catIDs)
|
||||
db := dao.GetDB()
|
||||
catList, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true)
|
||||
if err == nil && len(catList) > 0 {
|
||||
// TODO 同一平台不同账号会有影响needSyncParentIDs,暂不处理
|
||||
var needSyncParentIDs []int
|
||||
for _, cat := range catList {
|
||||
if cat.Level == 2 && cat.ParentVendorCatID == "" {
|
||||
@@ -128,7 +129,7 @@ func SyncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs
|
||||
}
|
||||
|
||||
func SyncSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, nameIDs, skuIDs []int, isAsync bool) (hint string, err error) {
|
||||
globals.SugarLogger.Debugf("SyncSkus nameIDs:%v, skuIDs:%v", nameIDs, skuIDs)
|
||||
globals.SugarLogger.Debugf("SyncSkus vendorIDs:%v, appOrgCodes:%v, nameIDs:%v, skuIDs:%v", vendorIDs, appOrgCodes, nameIDs, skuIDs)
|
||||
db := dao.GetDB()
|
||||
skuList, err := dao.GetSkusWithVendor(db, vendorIDs, appOrgCodes, nameIDs, skuIDs, true)
|
||||
if err == nil && len(skuList) > 0 {
|
||||
@@ -142,7 +143,7 @@ func SyncSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int,
|
||||
if skuVendorInfo.BindID == 0 {
|
||||
return nil, fmt.Errorf("商品:%d的数据异常", skuVendorInfo.SkuID)
|
||||
}
|
||||
skuVendorInfo.SkuName = jxutils.ComposeSkuName(skuVendorInfo.Prefix, skuVendorInfo.Name, skuVendorInfo.Comment, skuVendorInfo.Unit, skuVendorInfo.SpecQuality, skuVendorInfo.SpecUnit, 0)
|
||||
skuVendorInfo.SkuName = jxutils.ComposeSkuName(skuVendorInfo.Prefix, skuVendorInfo.Name, skuVendorInfo.Comment, skuVendorInfo.Unit, skuVendorInfo.SpecQuality, skuVendorInfo.SpecUnit, 0, skuVendorInfo.ExPrefix, skuVendorInfo.ExPrefixBegin, skuVendorInfo.ExPrefixEnd)
|
||||
skuVendorInfo.MergedStatus = jxutils.MergeSkuStatus(skuVendorInfo.Status, skuVendorInfo.NameStatus)
|
||||
if multiStoresHandler, ok := partner.GetPurchasePlatformFromVendorID(skuVendorInfo.VendorID).(partner.IMultipleStoresHandler); ok {
|
||||
if model.IsSyncStatusDelete(skuVendorInfo.SkuSyncStatus) { //删除
|
||||
|
||||
@@ -228,13 +228,16 @@ func calVendorPrice4StoreSku(inSku *dao.StoreSkuSyncInfo, pricePercentagePack mo
|
||||
func formalizeStoreSkuList(inSkuList []*dao.StoreSkuSyncInfo) []*dao.StoreSkuSyncInfo {
|
||||
for _, skuItem := range inSkuList {
|
||||
skuItem.MergedStatus = jxutils.MergeSkuStatus(skuItem.Status, skuItem.StoreSkuStatus)
|
||||
skuItem.SkuName = jxutils.ComposeSkuName(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 0)
|
||||
skuItem.SkuName = jxutils.ComposeSkuNameSync(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 0, skuItem.ExPrefix, skuItem.ExPrefixBegin, skuItem.ExPrefixEnd)
|
||||
}
|
||||
return inSkuList
|
||||
}
|
||||
|
||||
func sku2Update(vendorID int, sku *dao.StoreSkuSyncInfo, syncStatus int8) (item *dao.KVUpdateItem) {
|
||||
kvs := map[string]interface{}{}
|
||||
if !isSkuLockTimeValid(sku) {
|
||||
kvs[dao.GetVendorLockTimeStructField(model.VendorNames[vendorID])] = nil
|
||||
}
|
||||
if syncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask|model.SyncFlagModifiedMask) != 0 {
|
||||
if model.IsSyncStatusNew(syncStatus) {
|
||||
sku.SkuSyncStatus = 0
|
||||
@@ -289,6 +292,10 @@ func updateStoreSku(db *dao.DaoDB, vendorID int, storeSkuList []*dao.StoreSkuSyn
|
||||
return num, err
|
||||
}
|
||||
|
||||
func isSkuLockTimeValid(sku *dao.StoreSkuSyncInfo) bool {
|
||||
return sku.LockTime != nil && time.Now().Sub(*sku.LockTime) < 0
|
||||
}
|
||||
|
||||
func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bool, vendorID, storeID int, nameIDs, skuIDs, excludeSkuIDs []int, useVendorPriceDirectly, isContinueWhenError bool) (err error) {
|
||||
db := dao.GetDB()
|
||||
storeDetail, err := dao.GetStoreDetail(db, storeID, vendorID)
|
||||
@@ -334,7 +341,8 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
}
|
||||
now := jxutils.OperationTime2HourMinuteFormat(time.Now())
|
||||
for _, sku := range skus {
|
||||
if !useVendorPriceDirectly {
|
||||
if !useVendorPriceDirectly &&
|
||||
!isSkuLockTimeValid(sku) {
|
||||
sku.VendorPrice = 0
|
||||
}
|
||||
sku.MergedStatus = MergeSkuSaleStatusWithStoreOpTime(sku, storeDetail, now)
|
||||
@@ -354,14 +362,18 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
} else if model.IsSyncStatusNew(sku.SkuSyncStatus) {
|
||||
calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))
|
||||
if singleStoreHandler == nil {
|
||||
sku.SkuSyncStatus |= model.SyncFlagSaleMask | model.SyncFlagPriceMask
|
||||
bareSku = storeSkuSyncInfo2Bare(sku)
|
||||
stockList = append(stockList, bareSku)
|
||||
priceList = append(priceList, bareSku)
|
||||
if sku.MergedStatus == model.SkuStatusNormal {
|
||||
onlineList = append(onlineList, bareSku)
|
||||
if dao.IsVendorThingIDEmpty(sku.VendorSkuID) {
|
||||
// todo 多平台商品库没有正常创建,直接跳过
|
||||
} else {
|
||||
offlineList = append(offlineList, bareSku)
|
||||
sku.SkuSyncStatus |= model.SyncFlagSaleMask | model.SyncFlagPriceMask
|
||||
bareSku = storeSkuSyncInfo2Bare(sku)
|
||||
stockList = append(stockList, bareSku)
|
||||
priceList = append(priceList, bareSku)
|
||||
if sku.MergedStatus == model.SkuStatusNormal {
|
||||
onlineList = append(onlineList, bareSku)
|
||||
} else {
|
||||
offlineList = append(offlineList, bareSku)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if sku.MergedStatus == model.SkuStatusNormal {
|
||||
@@ -703,11 +715,13 @@ func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, v
|
||||
if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(sku2Delete) > 0 {
|
||||
_, err = putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
|
||||
if _, err = handler.DeleteStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList); err != nil {
|
||||
// 如果删除失败,尝试设置不可售,假定删除批处理SIZE小于等于设置门店商品可售批处理SIZE
|
||||
handler.UpdateStoreSkusStatus(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList, model.SkuStatusDontSale)
|
||||
if batchedStoreSkuList[0].Status == model.SkuStatusNormal {
|
||||
// 如果删除失败,尝试设置不可售,假定删除批处理SIZE小于等于设置门店商品可售批处理SIZE
|
||||
handler.UpdateStoreSkusStatus(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList, model.SkuStatusDontSale)
|
||||
}
|
||||
}
|
||||
return nil, 0, err
|
||||
}, ctx, task, sku2Delete, handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus), isContinueWhenError)
|
||||
}, ctx, task, sku2Delete, 1 /*handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus)*/, isContinueWhenError)
|
||||
}
|
||||
sku2Delete = nil
|
||||
case 2:
|
||||
|
||||
@@ -33,7 +33,7 @@ func TestFreeBatchStoreSkuInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTimeMixByInt(t *testing.T) {
|
||||
var (
|
||||
const (
|
||||
time1 = 1100
|
||||
time2 = 2300
|
||||
time3 = 1200
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/business/jxstore/report"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/baseapi/utils/errlist"
|
||||
"git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch"
|
||||
"git.rosy.net.cn/jx-callback/business/jxstore/act"
|
||||
@@ -34,8 +35,11 @@ var (
|
||||
dailyWorkTimeList = []string{
|
||||
"20:30:00",
|
||||
}
|
||||
priceReferTimeList = []string{
|
||||
"01:00:00",
|
||||
}
|
||||
createStorePriceTimeList = []string{
|
||||
"23:00:00",
|
||||
"02:00:00",
|
||||
}
|
||||
refreshPageActTimeList = []string{
|
||||
"7:00:00",
|
||||
@@ -113,7 +117,7 @@ func Init() {
|
||||
}, 5*time.Second, 1*time.Hour)
|
||||
|
||||
ScheduleTimerFuncByInterval(func() {
|
||||
defsch.FixedScheduler.ConfirmSelfTakeOrders(jxcontext.AdminCtx, nil, time.Now().Add(-48*time.Hour), time.Now().Add(-30*time.Minute), true, true)
|
||||
defsch.FixedScheduler.ConfirmSelfTakeOrders(jxcontext.AdminCtx, []int{model.VendorIDJD}, time.Now().Add(-48*time.Hour), time.Now().Add(-30*time.Minute), true, true)
|
||||
}, 5*time.Second, 10*time.Minute)
|
||||
|
||||
ScheduleTimerFunc("auto enable remote store", func() {
|
||||
@@ -129,7 +133,7 @@ func Init() {
|
||||
act.RefreshPageActs(jxcontext.AdminCtx, []int{model.VendorIDEBAI}, time.Now().Add(-30*24*time.Hour), false)
|
||||
}, refreshPageActTimeList)
|
||||
ScheduleTimerFunc("UpdateActStatusByTime", func() {
|
||||
dao.UpdateActStatusByTime(dao.GetDB(), time.Now().Add(-48*time.Hour))
|
||||
dao.UpdateActStatusByTime(dao.GetDB(), time.Now())
|
||||
}, updateActStatusTimeList)
|
||||
ScheduleScoreStore()
|
||||
ScheduleCheckStoreAlert()
|
||||
@@ -138,10 +142,10 @@ func Init() {
|
||||
}, ChangeStoreSkuSaleStatusList)
|
||||
ScheduleTimerFunc("BeginSavePriceRefer", func() {
|
||||
report.BeginSavePriceRefer(jxcontext.AdminCtx, nil, nil)
|
||||
}, createStorePriceTimeList)
|
||||
}, priceReferTimeList)
|
||||
ScheduleTimerFunc("CreateStorePriceScore", func() {
|
||||
cms.CreateStorePriceScore(jxcontext.AdminCtx, false)
|
||||
}, openRemoteStoreTimeList)
|
||||
cms.CreateStorePriceScore(jxcontext.AdminCtx)
|
||||
}, createStorePriceTimeList)
|
||||
}
|
||||
ScheduleTimerFunc("AutoSaleStoreSku", func() {
|
||||
cms.AutoSaleStoreSku(jxcontext.AdminCtx, nil, false)
|
||||
@@ -156,20 +160,55 @@ func Init() {
|
||||
}
|
||||
}
|
||||
|
||||
func doDailyWork() {
|
||||
globals.SugarLogger.Debug("doDailyWork")
|
||||
cms.SyncStoresCourierInfo(jxcontext.AdminCtx, nil, false, true)
|
||||
netprinter.RebindAllPrinters(jxcontext.AdminCtx, false, true)
|
||||
func syncStoreSku() {
|
||||
syncFlag := model.SyncFlagPriceMask
|
||||
if (time.Now().Unix()/24*3600)%10 == 0 {
|
||||
syncFlag |= model.SyncFlagSaleMask
|
||||
}
|
||||
// cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDJD}, nil, false, nil, []int{27379}, syncFlag, true, true)
|
||||
cms.CurVendorSync.FullSyncStoresSkus(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDJD}, nil, false, []int{27379}, true, true)
|
||||
task := tasksch.NewParallelTask("同步京西与平台数据", nil, jxcontext.AdminCtx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
step := batchItemList[0].(int)
|
||||
errList := errlist.New()
|
||||
db := dao.GetDB()
|
||||
switch step {
|
||||
case 0:
|
||||
errList.AddErr(cms.DeleteSkuNameExPrefixOverdue(db))
|
||||
errList.AddErr(cms.SetMultiStoreSkuSyncModifyStatus(db, partner.GetMultiStoreVendorIDs()))
|
||||
|
||||
SaveImportantTaskID(TaskNameSyncStoreSku, SpecialTaskID)
|
||||
taskID, _ := cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDEBAI, model.VendorIDMTWM}, nil, false, nil, nil, syncFlag, true, true)
|
||||
SaveImportantTaskID(TaskNameSyncStoreSku, taskID)
|
||||
_, err = cms.CurVendorSync.LoopMultiStoresVendors(jxcontext.AdminCtx, db, "同步多门店平台商品库", false, true,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
vendorInfo := batchItemList[0].(*cms.MultiStoreVendorInfo)
|
||||
_, err = cms.FullSyncVendorStuff(jxcontext.AdminCtx, task, vendorInfo.VendorID, vendorInfo.OrgCode, false, true)
|
||||
return retVal, err
|
||||
})
|
||||
errList.AddErr(err)
|
||||
|
||||
// cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, db, partner.GetMultiStoreVendorIDs(), nil, false, nil, []int{27379}, syncFlag, true, true)
|
||||
_, err = cms.CurVendorSync.FullSyncStoresSkus(jxcontext.AdminCtx, db, partner.GetMultiStoreVendorIDs(), nil, false, []int{27379}, true, true)
|
||||
errList.AddErr(err)
|
||||
case 1:
|
||||
errList.AddErr(cms.SetSingleStoreSkuSyncModifyStatus(db, partner.GetSingleStoreVendorIDs()))
|
||||
|
||||
_, err = cms.CurVendorSync.AmendAndPruneStoreStuff(jxcontext.AdminCtx, partner.GetSingleStoreVendorIDs(), nil, false, true, cms.AmendPruneAll, false)
|
||||
errList.AddErr(err)
|
||||
|
||||
SaveImportantTaskID(TaskNameSyncStoreSku, SpecialTaskID)
|
||||
taskID, err2 := cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, db, partner.GetSingleStoreVendorIDs(), nil, false, nil, nil, syncFlag, true, true)
|
||||
errList.AddErr(err2)
|
||||
SaveImportantTaskID(TaskNameSyncStoreSku, taskID)
|
||||
}
|
||||
err = errList.GetErrListAsOne()
|
||||
return retVal, err
|
||||
}, []int{0, 1})
|
||||
tasksch.HandleTask(task, nil, true).Run()
|
||||
}
|
||||
|
||||
func doDailyWork() {
|
||||
globals.SugarLogger.Debug("doDailyWork")
|
||||
cms.SyncStoresCourierInfo(jxcontext.AdminCtx, nil, false, true)
|
||||
netprinter.RebindAllPrinters(jxcontext.AdminCtx, false, true)
|
||||
|
||||
syncStoreSku()
|
||||
|
||||
InitEx()
|
||||
|
||||
@@ -180,6 +219,8 @@ func doDailyWork() {
|
||||
//fromDate, toDate都不传默认刷新当前天5天以前的订单,只传fromDate默认刷新fromDate到当天的订单
|
||||
//只传toDate默认刷新toDate到5天以前的订单
|
||||
orderman.RefreshOrdersWithoutJxStoreID(jxcontext.AdminCtx, "", "", true, true)
|
||||
//刷新京东门店的等级
|
||||
cms.RefreshJdLevel(jxcontext.AdminCtx)
|
||||
}
|
||||
|
||||
func RefreshRealMobile(ctx *jxcontext.Context, vendorID int, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
|
||||
@@ -396,7 +396,7 @@ func ScorePromotionSku(storeInfo *cms.StoreExt) {
|
||||
db := dao.GetDB()
|
||||
beginTime := time.Now()
|
||||
endTime := time.Now()
|
||||
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, nil, []int{storeID}, nil, beginTime, endTime)
|
||||
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, nil, model.ActTypeAll, []int{storeID}, nil, beginTime, endTime)
|
||||
finalScore := 0
|
||||
if err == nil && len(actStoreSkuList) > 0 {
|
||||
actStoreSkuMap := make(map[int]int)
|
||||
|
||||
@@ -149,7 +149,7 @@ func GetStoreSkuSalesInfo(ctx *jxcontext.Context, storeID int) (outStoreSkuSales
|
||||
if storeSkuInfo != nil {
|
||||
skuName := storeSkuInfo.SkuName
|
||||
skuInfo := storeSkuInfo.Skus[0]
|
||||
storeSkuSales.SkuName = jxutils.ComposeSkuName(skuName.Prefix, skuName.Name, skuInfo.Comment, skuName.Unit, skuInfo.SkuSpecQuality, skuInfo.SkuSpecUnit, 0)
|
||||
storeSkuSales.SkuName = jxutils.ComposeSkuName(skuName.Prefix, skuName.Name, skuInfo.Comment, skuName.Unit, skuInfo.SkuSpecQuality, skuInfo.SkuSpecUnit, 0,skuName.ExPrefix,skuName.ExPrefixBegin,skuName.ExPrefixEnd)
|
||||
storeSkuSales.SkuImage = storeSkuInfo.Img
|
||||
storeSkuSales.SkuPrice = jxutils.IntPrice2StandardCurrencyString(int64(storeSkuInfo.Skus[0].BindPrice))
|
||||
} else if skuAndNameInfo != nil {
|
||||
@@ -159,7 +159,7 @@ func GetStoreSkuSalesInfo(ctx *jxcontext.Context, storeID int) (outStoreSkuSales
|
||||
storeSkuSales.SkuImage = skuNameList[0].Img
|
||||
prefix = skuNameList[0].Prefix
|
||||
}
|
||||
storeSkuSales.SkuName = jxutils.ComposeSkuName(prefix, skuAndNameInfo.Name, skuAndNameInfo.Comment, skuAndNameInfo.Unit, skuAndNameInfo.SpecQuality, skuAndNameInfo.SpecUnit, 0)
|
||||
storeSkuSales.SkuName = jxutils.ComposeSkuName(prefix, skuAndNameInfo.Name, skuAndNameInfo.Comment, skuAndNameInfo.Unit, skuAndNameInfo.SpecQuality, skuAndNameInfo.SpecUnit, 0,skuAndNameInfo.ExPrefix,skuAndNameInfo.ExPrefixBegin,skuAndNameInfo.ExPrefixEnd)
|
||||
storeSkuSales.SkuPrice = "N/A"
|
||||
} else {
|
||||
storeSkuSales.SkuName = "N/A"
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
@@ -52,7 +54,7 @@ func StatisticsReportForStoreSkusPrice(ctx *jxcontext.Context, cityCodes, skuIDs
|
||||
|
||||
func BeginSavePriceRefer(ctx *jxcontext.Context, cityCodes, skuIDs []int) (err error) {
|
||||
db := dao.GetDB()
|
||||
snapshotAt := utils.Time2Date(time.Now())
|
||||
snapshotAt := utils.Time2Date(time.Now().AddDate(0, 0, -1))
|
||||
priceReferSnapshot, err := dao.GetStatisticsReportForStoreSkusPrice(db, cityCodes, skuIDs)
|
||||
if len(priceReferSnapshot) > 0 {
|
||||
dao.Begin(db)
|
||||
@@ -71,12 +73,12 @@ func BeginSavePriceRefer(ctx *jxcontext.Context, cityCodes, skuIDs []int) (err e
|
||||
for _, v := range priceReferSnapshot {
|
||||
dao.WrapAddIDCULDEntity(v, ctx.GetUserName())
|
||||
v.SnapshotAt = snapshotAt
|
||||
fmt.Println(v)
|
||||
if err = dao.CreateEntity(db, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dao.Commit(db)
|
||||
globals.SugarLogger.Debugf("CreatePriceRefer")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1451,7 +1451,7 @@ func BuildSkuFromEbaiStore(ctx *jxcontext.Context, baiduShopID int64, isAsync, i
|
||||
}
|
||||
price := sku.LinkID
|
||||
sku.LinkID = 0
|
||||
skuName := jxutils.ComposeSkuName(skuNameExt.Prefix, skuNameExt.Name, sku.Comment, skuNameExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameCharCount)
|
||||
skuName := jxutils.ComposeSkuNameOriginal(skuNameExt.Prefix, skuNameExt.Name, sku.Comment, skuNameExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameCharCount)
|
||||
fixedStatus := 1
|
||||
if sku.Status != model.SkuStatusNormal {
|
||||
fixedStatus = 2
|
||||
|
||||
@@ -327,7 +327,7 @@ func FloatWeight2Int(weight float32) int {
|
||||
return int(math.Round(float64(weight * 1000)))
|
||||
}
|
||||
|
||||
func ComposeSkuName(prefix, name, comment, unit string, spec_quality float32, spec_unit string, maxLen int) (skuName string) {
|
||||
func ComposeSkuNameOriginal(prefix, name, comment, unit string, spec_quality float32, spec_unit string, maxLen int) (skuName string) {
|
||||
if prefix != "" {
|
||||
skuName = "[" + prefix + "]"
|
||||
}
|
||||
@@ -348,6 +348,29 @@ func ComposeSkuName(prefix, name, comment, unit string, spec_quality float32, sp
|
||||
return skuName
|
||||
}
|
||||
|
||||
func ComposeSkuName(prefix, name, comment, unit string, spec_quality float32, spec_unit string, maxLen int, exPrefix string, exPrefixBegin, exPrefixEnd *time.Time) (skuName string) {
|
||||
if exPrefix != "" && exPrefixBegin != nil && exPrefixEnd != nil {
|
||||
if utils.Time2Date(time.Now().Add(6*time.Hour)).Sub(*exPrefixBegin) >= 0 && utils.Time2Date(time.Now()).Sub(*exPrefixEnd) <= 0 {
|
||||
skuName = exPrefix
|
||||
}
|
||||
}
|
||||
skuName += ComposeSkuNameOriginal(prefix, name, comment, unit, spec_quality, spec_unit, maxLen)
|
||||
return skuName
|
||||
}
|
||||
|
||||
func ComposeSkuNameSync(prefix, name, comment, unit string, spec_quality float32, spec_unit string, maxLen int, exPrefix string, exPrefixBegin, exPrefixEnd *time.Time) (skuName string) {
|
||||
if exPrefix != "" && exPrefixBegin != nil && exPrefixEnd != nil {
|
||||
if utils.Time2Date(time.Now().Add(6*time.Hour)).Sub(*exPrefixBegin) >= 0 && utils.Time2Date(time.Now()).Sub(*exPrefixEnd) <= 0 {
|
||||
skuName = exPrefix
|
||||
}
|
||||
if utils.Time2Date(time.Now().Add(6*time.Hour)).Sub(*exPrefixEnd) > 0 {
|
||||
skuName = ""
|
||||
}
|
||||
}
|
||||
skuName += ComposeSkuNameOriginal(prefix, name, comment, unit, spec_quality, spec_unit, maxLen)
|
||||
return skuName
|
||||
}
|
||||
|
||||
func ComposeSpuName(prefix, name string, maxLen int) (spuName string) {
|
||||
if prefix != "" {
|
||||
spuName = "[" + prefix + "]"
|
||||
@@ -409,6 +432,31 @@ func SplitSkuName(skuName string) (prefix, name, comment, specUnit, unit string,
|
||||
return prefix, name, comment, specUnit, unit, specQuality
|
||||
}
|
||||
|
||||
// https://my.oschina.net/hyller/blog/700414
|
||||
func CalUpcCheckSum(upc12 int64) (checkSum int) {
|
||||
var sum [2]int
|
||||
for i := 0; i < 12; i++ {
|
||||
base := int64(math.Pow10(i))
|
||||
sum[i%2] += int((upc12 / base) % 10)
|
||||
}
|
||||
sum[0] *= 3
|
||||
return (10 - (sum[0]+sum[1])%10) % 10
|
||||
}
|
||||
|
||||
func IsUpcValid(upc string) bool {
|
||||
if len(upc) != 13 {
|
||||
return false
|
||||
}
|
||||
upcInt := utils.Str2Int64WithDefault(upc, 0)
|
||||
checkSum := CalUpcCheckSum(upcInt / 10)
|
||||
return int(utils.Str2Int64(upc[12:])) == checkSum
|
||||
}
|
||||
|
||||
func GenFakeUPC(skuID int) string {
|
||||
id := int64(skuID) + 666600000000
|
||||
return fmt.Sprintf("%012d%d", id, CalUpcCheckSum(id))
|
||||
}
|
||||
|
||||
func MakeValidationMapFromSlice(validValues []string, flag int) map[string]int {
|
||||
retVal := make(map[string]int)
|
||||
for _, v := range validValues {
|
||||
|
||||
@@ -8,6 +8,7 @@ type ActStoreSkuMap struct {
|
||||
actStoreSkuMap map[int64]map[int]*model.ActStoreSku2
|
||||
}
|
||||
|
||||
// isActPrice为true表示是活动,false表示是结算
|
||||
func NewActStoreSkuMap(actStoreSkuList []*model.ActStoreSku2, isActPrice bool) (actMap *ActStoreSkuMap) {
|
||||
actMap = &ActStoreSkuMap{}
|
||||
actStoreSkuMap := make(map[int64]map[int]*model.ActStoreSku2)
|
||||
|
||||
@@ -2,18 +2,14 @@ package jxutils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
)
|
||||
|
||||
func TestGetActStoreSku(t *testing.T) {
|
||||
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(dao.GetDB(), 0, []int{model.VendorIDMTWM}, []int{102046}, []int{25430, 30611},
|
||||
utils.Str2Time("2019-07-27 13:29:57"), utils.Str2Time("2019-07-27 13:29:57"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
storeSkuMap := jxutils.NewActStoreSkuMap(actStoreSkuList, false)
|
||||
t.Log(storeSkuMap.GetActStoreSku(1, 2, 3))
|
||||
// actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(dao.GetDB(), 0, []int{model.VendorIDMTWM}, []int{102046}, []int{25430, 30611},
|
||||
// utils.Str2Time("2019-07-27 13:29:57"), utils.Str2Time("2019-07-27 13:29:57"))
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// storeSkuMap := jxutils.NewActStoreSkuMap(actStoreSkuList, false)
|
||||
// t.Log(storeSkuMap.GetActStoreSku(1, 2, 3))
|
||||
}
|
||||
|
||||
@@ -2,12 +2,10 @@ package jxutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
)
|
||||
|
||||
func TestSplitSlice(t *testing.T) {
|
||||
@@ -109,22 +107,22 @@ func TestCalcPolygonAreaAutonavi(t *testing.T) {
|
||||
// pointers := GetPolygonFromCircle(104.065702, 30.657488, 3000, 128)
|
||||
// area := CalcPolygonAreaAutonavi(pointers)
|
||||
// t.Logf("area:%f", area)
|
||||
db := dao.GetDB()
|
||||
storeList, err := dao.GetStoreList(db, nil, nil, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// db := dao.GetDB()
|
||||
// storeList, err := dao.GetStoreList(db, nil, nil, "")
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
strBuilder := &strings.Builder{}
|
||||
strBuilder.WriteString("\n")
|
||||
for _, v := range storeList {
|
||||
if v.DeliveryRangeType == model.DeliveryRangeTypePolygon {
|
||||
pointers := CoordinateStr2Points(v.DeliveryRange)
|
||||
area1 := CalcPolygonAreaAutonavi(pointers)
|
||||
strBuilder.WriteString(fmt.Sprintf("%d,%f\n", v.ID, area1))
|
||||
}
|
||||
}
|
||||
t.Log(strBuilder.String())
|
||||
// strBuilder := &strings.Builder{}
|
||||
// strBuilder.WriteString("\n")
|
||||
// for _, v := range storeList {
|
||||
// if v.DeliveryRangeType == model.DeliveryRangeTypePolygon {
|
||||
// pointers := CoordinateStr2Points(v.DeliveryRange)
|
||||
// area1 := CalcPolygonAreaAutonavi(pointers)
|
||||
// strBuilder.WriteString(fmt.Sprintf("%d,%f\n", v.ID, area1))
|
||||
// }
|
||||
// }
|
||||
// t.Log(strBuilder.String())
|
||||
}
|
||||
|
||||
func TestCaculateSkuPrice(t *testing.T) {
|
||||
|
||||
@@ -284,3 +284,26 @@ func TestGetOneEmailFromStr(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenFakeUPC(t *testing.T) {
|
||||
for _, v := range [][]string{
|
||||
[]string{
|
||||
"6666000298034",
|
||||
"29803",
|
||||
},
|
||||
[]string{
|
||||
"6666076543212",
|
||||
"7654321",
|
||||
},
|
||||
} {
|
||||
if str := GenFakeUPC(int(utils.Str2Int64(v[1]))); str != v[0] {
|
||||
t.Errorf("%s failed, result:%s, expect:%s", v[1], str, v[0])
|
||||
}
|
||||
}
|
||||
if !IsUpcValid("6666076543212") {
|
||||
t.Fatal("wrong1")
|
||||
}
|
||||
if IsUpcValid("6666076543210") {
|
||||
t.Fatal("wrong2")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,12 +418,6 @@ func (t *BaseTask) MarshalJSON() ([]byte, error) {
|
||||
func (t *BaseTask) run(taskHandler func()) {
|
||||
if t.GetStatus() == TaskStatusBegin {
|
||||
utils.CallFuncAsync(func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
globals.SugarLogger.Errorf("panic in BaseTask.run task:%s, task detail:%s, r:%v", t.Name, utils.Format4Output(t, false), r)
|
||||
}
|
||||
}()
|
||||
|
||||
taskHandler()
|
||||
|
||||
task := t
|
||||
|
||||
@@ -197,7 +197,7 @@ func getOrderDetailBrief(order *model.GoodsOrder) (brief string) {
|
||||
sb.WriteString(utils.Int2Str(order.Skus[0].Count))
|
||||
sb.WriteString("份(")
|
||||
sb.WriteString(jxutils.IntPrice2StandardString(order.Skus[0].SalePrice))
|
||||
sb.WriteString("元/份)等,共支付了")
|
||||
sb.WriteString("元/份)等,预计收入")
|
||||
sb.WriteString(jxutils.IntPrice2StandardString(order.ActualPayPrice))
|
||||
sb.WriteString("元")
|
||||
return sb.String()
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
ActTypeAll = -1
|
||||
ActSkuFake = 0 // 假活动,只用于存储活动结算信息
|
||||
ActSkuDirectDown = 3 // 兼容之前的
|
||||
ActSkuSecKill = 4 // 兼容之前的
|
||||
@@ -198,10 +199,13 @@ type ActStoreSku2 struct {
|
||||
|
||||
SkuName string `json:"skuName"`
|
||||
|
||||
Prefix string `json:"-"`
|
||||
SkuNameName string `orm:"column(sku_name_name)" json:"-"`
|
||||
Unit string `orm:"size(8)" json:"-"`
|
||||
SpecQuality float32 `json:"-"`
|
||||
SpecUnit string `json:"-"`
|
||||
Comment string `json:"-"`
|
||||
Prefix string `json:"-"`
|
||||
ExPrefix string
|
||||
ExPrefixBegin *time.Time
|
||||
ExPrefixEnd *time.Time
|
||||
SkuNameName string `orm:"column(sku_name_name)" json:"-"`
|
||||
Unit string `orm:"size(8)" json:"-"`
|
||||
SpecQuality float32 `json:"-"`
|
||||
SpecUnit string `json:"-"`
|
||||
Comment string `json:"-"`
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ type GoodsOrderExt struct {
|
||||
|
||||
type OrderSkuExt struct {
|
||||
OrderSku
|
||||
NameID int `orm:"column(name_id)" json:"nameID"`
|
||||
FullSkuName string `json:"fullSkuName"`
|
||||
Image string `json:"image"`
|
||||
RealEarningPrice int64 `json:"realEarningPrice"` // 实际单品结算给门店老板钱
|
||||
NameID int `orm:"column(name_id)" json:"nameID"`
|
||||
FullSkuName string `json:"fullSkuName"`
|
||||
Image string `json:"image"`
|
||||
// RealEarningPrice int64 `json:"realEarningPrice"` // 实际单品结算给门店老板钱
|
||||
}
|
||||
|
||||
type GoodsOrderCountInfo struct {
|
||||
@@ -83,3 +83,20 @@ type OrderFinancialSkuExt struct {
|
||||
OrderSkuFinancial
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
type ProductInfo struct {
|
||||
OriginalName string `json:"originalName"`
|
||||
OriginalSpec string `json:"originalSpec"`
|
||||
Name string `json:"name"`
|
||||
Img string `json:"img"`
|
||||
ImgList []string `json:"imgList"`
|
||||
SpecQuality int `json:"specQuality"`
|
||||
SpecUnit string `json:"specUnit"`
|
||||
Unit string `json:"unit"`
|
||||
Weight float32 `json:"weight"`
|
||||
Price int `json:"price"`
|
||||
Categories []string `json:"categories"`
|
||||
ManName string `json:"manName"` // 生产商
|
||||
BrandName string `json:"brandName"`
|
||||
UpcCode string `json:"upcCode"`
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ const (
|
||||
VendorIDPurchaseEnd = 11
|
||||
VendorIDJX = 9 // 这是一个假的京西VendorID
|
||||
|
||||
VendorIDWXPay = 51 // 微信支付
|
||||
|
||||
VendorIDDeliveryBegin = 101
|
||||
VendorIDDada = 101
|
||||
VendorIDMTPS = 102
|
||||
|
||||
@@ -33,9 +33,9 @@ var (
|
||||
|
||||
OrderStatusName = map[int]string{
|
||||
OrderStatusMsg: "通知消息",
|
||||
OrderStatusWaybillTipChanged: "小费变动",
|
||||
OrderStatusRefuseFailedGetGoods: "取货失败审核驳回",
|
||||
OrderStatusAdjust: "订单调整完成",
|
||||
OrderStatusWait4Pay: "待付款",
|
||||
OrderStatusApplyUrgeOrder: "催单",
|
||||
|
||||
OrderStatusUnlocked: "解锁",
|
||||
@@ -46,7 +46,7 @@ var (
|
||||
|
||||
OrderStatusUnknown: "一般事件",
|
||||
|
||||
OrderStatusCreated: "待支付",
|
||||
OrderStatusWait4Pay: "待付款",
|
||||
OrderStatusNew: "新订单",
|
||||
OrderStatusAccepted: "待拣货",
|
||||
OrderStatusFinishedPickup: "待配送",
|
||||
@@ -86,6 +86,18 @@ var (
|
||||
OrderTypeAfsOrder: "售后单",
|
||||
}
|
||||
|
||||
ComplaintReasons = map[int]string{
|
||||
ComplaintReasons1: "骑手态度恶劣",
|
||||
ComplaintReasons2: "骑手接单后未取货",
|
||||
ComplaintReasons3: "骑手取货太慢",
|
||||
ComplaintReasons4: "骑手送货太慢",
|
||||
ComplaintReasons5: "货品未送达",
|
||||
ComplaintReasons6: "货品有损坏",
|
||||
ComplaintReasons7: "骑手违规收取顾客其他费用",
|
||||
ComplaintReasons69: "骑手恶意取消订单",
|
||||
ComplaintReasons71: "骑手提前点击取货/送达",
|
||||
}
|
||||
|
||||
MultiStoresVendorMap = map[int]int{
|
||||
VendorIDJD: 1,
|
||||
VendorIDMTWM: 0,
|
||||
@@ -161,19 +173,21 @@ const (
|
||||
const (
|
||||
OrderStatusMsg = -100
|
||||
|
||||
OrderStatusWaybillTipChanged = -80 // 订单小费变化
|
||||
|
||||
OrderStatusRefuseFailedGetGoods = -70 // 取货失败审核驳回
|
||||
OrderStatusAdjust = -65 // 原值-35 订单调整完成
|
||||
OrderStatusWait4Pay = -60 // 原值-30 下单待支付,微盟在这个时间发新订单事件
|
||||
OrderStatusApplyUrgeOrder = -55 // 原值-15
|
||||
|
||||
OrderStatusUnlocked = -25
|
||||
OrderStatusLocked = -20
|
||||
// OrderStatusApplyRefund = -10
|
||||
OrderStatusUndoApplyCancel = -10
|
||||
OrderStatusApplyCancel = -5
|
||||
OrderStatusUnlocked = -25
|
||||
OrderStatusLocked = -20
|
||||
OrderStatusUndoApplyCancel = -10
|
||||
OrderStatusVendorRejectCancel = -7
|
||||
OrderStatusVendorAgreeCancel = -6
|
||||
OrderStatusApplyCancel = -5
|
||||
|
||||
OrderStatusUnknown = 0
|
||||
OrderStatusCreated = 2 // 已支付
|
||||
OrderStatusWait4Pay = 2 // 原值-60 下单待支付
|
||||
OrderStatusNew = 5 // 新订单,实际是已经支付
|
||||
OrderStatusAccepted = 10 // 已经接单,也即待出库,待拣货
|
||||
OrderStatusFinishedPickup = 15 // 拣货完成
|
||||
@@ -202,6 +216,19 @@ const (
|
||||
LockStatusLocked = 1
|
||||
)
|
||||
|
||||
//投诉原因
|
||||
const (
|
||||
ComplaintReasons1 = 1 //"骑手态度恶劣",
|
||||
ComplaintReasons2 = 2 //"骑手接单后未取货"
|
||||
ComplaintReasons3 = 3 //"骑手取货太慢",
|
||||
ComplaintReasons4 = 4 //"骑手送货太慢",
|
||||
ComplaintReasons5 = 5 //"货品未送达",
|
||||
ComplaintReasons6 = 6 //"货品有损坏",
|
||||
ComplaintReasons7 = 7 //"骑手违规收取顾客其他费用",
|
||||
ComplaintReasons69 = 69 //"骑手恶意取消订单",
|
||||
ComplaintReasons71 = 71 //"骑手提前点击取货/送达",
|
||||
)
|
||||
|
||||
const (
|
||||
WaybillStatusRefuseFailedGetGoods = -70
|
||||
WaybillStatusUnknown = 0
|
||||
@@ -222,6 +249,7 @@ const (
|
||||
WaybillStatusDelivered = 105 // todo 这个应该改为110,与订单对应
|
||||
WaybillStatusCanceled = 115
|
||||
WaybillStatusFailed = 120 // 这个状态存在的意义是区分于WaybillStatusCanceled,比如达达平台在这种状态下再次创建运单的方式不一样
|
||||
WaybillStatusEndEnd = 120
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -336,7 +364,7 @@ func IsOrderLockStatus(status int) bool {
|
||||
}
|
||||
|
||||
func IsOrderUnlockStatus(status int) bool {
|
||||
return status == OrderStatusUnlocked || status == OrderStatusUndoApplyCancel
|
||||
return status == OrderStatusUnlocked || status == OrderStatusUndoApplyCancel || status == OrderStatusVendorAgreeCancel || status == OrderStatusVendorRejectCancel
|
||||
}
|
||||
|
||||
func IsOrderMainStatus(status int) bool {
|
||||
@@ -367,3 +395,7 @@ func WaybillVendorID2Mask(vendorID int) (mask int8) {
|
||||
func IsAfsOrderFinalStatus(status int) bool {
|
||||
return status >= AfsOrderStatusFinished && status <= AfsOrderStatusFailed
|
||||
}
|
||||
|
||||
func IsWaybillFinalStatus(status int) bool {
|
||||
return status >= WaybillStatusEndBegin && status <= WaybillStatusEndEnd
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ func GetActStoreSkuVendorList(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs
|
||||
END vendor_sku_id,
|
||||
t4.comment, t4.spec_quality, t4.spec_unit,
|
||||
t6.name store_name,
|
||||
t7.name sku_name_name, t7.unit, t7.prefix
|
||||
t7.name sku_name_name, t7.unit, t7.prefix, t7.ex_prefix, t7.ex_prefix_begin, t7.ex_prefix_end
|
||||
FROM act_store_sku t1
|
||||
%s JOIN act_store_sku_map t2 ON t2.act_id = ? AND t2.bind_id = t1.id AND t2.deleted_at = ?`, jdVendorIDField, leftOrEmpty)
|
||||
sqlParams := []interface{}{
|
||||
@@ -204,25 +204,25 @@ func QueryActs(db *DaoDB, actID int, offset, pageSize int, syncStatus int, keywo
|
||||
SELECT
|
||||
t1.*,
|
||||
t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, t2.remark map_remark
|
||||
FROM act t1
|
||||
LEFT JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?`
|
||||
sqlParams = []interface{}{utils.DefaultTimeValue}
|
||||
if syncStatus >= 0 {
|
||||
sql += " AND (t2.sync_status = ? OR t2.sync_status & ? <> 0)"
|
||||
sqlParams = append(sqlParams, syncStatus, syncStatus)
|
||||
}
|
||||
} else if syncStatus >= 0 {
|
||||
sql += " JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ? AND (t2.sync_status = ? OR t2.sync_status & ? <> 0)"
|
||||
sqlParams = append(sqlParams, utils.DefaultTimeValue, syncStatus, syncStatus)
|
||||
FROM act t1`
|
||||
}
|
||||
sql += " LEFT JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?"
|
||||
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||||
if syncStatus >= 0 {
|
||||
sql += " AND (t2.sync_status = ? OR t2.sync_status & ? <> 0)"
|
||||
sqlParams = append(sqlParams, syncStatus, syncStatus)
|
||||
}
|
||||
sql += `
|
||||
WHERE t1.deleted_at = ?`
|
||||
if syncStatus >= 0 {
|
||||
sql += " AND t2.id IS NOT NULL"
|
||||
}
|
||||
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||||
keywordInt := int64(0)
|
||||
if keyword != "" {
|
||||
keywordLike := "%" + keyword + "%"
|
||||
sql += " AND ( t1.name LIKE ? OR t1.advertising LIKE ? OR t1.remark LIKE ?"
|
||||
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike)
|
||||
sql += " AND ( t1.name LIKE ? OR t1.advertising LIKE ? OR t1.remark LIKE ? OR t2.vendor_act_id LIKE ?"
|
||||
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike)
|
||||
keywordInt = utils.Str2Int64WithDefault(keyword, 0)
|
||||
if keywordInt > 0 {
|
||||
sql += `
|
||||
@@ -321,9 +321,12 @@ func QueryActs(db *DaoDB, actID int, offset, pageSize int, syncStatus int, keywo
|
||||
t2.id map_id, t2.vendor_id, t2.vendor_org_code, t2.vendor_act_id, t2.sync_status, t2.remark map_remark
|
||||
FROM act t1
|
||||
LEFT JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?
|
||||
WHERE t1.id IN (` + GenQuestionMarks(len(idList)) + `)
|
||||
ORDER BY t1.id DESC, t2.vendor_id
|
||||
`
|
||||
WHERE t1.id IN (` + GenQuestionMarks(len(idList)) + `)`
|
||||
if syncStatus >= 0 {
|
||||
sql += " AND t2.id IS NOT NULL"
|
||||
}
|
||||
sql += `
|
||||
ORDER BY t1.id DESC, t2.vendor_id`
|
||||
sqlParams = []interface{}{
|
||||
utils.DefaultTimeValue,
|
||||
idList,
|
||||
@@ -369,7 +372,7 @@ func GetExistVendorActIDs(db *DaoDB, vendorID int) (vendorActIDs []string, err e
|
||||
return vendorActIDs, err
|
||||
}
|
||||
|
||||
func GetEffectiveActStoreSkuInfo(db *DaoDB, actID int, vendorIDs []int, storeIDs, skuIDs []int, beginAt, endAt time.Time) (actStoreSkuList []*model.ActStoreSku2, err error) {
|
||||
func GetEffectiveActStoreSkuInfo(db *DaoDB, actID int, vendorIDs []int, actType int, storeIDs, skuIDs []int, beginAt, endAt time.Time) (actStoreSkuList []*model.ActStoreSku2, err error) {
|
||||
if utils.IsTimeZero(beginAt) {
|
||||
return nil, fmt.Errorf("GeActStoreSkuInfo必须指定活动开始时间")
|
||||
}
|
||||
@@ -406,9 +409,13 @@ func GetEffectiveActStoreSkuInfo(db *DaoDB, actID int, vendorIDs []int, storeIDs
|
||||
sqlParams = append(sqlParams, model.GetVendorMask(vendorIDs...), vendorIDs)
|
||||
}
|
||||
if actID > 0 {
|
||||
sql = " AND t1.id = ?"
|
||||
sql += " AND t1.id = ?"
|
||||
sqlParams = append(sqlParams, actID)
|
||||
}
|
||||
if actType != model.ActTypeAll {
|
||||
sql += " AND t1.type = ?"
|
||||
sqlParams = append(sqlParams, actType)
|
||||
}
|
||||
if len(storeIDs) > 0 {
|
||||
sql += " AND t2.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
|
||||
sqlParams = append(sqlParams, storeIDs)
|
||||
@@ -432,7 +439,7 @@ func UpdateActStatusByTime(db *DaoDB, refTime time.Time) (num int64, err error)
|
||||
model.ActStatusEnded,
|
||||
utils.DefaultTimeValue,
|
||||
model.ActStatusCanceled,
|
||||
refTime,
|
||||
utils.Time2Date(refTime),
|
||||
}
|
||||
num, err = ExecuteSQL(db, sql, sqlParams...)
|
||||
return num, err
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
)
|
||||
|
||||
func TestGetEffectiveActStoreSkuInfo(t *testing.T) {
|
||||
@@ -27,7 +28,7 @@ func TestGetEffectiveActStoreSkuInfo(t *testing.T) {
|
||||
ToTime: utils.Str2Time("2019-08-06 12:34:56"),
|
||||
},
|
||||
} {
|
||||
result, err := GetEffectiveActStoreSkuInfo(GetDB(), v.ActID, v.VendorIDs, v.StoreIDs, v.SkuIDs, v.FromTime, v.ToTime)
|
||||
result, err := GetEffectiveActStoreSkuInfo(GetDB(), v.ActID, v.VendorIDs, model.ActTypeAll, v.StoreIDs, v.SkuIDs, v.FromTime, v.ToTime)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -734,7 +734,7 @@ func GetOrders(db *DaoDB, ids []int64, isIncludeSku, isIncludeFake bool, fromDat
|
||||
IF(t3.jx_sku_id > 0, t3.jx_sku_id, t3.sku_id) sku_id,
|
||||
t3.count sku_count2,
|
||||
t3.shop_price sku_shop_price,
|
||||
t3.earning_price sku_earning_price,
|
||||
IF(t3.store_sub_id = 0, 0, t3.earning_price) sku_earning_price,
|
||||
t3.sale_price sku_sale_price,
|
||||
t3.sku_name`
|
||||
}
|
||||
@@ -1015,3 +1015,88 @@ func GetPendingFakeOrders(db *DaoDB, vendorIDs []int, orderCreatedAfter, orderCr
|
||||
err = GetRows(db, &orderList, sql, sqlParams...)
|
||||
return orderList, err
|
||||
}
|
||||
|
||||
// 不会有Skus信息
|
||||
func LoadPendingOrders(db *DaoDB, orderCreatedAfter time.Time, beforStatus int) (orderList []*model.GoodsOrder, err error) {
|
||||
sql := `
|
||||
SELECT *
|
||||
FROM goods_order
|
||||
WHERE order_created_at >= ?
|
||||
AND status < ?`
|
||||
sqlParams := []interface{}{orderCreatedAfter, beforStatus}
|
||||
err = GetRows(db, &orderList, sql, sqlParams...)
|
||||
return orderList, err
|
||||
}
|
||||
|
||||
func GetWayBillByOrderID(db *DaoDB, orderStatus, vendorID, waybillVendorID int, vendorOrderID string) (wayBillList []*model.Waybill, err error) {
|
||||
sql := `
|
||||
SELECT b.*
|
||||
FROM goods_order a
|
||||
JOIN waybill b ON IF(a.waybill_vendor_id = -1,a.vendor_order_id,a.vendor_waybill_id) = b.vendor_waybill_id AND b.order_vendor_id = a.vendor_id
|
||||
WHERE a.vendor_order_id = ?
|
||||
AND a.vendor_id = ?
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
vendorOrderID,
|
||||
vendorID,
|
||||
}
|
||||
if orderStatus > 0 {
|
||||
sql += ` AND a.status = ?`
|
||||
sqlParams = append(sqlParams, orderStatus)
|
||||
}
|
||||
if waybillVendorID > 0 {
|
||||
sql += ` AND b.waybill_vendor_id = ?`
|
||||
sqlParams = append(sqlParams, waybillVendorID)
|
||||
}
|
||||
err = GetRows(db, &wayBillList, sql, sqlParams...)
|
||||
return wayBillList, err
|
||||
}
|
||||
|
||||
func GetOrdersSupplement(db *DaoDB, storIDs, vendorIDs []int, vendorOrderID string, fromTime, toTime time.Time, status, stype, offset, pageSize int) (orderSupplementFee []*model.OrderSupplementFee, totalCount int, err error) {
|
||||
sql := `
|
||||
SELECT SQL_CALC_FOUND_ROWS *
|
||||
FROM order_supplement_fee
|
||||
WHERE 1=1
|
||||
AND deleted_at = ?
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
utils.DefaultTimeValue,
|
||||
}
|
||||
if !utils.IsTimeZero(fromTime) {
|
||||
sql += " AND supplement_time >= ?"
|
||||
sqlParams = append(sqlParams, fromTime)
|
||||
}
|
||||
if !utils.IsTimeZero(toTime) {
|
||||
sql += " AND supplement_time <= ?"
|
||||
sqlParams = append(sqlParams, toTime)
|
||||
}
|
||||
if len(storIDs) > 0 {
|
||||
sql += " AND store_id IN (" + GenQuestionMarks(len(storIDs)) + ")"
|
||||
sqlParams = append(sqlParams, storIDs)
|
||||
}
|
||||
if len(vendorIDs) > 0 {
|
||||
sql += " AND store_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
|
||||
sqlParams = append(sqlParams, vendorIDs)
|
||||
}
|
||||
if vendorOrderID != "" {
|
||||
sql += " AND vendor_order_id = ?"
|
||||
sqlParams = append(sqlParams, vendorOrderID)
|
||||
}
|
||||
if status >= 0 {
|
||||
sql += " AND status = ?"
|
||||
sqlParams = append(sqlParams, status)
|
||||
}
|
||||
if stype >= 0 {
|
||||
sql += " AND type = ?"
|
||||
sqlParams = append(sqlParams, stype)
|
||||
}
|
||||
sql += `
|
||||
LIMIT ? OFFSET ?`
|
||||
sqlParams = append(sqlParams, pageSize, offset)
|
||||
Begin(db)
|
||||
defer Commit(db)
|
||||
if err = GetRows(db, &orderSupplementFee, sql, sqlParams...); err == nil {
|
||||
totalCount = GetLastTotalRowCount(db)
|
||||
}
|
||||
return orderSupplementFee, totalCount, err
|
||||
}
|
||||
|
||||
@@ -160,6 +160,10 @@ func GetCategoryIDDBField(prefix string) string {
|
||||
return ConvertDBFieldPrefix(prefix) + "_category_id"
|
||||
}
|
||||
|
||||
func GetVendorLockTimeStructField(prefix string) string {
|
||||
return ConvertStructFieldPrefix(prefix) + "LockTime"
|
||||
}
|
||||
|
||||
func value2Value(srcValue, dstValue reflect.Value, copyType int) {
|
||||
srcType := srcValue.Type()
|
||||
for i := 0; i < srcType.NumField(); i++ {
|
||||
|
||||
@@ -188,10 +188,10 @@ func GetGetStatisticsReportForAfsOrders(db *DaoDB, storeIDs []int, fromDate time
|
||||
func GetStatisticsReportForStoreSkusPrice(db *DaoDB, cityCodes, skuIDs []int) (priceReferSnapshot []*model.PriceReferSnapshot, err error) {
|
||||
sql := `
|
||||
SELECT b.city_code,a.sku_id,
|
||||
MAX(a.price) max_price,
|
||||
MIN(a.price) min_price,
|
||||
ROUND(AVG(a.price)) avg_price,
|
||||
ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT((a.price/IF(b.pay_percentage=0,100,b.pay_percentage))*100 ORDER BY (a.price/IF(b.pay_percentage=0,100,b.pay_percentage))*100),',',Count(1)/2),',',-1),2) mid_price,
|
||||
ROUND(MAX(a.price/IF(b.pay_percentage=0,100,b.pay_percentage)*100)) max_price,
|
||||
ROUND(MIN(a.price/IF(b.pay_percentage=0,100,b.pay_percentage)*100)) min_price,
|
||||
ROUND(AVG(a.price/IF(b.pay_percentage=0,100,b.pay_percentage)*100)) avg_price,
|
||||
ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT((a.price/IF(b.pay_percentage=0,100,b.pay_percentage))*100 ORDER BY (a.price/IF(b.pay_percentage=0,100,b.pay_percentage))*100),',',Count(1)/2),',',-1)) mid_price,
|
||||
MAX(a.jd_price) max_jd_price,
|
||||
MIN(a.jd_price) min_jd_price,
|
||||
ROUND(AVG(a.jd_price)) avg_jd_price,
|
||||
@@ -211,8 +211,7 @@ func GetStatisticsReportForStoreSkusPrice(db *DaoDB, cityCodes, skuIDs []int) (p
|
||||
t1.min_vendor_price,
|
||||
t1.avg_vendor_price
|
||||
FROM store_sku_bind a
|
||||
JOIN store b ON a.store_id = b.id AND b.deleted_at = ?
|
||||
JOIN sku d ON a.sku_id = d.id AND d.deleted_at = ?
|
||||
JOIN store b ON a.store_id = b.id AND b.deleted_at = ? AND b.status != ?
|
||||
LEFT JOIN (
|
||||
SELECT SUM(t1.count),t1.sku_id,MAX(t1.sale_price) max_sale_price,MIN(t1.sale_price) min_sale_price,ROUND(AVG(t1.sale_price)) avg_sale_price,MAX(t1.vendor_price) max_vendor_price,MIN(t1.vendor_price) min_vendor_price,ROUND(AVG(t1.vendor_price)) avg_vendor_price
|
||||
FROM order_sku t1
|
||||
@@ -220,12 +219,14 @@ func GetStatisticsReportForStoreSkusPrice(db *DaoDB, cityCodes, skuIDs []int) (p
|
||||
GROUP BY 2
|
||||
)t1 ON t1.sku_id = a.sku_id
|
||||
WHERE a.deleted_at = ?
|
||||
AND a.status = ?
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
utils.DefaultTimeValue,
|
||||
utils.DefaultTimeValue,
|
||||
model.StoreStatusDisabled,
|
||||
time.Now().AddDate(0, -1, 0),
|
||||
utils.DefaultTimeValue,
|
||||
model.SkuStatusNormal,
|
||||
}
|
||||
if len(skuIDs) > 0 {
|
||||
sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||||
@@ -277,7 +278,7 @@ func GetPriceReferSnapshot(db *DaoDB, cityCodes, skuIDs []int, snapDate time.Tim
|
||||
err = err2
|
||||
if len(skuList) > 0 {
|
||||
skuAndName := skuList[0]
|
||||
jxSkuDetailName := jxutils.ComposeSkuName(skuAndName.Prefix, skuAndName.Name, skuAndName.Comment, skuAndName.Unit, skuAndName.SpecQuality, skuAndName.SpecUnit, 0)
|
||||
jxSkuDetailName := jxutils.ComposeSkuNameOriginal(skuAndName.Prefix, skuAndName.Name, skuAndName.Comment, skuAndName.Unit, skuAndName.SpecQuality, skuAndName.SpecUnit, 0)
|
||||
v.SkuName = jxSkuDetailName
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,16 +8,17 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
)
|
||||
|
||||
type tStoreSkuSyncInfo2 struct {
|
||||
StoreSkuSyncInfo
|
||||
VendorPlaceCode string
|
||||
}
|
||||
|
||||
type SkuCategoryWithVendor struct {
|
||||
*model.SkuCategory
|
||||
MapList []*model.ThingMap `json:"mapList"`
|
||||
}
|
||||
|
||||
type SkuNamePlace struct {
|
||||
model.Place
|
||||
NameID int `orm:"column(name_id)" json:"nameID"`
|
||||
SkuID int `orm:"column(sku_id)" json:"skuID"`
|
||||
}
|
||||
|
||||
func GetSellCities(db *DaoDB, nameID int, vendorID int) (cities []*model.Place, err error) {
|
||||
cities = []*model.Place{}
|
||||
sql := `
|
||||
@@ -49,7 +50,7 @@ func DeleteSkuNamePlace(db *DaoDB, nameID int, placeCodes []int) (num int64, err
|
||||
return ExecuteSQL(db, sql, sqlParams...)
|
||||
}
|
||||
|
||||
func GetCategories(db *DaoDB, parentID int, catIDs []int) (cats []*model.SkuCategory, err error) {
|
||||
func GetCategories(db *DaoDB, parentID, level int, catIDs []int) (cats []*model.SkuCategory, err error) {
|
||||
sql := `
|
||||
SELECT t1.*
|
||||
FROM sku_category t1
|
||||
@@ -62,16 +63,20 @@ func GetCategories(db *DaoDB, parentID int, catIDs []int) (cats []*model.SkuCate
|
||||
params = append(params, parentID)
|
||||
}
|
||||
if len(catIDs) > 0 {
|
||||
sql += " AND t1.id (" + GenQuestionMarks(len(catIDs)) + ")"
|
||||
sql += " AND t1.id IN (" + GenQuestionMarks(len(catIDs)) + ")"
|
||||
params = append(params, catIDs)
|
||||
}
|
||||
if level > 0 {
|
||||
sql += " AND t1.level = ?"
|
||||
params = append(params, level)
|
||||
}
|
||||
sql += " ORDER BY t1.level, t1.seq"
|
||||
return cats, GetRows(db, &cats, sql, params)
|
||||
}
|
||||
|
||||
func GetSkus(db *DaoDB, skuIDs, nameIDs, statuss, catIDs []int) (skuList []*model.SkuAndName, err error) {
|
||||
sql := `
|
||||
SELECT t1.*, t2.name, t2.unit, t2.prefix, t2.is_spu
|
||||
SELECT t1.*, t2.name, t2.unit, t2.prefix, t2.is_spu, t2.ex_prefix, t2.ex_prefix_begin, t2.ex_prefix_end
|
||||
FROM sku t1
|
||||
JOIN sku_name t2 ON t2.id = t1.name_id AND t2.deleted_at = ?
|
||||
`
|
||||
@@ -174,6 +179,9 @@ func SetSkuSyncStatus(db *DaoDB, vendorID int, skuIDs []int, syncStatus int) (nu
|
||||
return ExecuteSQL(db, sql, sqlParams...)
|
||||
}
|
||||
|
||||
// todo, GetSkuCategoryWithVendor与GetSkusWithVendor,
|
||||
// 如果mustDirty为true,应该是要thing_map为基表,LEFT JOIN原始实体表,否则当原始实体记录在未同步前被物理删除后,无法真正同步
|
||||
|
||||
// 多门店平台使用,当前只有京东
|
||||
func GetSkuCategoryWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, parentCatID int, catIDs []int, mustDirty bool) (catList []*SkuStoreCatInfo, err error) {
|
||||
sql := `
|
||||
@@ -211,7 +219,7 @@ func GetSkuCategoryWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string,
|
||||
`
|
||||
sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue)
|
||||
if mustDirty {
|
||||
sql += " AND t1m.sync_status <> 0"
|
||||
sql += " AND t1m.sync_status IS NOT NULL AND t1m.sync_status <> 0"
|
||||
} else {
|
||||
sql += " AND t1.deleted_at = ?"
|
||||
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||||
@@ -252,9 +260,9 @@ func GetSkusWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, nameIDs
|
||||
IF(t11.resource_type IS NULL OR t11.resource_type <> ?, t2.img, '') img,
|
||||
IF(t12.resource_type IS NULL OR t12.resource_type <> ?, t2.img2, '') img2,
|
||||
t2.desc_img,
|
||||
|
||||
t5.jd_code vendor_place_code,
|
||||
|
||||
t2.ex_prefix,
|
||||
t2.ex_prefix_begin,
|
||||
t2.ex_prefix_end,
|
||||
t3.jd_category_id vendor_vendor_cat_id,
|
||||
|
||||
t3m.sync_status cat_sync_status,
|
||||
@@ -281,15 +289,13 @@ func GetSkusWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, nameIDs
|
||||
LEFT JOIN sku_category t3 ON t3.id = t2.category_id
|
||||
LEFT JOIN thing_map t3m ON t3m.thing_id = t3.id AND t3m.thing_type = ? AND t3m.deleted_at = ?
|
||||
AND t3m.vendor_id = t1m.vendor_id AND t3m.vendor_org_code = t1m.vendor_org_code
|
||||
LEFT JOIN sku_name_place_bind t4 ON t2.is_global = 0 AND t4.name_id = t1.name_id
|
||||
LEFT JOIN place t5 ON t5.code = t4.place_code
|
||||
LEFT JOIN data_resource t11 ON t11.main_url = t2.img
|
||||
LEFT JOIN data_resource t12 ON t12.main_url = t2.img2
|
||||
WHERE 1 = 1
|
||||
`
|
||||
sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue)
|
||||
if mustDirty {
|
||||
sql += " AND t1m.sync_status <> 0"
|
||||
sql += " AND t1m.sync_status IS NOT NULL AND t1m.sync_status <> 0"
|
||||
} else {
|
||||
sql += " AND t1.deleted_at = ?"
|
||||
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||||
@@ -303,19 +309,47 @@ func GetSkusWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, nameIDs
|
||||
sqlParams = append(sqlParams, skuIDs)
|
||||
}
|
||||
sql += " ORDER BY t1.seq"
|
||||
|
||||
var list []*tStoreSkuSyncInfo2
|
||||
if err = GetRows(db, &list, sql, sqlParams...); err == nil {
|
||||
skuMap := make(map[int]*StoreSkuSyncInfo)
|
||||
for _, v := range list {
|
||||
if skuMap[v.SkuID] == nil {
|
||||
skuMap[v.SkuID] = &v.StoreSkuSyncInfo
|
||||
skuList = append(skuList, &v.StoreSkuSyncInfo)
|
||||
if err = GetRows(db, &skuList, sql, sqlParams...); err == nil {
|
||||
skuPlaceList, err2 := GetSkuNamePlaces(db, nameIDs, skuIDs)
|
||||
if err = err2; err == nil {
|
||||
skuPlaceMap := make(map[int][]*SkuNamePlace)
|
||||
for _, v := range skuPlaceList {
|
||||
skuPlaceMap[v.SkuID] = append(skuPlaceMap[v.SkuID], v)
|
||||
}
|
||||
if !IsVendorThingIDEmpty(v.VendorPlaceCode) {
|
||||
skuMap[v.SkuID].SellCities = append(skuMap[v.SkuID].SellCities, v.VendorPlaceCode)
|
||||
for _, v := range skuList {
|
||||
if v.IsGlobal == 0 {
|
||||
for _, v2 := range skuPlaceMap[v.SkuID] {
|
||||
// 京东到家
|
||||
if v2.JdCode > 0 {
|
||||
v.SellCities = append(v.SellCities, utils.Int2Str(v2.JdCode))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return skuList, err
|
||||
}
|
||||
|
||||
func GetSkuNamePlaces(db *DaoDB, nameIDs, skuIDs []int) (skuPlaceList []*SkuNamePlace, err error) {
|
||||
sql := `
|
||||
SELECT
|
||||
t4.*,
|
||||
t2.id sku_id, t2.name_id
|
||||
FROM sku t2
|
||||
JOIN sku_name_place_bind t3 ON t3.name_id = t2.name_id
|
||||
JOIN place t4 ON t4.code = t3.place_code
|
||||
WHERE t2.deleted_at = ?
|
||||
`
|
||||
sqlParams := []interface{}{utils.DefaultTimeValue}
|
||||
if len(nameIDs) > 0 {
|
||||
sql += " AND t2.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")"
|
||||
sqlParams = append(sqlParams, nameIDs)
|
||||
}
|
||||
if len(skuIDs) > 0 {
|
||||
sql += " AND t2.id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||||
sqlParams = append(sqlParams, skuIDs)
|
||||
}
|
||||
err = GetRows(db, &skuPlaceList, sql, sqlParams...)
|
||||
return skuPlaceList, err
|
||||
}
|
||||
|
||||
@@ -14,10 +14,11 @@ type StoreDetail struct {
|
||||
|
||||
VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空
|
||||
|
||||
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"`
|
||||
VendorStatus int `json:"vendor_status"` // 取值同Store.Status
|
||||
DeliveryFee int `json:"deliveryFee"`
|
||||
SyncStatus int8 `orm:"default(2)" json:"syncStatus"`
|
||||
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"`
|
||||
VendorStoreName string `json:"vendorStoreName"`
|
||||
VendorStatus int `json:"vendor_status"` // 取值同Store.Status
|
||||
DeliveryFee int `json:"deliveryFee"`
|
||||
SyncStatus int8 `orm:"default(2)" json:"syncStatus"`
|
||||
|
||||
PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格
|
||||
PricePercentagePackStr string `orm:"size(4096)" json:"-"` //
|
||||
@@ -38,6 +39,8 @@ type StoreDetail struct {
|
||||
MarketManName string `json:"marketManName"` //市场负责人
|
||||
OperatorName string `json:"operatorName"` //运营负责人
|
||||
OperatorName2 string `json:"operatorName2"`
|
||||
|
||||
JdStoreLevel string `json:"jdStoreLevel"` //京东门店等级
|
||||
}
|
||||
|
||||
// 带快递门店信息的
|
||||
@@ -60,10 +63,12 @@ type CityBrankBranch struct {
|
||||
}
|
||||
|
||||
type StorePriceScore struct {
|
||||
StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||
StoreName string `json:"storeName"`
|
||||
StoreScore float64 `json:"storeScore"`
|
||||
CityName string `json:"cityName"`
|
||||
StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||
StoreName string `json:"storeName"`
|
||||
StoreScore float64 `json:"storeScore"`
|
||||
CityName string `json:"cityName"`
|
||||
DirectDownCount int `json:"directDownCount"`
|
||||
SecKillCount int `json:"secKillCount"`
|
||||
}
|
||||
|
||||
type StorePriceScoreEx struct {
|
||||
@@ -78,8 +83,8 @@ func (s *StoreDetail) GetPricePerentage(price int) (pricePercentage int) {
|
||||
func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (storeDetail *StoreDetail, err error) {
|
||||
sql := `
|
||||
SELECT t1.*,
|
||||
t2.vendor_store_id, t2.status vendor_status, t2.delivery_fee, t2.sync_status,
|
||||
t2.price_percentage, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync,
|
||||
t2.vendor_store_id, t2.status vendor_status, t2.delivery_fee, t2.sync_status, t2.vendor_org_code,
|
||||
t2.price_percentage, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync, t2.vendor_store_name,
|
||||
t3.value price_percentage_pack_str,
|
||||
t4.value freight_deduction_pack_str,
|
||||
district.name district_name,
|
||||
@@ -484,16 +489,39 @@ func GetStoreMapsListWithoutDisabled(db *DaoDB, vendorIDs []int, status int) (st
|
||||
return storeMapList, err
|
||||
}
|
||||
|
||||
func GetStorePriceScore(db *DaoDB, storeIDs []int, fromScore, toScore, sort int, snapDate time.Time, offset, pageSize int) (StorePriceScore []*StorePriceScore, totalCount int, err error) {
|
||||
func GetStorePriceScore(db *DaoDB, storeIDs, vendorIDs []int, fromScore, toScore, sort int, snapDate time.Time, offset, pageSize int) (StorePriceScore []*StorePriceScore, totalCount int, err error) {
|
||||
sql := `
|
||||
SELECT SQL_CALC_FOUND_ROWS a.store_id,score store_score,e.name city_name,b.name store_name
|
||||
SELECT SQL_CALC_FOUND_ROWS a.store_id, score store_score, e.name city_name, b.name store_name, t1.direct_down_count, t1.sec_kill_count
|
||||
FROM store_price_score_snapshot a
|
||||
JOIN store b ON b.id = a.store_id
|
||||
JOIN place e ON e.code = b.city_code
|
||||
JOIN (SELECT a.store_id, count(d.type = ? OR NULL) direct_down_count, count(d.type = ? OR NULL) sec_kill_count
|
||||
FROM store_sku_bind a
|
||||
LEFT JOIN act_store_sku b ON a.store_id = b.store_id AND b.sku_id = a.sku_id
|
||||
LEFT JOIN act_map c ON c.act_id = b.act_id
|
||||
LEFT JOIN act d ON d.id = c.act_id
|
||||
WHERE 1=1
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
model.ActSkuDirectDown, model.ActSkuSecKill,
|
||||
}
|
||||
if len(storeIDs) > 0 {
|
||||
sql += " AND a.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")"
|
||||
sqlParams = append(sqlParams, storeIDs)
|
||||
}
|
||||
if len(vendorIDs) > 0 {
|
||||
sql += " AND c.vendor_id IN(" + GenQuestionMarks(len(vendorIDs)) + ")"
|
||||
sqlParams = append(sqlParams, vendorIDs)
|
||||
}
|
||||
sql += `
|
||||
AND NOW() BETWEEN d.begin_at AND d.end_at
|
||||
AND a.status = ?
|
||||
AND a.deleted_at = ?
|
||||
GROUP BY a.store_id)t1 ON t1.store_id = a.store_id
|
||||
WHERE 1=1
|
||||
`
|
||||
sqlParams := []interface{}{}
|
||||
if fromScore != 0 && toScore != 0 {
|
||||
sqlParams = append(sqlParams, model.StoreSkuBindStatusNormal, utils.DefaultTimeValue)
|
||||
if fromScore != 0 || toScore != 0 {
|
||||
sql += " AND a.score BETWEEN ? AND ?"
|
||||
sqlParams = append(sqlParams, fromScore, toScore)
|
||||
}
|
||||
@@ -505,10 +533,18 @@ func GetStorePriceScore(db *DaoDB, storeIDs []int, fromScore, toScore, sort int,
|
||||
sql += " AND a.snapshot_at = ?"
|
||||
sqlParams = append(sqlParams, snapDate)
|
||||
}
|
||||
if sort == 0 {
|
||||
if sort == 1 {
|
||||
sql += " ORDER BY a.score"
|
||||
} else {
|
||||
} else if sort == -1 {
|
||||
sql += " ORDER BY a.score DESC"
|
||||
} else if sort == 2 {
|
||||
sql += " ORDER BY t1.direct_down_count"
|
||||
} else if sort == -2 {
|
||||
sql += " ORDER BY t1.direct_down_count DESC"
|
||||
} else if sort == 3 {
|
||||
sql += " ORDER BY t1.sec_kill_count"
|
||||
} else if sort == -3 {
|
||||
sql += " ORDER BY t1.sec_kill_count DESC"
|
||||
}
|
||||
sql += " LIMIT ? OFFSET ?"
|
||||
sqlParams = append(sqlParams, pageSize, offset)
|
||||
|
||||
@@ -18,6 +18,7 @@ var (
|
||||
model.VendorIDMTWM: "mtwm_url",
|
||||
model.VendorIDEBAI: "ebai_url",
|
||||
}
|
||||
salePriceLimit = 100
|
||||
)
|
||||
|
||||
type SkuStoreCatInfo struct {
|
||||
@@ -56,7 +57,10 @@ type StoreSkuSyncInfo struct {
|
||||
model.Sku
|
||||
|
||||
// sku_name
|
||||
Prefix string
|
||||
Prefix string
|
||||
ExPrefix string
|
||||
ExPrefixBegin *time.Time
|
||||
ExPrefixEnd *time.Time
|
||||
// NameID int `orm:"column(name_id)"`
|
||||
VendorNameID string `orm:"column(vendor_name_id)"` // 暂时无用
|
||||
Name string
|
||||
@@ -69,7 +73,7 @@ type StoreSkuSyncInfo struct {
|
||||
// 平台相关的图片信息
|
||||
Img string
|
||||
Img2 string
|
||||
DescImg string // 饿百是SkuName中的DescImgEbai
|
||||
DescImg string
|
||||
|
||||
VendorVendorCatID int64 `orm:"column(vendor_vendor_cat_id)"` // 平台商品分类(叶子结点)
|
||||
|
||||
@@ -81,7 +85,9 @@ type StoreSkuSyncInfo struct {
|
||||
CatSyncStatus int8
|
||||
VendorCatID string `orm:"column(vendor_cat_id)"`
|
||||
|
||||
VendorPrice int64
|
||||
VendorPrice int64
|
||||
LockTime *time.Time
|
||||
|
||||
MergedStatus int
|
||||
SkuName string
|
||||
StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围
|
||||
@@ -167,6 +173,11 @@ type StoreSkuExt struct {
|
||||
MtwmPrice int `json:"mtwmPrice"`
|
||||
JxPrice int `json:"jxPrice"`
|
||||
|
||||
JdLockTime *time.Time `orm:"null" json:"jdLockTime,omitempty"`
|
||||
EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime,omitempty"`
|
||||
MtwmLockTime *time.Time `orm:"null" json:"mtwmLockTime,omitempty"`
|
||||
JxLockTime *time.Time `orm:"null" json:"jxLockTime,omitempty"`
|
||||
|
||||
AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"`
|
||||
|
||||
ActPrice int `json:"actPrice"`
|
||||
@@ -176,7 +187,7 @@ type StoreSkuExt struct {
|
||||
EarningPrice int `json:"earningPrice"`
|
||||
EarningActID int `orm:"column(earning_act_id)" json:"earningActID"`
|
||||
|
||||
RealEarningPrice int `json:"realEarningPrice"`
|
||||
// RealEarningPrice int `json:"realEarningPrice"`
|
||||
|
||||
StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围
|
||||
StatusSaleEnd int16 `json:"statusSaleEnd"`
|
||||
@@ -185,6 +196,15 @@ type StoreSkuExt struct {
|
||||
Times int `json:"times"`
|
||||
}
|
||||
|
||||
type SkuNameAndPlace struct {
|
||||
model.SkuName
|
||||
CityCode int `json:"cityCode"`
|
||||
CityName string `json:"cityName"`
|
||||
Sequence int `json:"sequence"`
|
||||
Count int `json:"count"`
|
||||
Type int `json:"type"`
|
||||
}
|
||||
|
||||
// todo 应该通过需要同步的skuid来驱动同步分类,而不是当前这种分开的逻辑
|
||||
// 单门店模式厂商适用
|
||||
// 从store_sku_bind中,得到所有依赖的商家分类信息
|
||||
@@ -302,16 +322,16 @@ func newGetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty
|
||||
SELECT
|
||||
t14.vendor_id, t14.vendor_org_code,
|
||||
t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status,
|
||||
%s vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price,
|
||||
%s vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time,
|
||||
t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end,
|
||||
t2.*,
|
||||
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc,
|
||||
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end,
|
||||
IF(t11.%s <> '', t11.%s, t3.img) img,
|
||||
IF(t12.%s <> '', t12.%s, t3.img2) img2,
|
||||
t13.%s desc_img,
|
||||
t4.%s_category_id vendor_vendor_cat_id`
|
||||
fmtParams := []interface{}{
|
||||
skuVendorIDField, fieldPrefix, fieldPrefix,
|
||||
skuVendorIDField, fieldPrefix, fieldPrefix, fieldPrefix,
|
||||
GetDataResFieldName(vendorID), GetDataResFieldName(vendorID),
|
||||
GetDataResFieldName(vendorID), GetDataResFieldName(vendorID),
|
||||
GetDataResFieldName(vendorID),
|
||||
@@ -329,7 +349,7 @@ func newGetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty
|
||||
}
|
||||
sql += `
|
||||
FROM store_sku_bind t1
|
||||
LEFT JOIN store_map t14 ON t14.store_id = t1.store_id AND t14.vendor_id = ? AND t14.deleted_at = ?
|
||||
JOIN store_map t14 ON t14.store_id = t1.store_id AND t14.vendor_id = ? AND t14.deleted_at = ?
|
||||
LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? AND t2.status = ?
|
||||
LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
||||
LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ?
|
||||
@@ -351,7 +371,7 @@ func newGetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty
|
||||
} else {
|
||||
sql += `
|
||||
LEFT JOIN sku_category t5sku ON t5sku.id = t2.category_id
|
||||
LEFT JOIN thing_map t2m ON t2m.thing_id = t1.sku_id AND t2m.vendor_org_code = t14.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ?
|
||||
JOIN thing_map t2m ON t2m.thing_id = t1.sku_id AND t2m.vendor_org_code = t14.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ?
|
||||
LEFT JOIN thing_map t4m ON t4m.thing_id = t3.category_id AND t4m.vendor_org_code = t14.vendor_org_code AND t4m.thing_type = ? AND t4m.vendor_id = ? AND t4m.deleted_at = ?
|
||||
LEFT JOIN thing_map t5skum ON t5skum.thing_id = t5sku.id AND t5skum.vendor_org_code = t14.vendor_org_code AND t5skum.thing_type = ? AND t5skum.vendor_id = ? AND t5skum.deleted_at = ?
|
||||
`
|
||||
@@ -410,7 +430,7 @@ func oldGetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty
|
||||
%s.%s_id vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price,
|
||||
t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end,
|
||||
t2.*,
|
||||
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc,
|
||||
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc,t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end,
|
||||
IF(t11.%s <> '', t11.%s, t3.img) img,
|
||||
IF(t12.%s <> '', t12.%s, t3.img2) img2,
|
||||
t13.%s desc_img,
|
||||
@@ -504,11 +524,15 @@ func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInf
|
||||
func newGetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInfo, err error) {
|
||||
globals.SugarLogger.Debugf("GetFullStoreSkus, storeID:%d, vendorID:%d", storeID, vendorID)
|
||||
|
||||
// 对于多门店平台,商品库删除后,不需要操作门店商品,所以sku_name用JOIN, sku与sku_name也可以直接排除下架的
|
||||
sql := `
|
||||
SELECT t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status,
|
||||
t1.%s_sync_status sku_sync_status, t1.store_id, t1.deleted_at bind_deleted_at,
|
||||
SELECT
|
||||
sm.vendor_id, sm.vendor_org_code,
|
||||
t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status,
|
||||
t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time,
|
||||
t1.store_id, t1.deleted_at bind_deleted_at,
|
||||
t2.*, t2.id sku_id, t2m.vendor_thing_id vendor_sku_id,
|
||||
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc,
|
||||
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end,
|
||||
IF(t11.%s <> '', t11.%s, t3.img) img,
|
||||
IF(t12.%s <> '', t12.%s, t3.img2) img2,
|
||||
t13.%s desc_img,
|
||||
@@ -516,12 +540,12 @@ func newGetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSync
|
||||
t4m.sync_status cat_sync_status, t4m.vendor_thing_id vendor_cat_id,
|
||||
t5skum.sync_status sku_cat_sync_status, t5skum.vendor_thing_id sku_vendor_cat_id
|
||||
FROM sku t2
|
||||
LEFT JOIN store_sku_bind t1 ON t1.sku_id = t2.id AND t1.store_id = ? AND t1.deleted_at = ?
|
||||
LEFT JOIN store_map sm ON sm.store_id = t1.store_id AND sm.vendor_id = ? AND sm.deleted_at = ?
|
||||
LEFT JOIN thing_map t2m ON t2m.thing_id = t2.id AND t2m.vendor_org_code = sm.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ?
|
||||
JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
||||
JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ?
|
||||
LEFT JOIN thing_map t4m ON t4m.thing_id = t3.category_id AND t4m.vendor_org_code = sm.vendor_org_code AND t4m.thing_type = ? AND t4m.vendor_id = ? AND t4m.deleted_at = ?
|
||||
JOIN store_map sm ON sm.vendor_id = ? AND sm.store_id = ? AND sm.deleted_at = ?
|
||||
JOIN thing_map t2m ON t2m.thing_id = t2.id AND t2m.vendor_org_code = sm.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ?
|
||||
JOIN thing_map t4m ON t4m.thing_id = t3.category_id AND t4m.vendor_org_code = sm.vendor_org_code AND t4m.thing_type = ? AND t4m.vendor_id = ? AND t4m.deleted_at = ?
|
||||
LEFT JOIN store_sku_bind t1 ON sm.store_id = t1.store_id AND t1.sku_id = t2.id AND t1.deleted_at = ?
|
||||
LEFT JOIN sku_category t5sku ON t2.category_id = t5sku.id
|
||||
LEFT JOIN thing_map t5skum ON t5skum.thing_id = t2.category_id AND t5skum.vendor_org_code = sm.vendor_org_code AND t5skum.thing_type = ? AND t5skum.vendor_id = ? AND t5skum.deleted_at = ?
|
||||
LEFT JOIN data_resource t11 ON t11.main_url = t3.img
|
||||
@@ -530,21 +554,18 @@ func newGetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSync
|
||||
WHERE t2.deleted_at = ? AND t2.status = ? AND t2m.vendor_thing_id <> ''
|
||||
ORDER BY t1.price DESC`
|
||||
sqlParams := []interface{}{
|
||||
storeID,
|
||||
utils.DefaultTimeValue, model.SkuStatusNormal,
|
||||
utils.DefaultTimeValue,
|
||||
vendorID, utils.DefaultTimeValue,
|
||||
vendorID, storeID, utils.DefaultTimeValue,
|
||||
model.ThingTypeSku, vendorID, utils.DefaultTimeValue,
|
||||
utils.DefaultTimeValue,
|
||||
model.SkuStatusNormal,
|
||||
utils.DefaultTimeValue,
|
||||
model.ThingTypeCategory, vendorID, utils.DefaultTimeValue,
|
||||
model.ThingTypeCategory, vendorID, utils.DefaultTimeValue,
|
||||
utils.DefaultTimeValue,
|
||||
model.SkuStatusNormal,
|
||||
model.ThingTypeCategory, vendorID, utils.DefaultTimeValue,
|
||||
utils.DefaultTimeValue, model.SkuStatusNormal,
|
||||
}
|
||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||
sql = fmt.Sprintf(sql,
|
||||
fieldPrefix,
|
||||
fieldPrefix, fieldPrefix, fieldPrefix,
|
||||
GetDataResFieldName(vendorID), GetDataResFieldName(vendorID),
|
||||
GetDataResFieldName(vendorID), GetDataResFieldName(vendorID),
|
||||
GetDataResFieldName(vendorID),
|
||||
@@ -860,7 +881,7 @@ func GetStoresSkusInfoBySaleTime(db *DaoDB, storeID int) (storeSkuBindList []*mo
|
||||
return storeSkuBindList, err
|
||||
}
|
||||
|
||||
func UpdateStoreSkuBindSyncStatus(db *DaoDB, vendorIDs []int, storeID int) (num int64, err error) {
|
||||
func UpdateStoreSkuBindSyncStatusForSaleStatus(db *DaoDB, vendorIDs []int, storeID int) (num int64, err error) {
|
||||
sql := `
|
||||
UPDATE store_sku_bind
|
||||
SET
|
||||
@@ -892,6 +913,74 @@ func UpdateStoreSkuBindSyncStatus(db *DaoDB, vendorIDs []int, storeID int) (num
|
||||
return ExecuteSQL(db, sql, sqlParams...)
|
||||
}
|
||||
|
||||
func UpdateStoreSkuBindSyncStatusForExPrefix(db *DaoDB, vendorIDs []int) (num int64, err error) {
|
||||
sql := `
|
||||
UPDATE store_sku_bind a
|
||||
JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ?
|
||||
JOIN sku_name c ON c.id = b.name_id AND c.deleted_at = ?
|
||||
SET
|
||||
`
|
||||
fmtParams := []interface{}{}
|
||||
sqlParams := []interface{}{
|
||||
utils.DefaultTimeValue,
|
||||
utils.DefaultTimeValue,
|
||||
}
|
||||
if len(vendorIDs) > 0 {
|
||||
for _, v := range vendorIDs {
|
||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[v])
|
||||
sql += ` %s_sync_status = %s_sync_status | ?,`
|
||||
fmtParams = append(fmtParams, fieldPrefix, fieldPrefix)
|
||||
sqlParams = append(sqlParams, model.SyncFlagModifiedMask)
|
||||
}
|
||||
} else {
|
||||
return 0, errors.New("取平台ID名有错误!partner.GetPurchasePlatformVendorIDs()")
|
||||
}
|
||||
sql = sql[0:strings.LastIndex(sql, ",")]
|
||||
sql = fmt.Sprintf(sql, fmtParams...)
|
||||
sql += ` WHERE a.deleted_at = ?
|
||||
AND c.ex_prefix != ""
|
||||
AND (c.ex_prefix_begin = DATE_FORMAT(DATE_ADD(NOW(),INTERVAL '6' HOUR),'%Y-%m-%d 00:00:00')
|
||||
OR c.ex_prefix_end = DATE_FORMAT(NOW(),'%Y-%m-%d 00:00:00'))
|
||||
`
|
||||
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||||
return ExecuteSQL(db, sql, sqlParams...)
|
||||
}
|
||||
|
||||
func UpdateSkuSyncStatusForExPrefix(db *DaoDB, vendorIDs []int) (num int64, err error) {
|
||||
sql := `
|
||||
UPDATE thing_map t1
|
||||
JOIN sku t2 ON t2.id = t1.thing_id AND t2.deleted_at = ?
|
||||
JOIN sku_name t3 ON t3.id = t2.name_id AND t3.deleted_at = ?
|
||||
AND t3.ex_prefix <> '' AND (t3.ex_prefix_begin = DATE_FORMAT(DATE_ADD(NOW(),INTERVAL '6' HOUR),'%Y-%m-%d 00:00:00')
|
||||
OR t3.ex_prefix_end = DATE_FORMAT(NOW(),'%Y-%m-%d 00:00:00'))
|
||||
SET
|
||||
t1.sync_status = t1.sync_status | ?
|
||||
WHERE t1.deleted_at = ? AND t1.thing_type = ? AND t1.sync_status & ? <> 0
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
utils.DefaultTimeValue,
|
||||
utils.DefaultTimeValue,
|
||||
model.SyncFlagModifiedMask,
|
||||
utils.DefaultTimeValue, model.ThingTypeSku, model.SyncFlagDeletedMask,
|
||||
}
|
||||
if len(vendorIDs) > 0 {
|
||||
sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
|
||||
sqlParams = append(sqlParams, vendorIDs)
|
||||
}
|
||||
return ExecuteSQL(db, sql, sqlParams...)
|
||||
}
|
||||
|
||||
func DeleteSkuNameExPrefixOverdue(db *DaoDB) (num int64, err error) {
|
||||
sql := `
|
||||
UPDATE sku_name
|
||||
SET ex_prefix_begin = null,ex_prefix_end = null
|
||||
WHERE deleted_at = ?
|
||||
AND DATE_FORMAT(DATE_ADD(NOW(),INTERVAL '6' HOUR),'%Y-%m-%d 00:00:00') >= ex_prefix_end
|
||||
`
|
||||
sqlParams := []interface{}{utils.DefaultTimeValue}
|
||||
return ExecuteSQL(db, sql, sqlParams...)
|
||||
}
|
||||
|
||||
func GetStoreSkusByNameIDs(db *DaoDB, storeIDs []int, nameID int) (skuList []*StoreSkuSyncInfo, err error) {
|
||||
sql := `
|
||||
SELECT a.*,c.unit,c.name
|
||||
@@ -924,7 +1013,7 @@ func GetTopSkusByStoreIDs(db *DaoDB, storeIDs []int) (storeSkuNameExt []*StoreSk
|
||||
JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id
|
||||
JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ?
|
||||
JOIN sku_name t1 ON t1.id = c.name_id AND t1.deleted_at = ?
|
||||
STRAIGHT_JOIN store_sku_bind t4 ON t4.store_id = IF(a.store_id = 0,a.jx_store_id,a.store_id) AND t4.sku_id = b.sku_id AND t4.status = ? AND t4.deleted_at = ?
|
||||
STRAIGHT_JOIN store_sku_bind t4 ON t4.store_id = IF(a.jx_store_id = 0,a.store_id,a.jx_store_id) AND t4.sku_id = b.sku_id AND t4.status = ? AND t4.deleted_at = ?
|
||||
JOIN store d ON d.id = a.store_id
|
||||
WHERE 1=1
|
||||
AND a.order_created_at BETWEEN ? and NOW()
|
||||
@@ -948,7 +1037,7 @@ func GetTopSkusByStoreIDs(db *DaoDB, storeIDs []int) (storeSkuNameExt []*StoreSk
|
||||
ORDER BY t1.count DESC
|
||||
LIMIT ?
|
||||
`
|
||||
sqlParams = append(sqlParams, 100, 30)
|
||||
sqlParams = append(sqlParams, salePriceLimit, 30)
|
||||
err = GetRows(db, &storeSkuNameExt, sql, sqlParams...)
|
||||
var skuNamesInfo = &StoreSkuNamesInfo{
|
||||
SkuNames: storeSkuNameExt,
|
||||
@@ -984,7 +1073,33 @@ func GetTopSkusByStoreIDs(db *DaoDB, storeIDs []int) (storeSkuNameExt []*StoreSk
|
||||
return storeSkuNameExt, err
|
||||
}
|
||||
|
||||
func GetTopCategorysByStoreIDs(db *DaoDB, storeIDs []int) (skuCategory []*model.SkuCategory, err error) {
|
||||
func GetTopSkusByCityCode(db *DaoDB, cityCode int, orderCreate time.Time) (skuNameAndPlace []*SkuNameAndPlace, err error) {
|
||||
sql := `
|
||||
SELECT SUM(b.count) count, e.name city_name, d.city_code, f.*
|
||||
FROM goods_order a
|
||||
JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id
|
||||
JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ?
|
||||
JOIN sku_name f ON f.id = c.name_id
|
||||
JOIN store d ON d.id = IF(a.jx_store_id = 0,a.store_id,a.jx_store_id) AND d.deleted_at = ? AND d.city_code = ?
|
||||
JOIN place e ON e.code = d.city_code
|
||||
WHERE 1=1
|
||||
AND b.sale_price > ?
|
||||
AND a.order_created_at BETWEEN ? and NOW()
|
||||
GROUP BY 2,3,4
|
||||
ORDER BY count DESC
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
utils.DefaultTimeValue,
|
||||
utils.DefaultTimeValue,
|
||||
cityCode,
|
||||
salePriceLimit,
|
||||
orderCreate,
|
||||
}
|
||||
err = GetRows(db, &skuNameAndPlace, sql, sqlParams...)
|
||||
return skuNameAndPlace, err
|
||||
}
|
||||
|
||||
func GetTopCategoriesByStoreIDs(db *DaoDB, storeIDs []int, limit int) (skuCategory []*model.SkuCategory, err error) {
|
||||
sql := `
|
||||
SELECT DISTINCT t5.* FROM(
|
||||
SELECT d.*
|
||||
@@ -993,10 +1108,10 @@ func GetTopCategorysByStoreIDs(db *DaoDB, storeIDs []int) (skuCategory []*model.
|
||||
FROM(
|
||||
SELECT SUM(b.count) count,d.category_id
|
||||
FROM goods_order a
|
||||
JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id
|
||||
JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id
|
||||
JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ?
|
||||
JOIN sku_name d ON d.id = c.name_id AND d.deleted_at = ?
|
||||
JOIN store e ON e.id = a.store_id
|
||||
JOIN store e ON e.id = IF(a.jx_store_id = 0,a.store_id,a.jx_store_id) AND e.status != -2
|
||||
JOIN (SELECT city_code FROM store WHERE 1=1
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
@@ -1023,11 +1138,51 @@ func GetTopCategorysByStoreIDs(db *DaoDB, storeIDs []int) (skuCategory []*model.
|
||||
Order by t4.count DESC)t5
|
||||
LIMIT ?
|
||||
`
|
||||
sqlParams = append(sqlParams, time.Now().AddDate(0, -1, 0), 100, 2, utils.DefaultTimeValue, 1, 10)
|
||||
sqlParams = append(sqlParams, time.Now().AddDate(0, -1, 0), salePriceLimit, 2, utils.DefaultTimeValue, 1, limit)
|
||||
err = GetRows(db, &skuCategory, sql, sqlParams...)
|
||||
return skuCategory, err
|
||||
}
|
||||
|
||||
func GetStoreSkuCategories(db *DaoDB, storeID, parentID int) (catList []*model.SkuCategory, err error) {
|
||||
sql := `
|
||||
SELECT
|
||||
t1.*
|
||||
FROM sku_category t1
|
||||
JOIN
|
||||
(
|
||||
SELECT DISTINCT t3.category_id
|
||||
FROM store_sku_bind t1
|
||||
JOIN sku t2 ON t2.id = t1.sku_id AND t2.deleted_at = ? AND t2.status = ?
|
||||
JOIN sku_name t3 ON t3.id = t2.name_id AND t3.deleted_at = ? AND t3.status = ?
|
||||
WHERE t1.deleted_at = ? AND t1.status = ? AND t1.store_id = ?
|
||||
) t2 ON t2.category_id = t1.id
|
||||
WHERE t1.deleted_at = ?`
|
||||
sqlParams := []interface{}{
|
||||
utils.DefaultTimeValue, model.SkuStatusNormal,
|
||||
utils.DefaultTimeValue, model.SkuStatusNormal,
|
||||
utils.DefaultTimeValue, model.SkuStatusNormal, storeID,
|
||||
utils.DefaultTimeValue,
|
||||
}
|
||||
if parentID >= 0 {
|
||||
sql += " AND t1.parent_id = ?"
|
||||
sqlParams = append(sqlParams, parentID)
|
||||
}
|
||||
sql += " ORDER BY t1.level, t1.seq"
|
||||
if err = GetRows(db, &catList, sql, sqlParams...); err == nil && len(catList) > 0 {
|
||||
parentIDMap := make(map[int]int)
|
||||
for _, v := range catList {
|
||||
parentIDMap[v.ParentID] = 1
|
||||
}
|
||||
paretnCats, err2 := GetCategories(db, -1, 0, jxutils.IntMap2List(parentIDMap))
|
||||
if err = err2; err == nil {
|
||||
catList = append(catList, paretnCats...)
|
||||
} else {
|
||||
catList = nil
|
||||
}
|
||||
}
|
||||
return catList, err
|
||||
}
|
||||
|
||||
func RefershStoreSkusMidPrice(db *DaoDB, storeIDs []int) (count int64, err error) {
|
||||
sql := `
|
||||
UPDATE store_sku_bind a
|
||||
@@ -1068,16 +1223,21 @@ func GetStoreSkuNamePrice(db *DaoDB) (storeSkuNamePriceList []*model.StoreSkuNam
|
||||
return storeSkuNamePriceList, err
|
||||
}
|
||||
|
||||
func SetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int, vendorPrice int) {
|
||||
func SetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int, vendorPrice int, lockTime time.Time) {
|
||||
pLockTime := utils.Time2Pointer(lockTime)
|
||||
switch vendorID {
|
||||
case model.VendorIDJD:
|
||||
storeSkuBind.JdPrice = vendorPrice
|
||||
storeSkuBind.JdLockTime = pLockTime
|
||||
case model.VendorIDMTWM:
|
||||
storeSkuBind.MtwmPrice = vendorPrice
|
||||
storeSkuBind.MtwmLockTime = pLockTime
|
||||
case model.VendorIDEBAI:
|
||||
storeSkuBind.EbaiPrice = vendorPrice
|
||||
storeSkuBind.EbaiLockTime = pLockTime
|
||||
case model.VendorIDJX:
|
||||
storeSkuBind.JxPrice = vendorPrice
|
||||
storeSkuBind.JxLockTime = pLockTime
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1136,7 +1296,7 @@ func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesI
|
||||
if actVendorID >= 0 {
|
||||
vendorIDs = []int{actVendorID}
|
||||
}
|
||||
actStoreSkuList, err := GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, storeIDs, skuIDs, time.Now(), time.Now())
|
||||
actStoreSkuList, err := GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, model.ActTypeAll, 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
|
||||
@@ -1151,15 +1311,16 @@ func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesI
|
||||
v.ActPrice = int(actStoreSku.ActualActPrice)
|
||||
v.ActID = actStoreSku.ActID
|
||||
v.ActType = actStoreSku.Type
|
||||
v.EarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.ActPrice), int64(v.ActPrice), skuName.PayPercentage))
|
||||
}
|
||||
if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil {
|
||||
v.EarningPrice = int(actStoreSku.EarningPrice)
|
||||
v.EarningActID = actStoreSku.ActID
|
||||
}
|
||||
|
||||
v.RealEarningPrice = v.EarningPrice
|
||||
if v.RealEarningPrice == 0 {
|
||||
v.RealEarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.BindPrice), skuName.PayPercentage))
|
||||
} else {
|
||||
earningPrice := int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.BindPrice), skuName.PayPercentage))
|
||||
if earningPrice < v.EarningPrice {
|
||||
v.EarningPrice = earningPrice
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1168,3 +1329,65 @@ func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesI
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func GetDeletedStoreSkuBind(db *DaoDB, storeID, skuID int) (storeSkuBind *model.StoreSkuBind) {
|
||||
sql := `
|
||||
SELECT a.*
|
||||
FROM store_sku_bind a
|
||||
WHERE a.store_id = ? AND a.sku_id = ?
|
||||
ORDER BY a.deleted_at DESC`
|
||||
sqlParams := []interface{}{
|
||||
storeID, skuID,
|
||||
}
|
||||
if err := GetRow(db, &storeSkuBind, sql, sqlParams...); err != nil {
|
||||
storeSkuBind = nil
|
||||
}
|
||||
return storeSkuBind
|
||||
}
|
||||
|
||||
func GetMidPriceByNameID(db *DaoDB, cityCode, skuNameID int, snapDate time.Time) (midPrice int, err error) {
|
||||
var (
|
||||
sku []*model.SkuAndName
|
||||
skuMap = make(map[int]int)
|
||||
)
|
||||
sql := `
|
||||
SELECT a.mid_price price, a.sku_id id, b.spec_quality, c.unit, b.spec_unit
|
||||
FROM price_refer_snapshot a
|
||||
JOIN sku b ON a.sku_id = b.id
|
||||
JOIN sku_name c ON c.id = b.name_id
|
||||
WHERE c.id = ?
|
||||
AND a.snapshot_at = ?
|
||||
AND a.city_code = ?
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
skuNameID,
|
||||
snapDate,
|
||||
cityCode,
|
||||
}
|
||||
err = GetRows(db, &sku, sql, sqlParams...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(sku) > 0 {
|
||||
for _, v := range sku {
|
||||
var (
|
||||
price int
|
||||
specQuality float64
|
||||
)
|
||||
if v.Unit == model.SpecialUnit {
|
||||
if v.SpecUnit == model.SpecUnitNames[1] || v.SpecUnit == model.SpecUnitNames[2] {
|
||||
specQuality = float64(v.SpecQuality) * 1000
|
||||
} else {
|
||||
specQuality = float64(v.SpecQuality)
|
||||
}
|
||||
price = int(utils.Float64TwoInt64(utils.Int2Float64(model.SpecialSpecQuality) / specQuality * utils.Int2Float64(v.Price)))
|
||||
} else {
|
||||
price = v.Price
|
||||
}
|
||||
if skuMap[skuNameID] < price {
|
||||
skuMap[skuNameID] = price
|
||||
}
|
||||
}
|
||||
}
|
||||
return skuMap[skuNameID], err
|
||||
}
|
||||
|
||||
30
business/model/dao/store_sku_test.go
Normal file
30
business/model/dao/store_sku_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
)
|
||||
|
||||
func TestGetFullStoreSkus(t *testing.T) {
|
||||
skuList, err := GetFullStoreSkus(GetDB(), model.VendorIDJD, 100118)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
globals.SugarLogger.Debug(utils.Format4Output(skuList, false))
|
||||
}
|
||||
|
||||
func TestGetStoreSkus(t *testing.T) {
|
||||
skuList, err := GetStoreSkus(GetDB(), model.VendorIDMTWM, 100134, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
globals.SugarLogger.Debug(utils.Format4Output(skuList, false))
|
||||
}
|
||||
|
||||
func TestGetDeletedStoreSkuBind(t *testing.T) {
|
||||
storeSkuBind := GetDeletedStoreSkuBind(GetDB(), 100123, 30648)
|
||||
globals.SugarLogger.Debug(utils.Format4Output(storeSkuBind, false))
|
||||
}
|
||||
@@ -59,6 +59,7 @@ type GoodsOrder struct {
|
||||
TotalShopMoney int64 `json:"totalShopMoney"` // 应结金额-第三方平台结算给京西的金额(包括了所有的补贴,扣除)
|
||||
DiscountMoney int64 `json:"discountMoney"` // 订单总优惠金额
|
||||
PmSubsidyMoney int64 `json:"pmSubsidyMoney"` // 平台活动补贴(订单主体活动补贴+订单单条sku补贴)1+
|
||||
BaseFreightMoney int64 `json:"baseFreightMoney"` // 商户承担的配送费(不包括DistanceFreightMoney)
|
||||
DistanceFreightMoney int64 `json:"distanceFreightMoney"` // 商户承担的远距离配送费(当前只有京东到家有值)
|
||||
WaybillTipMoney int64 `json:"waybillTipMoney"` // 京西加的平台配送小费
|
||||
EarningPrice int64 `json:"earningPrice"` // 结算给门店老板的钱(未扣除可能的三方配送费)
|
||||
@@ -76,7 +77,7 @@ type GoodsOrder struct {
|
||||
GoodsCount int `json:"goodsCount"` // 商品个数
|
||||
Status int `json:"status"` // 参见OrderStatus*相关的常量定义
|
||||
VendorStatus string `orm:"size(255)" json:"vendorStatus"`
|
||||
LockStatus int `json:"lockStatus"`
|
||||
LockStatus int `json:"lockStatus"` // 当前只支持单一锁定
|
||||
LockStatusTime time.Time `orm:"type(datetime);null" json:"lockStatusTime"` // last lock status time
|
||||
OrderSeq int `json:"orderSeq"` // 门店订单序号
|
||||
BuyerComment string `orm:"size(255)" json:"buyerComment"`
|
||||
@@ -133,7 +134,7 @@ type OrderSku struct {
|
||||
ID int64 `orm:"column(id)" json:"-"`
|
||||
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"`
|
||||
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||
StoreSubID int `orm:"column(store_sub_id)" json:"storeSubID"` // 当前这个字段被当成结算活动ID用
|
||||
StoreSubID int `orm:"column(store_sub_id)" json:"storeSubID"` // EarningActID,当前这个字段被当成结算活动ID用
|
||||
StoreSubName string `orm:"size(64)" json:"storeSubName"` // 当前这个字段被用作vendorActType
|
||||
Count int `json:"count"`
|
||||
VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"`
|
||||
@@ -172,6 +173,7 @@ type Waybill struct {
|
||||
VendorStatus string `orm:"size(255)" json:"-"`
|
||||
ActualFee int64 `json:"actualFee"` // 实际要支付给快递公司的费用
|
||||
DesiredFee int64 `json:"desiredFee"` // 运单总费用
|
||||
TipFee int64 `json:"tipFee"` // 运单小费,不含在上两项中
|
||||
DuplicatedCount int `json:"-"` // 重复新订单消息数,这个一般不是由于消息重发造成的(消息重发由OrderStatus过滤),一般是业务逻辑造成的
|
||||
DeliveryFlag int8 `json:"deliveryFlag"`
|
||||
WaybillCreatedAt time.Time `orm:"type(datetime);index" json:"waybillCreatedAt"`
|
||||
@@ -196,6 +198,12 @@ func (w *Waybill) TableIndex() [][]string {
|
||||
}
|
||||
}
|
||||
|
||||
type WaybillExt struct {
|
||||
Waybill
|
||||
Lng float64 `json:"lng"`
|
||||
Lat float64 `json:"lat"`
|
||||
}
|
||||
|
||||
// 包含订单与运单的状态及事件vendor status
|
||||
type OrderStatus struct {
|
||||
ID int64 `orm:"column(id)" json:"id"`
|
||||
@@ -296,25 +304,26 @@ type OrderComment struct {
|
||||
type OrderPay struct {
|
||||
ModelIDCULD
|
||||
|
||||
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"`
|
||||
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||
PayType int `json:"payType"`
|
||||
PayOrderID string `orm:"column(pay_order_id);size(48)" json:"payOrderID"` // 京西支付定单号
|
||||
PayType int `json:"payType"`
|
||||
|
||||
VendorPayType string `orm:"size(48)" json:"vendorPayType"`
|
||||
VendorOrderID string `orm:"column(vendor_order_id);size(48);index" json:"vendorOrderID"` // 支付对应的购物订单号
|
||||
VendorID int `orm:"column(vendor_id)" json:"vendorID"` // 购物订单所属厂商代码(当前只有京西)
|
||||
Status int `json:"status"`
|
||||
PayCreatedAt time.Time `orm:"type(datetime);index" json:"payCreatedAt"`
|
||||
PayFinishedAt *time.Time `orm:"type(datetime);null" json:"payFinishedAt"`
|
||||
TotalFee int `json:"totalFee"`
|
||||
|
||||
TransactionID string `orm:"column(transaction_id);index;size(48)" json:"transactionID"`
|
||||
PrepayID string `orm:"column(prepay_id);unique;size(48)" json:"prepayID"`
|
||||
PrepayID string `orm:"column(prepay_id);index;size(48)" json:"prepayID"` // 下单后,支付前,支付方生成的事务ID
|
||||
TransactionID string `orm:"column(transaction_id);index;size(48)" json:"transactionID"` // 支付成功后,支付方生成的事务ID
|
||||
CodeURL string `orm:"column(code_url);size(256)" json:"codeURL"`
|
||||
PayOrderID string `orm:"column(pay_order_id);size(48)" json:"payOrderID"`
|
||||
OriginalData string `orm:"type(text)" json:"-"`
|
||||
}
|
||||
|
||||
func (v *OrderPay) TableIndex() [][]string {
|
||||
return [][]string{
|
||||
[]string{"VendorOrderID", "VendorID", "PayType", "DeletedAt"},
|
||||
[]string{"PayOrderID", "PayType", "DeletedAt"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,12 +331,11 @@ type OrderPayRefund struct {
|
||||
ModelIDCULD
|
||||
|
||||
RefundID string `orm:"column(refund_id);unique;size(48)" json:"refundID"`
|
||||
VendorRefundID string `orm:"column(vendor_refund_id);unique;size(48)" json:"vendorRefundID"`
|
||||
VendorRefundID string `orm:"column(vendor_refund_id);unique;size(48)" json:"vendorRefundID"` // 支付方退款成功后生成的退款单号
|
||||
|
||||
AfsOrderID string `orm:"column(afs_order_id);index;size(48)" json:"afsOrderID"` // AfsOrderID与RefundID的区别?
|
||||
VendorOrderID string `orm:"column(vendor_order_id);index;size(48)" json:"vendorOrderID"`
|
||||
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||
TransactionID string `orm:"column(transaction_id);index;size(48)" json:"transactionID"`
|
||||
TransactionID string `orm:"column(transaction_id);index;size(48)" json:"transactionID"` // 支付成功后,支付方生成的事务ID
|
||||
Status int `json:"status"`
|
||||
RefundCreatedAt time.Time `orm:"type(datetime);index" json:"payCreatedAt"`
|
||||
RefundFinishedAt *time.Time `orm:"type(datetime);null" json:"payFinishedAt"`
|
||||
@@ -336,6 +344,11 @@ type OrderPayRefund struct {
|
||||
OriginalData string `orm:"type(text)" json:"-"`
|
||||
}
|
||||
|
||||
type OrderSupplementFee struct {
|
||||
ModelIDCULD
|
||||
VendorOrderID string `orm:"column(vendor_order_id);index;size(48)" json:"vendorOrderID"`
|
||||
}
|
||||
|
||||
// 判断是否是购买平台自有物流
|
||||
// 对于京东,饿百来说,就是其自有的物流,对于微商城来说,是达达
|
||||
func IsWaybillPlatformOwn(bill *Waybill) bool {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
SkuCategoryNormal = 0
|
||||
SkuCategorySpecial = 1
|
||||
@@ -166,8 +168,12 @@ func (*SkuCategory) TableIndex() [][]string {
|
||||
type SkuName struct {
|
||||
ModelIDCULD
|
||||
|
||||
Prefix string `orm:"size(255)" json:"prefix"`
|
||||
Name string `orm:"size(255);index" json:"name"`
|
||||
Prefix string `orm:"size(255)" json:"prefix"`
|
||||
Name string `orm:"size(255)" json:"name"`
|
||||
ExPrefix string `orm:"size(255)" json:"exPrefix"`
|
||||
|
||||
ExPrefixBegin *time.Time `orm:"null" json:"exPrefixBegin"`
|
||||
ExPrefixEnd *time.Time `orm:"null" json:"exPrefixEnd"`
|
||||
|
||||
BrandID int `orm:"column(brand_id);default(0)" json:"brandID"` // todo,此属性暂时没有使用,且有问题,应该是不同平台都有一个brandid
|
||||
CategoryID int `orm:"column(category_id);index" json:"categoryID"` // 标准类别
|
||||
@@ -187,9 +193,9 @@ type SkuName struct {
|
||||
DescImg string `orm:"size(255)" json:"descImg"` // 商品详情图片描述
|
||||
// DescImgEbai string `orm:"size(255)" json:"descImgEbai"` // 饿百的商品详情图片描述RTF
|
||||
|
||||
Upc string `orm:"size(20);index"`
|
||||
Status int `orm:"default(1)" json:"status"` // skuname状态,取值同sku.Status
|
||||
IsSpu int8 `orm:"column(is_spu)" json:"isSpu"` // 用于指明是否SKUNAME当成SPU
|
||||
Upc *string `orm:"size(20)"`
|
||||
Status int `orm:"default(1)" json:"status"` // skuname状态,取值同sku.Status
|
||||
IsSpu int8 `orm:"column(is_spu)" json:"isSpu"` // 用于指明是否SKUNAME当成SPU
|
||||
|
||||
JdID int64 `orm:"column(jd_id);null;index" json:"jdID"`
|
||||
JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"`
|
||||
@@ -200,6 +206,13 @@ type SkuName struct {
|
||||
func (*SkuName) TableUnique() [][]string {
|
||||
return [][]string{
|
||||
[]string{"Name", "Prefix", "SpecQuality", "SpecUnit", "Unit", "IsSpu", "DeletedAt"},
|
||||
[]string{"Upc", "DeletedAt"},
|
||||
}
|
||||
}
|
||||
|
||||
func (*SkuName) TableIndex() [][]string {
|
||||
return [][]string{
|
||||
[]string{"ExPrefix", "ExPrefixBegin", "ExPrefixEnd", "DeletedAt"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,10 +236,14 @@ type Sku struct {
|
||||
|
||||
type SkuAndName struct {
|
||||
Sku
|
||||
Name string
|
||||
Unit string
|
||||
Prefix string
|
||||
IsSpu int
|
||||
Name string
|
||||
Unit string
|
||||
Prefix string
|
||||
IsSpu int
|
||||
ExPrefix string
|
||||
ExPrefixBegin *time.Time
|
||||
ExPrefixEnd *time.Time
|
||||
Price int
|
||||
}
|
||||
|
||||
func (*Sku) TableUnique() [][]string {
|
||||
@@ -255,9 +272,9 @@ type SkuWithVendor struct {
|
||||
|
||||
type SkuNameExt struct {
|
||||
SkuName
|
||||
Skus []*SkuWithVendor `orm:"-" json:"skus"`
|
||||
SkusStr string `json:"-"`
|
||||
|
||||
Places []int `orm:"-" json:"places"`
|
||||
PlacesStr string `json:"-"`
|
||||
Skus []*SkuWithVendor `orm:"-" json:"skus"`
|
||||
SkusStr string `json:"-"`
|
||||
FullName string `json:"fullName"`
|
||||
Places []int `orm:"-" json:"places"`
|
||||
PlacesStr string `json:"-"`
|
||||
}
|
||||
|
||||
@@ -49,6 +49,12 @@ const (
|
||||
StoreChangePriceTypeManagedStore = 3 // 直营门店,禁止改价
|
||||
)
|
||||
|
||||
const (
|
||||
AutoReplyAll = 0 // 全部自动回复
|
||||
AutoReplyGoodComment = 1 // 禁止差评自动回复
|
||||
AutoReplyDisabled = 2 // 禁止自动回复
|
||||
)
|
||||
|
||||
var (
|
||||
StoreStatusName = map[int]string{
|
||||
StoreStatusDisabled: "禁用",
|
||||
@@ -240,6 +246,11 @@ var (
|
||||
StoreChangePriceTypeBossDisabled: "普通门店禁止改价",
|
||||
StoreChangePriceTypeManagedStore: "直营门店禁止改价",
|
||||
}
|
||||
AutoReplyTypeName = map[int]string{
|
||||
AutoReplyAll: "全部自动回复",
|
||||
AutoReplyGoodComment: "禁止差评自动回复",
|
||||
AutoReplyDisabled: "禁止自动回复",
|
||||
}
|
||||
)
|
||||
|
||||
type Store struct {
|
||||
@@ -264,6 +275,7 @@ type Store struct {
|
||||
AutoEnableAt *time.Time `orm:"type(datetime);null" json:"autoEnableAt"` // 自动营业时间(临时休息用)
|
||||
ChangePriceType int8 `json:"changePriceType"` // 修改价格类型,即是否需要审核
|
||||
SMSNotify int8 `orm:"column(sms_notify);" json:"smsNotify"` // 是否通过短信接收订单消息
|
||||
AutoReplyType int8 `json:"autoReplyType"` // 订单评价自动回复类型
|
||||
|
||||
PrinterDisabled int8 `orm:"default(0)" json:"printerDisabled"` // 是否禁用网络打印机
|
||||
PrinterFontSize int8 `orm:"default(0)" json:"printerFontSize"` // 打印字体-1:小,0:正常,1:大
|
||||
@@ -314,6 +326,7 @@ type Store struct {
|
||||
|
||||
OperatorPhone2 string `orm:"size(16)" json:"operatorPhone2"` // 非京东运营人电话
|
||||
OperatorRole2 string `orm:"size(32)" json:"operatorRole2"` // 非京东运营人组(角色)
|
||||
PromoteInfo string `orm:"size(255)" json:"promoteInfo"` //门店公告(所有平台统一的公告)
|
||||
}
|
||||
|
||||
func (*Store) TableUnique() [][]string {
|
||||
@@ -375,9 +388,10 @@ type StoreMap struct {
|
||||
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||
VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空
|
||||
|
||||
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"`
|
||||
Status int `json:"status"` // 取值同Store.Status
|
||||
StoreName string `orm:"size(255)" json:"storeName"` // 平台门店的名字
|
||||
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"`
|
||||
Status int `json:"status"` // 取值同Store.Status
|
||||
StoreName string `orm:"size(255)" json:"storeName"` // 平台门店的名字,由平台到京西
|
||||
VendorStoreName string `orm:"size(255)" json:"vendorStoreName"` //平台门店名,由京西到平台
|
||||
|
||||
PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格
|
||||
PricePercentagePack string `orm:"size(32)" json:"pricePercentagePack"` //
|
||||
@@ -389,10 +403,11 @@ type StoreMap struct {
|
||||
DeliveryFee int `json:"deliveryFee"`
|
||||
DeliveryCompetition int8 `orm:"default(1)" json:"deliveryCompetition"` // 是否支持配送竞争
|
||||
|
||||
SyncStatus int8 `orm:"default(2)" json:"syncStatus"`
|
||||
IsSync int8 `orm:"default(1)" json:"isSync"` // 是否同步
|
||||
FakeOpenStart int16 `orm:"default(0)" json:"fakeOpenStart"` // 假开店开始
|
||||
FakeOpenStop int16 `orm:"default(0)" json:"fakeOpenStop"` // 假开店结束
|
||||
SyncStatus int8 `orm:"default(2)" json:"syncStatus"`
|
||||
IsSync int8 `orm:"default(1)" json:"isSync"` // 是否同步
|
||||
FakeOpenStart int16 `orm:"default(0)" json:"fakeOpenStart"` // 假开店开始
|
||||
FakeOpenStop int16 `orm:"default(0)" json:"fakeOpenStop"` // 假开店结束
|
||||
JdStoreLevel string `orm:"size(32)" json:"jdStoreLevel"` //京东门店等级
|
||||
}
|
||||
|
||||
func (*StoreMap) TableUnique() [][]string {
|
||||
@@ -522,6 +537,7 @@ type VendorStoreSnapshot struct {
|
||||
DeliveryType int8 `orm:"default(0)" json:"deliveryType"` // 配送类型
|
||||
StoreName string `orm:"size(255)" json:"storeName"` // 平台门店的名字
|
||||
IsAutoOrder int8 `json:"isAutoOrder"` // 平台是否自动接单,-1:否,0:未知,1:是
|
||||
JdStoreLevel string `orm:"size(32)" json:"jdStoreLevel"` //京东门店等级
|
||||
}
|
||||
|
||||
func (*VendorStoreSnapshot) TableUnique() [][]string {
|
||||
|
||||
@@ -94,22 +94,26 @@ type StoreSkuBind struct {
|
||||
Status int
|
||||
|
||||
// ElmID int64 `orm:"column(elm_id);index"`
|
||||
MtwmID int64 `orm:"column(mtwm_id);index"`
|
||||
EbaiID int64 `orm:"column(ebai_id);index"`
|
||||
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)"`
|
||||
EbaiSyncStatus int8 `orm:"default(2)"`
|
||||
// WscSyncStatus int8 `orm:"default(2)"`
|
||||
|
||||
JdPrice int `json:"jdPrice"`
|
||||
EbaiPrice int `json:"ebaiPrice"`
|
||||
MtwmPrice int `json:"mtwmPrice"`
|
||||
EbaiPrice int `json:"ebaiPrice"`
|
||||
JxPrice int `json:"jxPrice"`
|
||||
// WscPrice int `json:"wscPrice"`
|
||||
|
||||
JdLockTime *time.Time `orm:"null" json:"jdLockTime"`
|
||||
MtwmLockTime *time.Time `orm:"null" json:"mtwmLockTime"`
|
||||
EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime"`
|
||||
JxLockTime *time.Time `orm:"null" json:"jxLockTime"`
|
||||
|
||||
AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"`
|
||||
|
||||
|
||||
@@ -69,16 +69,12 @@ func (c *DeliveryHandler) onWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaap
|
||||
order := c.callbackMsg2Waybill(msg)
|
||||
switch msg.OrderStatus {
|
||||
case dadaapi.OrderStatusWaitingForAccept:
|
||||
if result, err := api.DadaAPI.QueryOrderInfo(msg.OrderID); err == nil {
|
||||
order.ActualFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["actualFee"], 0.0))
|
||||
order.DesiredFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["deliveryFee"], 0.0))
|
||||
if dadaOrder, err := api.DadaAPI.QueryOrderInfo2(msg.OrderID); err == nil {
|
||||
order.ActualFee = jxutils.StandardPrice2Int(dadaOrder.ActualFee)
|
||||
order.DesiredFee = jxutils.StandardPrice2Int(dadaOrder.DeliveryFee)
|
||||
}
|
||||
order.Status = model.WaybillStatusNew
|
||||
case dadaapi.OrderStatusAccepted:
|
||||
// if result, err := api.DadaAPI.QueryOrderInfo(msg.OrderID); err == nil {
|
||||
// order.ActualFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["actualFee"], 0.0))
|
||||
// order.DesiredFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["deliveryFee"], 0.0))
|
||||
// }
|
||||
order.Status = model.WaybillStatusAccepted
|
||||
case dadaapi.OrderStatusDelivering:
|
||||
order.Status = model.WaybillStatusDelivering
|
||||
@@ -204,10 +200,12 @@ func (c *DeliveryHandler) IsErrStoreExist(err error) bool {
|
||||
func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) {
|
||||
db := dao.GetDB()
|
||||
deliveryFeeInfo = &partner.WaybillFeeInfo{}
|
||||
billParams, addParams, err := c.getBillParams(db, order)
|
||||
// billParams, addParams, err := c.getBillParams(db, order)
|
||||
billParams, err := c.getBillParams2(db, order)
|
||||
if err == nil {
|
||||
var result *dadaapi.CreateOrderResponse
|
||||
if result, err = api.DadaAPI.QueryDeliverFee(billParams, addParams); err != nil {
|
||||
// if result, err = api.DadaAPI.QueryDeliverFee(billParams, addParams); err != nil {
|
||||
if result, err = api.DadaAPI.QueryDeliverFee2(billParams); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deliveryFeeInfo.DeliveryFee = jxutils.StandardPrice2Int(result.Fee)
|
||||
@@ -216,9 +214,34 @@ func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInf
|
||||
return deliveryFeeInfo, err
|
||||
}
|
||||
|
||||
func (c *DeliveryHandler) getBillParams(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dadaapi.OperateOrderRequiredParams, addParams map[string]interface{}, err error) {
|
||||
billParams = &dadaapi.OperateOrderRequiredParams{
|
||||
// ShopNo: utils.Int2Str(order.StoreID), // 当前达达的门店号与京西是一样的
|
||||
// func (c *DeliveryHandler) getBillParams(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dadaapi.OperateOrderRequiredParams, addParams map[string]interface{}, err error) {
|
||||
// billParams = &dadaapi.OperateOrderRequiredParams{
|
||||
// // ShopNo: utils.Int2Str(order.StoreID), // 当前达达的门店号与京西是一样的
|
||||
// OriginID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID),
|
||||
// CargoPrice: jxutils.IntPrice2Standard(limitOrderPrice(order.ActualPayPrice)),
|
||||
// IsPrepay: 0,
|
||||
// ReceiverName: utils.FilterMb4(order.ConsigneeName),
|
||||
// ReceiverAddress: utils.FilterMb4(order.ConsigneeAddress),
|
||||
// ReceiverPhone: order.ConsigneeMobile,
|
||||
// }
|
||||
// if billParams.ShopNo, err = c.getDadaShopID(order, db); err == nil {
|
||||
// if billParams.CityCode, err = c.getDataCityCodeFromOrder(order, db); err == nil {
|
||||
// billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
|
||||
// addParams = map[string]interface{}{
|
||||
// "info": fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4(order.BuyerComment)),
|
||||
// // "origin_mark": model.VendorNames[order.VendorID], // 订单来源标示(该字段可以显示在达达app订单详情页面,只支持字母,最大长度为10)
|
||||
// // "origin_mark_no": fmt.Sprintf("%d", order.OrderSeq), // 订单来源编号(该字段可以显示在达达app订单详情页面,支持字母和数字,最大长度为30)
|
||||
// "cargo_type": 13,
|
||||
// "cargo_weight": jxutils.IntWeight2Float(limitOrderWeight(order.Weight)),
|
||||
// "cargo_num": order.GoodsCount,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return billParams, addParams, err
|
||||
// }
|
||||
|
||||
func (c *DeliveryHandler) getBillParams2(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dadaapi.OperateOrderParams, err error) {
|
||||
billParams = &dadaapi.OperateOrderParams{
|
||||
OriginID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID),
|
||||
CargoPrice: jxutils.IntPrice2Standard(limitOrderPrice(order.ActualPayPrice)),
|
||||
IsPrepay: 0,
|
||||
@@ -229,23 +252,20 @@ func (c *DeliveryHandler) getBillParams(db *dao.DaoDB, order *model.GoodsOrder)
|
||||
if billParams.ShopNo, err = c.getDadaShopID(order, db); err == nil {
|
||||
if billParams.CityCode, err = c.getDataCityCodeFromOrder(order, db); err == nil {
|
||||
billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
|
||||
addParams = map[string]interface{}{
|
||||
"info": fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4(order.BuyerComment)),
|
||||
// "origin_mark": model.VendorNames[order.VendorID], // 订单来源标示(该字段可以显示在达达app订单详情页面,只支持字母,最大长度为10)
|
||||
// "origin_mark_no": fmt.Sprintf("%d", order.OrderSeq), // 订单来源编号(该字段可以显示在达达app订单详情页面,支持字母和数字,最大长度为30)
|
||||
"cargo_type": 13,
|
||||
"cargo_weight": jxutils.IntWeight2Float(limitOrderWeight(order.Weight)),
|
||||
"cargo_num": order.GoodsCount,
|
||||
}
|
||||
billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4(order.BuyerComment))
|
||||
billParams.CargoType = dadaapi.CargoTypeFresh
|
||||
billParams.CargoWeight = float64(jxutils.IntWeight2Float(limitOrderWeight(order.Weight)))
|
||||
billParams.CargoNum = order.GoodsCount
|
||||
}
|
||||
}
|
||||
return billParams, addParams, err
|
||||
return billParams, err
|
||||
}
|
||||
|
||||
// IDeliveryPlatformHandler
|
||||
func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) {
|
||||
db := dao.GetDB()
|
||||
billParams, addParams, err := c.getBillParams(db, order)
|
||||
// billParams, addParams, err := c.getBillParams(db, order)
|
||||
billParams, err := c.getBillParams2(db, order)
|
||||
if err == nil {
|
||||
if globals.EnableStoreWrite {
|
||||
// 达达要求第二次创建运单,调用函数不同。所以查找两天内有无相同订单号的运单
|
||||
@@ -265,16 +285,19 @@ func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee
|
||||
if err = delivery.CallCreateWaybillPolicy(waybillList[0].ActualFee, maxDeliveryFee, order, model.VendorIDDada); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err = api.DadaAPI.ReaddOrder(billParams, addParams)
|
||||
// result, err = api.DadaAPI.ReaddOrder(billParams, addParams)
|
||||
result, err = api.DadaAPI.ReaddOrder2(billParams)
|
||||
} else {
|
||||
// 第一次创建
|
||||
if err != nil {
|
||||
globals.SugarLogger.Warnf("CreateWaybill orderID:%s error:%v", order.VendorOrderID, err)
|
||||
}
|
||||
if false {
|
||||
result, err = api.DadaAPI.AddOrder(billParams, addParams)
|
||||
// result, err = api.DadaAPI.AddOrder(billParams, addParams)
|
||||
result, err = api.DadaAPI.AddOrder2(billParams)
|
||||
} else {
|
||||
if result, err = api.DadaAPI.QueryDeliverFee(billParams, addParams); err != nil {
|
||||
// if result, err = api.DadaAPI.QueryDeliverFee(billParams, addParams); err != nil {
|
||||
if result, err = api.DadaAPI.QueryDeliverFee2(billParams); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = delivery.CallCreateWaybillPolicy(jxutils.StandardPrice2Int(result.Fee), maxDeliveryFee, order, model.VendorIDDada); err != nil {
|
||||
@@ -363,3 +386,34 @@ func limitOrderWeight(weight int) int {
|
||||
}
|
||||
return weight
|
||||
}
|
||||
|
||||
func (c *DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) {
|
||||
if globals.EnableStoreWrite {
|
||||
err = api.DadaAPI.ComplaintRider(bill.VendorOrderID, resonID)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *DeliveryHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) {
|
||||
order, err := api.DadaAPI.QueryOrderInfo2(vendorOrderID)
|
||||
if err == nil {
|
||||
tipFee = jxutils.StandardPrice2Int(order.Tips)
|
||||
}
|
||||
return tipFee, err
|
||||
}
|
||||
|
||||
func (c *DeliveryHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) {
|
||||
if globals.EnableStoreWrite {
|
||||
err = api.DadaAPI.AddTip(vendorOrderID, jxutils.IntPrice2Standard(tipFee), cityCode, "")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *DeliveryHandler) GetRidderPosition(ctx *jxcontext.Context, vendorOrgCode, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (lng, lat float64, err error) {
|
||||
order, err := api.DadaAPI.QueryOrderInfo2(vendorOrderID)
|
||||
if err == nil {
|
||||
lng = utils.Str2Float64WithDefault(order.TransporterLng, 0)
|
||||
lat = utils.Str2Float64WithDefault(order.TransporterLat, 0)
|
||||
}
|
||||
return lng, lat, err
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
_ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
"git.rosy.net.cn/jx-callback/globals/testinit"
|
||||
@@ -18,15 +19,14 @@ func TestCreateWaybill(t *testing.T) {
|
||||
orderID := "817540316000041"
|
||||
if order, err := partner.CurOrderManager.LoadOrder(orderID, model.VendorIDJD); err == nil {
|
||||
// globals.SugarLogger.Debug(order)
|
||||
c := new(DeliveryHandler)
|
||||
_, err = c.CreateWaybill(order, nil)
|
||||
_, err = CurDeliveryHandler.CreateWaybill(order, 0)
|
||||
if err == nil {
|
||||
time.Sleep(1 * time.Second)
|
||||
bill := &model.Waybill{
|
||||
VendorOrderID: orderID,
|
||||
WaybillVendorID: model.VendorIDDada,
|
||||
}
|
||||
err = c.CancelWaybill(bill, partner.CancelWaybillReasonOther, "")
|
||||
err = CurDeliveryHandler.CancelWaybill(bill, partner.CancelWaybillReasonOther, "")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
@@ -37,3 +37,11 @@ func TestCreateWaybill(t *testing.T) {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRidderPosition(t *testing.T) {
|
||||
lng, lat, err := CurDeliveryHandler.GetRidderPosition(jxcontext.AdminCtx, "", "80704840263399812", "", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("lng:%f, lat:%f", lng, lat)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"git.rosy.net.cn/baseapi/platformapi/mtpsapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
@@ -173,14 +174,18 @@ func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee
|
||||
item.GoodCount += goodItem.GoodCount
|
||||
}
|
||||
}
|
||||
addParams := map[string]interface{}{
|
||||
"note": utils.FilterMb4(order.BuyerComment),
|
||||
"goods_detail": string(utils.MustMarshal(goods)),
|
||||
"goods_pickup_info": fmt.Sprintf("%s第%d号单", model.VendorChineseNames[order.VendorID], order.OrderSeq),
|
||||
"poi_seq": fmt.Sprintf("#%d", order.OrderSeq),
|
||||
}
|
||||
// addParams := map[string]interface{}{
|
||||
// "note": utils.FilterMb4(order.BuyerComment),
|
||||
// "goods_detail": string(utils.MustMarshal(goods)),
|
||||
// "goods_pickup_info": fmt.Sprintf("%s第%d号单", model.VendorChineseNames[order.VendorID], order.OrderSeq),
|
||||
// "poi_seq": fmt.Sprintf("#%d", order.OrderSeq),
|
||||
// }
|
||||
billParams.Note = utils.FilterMb4(order.BuyerComment)
|
||||
billParams.GoodsDetail = string(utils.MustMarshal(goods))
|
||||
billParams.GoodsPickupInfo = fmt.Sprintf("%s第%d号单", model.VendorChineseNames[order.VendorID], order.OrderSeq)
|
||||
billParams.PoiSeq = fmt.Sprintf("#%d", order.OrderSeq)
|
||||
if globals.EnableStoreWrite {
|
||||
result, err2 := api.MtpsAPI.CreateOrderByShop(billParams, addParams)
|
||||
result, err2 := api.MtpsAPI.CreateOrderByShop2(billParams)
|
||||
if err = err2; err == nil {
|
||||
bill = &model.Waybill{
|
||||
VendorOrderID: order.VendorOrderID,
|
||||
@@ -192,7 +197,7 @@ func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee
|
||||
}
|
||||
delivery.OnWaybillCreated(bill)
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("CreateWaybill failed, orderID:%s, billParams:%v, addParams:%v, error:%v", order.VendorOrderID, billParams, addParams, err)
|
||||
globals.SugarLogger.Debugf("CreateWaybill failed, orderID:%s, billParams:%v, error:%v", order.VendorOrderID, billParams, err)
|
||||
}
|
||||
} else {
|
||||
err = fmt.Errorf("测试环境不能真正创建运单")
|
||||
@@ -246,3 +251,19 @@ func limitOrderWeight(weight int) int {
|
||||
}
|
||||
return weight
|
||||
}
|
||||
|
||||
func (c *DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) {
|
||||
if globals.EnableStoreWrite {
|
||||
err = api.MtpsAPI.EvaluateRider(utils.Str2Int64(bill.VendorWaybillID2), bill.VendorWaybillID, 1, resonContent)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *DeliveryHandler) GetRidderPosition(ctx *jxcontext.Context, vendorOrgCode, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (lng, lat float64, err error) {
|
||||
intLng, intLat, err := api.MtpsAPI.RiderLocation(utils.Str2Int64(vendorWaybillID2), vendorWaybillID)
|
||||
if err == nil {
|
||||
lng = jxutils.IntCoordinate2Standard(intLng)
|
||||
lat = jxutils.IntCoordinate2Standard(intLat)
|
||||
}
|
||||
return lng, lat, err
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ type IOrderManager interface {
|
||||
SaveOrderFinancialInfo(order *model.OrderFinancial, operation string) (err error)
|
||||
SaveAfsOrderFinancialInfo(afsOrder *model.AfsOrder) (err error)
|
||||
|
||||
GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded bool) (bills []*model.Waybill, err error)
|
||||
GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded, isGetPos bool) (bills []*model.WaybillExt, err error)
|
||||
|
||||
// afs order
|
||||
OnAfsOrderAdjust(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error)
|
||||
@@ -156,10 +156,10 @@ type IMultipleStoresHandler interface {
|
||||
IPurchasePlatformHandler
|
||||
GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*BareCategoryInfo, err error)
|
||||
|
||||
CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error)
|
||||
UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error
|
||||
DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error
|
||||
ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error)
|
||||
// CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error)
|
||||
// UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error
|
||||
// DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error
|
||||
// ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error)
|
||||
|
||||
CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error)
|
||||
UpdateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error)
|
||||
@@ -167,9 +167,9 @@ type IMultipleStoresHandler interface {
|
||||
ReorderCategories2(ctx *jxcontext.Context, vendorOrgCode, vendorParentCatID string, vendorCatIDList []string) (err error)
|
||||
|
||||
// sku
|
||||
CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error)
|
||||
UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error)
|
||||
DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error)
|
||||
// CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error)
|
||||
// UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error)
|
||||
// DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error)
|
||||
|
||||
// ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error)
|
||||
CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error)
|
||||
@@ -277,3 +277,23 @@ func IsMultiStore(vendorID int) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func GetRidderPositionGetter(vendorID int) (handler IRidderPositionGetter) {
|
||||
if handlerInfo := GetDeliveryPlatformFromVendorID(vendorID); handlerInfo != nil {
|
||||
if handler, _ = handlerInfo.Handler.(IRidderPositionGetter); handler != nil {
|
||||
return handler
|
||||
}
|
||||
}
|
||||
handler, _ = GetPurchasePlatformFromVendorID(vendorID).(IRidderPositionGetter)
|
||||
return handler
|
||||
}
|
||||
|
||||
func GetWaybillTipUpdater(vendorID int) (handler IAddWaybillTip) {
|
||||
if handlerInfo := GetDeliveryPlatformFromVendorID(vendorID); handlerInfo != nil {
|
||||
if handler, _ = handlerInfo.Handler.(IAddWaybillTip); handler != nil {
|
||||
return handler
|
||||
}
|
||||
}
|
||||
handler, _ = GetPurchasePlatformFromVendorID(vendorID).(IAddWaybillTip)
|
||||
return handler
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ type IDeliveryPlatformHandler interface {
|
||||
CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error)
|
||||
CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error)
|
||||
GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *WaybillFeeInfo, err error)
|
||||
//投诉骑手
|
||||
ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error)
|
||||
}
|
||||
|
||||
type IDeliveryUpdateStoreHandler interface {
|
||||
|
||||
@@ -13,6 +13,7 @@ type OrderPhoneNumberInfo struct {
|
||||
type IPurchasePlatformOrderHandler interface {
|
||||
Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder)
|
||||
GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error)
|
||||
GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error)
|
||||
GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *StatusActionParams)
|
||||
|
||||
AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error)
|
||||
@@ -57,6 +58,10 @@ type IPurchasePlatformOrderHandler interface {
|
||||
}
|
||||
|
||||
type IAddWaybillTip interface {
|
||||
GetWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder) (tipFee int64, err error)
|
||||
AddWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee2Add int64) (err error)
|
||||
GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error)
|
||||
UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error)
|
||||
}
|
||||
|
||||
type IRidderPositionGetter interface {
|
||||
GetRidderPosition(ctx *jxcontext.Context, vendorOrgCode, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (lng, lat float64, err error)
|
||||
}
|
||||
|
||||
51
business/partner/pay/pay.go
Normal file
51
business/partner/pay/pay.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package pay
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||
)
|
||||
|
||||
type PayOpStatus int
|
||||
|
||||
const (
|
||||
OpStatusFailed PayOpStatus = 0
|
||||
OpStatusSuccessed PayOpStatus = 1
|
||||
)
|
||||
|
||||
type CreatePayParam struct {
|
||||
PayOrderID string
|
||||
VendorPayType string
|
||||
|
||||
VendorOrderID string
|
||||
ProductDesc string
|
||||
ProductDetail string
|
||||
FeeType string
|
||||
TotalFee int
|
||||
TimeStart time.Time
|
||||
TimeExpire time.Time
|
||||
|
||||
UserData string
|
||||
}
|
||||
|
||||
type PayOpResult struct {
|
||||
Status PayOpStatus
|
||||
VendorStatus string
|
||||
ErrMsg string
|
||||
|
||||
ID string
|
||||
VendorID string
|
||||
|
||||
OriginalData string
|
||||
}
|
||||
|
||||
type ResponseHandler interface {
|
||||
OnCreatePay(vendorID int, result *PayOpResult) (err error)
|
||||
OnRefundPay(vendorID int, result *PayOpResult) (err error)
|
||||
}
|
||||
|
||||
type IPayPlatformHandler interface {
|
||||
CreatePay(ctx *jxcontext.Context, param *CreatePayParam, isOffline bool) (prepayID, qrCodeURL string, err error)
|
||||
ClosePay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID string) (err error)
|
||||
RefundPay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID, refundID, reason string, totalFee, refundFee int) (vendorRefundID string, err error)
|
||||
}
|
||||
60
business/partner/pay/wxpay/callback.go
Normal file
60
business/partner/pay/wxpay/callback.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package wxpay
|
||||
|
||||
import (
|
||||
"git.rosy.net.cn/baseapi/platformapi/wxpayapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/pay"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
)
|
||||
|
||||
func OnCallback(msg *wxpayapi.CallbackMsg) (err error) {
|
||||
globals.SugarLogger.Debugf("wxpay OnCallback msg:%s", utils.Format4Output(msg, true))
|
||||
switch msg.MsgType {
|
||||
case wxpayapi.MsgTypePay:
|
||||
err = onWxpayFinished(msg.Data.(*wxpayapi.PayResultMsg))
|
||||
case wxpayapi.MsgTypeRefund:
|
||||
err = onWxpayRefund(msg.Data.(*wxpayapi.RefundResultMsg))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func onWxpayFinished(msg *wxpayapi.PayResultMsg) (err error) {
|
||||
opResult := &pay.PayOpResult{
|
||||
OriginalData: string(utils.MustMarshal(msg)),
|
||||
}
|
||||
if msg.ReturnCode == wxpayapi.ResponseCodeSuccess {
|
||||
opResult.Status = pay.OpStatusSuccessed
|
||||
opResult.ID = msg.OutTradeNo
|
||||
if msg.ResultCode == wxpayapi.ResponseCodeSuccess {
|
||||
opResult.VendorID = msg.TransactionID
|
||||
} else {
|
||||
opResult.VendorStatus = msg.ErrCode
|
||||
opResult.ErrMsg = msg.ErrCodeDes
|
||||
}
|
||||
} else {
|
||||
opResult.Status = pay.OpStatusFailed
|
||||
}
|
||||
err = payHandler.responseHandler.OnCreatePay(model.VendorIDWXPay, opResult)
|
||||
return err
|
||||
}
|
||||
|
||||
func onWxpayRefund(msg *wxpayapi.RefundResultMsg) (err error) {
|
||||
opResult := &pay.PayOpResult{
|
||||
OriginalData: string(utils.MustMarshal(msg)),
|
||||
}
|
||||
if msg.ReturnCode == wxpayapi.ResponseCodeSuccess {
|
||||
opResult.Status = pay.OpStatusSuccessed
|
||||
if msg.ResultCode == wxpayapi.ResponseCodeSuccess {
|
||||
opResult.ID = msg.ReqInfoObj.OutRefundNo
|
||||
opResult.VendorID = msg.ReqInfoObj.RefundID
|
||||
} else {
|
||||
opResult.VendorStatus = msg.ErrCode
|
||||
opResult.ErrMsg = msg.ErrCodeDes
|
||||
}
|
||||
} else {
|
||||
opResult.Status = pay.OpStatusFailed
|
||||
}
|
||||
err = payHandler.responseHandler.OnRefundPay(model.VendorIDWXPay, opResult)
|
||||
return err
|
||||
}
|
||||
73
business/partner/pay/wxpay/wxpay.go
Normal file
73
business/partner/pay/wxpay/wxpay.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package wxpay
|
||||
|
||||
import (
|
||||
"git.rosy.net.cn/baseapi/platformapi/wxpayapi"
|
||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/pay"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"git.rosy.net.cn/jx-callback/globals/api"
|
||||
)
|
||||
|
||||
type PayHandler struct {
|
||||
responseHandler pay.ResponseHandler
|
||||
}
|
||||
|
||||
var (
|
||||
payHandler *PayHandler
|
||||
)
|
||||
|
||||
func New(responseHandler pay.ResponseHandler) (handler *PayHandler) {
|
||||
return &PayHandler{
|
||||
responseHandler: responseHandler,
|
||||
}
|
||||
}
|
||||
|
||||
func vendorPayType2WxpayType(vendorPayType string) string {
|
||||
return vendorPayType
|
||||
}
|
||||
|
||||
func (p *PayHandler) CreatePay(ctx *jxcontext.Context, createParam *pay.CreatePayParam, isOffline bool) (prepayID, qrCodeURL string, err error) {
|
||||
param := &wxpayapi.CreateOrderParam{
|
||||
OutTradeNo: createParam.PayOrderID,
|
||||
Body: createParam.ProductDesc,
|
||||
NotifyURL: globals.WxpayNotifyURL,
|
||||
SpbillCreateIP: ctx.GetRealRemoteIP(),
|
||||
TradeType: vendorPayType2WxpayType(createParam.VendorPayType),
|
||||
TotalFee: createParam.TotalFee,
|
||||
|
||||
TimeStart: wxpayapi.Time2PayTime(createParam.TimeStart),
|
||||
TimeExpire: wxpayapi.Time2PayTime(createParam.TimeExpire),
|
||||
}
|
||||
if isOffline {
|
||||
param.TradeType = wxpayapi.TradeTypeNative
|
||||
}
|
||||
if authInfo, err := ctx.GetV2AuthInfo(); err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini {
|
||||
param.OpenID = authInfo.GetAuthID()
|
||||
}
|
||||
if result, err := api.WxpayAPI.CreateUnifiedOrder(param); err == nil {
|
||||
prepayID = result.PrepayID
|
||||
qrCodeURL = result.CodeURL
|
||||
}
|
||||
return prepayID, qrCodeURL, err
|
||||
}
|
||||
|
||||
func (p *PayHandler) ClosePay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID string) (err error) {
|
||||
return api.WxpayAPI.CloseOrder(payOrderID)
|
||||
}
|
||||
|
||||
func (p *PayHandler) RefundPay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID, refundID, reason string, totalFee, refundFee int) (vendorRefundID string, err error) {
|
||||
param := &wxpayapi.PayRefundParam{
|
||||
OutTradeNo: payOrderID,
|
||||
NotifyURL: globals.WxpayNotifyURL,
|
||||
OutRefundNo: refundID,
|
||||
TotalFee: totalFee,
|
||||
RefundFee: refundFee,
|
||||
RefundDesc: wxpayapi.CData(reason),
|
||||
}
|
||||
retVal, err := api.WxpayAPI.PayRefund(param)
|
||||
if err == nil {
|
||||
vendorRefundID = retVal.RefundID
|
||||
}
|
||||
return vendorRefundID, err
|
||||
}
|
||||
@@ -57,11 +57,11 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
||||
<B>%s</B><BR>
|
||||
<BR>
|
||||
|
||||
<BOLD>实际支付:</BOLD>%s<BR>
|
||||
<BR>
|
||||
商品明细: <BR>
|
||||
品名 数量 单价 小计<BR>
|
||||
--------------------------------<BR>`
|
||||
// <BOLD>实际支付:</BOLD>%s<BR>
|
||||
orderParams := []interface{}{
|
||||
globals.StoreName,
|
||||
utils.Time2Str(order.OrderCreatedAt),
|
||||
@@ -74,7 +74,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
||||
order.ConsigneeMobile,
|
||||
order.ConsigneeAddress,
|
||||
order.BuyerComment,
|
||||
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
// jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
}
|
||||
|
||||
for _, sku := range order.Skus {
|
||||
@@ -131,11 +131,11 @@ func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel st
|
||||
<B>%s</B><BR>
|
||||
<BR>
|
||||
|
||||
<B><BOLD>实际支付:</BOLD></B><B>%s<BR></B>
|
||||
<BR>
|
||||
<B>商品明细: <BR></B>
|
||||
<B>品名数量单价小计<BR></B>
|
||||
--------------------------------<BR>`
|
||||
// <B><BOLD>实际支付:</BOLD></B><B>%s<BR></B>
|
||||
orderParams := []interface{}{
|
||||
globals.StoreName,
|
||||
utils.Time2Str(order.OrderCreatedAt),
|
||||
@@ -148,7 +148,7 @@ func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel st
|
||||
order.ConsigneeMobile,
|
||||
order.ConsigneeAddress,
|
||||
order.BuyerComment,
|
||||
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
// jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
}
|
||||
|
||||
for _, sku := range order.Skus {
|
||||
|
||||
@@ -59,11 +59,11 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
||||
*
|
||||
客户备注: *
|
||||
<big>%s*
|
||||
<S011>实际支付: %s*
|
||||
商品明细: *
|
||||
品名 数量 单价 小计
|
||||
--------------------------------*
|
||||
`
|
||||
// <S011>实际支付: %s*
|
||||
orderParams := []interface{}{
|
||||
globals.StoreName,
|
||||
utils.Time2Str(order.OrderCreatedAt),
|
||||
@@ -76,7 +76,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
||||
order.ConsigneeMobile,
|
||||
order.ConsigneeAddress,
|
||||
buyerComment,
|
||||
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
// jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
}
|
||||
for _, sku := range order.Skus {
|
||||
orderFmt += `%s*`
|
||||
@@ -128,17 +128,17 @@ func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel st
|
||||
<big>%s\#%d*
|
||||
<qrcA4>%s*
|
||||
` + getCode +
|
||||
`<big>客户: %s*
|
||||
`<big>客户: %s*
|
||||
<big>电话: %s*
|
||||
<big>地址: %s*
|
||||
*
|
||||
<big>客户备注: *
|
||||
<big>%s*
|
||||
<big>实际支付: %s*
|
||||
<big>商品明细: *
|
||||
<big>品名数量单价小计*
|
||||
--------------------------------*
|
||||
`
|
||||
// <big>实际支付: %s*
|
||||
orderParams := []interface{}{
|
||||
globals.StoreName,
|
||||
utils.Time2Str(order.OrderCreatedAt),
|
||||
@@ -151,7 +151,7 @@ func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel st
|
||||
order.ConsigneeMobile,
|
||||
order.ConsigneeAddress,
|
||||
buyerComment,
|
||||
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
// jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
}
|
||||
for _, sku := range order.Skus {
|
||||
orderFmt += `<big>%s*`
|
||||
@@ -209,12 +209,12 @@ func (c *PrinterHandler) getOrderContent2(order *model.GoodsOrder, storeTel stri
|
||||
|5客户备注:
|
||||
|7%s
|
||||
|5
|
||||
|6实际支付: %s
|
||||
|5
|
||||
|5商品明细:
|
||||
|5品名 数量 单价 小计
|
||||
|5--------------------------------
|
||||
`
|
||||
// |6实际支付: %s
|
||||
orderParams := []interface{}{
|
||||
globals.StoreName,
|
||||
utils.Time2Str(order.OrderCreatedAt),
|
||||
@@ -227,7 +227,7 @@ func (c *PrinterHandler) getOrderContent2(order *model.GoodsOrder, storeTel stri
|
||||
order.ConsigneeMobile,
|
||||
order.ConsigneeAddress,
|
||||
buyerComment,
|
||||
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
// jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
}
|
||||
for _, sku := range order.Skus {
|
||||
orderFmt += `|5%s`
|
||||
|
||||
@@ -55,11 +55,11 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
||||
客户备注: \n
|
||||
<FS2>%s</FS2>\n
|
||||
\n
|
||||
<FB>实际支付:</FB>%s\n
|
||||
\n
|
||||
商品明细: \n
|
||||
品名 数量 单价 小计\n
|
||||
--------------------------------\n`
|
||||
// <FB>实际支付:</FB>%s\n
|
||||
orderParams := []interface{}{
|
||||
globals.StoreName,
|
||||
utils.Time2Str(order.OrderCreatedAt),
|
||||
@@ -72,7 +72,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
||||
order.ConsigneeMobile,
|
||||
order.ConsigneeAddress,
|
||||
order.BuyerComment,
|
||||
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
// jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
}
|
||||
|
||||
for _, sku := range order.Skus {
|
||||
@@ -123,11 +123,11 @@ func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel st
|
||||
<FS2>客户备注: \n</FS2>
|
||||
<FS2>%s</FS2>\n
|
||||
\n
|
||||
<FS2><FB>实际支付:</FB>%s\n</FS2>
|
||||
\n
|
||||
<FS2>商品明细: \n</FS2>
|
||||
<FS2>品名数量单价小计\n</FS2>
|
||||
--------------------------------\n`
|
||||
// <FS2><FB>实际支付:</FB>%s\n</FS2>
|
||||
orderParams := []interface{}{
|
||||
globals.StoreName,
|
||||
utils.Time2Str(order.OrderCreatedAt),
|
||||
@@ -140,7 +140,7 @@ func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel st
|
||||
order.ConsigneeMobile,
|
||||
order.ConsigneeAddress,
|
||||
order.BuyerComment,
|
||||
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
// jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
}
|
||||
|
||||
for _, sku := range order.Skus {
|
||||
|
||||
@@ -56,11 +56,11 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
||||
客户备注: <RN>
|
||||
<S2>%s</S2><RN>
|
||||
<RN>
|
||||
<B1>实际支付:</B1>%s<RN>
|
||||
<RN>
|
||||
商品明细: <RN>
|
||||
品名 数量 单价 小计<RN>
|
||||
********************************<RN>`
|
||||
// <B1>实际支付:</B1>%s<RN>
|
||||
orderParams := []interface{}{
|
||||
globals.StoreName,
|
||||
utils.Time2Str(order.OrderCreatedAt),
|
||||
@@ -73,7 +73,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
||||
order.ConsigneeMobile,
|
||||
order.ConsigneeAddress,
|
||||
order.BuyerComment,
|
||||
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
// jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
}
|
||||
|
||||
for _, sku := range order.Skus {
|
||||
@@ -124,11 +124,11 @@ func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel st
|
||||
<S2>客户备注: <RN></S2>
|
||||
<S2>%s</S2><RN>
|
||||
<RN>
|
||||
<S2><B1>实际支付:</B1>%s<RN></S2>
|
||||
<RN>
|
||||
<S2>商品明细: <RN></S2>
|
||||
<S2>品名数量单价小计<RN></S2>
|
||||
********************************<RN>`
|
||||
// <S2><B1>实际支付:</B1>%s<RN></S2>
|
||||
orderParams := []interface{}{
|
||||
globals.StoreName,
|
||||
utils.Time2Str(order.OrderCreatedAt),
|
||||
@@ -141,7 +141,7 @@ func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel st
|
||||
order.ConsigneeMobile,
|
||||
order.ConsigneeAddress,
|
||||
order.BuyerComment,
|
||||
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
// jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||
}
|
||||
|
||||
for _, sku := range order.Skus {
|
||||
|
||||
@@ -5,9 +5,11 @@ 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/globals"
|
||||
)
|
||||
|
||||
func OnCallbackMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) {
|
||||
globals.SugarLogger.Debugf("ebai OnCallbackMsg msg:%s", utils.Format4Output(msg, true))
|
||||
if CurPurchaseHandler != nil {
|
||||
if orderID := GetOrderIDFromMsg(msg); orderID != "" {
|
||||
jxutils.CallMsgHandler(func() {
|
||||
|
||||
@@ -28,8 +28,6 @@ const (
|
||||
callDeliveryDelay = 10 * time.Minute
|
||||
callDeliveryDelayGap = 30
|
||||
|
||||
fakeUserApplyCancel = "fake_user_apply_cancel"
|
||||
fakeUserUndoApplyCancel = "fake_user_undo_apply_cancel"
|
||||
fakeAcceptOrder = "fake_accept_order"
|
||||
fakeOrderAdjustFinished = "fake_order_adjust_finished"
|
||||
fakeOrderCanceled = "fake_order_canceled"
|
||||
@@ -49,8 +47,6 @@ var (
|
||||
ebaiapi.OrderStatusCanceled: model.OrderStatusCanceled,
|
||||
|
||||
fakeOrderAdjustFinished: model.OrderStatusAdjust,
|
||||
fakeUserApplyCancel: model.OrderStatusApplyCancel,
|
||||
fakeUserUndoApplyCancel: model.OrderStatusUndoApplyCancel,
|
||||
fakeOrderCanceled: model.OrderStatusCanceled,
|
||||
}
|
||||
|
||||
@@ -83,6 +79,14 @@ func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *
|
||||
return order, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) {
|
||||
status, err = api.EbaiAPI.OrderStatusGet(vendorOrderID)
|
||||
if err == nil {
|
||||
status = p.getStatusFromVendorStatus(utils.Int2Str(status))
|
||||
}
|
||||
return status, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) getOrder(vendorOrderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) {
|
||||
result, err := api.EbaiAPI.OrderGet(vendorOrderID)
|
||||
if err == nil {
|
||||
@@ -202,6 +206,7 @@ func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
||||
OrderCreatedAt: getTimeFromInterface(orderMap["create_time"]),
|
||||
OriginalData: string(utils.MustMarshal(result)),
|
||||
ActualPayPrice: utils.ForceInterface2Int64(orderMap["user_fee"]),
|
||||
BaseFreightMoney: utils.ForceInterface2Int64(orderMap["send_fee"]),
|
||||
TotalShopMoney: utils.ForceInterface2Int64(orderMap["shop_fee"]),
|
||||
DeliveryType: mapDeliveryType(int(utils.ForceInterface2Int64(orderMap["delivery_party"]))),
|
||||
|
||||
@@ -404,7 +409,7 @@ func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName
|
||||
//
|
||||
func (c *PurchaseHandler) onOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) {
|
||||
if c.isAfsMsg(msg) {
|
||||
retVal = c.OnAfsOrderMsg(msg)
|
||||
retVal = c.onAfsOrderMsg(msg)
|
||||
} else {
|
||||
status := c.callbackMsg2Status(msg)
|
||||
if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 {
|
||||
@@ -424,7 +429,7 @@ func (c *PurchaseHandler) onOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.
|
||||
// 处理饿百降级订单的情况
|
||||
// 是否降级;1:是,0:否;极少数订单因网络或信息交互异常,导致订单部分字段(如订单金额)生成延迟,此时订单会被标记为“已降级”状态,需开发者重新调用查看订单详情接口获取完整订单数据。
|
||||
// toto sku是否也需要处理?
|
||||
if status.Status == model.OrderStatusFinished {
|
||||
if status.Status == model.OrderStatusDelivering || status.Status == model.OrderStatusFinished {
|
||||
if order, err2 := partner.CurOrderManager.LoadOrder(status.VendorOrderID, status.VendorID); err2 == nil {
|
||||
if order.TotalShopMoney == 0 {
|
||||
if order2, err2 := c.GetOrder(msg.Source, status.VendorOrderID); err2 == nil {
|
||||
@@ -478,11 +483,15 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *ebaiapi.CallbackMsg) (orderSta
|
||||
if cancelType == ebaiapi.OrderUserCancelTypeBeforeSale {
|
||||
if msgType == ebaiapi.OrderUserCancelApply ||
|
||||
msgType == ebaiapi.OrderUserCancelCSIntervene {
|
||||
orderStatus.VendorStatus = fakeUserApplyCancel
|
||||
} else if msgType == ebaiapi.OrderUserCancelInvalid ||
|
||||
msgType == ebaiapi.OrderUserCancelMerchantRefused ||
|
||||
msgType == ebaiapi.OrderUserCancelCSRefused {
|
||||
orderStatus.VendorStatus = fakeUserUndoApplyCancel
|
||||
orderStatus.Status = model.OrderStatusApplyCancel
|
||||
} else if msgType == ebaiapi.OrderUserCancelCSRefused ||
|
||||
msgType == ebaiapi.OrderUserCancelMerchantRefused {
|
||||
orderStatus.Status = model.OrderStatusVendorRejectCancel
|
||||
} else if msgType == ebaiapi.OrderUserCancelInvalid {
|
||||
orderStatus.Status = model.OrderStatusUndoApplyCancel
|
||||
} else if msgType == ebaiapi.OrderUserCancelCSAgreed ||
|
||||
msgType == ebaiapi.OrderUserCancelMerchantAgreed {
|
||||
orderStatus.Status = model.OrderStatusVendorAgreeCancel
|
||||
}
|
||||
}
|
||||
} else if msg.Cmd == ebaiapi.CmdOrderPartRefund {
|
||||
@@ -500,7 +509,9 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *ebaiapi.CallbackMsg) (orderSta
|
||||
}
|
||||
orderStatus.Remark = utils.Interface2String(msg.Body["reason"])
|
||||
}
|
||||
orderStatus.Status = c.getStatusFromVendorStatus(orderStatus.VendorStatus)
|
||||
if orderStatus.Status == 0 {
|
||||
orderStatus.Status = c.getStatusFromVendorStatus(orderStatus.VendorStatus)
|
||||
}
|
||||
return orderStatus
|
||||
}
|
||||
|
||||
@@ -649,3 +660,20 @@ func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode strin
|
||||
}
|
||||
return vendorOrderIDs, err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) {
|
||||
orderInfo, err := api.EbaiAPI.GetStoreOrderInfo(vendorOrderID)
|
||||
if err == nil {
|
||||
if orderBasic, _ := orderInfo["order_basic"].(map[string]interface{}); orderBasic != nil {
|
||||
tipFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(orderBasic["delivery_tip_amount"], 0))
|
||||
}
|
||||
}
|
||||
return tipFee, err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) {
|
||||
if globals.EnableEbaiStoreWrite {
|
||||
err = api.EbaiAPI.ModifyTip4OrderWaybill(vendorOrderID, "", jxutils.IntPrice2Standard(tipFee), 0)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaia
|
||||
afsOrder.Skus = append(afsOrder.Skus, orderSku)
|
||||
}
|
||||
} else if msg.Cmd == ebaiapi.CmdOrderUserCancel {
|
||||
if afsOrder := c.createAfsOrder(msg); afsOrder != nil {
|
||||
if afsOrder = c.createAfsOrder(msg); afsOrder != nil {
|
||||
// if orderFinancial, err2 := partner.CurOrderManager.LoadOrderFinancial(orderStatus.RefVendorOrderID, model.VendorIDEBAI); err2 == nil {
|
||||
// afsOrder = c.OrderFinancialDetail2Refund(orderFinancial, msg)
|
||||
cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo)
|
||||
|
||||
@@ -30,9 +30,10 @@ type tEbaiStoreInfo struct {
|
||||
EbaiStoreStatus int
|
||||
SyncStatus int
|
||||
|
||||
ProvinceID int `orm:"column(province_id)"`
|
||||
CityID int `orm:"column(city_id)"`
|
||||
DistrictID int `orm:"column(district_id)"`
|
||||
ProvinceID int `orm:"column(province_id)"`
|
||||
CityID int `orm:"column(city_id)"`
|
||||
DistrictID int `orm:"column(district_id)"`
|
||||
VendorStoreName string
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) CreateStore(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) {
|
||||
@@ -156,7 +157,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
||||
SELECT
|
||||
t1.*,
|
||||
t2.status ebai_store_status, t2.vendor_store_id, t2.vendor_org_code,
|
||||
IF(t1.updated_at > t2.updated_at, t1.last_operator, t2.last_operator) real_last_operator, t2.sync_status
|
||||
IF(t1.updated_at > t2.updated_at, t1.last_operator, t2.last_operator) real_last_operator, t2.sync_status, t2.vendor_store_name
|
||||
FROM store t1
|
||||
JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND (t2.deleted_at = ?)
|
||||
WHERE t1.id = ?
|
||||
@@ -193,6 +194,9 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
||||
}
|
||||
params := genStoreMapFromStore(store)
|
||||
if err = api.EbaiAPI.ShopUpdate(params); err == nil {
|
||||
if store.PromoteInfo != "" {
|
||||
err = api.EbaiAPI.ShopAnnouncementSet("", utils.Str2Int64(store.VendorStoreID), store.PromoteInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,8 +393,12 @@ func genStoreMapFromStore(store *tEbaiStoreInfo) map[string]interface{} {
|
||||
if store.VendorStoreID != "" {
|
||||
params["baidu_shop_id"] = store.VendorStoreID
|
||||
}
|
||||
if store.SyncStatus&(model.SyncFlagNewMask /*|model.SyncFlagStoreName*/) != 0 {
|
||||
params["name"] = jxutils.ComposeStoreName(store.Name, model.VendorIDEBAI)
|
||||
if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 {
|
||||
if store.VendorStoreName != "" {
|
||||
params["name"] = store.VendorStoreName
|
||||
} else {
|
||||
params["name"] = jxutils.ComposeStoreName(store.Name, model.VendorIDEBAI)
|
||||
}
|
||||
}
|
||||
params["address"] = store.Address
|
||||
// todo 饿百 开店审核通过后不允许修改商户信息
|
||||
|
||||
@@ -113,7 +113,7 @@ func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
|
||||
return ebaiapi.IsErrSkuNotExist(err)
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||
func (p *PurchaseHandler) updateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isNeedMapCat bool) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||
storeSku := storeSkuList[0]
|
||||
strStoreID := utils.Int2Str(storeID)
|
||||
params := genSkuParamsFromStoreSkuInfo2(storeSku, false)
|
||||
@@ -122,13 +122,19 @@ func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, v
|
||||
if err != nil {
|
||||
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDEBAI, "更新商品基础信息")
|
||||
}
|
||||
utils.CallFuncAsync(func() {
|
||||
api.EbaiAPI.SkuShopCategoryMap(strStoreID, utils.Str2Int64(storeSku.VendorSkuID), "", utils.Str2Int64(storeSku.VendorCatID), genSkuCatRank(storeSku))
|
||||
})
|
||||
if isNeedMapCat {
|
||||
utils.CallFuncAsync(func() {
|
||||
api.EbaiAPI.SkuShopCategoryMap(strStoreID, utils.Str2Int64(storeSku.VendorSkuID), "", utils.Str2Int64(storeSku.VendorCatID), genSkuCatRank(storeSku))
|
||||
})
|
||||
}
|
||||
}
|
||||
return failedList, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||
return p.updateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true)
|
||||
}
|
||||
|
||||
// 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义
|
||||
func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||
storeSku := storeSkuList[0]
|
||||
@@ -139,6 +145,9 @@ func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, v
|
||||
if vendorSkuID, err = api.EbaiAPI.SkuCreate(ctx.GetTrackInfo(), strStoreID, storeSku.SkuID, params); err == nil {
|
||||
utils.AfterFuncWithRecover(5*time.Second, func() {
|
||||
api.EbaiAPI.SkuShopCategoryMap(strStoreID, vendorSkuID, "", utils.Str2Int64(storeSku.VendorCatID), genSkuCatRank(storeSku))
|
||||
// 饿百平台有BUG,会导致新建一个之前删除的商品时,信息不会及时更新,强制刷新一下
|
||||
// 比如门店:100887, skuID:33805,订单:1577176719141226065
|
||||
p.updateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false)
|
||||
})
|
||||
} else {
|
||||
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDEBAI, "创建商品")
|
||||
@@ -321,7 +330,7 @@ func jxCatSeq2Ebai(seq int) int {
|
||||
}
|
||||
|
||||
func formatCatName(name string) string {
|
||||
return name
|
||||
return utils.LimitUTF8StringLen(name, ebaiapi.MaxCategoryNameLen)
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) {
|
||||
|
||||
@@ -120,7 +120,7 @@ func (c *PurchaseHandler) onOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancel
|
||||
default:
|
||||
status.Status = model.OrderStatusUnknown
|
||||
}
|
||||
return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnOrderStatusChanged(status), status.VendorStatus)
|
||||
return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnOrderStatusChanged("", status), status.VendorStatus)
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) {
|
||||
@@ -223,7 +223,7 @@ func (c *PurchaseHandler) onOrderUserUrgeOrder(msg *elmapi.CallbackOrderUrgeMsg)
|
||||
StatusTime: utils.Timestamp2Time(msg.UpdateTime),
|
||||
}
|
||||
c.ClientUrgeOrder(msg.OrderID)
|
||||
return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnOrderStatusChanged(status), status.VendorStatus)
|
||||
return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnOrderStatusChanged("", status), status.VendorStatus)
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) stateAndType2Str(state string, msgType int) string {
|
||||
|
||||
@@ -325,7 +325,7 @@ func (c *PurchaseHandler) onActMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.C
|
||||
if _, ok := actMap.Load(intPromotionID); !ok {
|
||||
utils.CallFuncAsync(func() {
|
||||
if !partner.CurActManager.IsVendorActExist(jxcontext.AdminCtx, promotionID, model.VendorIDJD) {
|
||||
act, actStoreSkuList, err := getActFromJD(appKey2OrgCode(msg.AppKey), promotionID)
|
||||
act, actStoreSkuList, err := getActFromJD(AppKey2OrgCode(msg.AppKey), promotionID)
|
||||
if err == nil && len(actStoreSkuList) > 0 {
|
||||
_, err = partner.CurActManager.CreateActFromVendor(jxcontext.AdminCtx, act, actStoreSkuList)
|
||||
}
|
||||
|
||||
@@ -6,21 +6,21 @@ import (
|
||||
|
||||
func OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||
if CurPurchaseHandler != nil {
|
||||
retVal = CurPurchaseHandler.OnOrderMsg(appKey2OrgCode(msg.AppKey), msg)
|
||||
retVal = CurPurchaseHandler.OnOrderMsg(AppKey2OrgCode(msg.AppKey), msg)
|
||||
}
|
||||
return retVal
|
||||
}
|
||||
|
||||
func OnWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) {
|
||||
if CurPurchaseHandler != nil {
|
||||
retVal = CurPurchaseHandler.OnWaybillMsg(appKey2OrgCode(msg.AppKey), msg)
|
||||
retVal = CurPurchaseHandler.OnWaybillMsg(AppKey2OrgCode(msg.AppKey), msg)
|
||||
}
|
||||
return retVal
|
||||
}
|
||||
|
||||
func OnStoreMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||
if CurPurchaseHandler != nil {
|
||||
retVal = CurPurchaseHandler.OnStoreMsg(appKey2OrgCode(msg.AppKey), msg)
|
||||
retVal = CurPurchaseHandler.OnStoreMsg(AppKey2OrgCode(msg.AppKey), msg)
|
||||
}
|
||||
return retVal
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ func (p *PurchaseHandler) OnFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *j
|
||||
// 京东正向/退款订单类型处理--存储
|
||||
func (p *PurchaseHandler) onFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||
var err error
|
||||
a := GetAPIByAppKey(msg.AppKey)
|
||||
a := getAPI(AppKey2OrgCode(msg.AppKey))
|
||||
// if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单
|
||||
if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusAdjustSettle || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单
|
||||
order, err2 := partner.CurOrderManager.LoadOrder(msg.BillID, model.VendorIDJD)
|
||||
|
||||
@@ -23,6 +23,9 @@ func init() {
|
||||
}
|
||||
|
||||
func getAPI(appOrgCode string) (apiObj *jdapi.API) {
|
||||
if appOrgCode == "" {
|
||||
globals.SugarLogger.Warnf("getAPI appOrgCode is empty")
|
||||
}
|
||||
return partner.CurAPIManager.GetAPI(model.VendorIDJD, appOrgCode).(*jdapi.API)
|
||||
}
|
||||
|
||||
@@ -30,7 +33,7 @@ func GetAPI(appOrgCode string) (apiObj *jdapi.API) {
|
||||
return getAPI(appOrgCode)
|
||||
}
|
||||
|
||||
func appKey2OrgCode(appKey string) (vendorOrgCode string) {
|
||||
func AppKey2OrgCode(appKey string) (vendorOrgCode string) {
|
||||
apiList := partner.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD)
|
||||
for _, v := range apiList {
|
||||
jdAPI := partner.CurAPIManager.GetAPI(model.VendorIDJD, v).(*jdapi.API)
|
||||
@@ -39,23 +42,10 @@ func appKey2OrgCode(appKey string) (vendorOrgCode string) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return vendorOrgCode
|
||||
}
|
||||
|
||||
func GetAPIByAppKey(appKey string) (apiObj *jdapi.API) {
|
||||
if appKey == "" {
|
||||
apiObj = getAPI("")
|
||||
} else {
|
||||
apiList := partner.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD)
|
||||
for _, v := range apiList {
|
||||
jdAPI := partner.CurAPIManager.GetAPI(model.VendorIDJD, v).(*jdapi.API)
|
||||
if jdAPI.GetAppKey() == appKey {
|
||||
apiObj = jdAPI
|
||||
break
|
||||
}
|
||||
}
|
||||
if vendorOrgCode == "" {
|
||||
globals.SugarLogger.Warnf("AppKey2OrgCode appKey:%s get empty vendorOrgCode", appKey)
|
||||
}
|
||||
return apiObj
|
||||
return vendorOrgCode
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) GetVendorID() int {
|
||||
|
||||
@@ -27,13 +27,17 @@ var (
|
||||
jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup,
|
||||
jdapi.OrderStatusDelivering: model.OrderStatusDelivering,
|
||||
jdapi.OrderStatusDelivered: model.OrderStatusFinished,
|
||||
// jdapi.OrderStatusFinished: model.OrderStatusFinished, // todo 这个状态不是真正都完成的意思
|
||||
jdapi.OrderStatusCanceled: model.OrderStatusCanceled,
|
||||
jdapi.OrderStatusFinished: model.OrderStatusFinished, // todo 这个状态不是真正都完成的意思?
|
||||
jdapi.OrderStatusCanceled: model.OrderStatusCanceled,
|
||||
|
||||
jdapi.OrderStatusAdjust: model.OrderStatusAdjust,
|
||||
jdapi.OrderStatusUserApplyCancel: model.OrderStatusApplyCancel,
|
||||
jdapi.OrderStatusLocked: model.OrderStatusLocked,
|
||||
jdapi.OrderStatusUnlocked: model.OrderStatusUnlocked,
|
||||
|
||||
jdapi.OrderStatusVenderAgreeCancel: model.OrderStatusVendorAgreeCancel,
|
||||
jdapi.OrderStatusVenderRejectCancel: model.OrderStatusVendorRejectCancel,
|
||||
jdapi.CallbackMsgOrderAddTips: model.OrderStatusWaybillTipChanged,
|
||||
}
|
||||
deliveryTypeMap = map[int]string{
|
||||
jdapi.CarrierNoCrowdSourcing: model.OrderDeliveryTypePlatform,
|
||||
@@ -93,9 +97,6 @@ func (c *PurchaseHandler) onOrderMsg(vendorOrgCode string, msg *jdapi.CallbackOr
|
||||
})
|
||||
}
|
||||
err := partner.CurOrderManager.OnOrderStatusChanged(vendorOrgCode, status)
|
||||
// if globals.HandleLegacyJxOrder && err == nil {
|
||||
// c.legacyJdOrderStatusChanged(status)
|
||||
// }
|
||||
retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus)
|
||||
}
|
||||
}
|
||||
@@ -147,6 +148,14 @@ func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.
|
||||
return order, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) {
|
||||
order, err := getAPI(vendorOrgCode).QuerySingleOrder2(vendorOrderID)
|
||||
if err == nil {
|
||||
status = p.getStatusFromVendorStatus(utils.Int2Str(order.OrderStatus))
|
||||
}
|
||||
return status, err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
|
||||
result := orderData
|
||||
orderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderId"]))
|
||||
@@ -177,6 +186,7 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
||||
OrderCreatedAt: utils.Str2Time(result[statusTimeField].(string)),
|
||||
OriginalData: string(utils.MustMarshal(result)),
|
||||
ActualPayPrice: utils.MustInterface2Int64(result["orderBuyerPayableMoney"]),
|
||||
BaseFreightMoney: utils.Interface2Int64WithDefault(result["orderBaseFreightMoney"], 0),
|
||||
DistanceFreightMoney: utils.Interface2Int64WithDefault(result["merchantPaymentDistanceFreightMoney"], 0),
|
||||
DeliveryType: deliveryTypeMap[int(utils.Str2Int64WithDefault(utils.Interface2String(result["deliveryCarrierNo"]), 0))],
|
||||
VendorOrgCode: utils.Interface2String(result["orgCode"]),
|
||||
@@ -277,19 +287,24 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *jdapi.CallbackOrderMsg) *model
|
||||
RefVendorOrderID: msg.BillID,
|
||||
RefVendorID: model.VendorIDJD,
|
||||
VendorStatus: msg.StatusID,
|
||||
Status: c.getStatusFromVendorStatus(msg.StatusID),
|
||||
StatusTime: utils.Str2Time(msg.Timestamp),
|
||||
Remark: msg.Remark,
|
||||
}
|
||||
if msg.MsgURL == jdapi.CallbackMsgOrderAddTips {
|
||||
orderStatus.VendorStatus = jdapi.CallbackMsgOrderAddTips
|
||||
}
|
||||
orderStatus.Status = c.getStatusFromVendorStatus(orderStatus.VendorStatus)
|
||||
return orderStatus
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) postFakeMsg(vendorOrderID, vendorStatus string) {
|
||||
func (c *PurchaseHandler) postFakeMsg(vendorOrgCode, vendorOrderID, vendorStatus string) {
|
||||
msg := &jdapi.CallbackOrderMsg{
|
||||
CallbackMsg: &jdapi.CallbackMsg{},
|
||||
BillID: vendorOrderID,
|
||||
StatusID: vendorStatus,
|
||||
Timestamp: utils.Time2Str(time.Now()),
|
||||
CallbackMsg: &jdapi.CallbackMsg{
|
||||
AppKey: getAPI(vendorOrgCode).GetAppKey(),
|
||||
},
|
||||
BillID: vendorOrderID,
|
||||
StatusID: vendorStatus,
|
||||
Timestamp: utils.Time2Str(time.Now()),
|
||||
}
|
||||
utils.CallFuncAsync(func() {
|
||||
OnOrderMsg(msg)
|
||||
@@ -309,14 +324,14 @@ func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptI
|
||||
if globals.EnableJdStoreWrite {
|
||||
err = getAPI(order.VendorOrgCode).OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName)
|
||||
if isAcceptIt && err == nil {
|
||||
c.postFakeMsg(order.VendorOrderID, jdapi.StatusIDWaitOutStore)
|
||||
c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.StatusIDWaitOutStore)
|
||||
}
|
||||
} else {
|
||||
if isAcceptIt {
|
||||
c.postFakeMsg(order.VendorOrderID, jdapi.StatusIDWaitOutStore)
|
||||
c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.StatusIDWaitOutStore)
|
||||
} else {
|
||||
|
||||
c.postFakeMsg(order.VendorOrderID, jdapi.OrderStatusCanceled)
|
||||
c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.OrderStatusCanceled)
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -327,7 +342,7 @@ func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bo
|
||||
if !isSelfDelivery && globals.EnableJdStoreWrite {
|
||||
_, err = getAPI(order.VendorOrgCode).OrderJDZBDelivery(order.VendorOrderID, userName)
|
||||
} else {
|
||||
c.postFakeMsg(order.VendorOrderID, jdapi.OrderStatusFinishedPickup)
|
||||
c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.OrderStatusFinishedPickup)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -426,11 +441,18 @@ func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.Goods
|
||||
func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
||||
order = jxutils.RemoveSkuFromOrder(order, removedSkuList)
|
||||
var oaosAdjustDTOList []*jdapi.OAOSAdjustDTO
|
||||
dtoMap := make(map[int]*jdapi.OAOSAdjustDTO)
|
||||
for _, sku := range order.Skus {
|
||||
oaosAdjustDTOList = append(oaosAdjustDTOList, &jdapi.OAOSAdjustDTO{
|
||||
OutSkuID: utils.Int2Str(jxutils.GetSkuIDFromOrderSku(sku)),
|
||||
SkuCount: sku.Count,
|
||||
})
|
||||
skuID := jxutils.GetSkuIDFromOrderSku(sku)
|
||||
if dtoMap[skuID] == nil {
|
||||
dtoMap[skuID] = &jdapi.OAOSAdjustDTO{
|
||||
OutSkuID: utils.Int2Str(skuID),
|
||||
SkuCount: sku.Count,
|
||||
}
|
||||
oaosAdjustDTOList = append(oaosAdjustDTOList, dtoMap[skuID])
|
||||
} else {
|
||||
dtoMap[skuID].SkuCount += sku.Count
|
||||
}
|
||||
}
|
||||
if globals.EnableJdStoreWrite {
|
||||
err = getAPI(order.VendorOrgCode).AdjustOrder(order.VendorOrderID, ctx.GetUserName(), reason, oaosAdjustDTOList)
|
||||
@@ -462,31 +484,22 @@ func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode strin
|
||||
return vendorOrderIDs, err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee int64) (err error) {
|
||||
a := getAPI(order.VendorOrgCode)
|
||||
orderInfo, err := a.QuerySingleOrder2(order.VendorOrderID)
|
||||
if err == nil {
|
||||
tip2Add := int(tipFee) - orderInfo.Tips
|
||||
if tip2Add != 0 {
|
||||
if globals.EnableJdStoreWrite {
|
||||
err = a.OrderAddTips(order.VendorOrderID, tip2Add, ctx.GetUserName())
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder) (tipFee int64, err error) {
|
||||
orderInfo, err := getAPI(order.VendorOrgCode).QuerySingleOrder2(order.VendorOrderID)
|
||||
func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) {
|
||||
orderInfo, err := getAPI(vendorOrgCode).QuerySingleOrder2(vendorOrderID)
|
||||
if err == nil {
|
||||
tipFee = int64(orderInfo.Tips)
|
||||
}
|
||||
return tipFee, err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) AddWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee2Add int64) (err error) {
|
||||
if globals.EnableJdStoreWrite {
|
||||
err = getAPI(order.VendorOrgCode).OrderAddTips(order.VendorOrderID, int(tipFee2Add), ctx.GetUserName())
|
||||
func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) {
|
||||
curTipFee, err := c.GetWaybillTip(ctx, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2)
|
||||
if err == nil {
|
||||
if tipFee2Add := tipFee - curTipFee; tipFee2Add > 0 {
|
||||
if globals.EnableJdStoreWrite {
|
||||
err = getAPI(vendorOrgCode).OrderAddTips(vendorOrderID, int(tipFee2Add), ctx.GetUserName())
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -32,6 +32,14 @@ func TestGetOrder(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderStatus(t *testing.T) {
|
||||
status, err := CurPurchaseHandler.GetOrderStatus("", "929203144000041")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
t.Log(status)
|
||||
}
|
||||
|
||||
func TestListOrders(t *testing.T) {
|
||||
result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "", nil, time.Now(), "")
|
||||
if err != nil {
|
||||
|
||||
@@ -2,491 +2,479 @@ package jd
|
||||
|
||||
// 这里函数取得的信息,除了与自身实体相关的ID(比如PARENT ID),都已经转换成了本地ID了
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unicode/utf8"
|
||||
// type tSkuInfoExt struct {
|
||||
// model.SkuName
|
||||
// JdCatID int64 `orm:"column(jd_cat_id)"` // 商家类别
|
||||
// JdCategoryID int `orm:"column(jd_category_id)"` // 到家类别
|
||||
// SkuCatID int64 `orm:"column(sku_cat_id)"` // 商家特殊类别
|
||||
// Comment string `orm:"size(255)" json:"comment"`
|
||||
// }
|
||||
|
||||
"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/model/dao"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
)
|
||||
// var (
|
||||
// skuAddParamsKeyMap = map[string]int{
|
||||
// jdapi.KeyUpcCode: 1,
|
||||
// }
|
||||
// )
|
||||
|
||||
type tSkuInfoExt struct {
|
||||
model.SkuName
|
||||
JdCatID int64 `orm:"column(jd_cat_id)"` // 商家类别
|
||||
JdCategoryID int `orm:"column(jd_category_id)"` // 到家类别
|
||||
SkuCatID int64 `orm:"column(sku_cat_id)"` // 商家特殊类别
|
||||
Comment string `orm:"size(255)" json:"comment"`
|
||||
}
|
||||
// func (p *PurchaseHandler) CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||
// var jdPid int64
|
||||
// if cat.ParentID != 0 {
|
||||
// pCat := &model.SkuCategory{}
|
||||
// pCat.ID = cat.ParentID
|
||||
// if err = dao.GetEntity(db, pCat); err == nil {
|
||||
// jdPid = pCat.JdID
|
||||
// } else {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// result, err2 := getAPI("").AddShopCategory(jdPid, cat.Name, int(cat.Level), cat.Seq, userName)
|
||||
// if err = err2; err == nil {
|
||||
// if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 {
|
||||
// cat.JdID = jdID
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// cat.JdID = jxutils.GenFakeID()
|
||||
// }
|
||||
// return err
|
||||
// }
|
||||
|
||||
var (
|
||||
skuAddParamsKeyMap = map[string]int{
|
||||
jdapi.KeyUpcCode: 1,
|
||||
}
|
||||
)
|
||||
// func (p *PurchaseHandler) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error {
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// return getAPI("").UpdateShopCategory(cat.JdID, cat.Name)
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||
var jdPid int64
|
||||
if cat.ParentID != 0 {
|
||||
pCat := &model.SkuCategory{}
|
||||
pCat.ID = cat.ParentID
|
||||
if err = dao.GetEntity(db, pCat); err == nil {
|
||||
jdPid = pCat.JdID
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if globals.EnableJdStoreWrite {
|
||||
result, err2 := getAPI("").AddShopCategory(jdPid, cat.Name, int(cat.Level), cat.Seq, userName)
|
||||
if err = err2; err == nil {
|
||||
if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 {
|
||||
cat.JdID = jdID
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cat.JdID = jxutils.GenFakeID()
|
||||
}
|
||||
return err
|
||||
}
|
||||
// func (p *PurchaseHandler) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error {
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// return getAPI("").DelShopCategory(cat.JdID)
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error {
|
||||
if globals.EnableJdStoreWrite {
|
||||
return getAPI("").UpdateShopCategory(cat.JdID, cat.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error) {
|
||||
// var parentJDID int64
|
||||
// if parentCatID != 0 {
|
||||
// cat := &model.SkuCategory{}
|
||||
// cat.ID = parentCatID
|
||||
// if err = dao.GetEntity(db, cat); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// parentJDID = cat.JdID
|
||||
// }
|
||||
// var cats []*model.SkuCategory
|
||||
// if err = dao.GetRows(db, &cats, `
|
||||
// SELECT *
|
||||
// FROM sku_category
|
||||
// WHERE parent_id = ? AND deleted_at = ?
|
||||
// ORDER BY seq`, parentCatID, utils.DefaultTimeValue); err == nil {
|
||||
// jdCatIDs := make([]int64, len(cats))
|
||||
// for k, v := range cats {
|
||||
// jdCatIDs[k] = v.JdID
|
||||
// }
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// err = getAPI("").ChangeShopCategoryOrder(parentJDID, jdCatIDs)
|
||||
// }
|
||||
// }
|
||||
// return err
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error {
|
||||
if globals.EnableJdStoreWrite {
|
||||
return getAPI("").DelShopCategory(cat.JdID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error) {
|
||||
var parentJDID int64
|
||||
if parentCatID != 0 {
|
||||
cat := &model.SkuCategory{}
|
||||
cat.ID = parentCatID
|
||||
if err = dao.GetEntity(db, cat); err != nil {
|
||||
return err
|
||||
}
|
||||
parentJDID = cat.JdID
|
||||
}
|
||||
var cats []*model.SkuCategory
|
||||
if err = dao.GetRows(db, &cats, `
|
||||
SELECT *
|
||||
FROM sku_category
|
||||
WHERE parent_id = ? AND deleted_at = ?
|
||||
ORDER BY seq`, parentCatID, utils.DefaultTimeValue); err == nil {
|
||||
jdCatIDs := make([]int64, len(cats))
|
||||
for k, v := range cats {
|
||||
jdCatIDs[k] = v.JdID
|
||||
}
|
||||
if globals.EnableJdStoreWrite {
|
||||
err = getAPI("").ChangeShopCategoryOrder(parentJDID, jdCatIDs)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (string, error)) (err error) {
|
||||
var skuInfoExt tSkuInfoExt
|
||||
err = dao.GetRow(nil, &skuInfoExt, `
|
||||
SELECT
|
||||
t2.*, IF(t2.jd_category_id > 0, t2.jd_category_id, t3.jd_category_id) jd_category_id,
|
||||
t3.jd_id jd_cat_id,
|
||||
t4.jd_id sku_cat_id
|
||||
FROM sku t1
|
||||
JOIN sku_name t2 ON t1.name_id = t2.id
|
||||
JOIN sku_category t3 ON t2.category_id = t3.id
|
||||
LEFT JOIN sku_category t4 ON t1.category_id = t4.id
|
||||
WHERE t1.id = ?
|
||||
`, sku.ID)
|
||||
if err == nil {
|
||||
shopCategories := []int64{skuInfoExt.JdCatID}
|
||||
// SPU只支持SPU的商家分类,不支持单独SKU的,去除SKU的分类
|
||||
// if skuInfoExt.SkuCatID != 0 {
|
||||
// shopCategories = append(shopCategories, skuInfoExt.SkuCatID)
|
||||
// }
|
||||
if skuInfoExt.JdCategoryID == 0 {
|
||||
skuInfoExt.JdCategoryID = getDefJdCategoryID()
|
||||
}
|
||||
if skuInfoExt.BrandID == 0 {
|
||||
skuInfoExt.BrandID = DefBrandID
|
||||
}
|
||||
addParams := map[string]interface{}{}
|
||||
|
||||
if skuInfoExt.IsGlobal == 0 { //如果不是全国可售,要查可售区域
|
||||
sellPlaces, err2 := dao.GetSellCities(db, skuInfoExt.ID, model.VendorIDJD)
|
||||
if err = err2; err == nil && len(sellPlaces) > 0 {
|
||||
sellCites := make([]int, len(sellPlaces))
|
||||
for k, v := range sellPlaces {
|
||||
sellCites[k] = v.JdCode
|
||||
}
|
||||
addParams["sellCities"] = sellCites
|
||||
}
|
||||
}
|
||||
if addParams["sellCities"] == nil {
|
||||
addParams["sellCities"] = []int{0}
|
||||
}
|
||||
if skuInfoExt.DescImg != "" {
|
||||
addParams[jdapi.KeyProductDesc] = fmt.Sprintf(`<img src="%s" alt="一张图片" />`, skuInfoExt.DescImg)
|
||||
addParams[jdapi.KeyIfViewDesc] = 0
|
||||
} else {
|
||||
addParams[jdapi.KeyIfViewDesc] = 1
|
||||
}
|
||||
if err == nil {
|
||||
skuName := jxutils.ComposeSkuName(skuInfoExt.Prefix, skuInfoExt.Name, sku.Comment, skuInfoExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameCharCount)
|
||||
skuPrice := jxutils.CaculateSkuPrice(skuInfoExt.Price, sku.SpecQuality, sku.SpecUnit, skuInfoExt.Unit)
|
||||
if skuInfoExt.Upc != "" {
|
||||
addParams[jdapi.KeyUpcCode] = skuInfoExt.Upc
|
||||
}
|
||||
result, err2 := handler(&skuInfoExt, skuPrice, skuName, shopCategories, addParams)
|
||||
if err = err2; err == nil {
|
||||
if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 {
|
||||
sku.JdID = jdID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
return p.cuSku(db, sku, func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) {
|
||||
if skuExt.IsSpu == 0 {
|
||||
if globals.EnableJdStoreWrite {
|
||||
vendorSkuID, err = getAPI("").AddSku(utils.Int2Str(sku.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), jxutils.BatchString2Slice(skuExt.Img, skuExt.Img2), jxStatus2jdStatus(sku.Status), true, addParams)
|
||||
if err != nil {
|
||||
if jdSkuID := jdapi.GetJdSkuIDFromError(err); jdSkuID > 0 {
|
||||
vendorSkuID = utils.Int64ToStr(jdSkuID)
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vendorSkuID = utils.Int64ToStr(jxutils.GenFakeID())
|
||||
}
|
||||
} else {
|
||||
vendorSkuID, err = p.syncSkuNameAsSpu(db, sku, skuExt, price, skuName, shopCategories, addParams)
|
||||
}
|
||||
return vendorSkuID, err
|
||||
})
|
||||
}
|
||||
|
||||
// func (p *PurchaseHandler) ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) {
|
||||
// jdSkuID := utils.Str2Int64(vendorSkuID)
|
||||
// a := getAPI(vendorOrgCode)
|
||||
// skuList, _, err := a.QuerySkuInfos(&jdapi.QuerySkuParam{
|
||||
// SkuID: jdSkuID,
|
||||
// })
|
||||
// func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (string, error)) (err error) {
|
||||
// var skuInfoExt tSkuInfoExt
|
||||
// err = dao.GetRow(nil, &skuInfoExt, `
|
||||
// SELECT
|
||||
// t2.*, IF(t2.jd_category_id > 0, t2.jd_category_id, t3.jd_category_id) jd_category_id,
|
||||
// t3.jd_id jd_cat_id,
|
||||
// t4.jd_id sku_cat_id
|
||||
// FROM sku t1
|
||||
// JOIN sku_name t2 ON t1.name_id = t2.id
|
||||
// JOIN sku_category t3 ON t2.category_id = t3.id
|
||||
// LEFT JOIN sku_category t4 ON t1.category_id = t4.id
|
||||
// WHERE t1.id = ?
|
||||
// `, sku.ID)
|
||||
// if err == nil {
|
||||
// if len(skuList) >= 1 {
|
||||
// skuNameExt = &model.SkuNameExt{}
|
||||
// if imgList, err2 := a.QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{
|
||||
// SkuIDs: []int64{jdSkuID},
|
||||
// }); err2 == nil && len(imgList) > 0 {
|
||||
// skuNameExt.Img = imgList[0].SourceImgURL
|
||||
// }
|
||||
// sku := skuList[0]
|
||||
// prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(sku.SkuName)
|
||||
// if name == "" {
|
||||
// name = sku.SkuName
|
||||
// unit = "份"
|
||||
// specUnit = "g"
|
||||
// }
|
||||
// skuNameExt.Prefix = prefix
|
||||
// skuNameExt.Name = name
|
||||
// skuNameExt.Unit = unit
|
||||
// skuNameExt.Price = sku.SkuPrice
|
||||
// skuNameExt.Skus = []*model.SkuWithVendor{
|
||||
// &model.SkuWithVendor{
|
||||
// Sku: &model.Sku{
|
||||
// SpecQuality: specQuality,
|
||||
// SpecUnit: specUnit,
|
||||
// Weight: jxutils.FloatWeight2Int(float32(sku.Weight)),
|
||||
// JdID: sku.SkuID,
|
||||
// Status: jdStatus2jxStatus(sku.FixedStatus),
|
||||
// Comment: comment,
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// skuNameExt.Skus[0].ID = int(utils.Str2Int64(sku.OutSkuID))
|
||||
// shopCategories := []int64{skuInfoExt.JdCatID}
|
||||
// // SPU只支持SPU的商家分类,不支持单独SKU的,去除SKU的分类
|
||||
// // if skuInfoExt.SkuCatID != 0 {
|
||||
// // shopCategories = append(shopCategories, skuInfoExt.SkuCatID)
|
||||
// // }
|
||||
// if skuInfoExt.JdCategoryID == 0 {
|
||||
// skuInfoExt.JdCategoryID = getDefJdCategoryID()
|
||||
// }
|
||||
// if skuInfoExt.BrandID == 0 {
|
||||
// skuInfoExt.BrandID = DefBrandID
|
||||
// }
|
||||
// addParams := map[string]interface{}{}
|
||||
|
||||
// db := dao.GetDB()
|
||||
// shopCategories := sku.ShopCategories
|
||||
// if len(shopCategories) > 0 {
|
||||
// skuCat := &model.SkuCategory{}
|
||||
// skuCat.JdID = shopCategories[0]
|
||||
// if dao.GetEntity(db, skuCat, "JdID") == nil {
|
||||
// skuNameExt.CategoryID = skuCat.ID
|
||||
// if skuInfoExt.IsGlobal == 0 { //如果不是全国可售,要查可售区域
|
||||
// sellPlaces, err2 := dao.GetSellCities(db, skuInfoExt.ID, model.VendorIDJD)
|
||||
// if err = err2; err == nil && len(sellPlaces) > 0 {
|
||||
// sellCites := make([]int, len(sellPlaces))
|
||||
// for k, v := range sellPlaces {
|
||||
// sellCites[k] = v.JdCode
|
||||
// }
|
||||
// addParams["sellCities"] = sellCites
|
||||
// }
|
||||
// }
|
||||
// if addParams["sellCities"] == nil {
|
||||
// addParams["sellCities"] = []int{0}
|
||||
// }
|
||||
// if skuInfoExt.DescImg != "" {
|
||||
// addParams[jdapi.KeyProductDesc] = fmt.Sprintf(`<img src="%s" alt="一张图片" />`, skuInfoExt.DescImg)
|
||||
// addParams[jdapi.KeyIfViewDesc] = 0
|
||||
// } else {
|
||||
// addParams[jdapi.KeyIfViewDesc] = 1
|
||||
// }
|
||||
// if err == nil {
|
||||
// skuName := jxutils.ComposeSkuName(skuInfoExt.Prefix, skuInfoExt.Name, sku.Comment, skuInfoExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameCharCount)
|
||||
// skuPrice := jxutils.CaculateSkuPrice(skuInfoExt.Price, sku.SpecQuality, sku.SpecUnit, skuInfoExt.Unit)
|
||||
// if skuInfoExt.Upc != "" {
|
||||
// addParams[jdapi.KeyUpcCode] = skuInfoExt.Upc
|
||||
// }
|
||||
// result, err2 := handler(&skuInfoExt, skuPrice, skuName, shopCategories, addParams)
|
||||
// if err = err2; err == nil {
|
||||
// if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 {
|
||||
// sku.JdID = jdID
|
||||
// }
|
||||
// }
|
||||
// sellCities := sku.SellCities
|
||||
// for _, v := range sellCities {
|
||||
// if v == 0 {
|
||||
// skuNameExt.IsGlobal = 1
|
||||
// }
|
||||
// }
|
||||
// return err
|
||||
// }
|
||||
|
||||
// func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
// return p.cuSku(db, sku, func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) {
|
||||
// if skuExt.IsSpu == 0 {
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// vendorSkuID, err = getAPI("").AddSku(utils.Int2Str(sku.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), jxutils.BatchString2Slice(skuExt.Img, skuExt.Img2), jxStatus2jdStatus(sku.Status), true, addParams)
|
||||
// if err != nil {
|
||||
// if jdSkuID := jdapi.GetJdSkuIDFromError(err); jdSkuID > 0 {
|
||||
// vendorSkuID = utils.Int64ToStr(jdSkuID)
|
||||
// err = nil
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if len(sellCities) == 0 || skuNameExt.IsGlobal == 1 {
|
||||
// skuNameExt.IsGlobal = 1
|
||||
// } else {
|
||||
// var places []*model.Place
|
||||
// if err = dao.GetRows(db, &places, "SELECT * FROM place WHERE jd_code IN ("+dao.GenQuestionMarks(len(sellCities))+") AND level = 2", sellCities); err == nil {
|
||||
// skuNameExt.Places = make([]int, len(places))
|
||||
// for k, v := range places {
|
||||
// skuNameExt.Places[k] = v.Code
|
||||
// vendorSkuID = utils.Int64ToStr(jxutils.GenFakeID())
|
||||
// }
|
||||
// } else {
|
||||
// vendorSkuID, err = p.syncSkuNameAsSpu(db, sku, skuExt, price, skuName, shopCategories, addParams)
|
||||
// }
|
||||
// return vendorSkuID, err
|
||||
// })
|
||||
// }
|
||||
|
||||
// // func (p *PurchaseHandler) ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) {
|
||||
// // jdSkuID := utils.Str2Int64(vendorSkuID)
|
||||
// // a := getAPI(vendorOrgCode)
|
||||
// // skuList, _, err := a.QuerySkuInfos(&jdapi.QuerySkuParam{
|
||||
// // SkuID: jdSkuID,
|
||||
// // })
|
||||
// // if err == nil {
|
||||
// // if len(skuList) >= 1 {
|
||||
// // skuNameExt = &model.SkuNameExt{}
|
||||
// // if imgList, err2 := a.QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{
|
||||
// // SkuIDs: []int64{jdSkuID},
|
||||
// // }); err2 == nil && len(imgList) > 0 {
|
||||
// // skuNameExt.Img = imgList[0].SourceImgURL
|
||||
// // }
|
||||
// // sku := skuList[0]
|
||||
// // prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(sku.SkuName)
|
||||
// // if name == "" {
|
||||
// // name = sku.SkuName
|
||||
// // unit = "份"
|
||||
// // specUnit = "g"
|
||||
// // }
|
||||
// // skuNameExt.Prefix = prefix
|
||||
// // skuNameExt.Name = name
|
||||
// // skuNameExt.Unit = unit
|
||||
// // skuNameExt.Price = sku.SkuPrice
|
||||
// // skuNameExt.Skus = []*model.SkuWithVendor{
|
||||
// // &model.SkuWithVendor{
|
||||
// // Sku: &model.Sku{
|
||||
// // SpecQuality: specQuality,
|
||||
// // SpecUnit: specUnit,
|
||||
// // Weight: jxutils.FloatWeight2Int(float32(sku.Weight)),
|
||||
// // JdID: sku.SkuID,
|
||||
// // Status: jdStatus2jxStatus(sku.FixedStatus),
|
||||
// // Comment: comment,
|
||||
// // },
|
||||
// // },
|
||||
// // }
|
||||
// // skuNameExt.Skus[0].ID = int(utils.Str2Int64(sku.OutSkuID))
|
||||
|
||||
// // db := dao.GetDB()
|
||||
// // shopCategories := sku.ShopCategories
|
||||
// // if len(shopCategories) > 0 {
|
||||
// // skuCat := &model.SkuCategory{}
|
||||
// // skuCat.JdID = shopCategories[0]
|
||||
// // if dao.GetEntity(db, skuCat, "JdID") == nil {
|
||||
// // skuNameExt.CategoryID = skuCat.ID
|
||||
// // }
|
||||
// // }
|
||||
// // sellCities := sku.SellCities
|
||||
// // for _, v := range sellCities {
|
||||
// // if v == 0 {
|
||||
// // skuNameExt.IsGlobal = 1
|
||||
// // }
|
||||
// // }
|
||||
// // if len(sellCities) == 0 || skuNameExt.IsGlobal == 1 {
|
||||
// // skuNameExt.IsGlobal = 1
|
||||
// // } else {
|
||||
// // var places []*model.Place
|
||||
// // if err = dao.GetRows(db, &places, "SELECT * FROM place WHERE jd_code IN ("+dao.GenQuestionMarks(len(sellCities))+") AND level = 2", sellCities); err == nil {
|
||||
// // skuNameExt.Places = make([]int, len(places))
|
||||
// // for k, v := range places {
|
||||
// // skuNameExt.Places[k] = v.Code
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // } else {
|
||||
// // err = partner.ErrCanNotFindItem
|
||||
// // }
|
||||
// // }
|
||||
// // return skuNameExt, err
|
||||
// // }
|
||||
|
||||
// func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
// return p.cuSku(db, sku, func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) {
|
||||
// params := utils.MergeMaps(addParams)
|
||||
// params[jdapi.KeyCategoryId] = skuExt.JdCategoryID
|
||||
// params[jdapi.KeyShopCategories] = shopCategories
|
||||
// params[jdapi.KeyBrandId] = skuExt.BrandID
|
||||
// params[jdapi.KeySkuName] = skuName
|
||||
// params[jdapi.KeyWeight] = jxutils.IntWeight2Float(sku.Weight)
|
||||
// params[jdapi.KeyImages] = jxutils.BatchString2Slice(skuExt.Img, skuExt.Img2)
|
||||
// params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status)
|
||||
// if skuExt.IsSpu == 0 {
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// vendorSkuID, err = getAPI("").UpdateSku(utils.Int2Str(sku.ID), params)
|
||||
// }
|
||||
// } else {
|
||||
// vendorSkuID, err = p.syncSkuNameAsSpu(db, sku, skuExt, price, skuName, shopCategories, addParams)
|
||||
// }
|
||||
// return vendorSkuID, err
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
// params := map[string]interface{}{
|
||||
// jdapi.KeyFixedStatus: jdapi.SkuFixedStatusDeleted,
|
||||
// }
|
||||
// sql := `
|
||||
// SELECT t2.*
|
||||
// FROM sku t1
|
||||
// JOIN sku_name t2 ON t1.name_id = t2.id
|
||||
// WHERE t1.id = ?
|
||||
// `
|
||||
// var skuExt tSkuInfoExt
|
||||
// err = dao.GetRow(db, &skuExt, sql, sku.ID)
|
||||
// if err == nil {
|
||||
// if skuExt.IsSpu == 0 {
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// _, err = getAPI("").UpdateSku(utils.Int2Str(sku.ID), params)
|
||||
// }
|
||||
// } else {
|
||||
// _, err = p.syncSkuNameAsSpu(db, sku, &skuExt, 0, "", nil, nil)
|
||||
// }
|
||||
// }
|
||||
// return err
|
||||
// }
|
||||
|
||||
// // func (p *PurchaseHandler) RefreshAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) {
|
||||
// // globals.SugarLogger.Debugf("jd RefreshAllSkusID")
|
||||
|
||||
// // db := dao.GetDB()
|
||||
// // var skuPairs []*jdapi.SkuIDPair
|
||||
// // const stepCount = 2
|
||||
|
||||
// // rootTask := tasksch.NewSeqTask("jd RefreshAllSkusID", ctx,
|
||||
// // func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||
// // switch step {
|
||||
// // case 0:
|
||||
// // err = dao.GetRows(db, &skuPairs, `
|
||||
// // SELECT t1.id out_sku_id, t1.jd_id sku_id
|
||||
// // FROM sku t1
|
||||
// // WHERE t1.deleted_at = ?
|
||||
// // `, utils.DefaultTimeValue)
|
||||
// // default:
|
||||
// // taskName := "RefreshAllSkusID update id"
|
||||
// // if step != stepCount-1 {
|
||||
// // taskName = "RefreshAllSkusID update uuid"
|
||||
// // }
|
||||
// // task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true).SetBatchSize(jdapi.MaxBatchSize4BatchUpdateOutSkuId), ctx,
|
||||
// // func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
// // skuPairs := make([]*jdapi.SkuIDPair, len(batchItemList))
|
||||
// // for k, v := range batchItemList {
|
||||
// // pair := v.(*jdapi.SkuIDPair)
|
||||
// // skuPairs[k] = &jdapi.SkuIDPair{
|
||||
// // SkuId: pair.SkuId,
|
||||
// // OutSkuId: pair.OutSkuId,
|
||||
// // }
|
||||
// // if step != stepCount-1 {
|
||||
// // skuPairs[k].OutSkuId = utils.GetUUID()
|
||||
// // }
|
||||
// // }
|
||||
// // globals.SugarLogger.Debug(utils.Format4Output(skuPairs, false))
|
||||
// // if globals.EnableJdStoreWrite {
|
||||
// // _, err = getAPI("").BatchUpdateOutSkuId(skuPairs)
|
||||
// // }
|
||||
// // return nil, err
|
||||
// // }, skuPairs)
|
||||
// // rootTask.AddChild(task1).Run()
|
||||
// // _, err = task1.GetResult(0)
|
||||
// // }
|
||||
// // return nil, err
|
||||
// // }, stepCount)
|
||||
// // tasksch.HandleTask(rootTask, parentTask, false).Run()
|
||||
// // if !isAsync {
|
||||
// // _, err = rootTask.GetResult(0)
|
||||
// // }
|
||||
// // return rootTask.ID, err
|
||||
// // }
|
||||
|
||||
// func splitAddParams(addParams map[string]interface{}) (spuAddParams, skuAddParams map[string]interface{}) {
|
||||
// if addParams != nil {
|
||||
// spuAddParams = make(map[string]interface{})
|
||||
// skuAddParams = make(map[string]interface{})
|
||||
// for key := range addParams {
|
||||
// if skuAddParamsKeyMap[key] == 1 {
|
||||
// skuAddParams[key] = addParams[key]
|
||||
// } else {
|
||||
// spuAddParams[key] = addParams[key]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return spuAddParams, skuAddParams
|
||||
// }
|
||||
|
||||
// // 这个处理JD SPU,补丁形式
|
||||
// func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) {
|
||||
// // SPU的SKU NAME不需要规格信息
|
||||
// skuName = jxutils.ComposeSkuName(skuExt.Prefix, skuExt.Name, sku.Comment, "", 0, "", 0)
|
||||
// skuNameJdID := skuExt.JdID
|
||||
// globals.SugarLogger.Debugf("syncSkuNameAsSpu1 sku.id=%d, bareSkuName:%s, skuName:%s, skuNameJdID:%d", sku.ID, skuExt.Name, skuName, skuNameJdID)
|
||||
// spuAddParams, skuAddParams := splitAddParams(addParams)
|
||||
// if !jxutils.IsEmptyID(skuNameJdID) && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除SKU
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// err = getAPI("").UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted))
|
||||
// }
|
||||
// }
|
||||
// if err == nil {
|
||||
// updateFields := []string{}
|
||||
// if skuExt.JdSyncStatus&model.SyncFlagDeletedMask != 0 {
|
||||
// sql := `
|
||||
// SELECT COUNT(*) ct
|
||||
// FROM sku t1
|
||||
// WHERE t1.name_id = ? AND (t1.status <> ? OR t1.jd_sync_status <> 0)
|
||||
// `
|
||||
// var count struct {
|
||||
// Ct int
|
||||
// }
|
||||
// if err = dao.GetRow(db, &count, sql, sku.NameID, model.SkuStatusDeleted); err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
// if count.Ct <= 1 && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 1就是最后删的那个
|
||||
// updateFields = append(updateFields, model.FieldJdSyncStatus)
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// if err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusOffline)); err == nil {
|
||||
// err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// err = partner.ErrCanNotFindItem
|
||||
// } else if skuExt.JdSyncStatus&model.SyncFlagNewMask != 0 && jxutils.IsEmptyID(skuNameJdID) {
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// spuName := jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0)
|
||||
// skus := []map[string]interface{}{
|
||||
// map[string]interface{}{
|
||||
// jdapi.KeyOutSkuId: utils.Int2Str(sku.ID),
|
||||
// jdapi.KeySkuName: skuName,
|
||||
// jdapi.KeyFixedStatus: jxStatus2jdStatus(sku.Status),
|
||||
// jdapi.KeySkuPrice: price,
|
||||
// jdapi.KeyWeight: jxutils.IntWeight2Float(sku.Weight),
|
||||
// jdapi.KeyIsSale: true,
|
||||
// jdapi.FakeKeySpecAttr: composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit),
|
||||
// },
|
||||
// }
|
||||
// skus[0] = utils.MergeMaps(skus[0], skuAddParams)
|
||||
// updateFields = append(updateFields, model.FieldJdSyncStatus)
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// vendorSpuID, skuPairs, err2 := getAPI("").AddSpu(utils.Int2Str(skuExt.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, spuName, []string{skuExt.Img}, jxStatus2jdStatus(skuExt.Status), spuAddParams, skus)
|
||||
// if err = err2; err == nil {
|
||||
// skuExt.JdID = vendorSpuID
|
||||
// // skuNameJdID = skuExt.JdID // 这个是故意去掉的,这样之后的首次SKU修改操作就会被忽略,下一条语句也就可以不用了
|
||||
// // sku.JdSyncStatus &= ^model.SyncFlagNewMask
|
||||
// vendorSkuID = utils.Int64ToStr(skuPairs[0].SkuId)
|
||||
// updateFields = append(updateFields, model.FieldJdID)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else if skuExt.JdSyncStatus&model.SyncFlagModifiedMask != 0 {
|
||||
// params := utils.MergeMaps(map[string]interface{}{
|
||||
// jdapi.KeySpuName: jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0),
|
||||
// jdapi.KeyShopCategories: shopCategories,
|
||||
// jdapi.KeyCategoryId: skuExt.JdCategoryID,
|
||||
// jdapi.KeyBrandId: skuExt.BrandID,
|
||||
// jdapi.KeyImages: []string{skuExt.Img},
|
||||
// jdapi.KeyFixedStatus: jxStatus2jdStatus(skuExt.Status),
|
||||
// }, spuAddParams)
|
||||
// updateFields = append(updateFields, model.FieldJdSyncStatus)
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), params)
|
||||
// }
|
||||
// }
|
||||
// if err == nil {
|
||||
// if skuExt.JdSyncStatus != 0 && len(updateFields) > 0 {
|
||||
// skuExt.JdSyncStatus = 0
|
||||
// _, err = dao.UpdateEntity(db, &skuExt.SkuName, updateFields...)
|
||||
// globals.SugarLogger.Debugf("syncSkuNameAsSpu4 sku.id=%d, skuName:%s, skuName:%s", sku.ID, skuExt.Name, utils.Format4Output(&skuExt.SkuName, false))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return skuNameExt, err
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
return p.cuSku(db, sku, func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) {
|
||||
params := utils.MergeMaps(addParams)
|
||||
params[jdapi.KeyCategoryId] = skuExt.JdCategoryID
|
||||
params[jdapi.KeyShopCategories] = shopCategories
|
||||
params[jdapi.KeyBrandId] = skuExt.BrandID
|
||||
params[jdapi.KeySkuName] = skuName
|
||||
params[jdapi.KeyWeight] = jxutils.IntWeight2Float(sku.Weight)
|
||||
params[jdapi.KeyImages] = jxutils.BatchString2Slice(skuExt.Img, skuExt.Img2)
|
||||
params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status)
|
||||
if skuExt.IsSpu == 0 {
|
||||
if globals.EnableJdStoreWrite {
|
||||
vendorSkuID, err = getAPI("").UpdateSku(utils.Int2Str(sku.ID), params)
|
||||
}
|
||||
} else {
|
||||
vendorSkuID, err = p.syncSkuNameAsSpu(db, sku, skuExt, price, skuName, shopCategories, addParams)
|
||||
}
|
||||
return vendorSkuID, err
|
||||
})
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
params := map[string]interface{}{
|
||||
jdapi.KeyFixedStatus: jdapi.SkuFixedStatusDeleted,
|
||||
}
|
||||
sql := `
|
||||
SELECT t2.*
|
||||
FROM sku t1
|
||||
JOIN sku_name t2 ON t1.name_id = t2.id
|
||||
WHERE t1.id = ?
|
||||
`
|
||||
var skuExt tSkuInfoExt
|
||||
err = dao.GetRow(db, &skuExt, sql, sku.ID)
|
||||
if err == nil {
|
||||
if skuExt.IsSpu == 0 {
|
||||
if globals.EnableJdStoreWrite {
|
||||
_, err = getAPI("").UpdateSku(utils.Int2Str(sku.ID), params)
|
||||
}
|
||||
} else {
|
||||
_, err = p.syncSkuNameAsSpu(db, sku, &skuExt, 0, "", nil, nil)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// func (p *PurchaseHandler) RefreshAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) {
|
||||
// globals.SugarLogger.Debugf("jd RefreshAllSkusID")
|
||||
|
||||
// db := dao.GetDB()
|
||||
// var skuPairs []*jdapi.SkuIDPair
|
||||
// const stepCount = 2
|
||||
|
||||
// rootTask := tasksch.NewSeqTask("jd RefreshAllSkusID", ctx,
|
||||
// func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||
// switch step {
|
||||
// case 0:
|
||||
// err = dao.GetRows(db, &skuPairs, `
|
||||
// SELECT t1.id out_sku_id, t1.jd_id sku_id
|
||||
// FROM sku t1
|
||||
// WHERE t1.deleted_at = ?
|
||||
// `, utils.DefaultTimeValue)
|
||||
// default:
|
||||
// taskName := "RefreshAllSkusID update id"
|
||||
// if step != stepCount-1 {
|
||||
// taskName = "RefreshAllSkusID update uuid"
|
||||
// if err == nil && !jxutils.IsEmptyID(skuNameJdID) {
|
||||
// if sku.JdSyncStatus&model.SyncFlagNewMask != 0 { // 非首次新增SKU
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// vendorSkuID2, err2 := getAPI("").AppendSku(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{skuExt.Img}, jxStatus2jdStatus(sku.Status), true, composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit), skuAddParams)
|
||||
// if err = err2; err == nil {
|
||||
// vendorSkuID = utils.Int64ToStr(vendorSkuID2)
|
||||
// }
|
||||
// task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true).SetBatchSize(jdapi.MaxBatchSize4BatchUpdateOutSkuId), ctx,
|
||||
// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
// skuPairs := make([]*jdapi.SkuIDPair, len(batchItemList))
|
||||
// for k, v := range batchItemList {
|
||||
// pair := v.(*jdapi.SkuIDPair)
|
||||
// skuPairs[k] = &jdapi.SkuIDPair{
|
||||
// SkuId: pair.SkuId,
|
||||
// OutSkuId: pair.OutSkuId,
|
||||
// }
|
||||
// if step != stepCount-1 {
|
||||
// skuPairs[k].OutSkuId = utils.GetUUID()
|
||||
// }
|
||||
// }
|
||||
// globals.SugarLogger.Debug(utils.Format4Output(skuPairs, false))
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// _, err = getAPI("").BatchUpdateOutSkuId(skuPairs)
|
||||
// }
|
||||
// return nil, err
|
||||
// }, skuPairs)
|
||||
// rootTask.AddChild(task1).Run()
|
||||
// _, err = task1.GetResult(0)
|
||||
// }
|
||||
// return nil, err
|
||||
// }, stepCount)
|
||||
// tasksch.HandleTask(rootTask, parentTask, false).Run()
|
||||
// if !isAsync {
|
||||
// _, err = rootTask.GetResult(0)
|
||||
// } else if sku.JdSyncStatus&model.SyncFlagModifiedMask != 0 {
|
||||
// params := make(map[string]interface{})
|
||||
// params[jdapi.KeySkuName] = skuName
|
||||
// params[jdapi.KeyImages] = []string{skuExt.Img}
|
||||
// params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status)
|
||||
// params[jdapi.KeyWeight] = jxutils.IntWeight2Float(sku.Weight)
|
||||
// params[jdapi.KeySkuPrice] = price
|
||||
// if globals.EnableJdStoreWrite {
|
||||
// err = getAPI("").UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.MergeMaps(params, skuAddParams))
|
||||
// if sku.JdSyncStatus&model.SyncFlagSpecMask != 0 {
|
||||
// skuIndex := sku.SkuIndex
|
||||
// if skuIndex > 0 {
|
||||
// saleAttrValue := composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit)
|
||||
// globals.SugarLogger.Debugf("syncSkuNameAsSpu outSuperId:%d, saleAttrId:%d, saleAttrValueId:%d, saleAttrValueName:%s", skuExt.ID, jdapi.SaleAttrIDBase, jdapi.SaleAttrValueIDBase+skuIndex-1, saleAttrValue)
|
||||
// err = getAPI("").UpdateSpuSaleAttr(utils.Int2Str(skuExt.ID), utils.Int2Str(jdapi.SaleAttrIDBase), "", utils.Int2Str(jdapi.SaleAttrValueIDBase+skuIndex-1), saleAttrValue)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if err == nil {
|
||||
// sku.JdSyncStatus = 0
|
||||
// }
|
||||
// }
|
||||
// return rootTask.ID, err
|
||||
// return vendorSkuID, err
|
||||
// }
|
||||
|
||||
func splitAddParams(addParams map[string]interface{}) (spuAddParams, skuAddParams map[string]interface{}) {
|
||||
if addParams != nil {
|
||||
spuAddParams = make(map[string]interface{})
|
||||
skuAddParams = make(map[string]interface{})
|
||||
for key := range addParams {
|
||||
if skuAddParamsKeyMap[key] == 1 {
|
||||
skuAddParams[key] = addParams[key]
|
||||
} else {
|
||||
spuAddParams[key] = addParams[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
return spuAddParams, skuAddParams
|
||||
}
|
||||
|
||||
// 这个处理JD SPU,补丁形式
|
||||
func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) {
|
||||
// SPU的SKU NAME不需要规格信息
|
||||
skuName = jxutils.ComposeSkuName(skuExt.Prefix, skuExt.Name, sku.Comment, "", 0, "", 0)
|
||||
skuNameJdID := skuExt.JdID
|
||||
globals.SugarLogger.Debugf("syncSkuNameAsSpu1 sku.id=%d, bareSkuName:%s, skuName:%s, skuNameJdID:%d", sku.ID, skuExt.Name, skuName, skuNameJdID)
|
||||
spuAddParams, skuAddParams := splitAddParams(addParams)
|
||||
if !jxutils.IsEmptyID(skuNameJdID) && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除SKU
|
||||
if globals.EnableJdStoreWrite {
|
||||
err = getAPI("").UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted))
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
updateFields := []string{}
|
||||
if skuExt.JdSyncStatus&model.SyncFlagDeletedMask != 0 {
|
||||
sql := `
|
||||
SELECT COUNT(*) ct
|
||||
FROM sku t1
|
||||
WHERE t1.name_id = ? AND (t1.status <> ? OR t1.jd_sync_status <> 0)
|
||||
`
|
||||
var count struct {
|
||||
Ct int
|
||||
}
|
||||
if err = dao.GetRow(db, &count, sql, sku.NameID, model.SkuStatusDeleted); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if count.Ct <= 1 && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 1就是最后删的那个
|
||||
updateFields = append(updateFields, model.FieldJdSyncStatus)
|
||||
if globals.EnableJdStoreWrite {
|
||||
if err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusOffline)); err == nil {
|
||||
err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if skuExt.JdSyncStatus&model.SyncFlagNewMask != 0 && jxutils.IsEmptyID(skuNameJdID) {
|
||||
if globals.EnableJdStoreWrite {
|
||||
spuName := jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0)
|
||||
skus := []map[string]interface{}{
|
||||
map[string]interface{}{
|
||||
jdapi.KeyOutSkuId: utils.Int2Str(sku.ID),
|
||||
jdapi.KeySkuName: skuName,
|
||||
jdapi.KeyFixedStatus: jxStatus2jdStatus(sku.Status),
|
||||
jdapi.KeySkuPrice: price,
|
||||
jdapi.KeyWeight: jxutils.IntWeight2Float(sku.Weight),
|
||||
jdapi.KeyIsSale: true,
|
||||
jdapi.FakeKeySpecAttr: composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit),
|
||||
},
|
||||
}
|
||||
skus[0] = utils.MergeMaps(skus[0], skuAddParams)
|
||||
updateFields = append(updateFields, model.FieldJdSyncStatus)
|
||||
if globals.EnableJdStoreWrite {
|
||||
vendorSpuID, skuPairs, err2 := getAPI("").AddSpu(utils.Int2Str(skuExt.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, spuName, []string{skuExt.Img}, jxStatus2jdStatus(skuExt.Status), spuAddParams, skus)
|
||||
if err = err2; err == nil {
|
||||
skuExt.JdID = vendorSpuID
|
||||
// skuNameJdID = skuExt.JdID // 这个是故意去掉的,这样之后的首次SKU修改操作就会被忽略,下一条语句也就可以不用了
|
||||
// sku.JdSyncStatus &= ^model.SyncFlagNewMask
|
||||
vendorSkuID = utils.Int64ToStr(skuPairs[0].SkuId)
|
||||
updateFields = append(updateFields, model.FieldJdID)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if skuExt.JdSyncStatus&model.SyncFlagModifiedMask != 0 {
|
||||
params := utils.MergeMaps(map[string]interface{}{
|
||||
jdapi.KeySpuName: jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0),
|
||||
jdapi.KeyShopCategories: shopCategories,
|
||||
jdapi.KeyCategoryId: skuExt.JdCategoryID,
|
||||
jdapi.KeyBrandId: skuExt.BrandID,
|
||||
jdapi.KeyImages: []string{skuExt.Img},
|
||||
jdapi.KeyFixedStatus: jxStatus2jdStatus(skuExt.Status),
|
||||
}, spuAddParams)
|
||||
updateFields = append(updateFields, model.FieldJdSyncStatus)
|
||||
if globals.EnableJdStoreWrite {
|
||||
err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), params)
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
if skuExt.JdSyncStatus != 0 && len(updateFields) > 0 {
|
||||
skuExt.JdSyncStatus = 0
|
||||
_, err = dao.UpdateEntity(db, &skuExt.SkuName, updateFields...)
|
||||
globals.SugarLogger.Debugf("syncSkuNameAsSpu4 sku.id=%d, skuName:%s, skuName:%s", sku.ID, skuExt.Name, utils.Format4Output(&skuExt.SkuName, false))
|
||||
}
|
||||
}
|
||||
}
|
||||
if err == nil && !jxutils.IsEmptyID(skuNameJdID) {
|
||||
if sku.JdSyncStatus&model.SyncFlagNewMask != 0 { // 非首次新增SKU
|
||||
if globals.EnableJdStoreWrite {
|
||||
vendorSkuID2, err2 := getAPI("").AppendSku(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{skuExt.Img}, jxStatus2jdStatus(sku.Status), true, composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit), skuAddParams)
|
||||
if err = err2; err == nil {
|
||||
vendorSkuID = utils.Int64ToStr(vendorSkuID2)
|
||||
}
|
||||
}
|
||||
} else if sku.JdSyncStatus&model.SyncFlagModifiedMask != 0 {
|
||||
params := make(map[string]interface{})
|
||||
params[jdapi.KeySkuName] = skuName
|
||||
params[jdapi.KeyImages] = []string{skuExt.Img}
|
||||
params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status)
|
||||
params[jdapi.KeyWeight] = jxutils.IntWeight2Float(sku.Weight)
|
||||
params[jdapi.KeySkuPrice] = price
|
||||
if globals.EnableJdStoreWrite {
|
||||
err = getAPI("").UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.MergeMaps(params, skuAddParams))
|
||||
if sku.JdSyncStatus&model.SyncFlagSpecMask != 0 {
|
||||
skuIndex := sku.SkuIndex
|
||||
if skuIndex > 0 {
|
||||
saleAttrValue := composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit)
|
||||
globals.SugarLogger.Debugf("syncSkuNameAsSpu outSuperId:%d, saleAttrId:%d, saleAttrValueId:%d, saleAttrValueName:%s", skuExt.ID, jdapi.SaleAttrIDBase, jdapi.SaleAttrValueIDBase+skuIndex-1, saleAttrValue)
|
||||
err = getAPI("").UpdateSpuSaleAttr(utils.Int2Str(skuExt.ID), utils.Int2Str(jdapi.SaleAttrIDBase), "", utils.Int2Str(jdapi.SaleAttrValueIDBase+skuIndex-1), saleAttrValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
sku.JdSyncStatus = 0
|
||||
}
|
||||
}
|
||||
return vendorSkuID, err
|
||||
}
|
||||
|
||||
func composeSkuSpec(specQuality float32, specUnit, unit string) string {
|
||||
prefix := ""
|
||||
if unit == model.SpecialUnit {
|
||||
prefix = "约"
|
||||
}
|
||||
value := prefix + jxutils.ComposeSkuSpec(specQuality, specUnit)
|
||||
suffix := "/" + unit
|
||||
if utf8.RuneCountInString(value) <= 8-utf8.RuneCountInString(suffix) {
|
||||
value += suffix
|
||||
}
|
||||
return value
|
||||
}
|
||||
// func composeSkuSpec(specQuality float32, specUnit, unit string) string {
|
||||
// prefix := ""
|
||||
// if unit == model.SpecialUnit {
|
||||
// prefix = "约"
|
||||
// }
|
||||
// value := prefix + jxutils.ComposeSkuSpec(specQuality, specUnit)
|
||||
// suffix := "/" + unit
|
||||
// if utf8.RuneCountInString(value) <= 8-utf8.RuneCountInString(suffix) {
|
||||
// value += suffix
|
||||
// }
|
||||
// return value
|
||||
// }
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"git.rosy.net.cn/jx-callback/globals/api"
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
@@ -113,7 +114,7 @@ func (p *PurchaseHandler) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCo
|
||||
|
||||
func (p *PurchaseHandler) getVendorCategories(level int, pid int64) (vendorCats []*model.SkuVendorCategory, err error) {
|
||||
// 得到平台的分类,不需要指定分账号
|
||||
cats, err := getAPI("").QueryChildCategoriesForOP(pid)
|
||||
cats, err := api.Jd2API.QueryChildCategoriesForOP(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -169,6 +170,10 @@ func skuInfo2Param(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (param *jd
|
||||
if param.CategoryID == 0 {
|
||||
param.CategoryID = int64(getDefJdCategoryID())
|
||||
}
|
||||
// 京东强制要求upc的商品,如果没有设置upc,自动生成一个假的
|
||||
if param.Upc == "" && isSkuMustHaveUpc(sku.Unit, param.CategoryID) {
|
||||
param.Upc = jxutils.GenFakeUPC(sku.SkuID)
|
||||
}
|
||||
if sku.IsGlobal == 0 && len(sku.SellCities) > 0 {
|
||||
param.SellCities = utils.StringSlice2Int64(sku.SellCities)
|
||||
}
|
||||
@@ -200,6 +205,23 @@ func (p *PurchaseHandler) UpdateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSy
|
||||
|
||||
func (p *PurchaseHandler) DeleteSku2(ctx *jxcontext.Context, vendorOrgCode string, sku *partner.StoreSkuInfo) (err error) {
|
||||
globals.SugarLogger.Debugf("DeleteSku2 vendorOrgCode:%s, sku:%s", vendorOrgCode, utils.Format4Output(sku, true))
|
||||
|
||||
// 京东到家只能通过商家ID删除SKU,如果没有的话,先绑定,再删除
|
||||
if sku.SkuID == 0 {
|
||||
skuPairList := []*jdapi.SkuIDPair{
|
||||
&jdapi.SkuIDPair{
|
||||
SkuId: utils.Str2Int64(sku.VendorSkuID),
|
||||
OutSkuId: sku.VendorSkuID,
|
||||
},
|
||||
}
|
||||
if globals.EnableJdStoreWrite {
|
||||
_, err = getAPI(vendorOrgCode).BatchUpdateOutSkuId(skuPairList)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sku.SkuID = int(utils.Str2Int64(sku.VendorSkuID))
|
||||
}
|
||||
}
|
||||
param := &jdapi.OpSkuParam{
|
||||
TraceID: ctx.GetTrackInfo(),
|
||||
OutSkuID: utils.Int2Str(sku.SkuID),
|
||||
@@ -357,3 +379,101 @@ func jxStatus2jdStatus(jxStatus int) (jdStatus int) {
|
||||
}
|
||||
return jdStatus
|
||||
}
|
||||
|
||||
func isSkuMustHaveUpc(unit string, vendorVendorCatID int64) bool {
|
||||
return unit != model.SpecialUnit || !upcLessMap[vendorVendorCatID]
|
||||
}
|
||||
|
||||
var (
|
||||
upcLessMap = map[int64]bool{
|
||||
20250: true,
|
||||
20252: true,
|
||||
20258: true,
|
||||
20259: true,
|
||||
20261: true,
|
||||
20262: true,
|
||||
20263: true,
|
||||
20264: true,
|
||||
20265: true,
|
||||
20266: true,
|
||||
20267: true,
|
||||
22822: true,
|
||||
20269: true,
|
||||
20270: true,
|
||||
20271: true,
|
||||
20272: true,
|
||||
20273: true,
|
||||
20275: true,
|
||||
20276: true,
|
||||
20277: true,
|
||||
20278: true,
|
||||
20279: true,
|
||||
20281: true,
|
||||
20282: true,
|
||||
20283: true,
|
||||
20285: true,
|
||||
20286: true,
|
||||
20287: true,
|
||||
22821: true,
|
||||
20289: true,
|
||||
20290: true,
|
||||
23018: true,
|
||||
20354: true,
|
||||
20355: true,
|
||||
20357: true,
|
||||
20359: true,
|
||||
23019: true,
|
||||
20294: true,
|
||||
20295: true,
|
||||
20296: true,
|
||||
20297: true,
|
||||
20298: true,
|
||||
20299: true,
|
||||
20300: true,
|
||||
20302: true,
|
||||
20303: true,
|
||||
20304: true,
|
||||
22840: true,
|
||||
22841: true,
|
||||
20317: true,
|
||||
20320: true,
|
||||
20321: true,
|
||||
20323: true,
|
||||
20325: true,
|
||||
20326: true,
|
||||
20328: true,
|
||||
20329: true,
|
||||
20331: true,
|
||||
20335: true,
|
||||
20337: true,
|
||||
20338: true,
|
||||
20339: true,
|
||||
22842: true,
|
||||
22843: true,
|
||||
23020: true,
|
||||
20309: true,
|
||||
20310: true,
|
||||
20311: true,
|
||||
20312: true,
|
||||
20313: true,
|
||||
20314: true,
|
||||
20315: true,
|
||||
22410: true,
|
||||
23050: true,
|
||||
20319: true,
|
||||
20322: true,
|
||||
20330: true,
|
||||
20332: true,
|
||||
20334: true,
|
||||
20336: true,
|
||||
20340: true,
|
||||
20342: true,
|
||||
23049: true,
|
||||
20356: true,
|
||||
20358: true,
|
||||
20360: true,
|
||||
20361: true,
|
||||
20362: true,
|
||||
20364: true,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -23,20 +23,6 @@ func TestCreateSku(t *testing.T) {
|
||||
// }
|
||||
}
|
||||
|
||||
func TestUpdateSku(t *testing.T) {
|
||||
// t.Log(beego.BConfig.RunMode)
|
||||
db := dao.GetDB()
|
||||
skuID := 21741
|
||||
sku := &model.Sku{}
|
||||
sku.ID = skuID
|
||||
dao.GetEntity(db, sku)
|
||||
|
||||
err := CurPurchaseHandler.UpdateSku(db, sku, "autotest")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllCategories(t *testing.T) {
|
||||
result, err := CurPurchaseHandler.GetAllCategories(jxcontext.AdminCtx, "")
|
||||
if err != nil || len(result) == 0 {
|
||||
|
||||
@@ -36,6 +36,7 @@ type tJdStoreInfo struct {
|
||||
VendorStoreID string `orm:"column(vendor_store_id)"`
|
||||
RealLastOperator string
|
||||
SyncStatus int
|
||||
VendorStoreName string
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -123,7 +124,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
||||
t1.*, city.jd_code jd_city_code, district.jd_code jd_district_code,
|
||||
t2.status jd_store_status, t2.vendor_store_id, IF(t1.updated_at > t2.updated_at, t1.last_operator,
|
||||
t2.last_operator) real_last_operator,
|
||||
t2.sync_status, t2.freight_deduction_pack, t2.vendor_org_code
|
||||
t2.sync_status, t2.freight_deduction_pack, t2.vendor_org_code, t2.vendor_store_name
|
||||
FROM store t1
|
||||
JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND (t2.deleted_at = ?)
|
||||
LEFT JOIN place city ON t1.city_code = city.code
|
||||
@@ -146,7 +147,11 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
||||
storeParams.OutSystemID = store.VendorStoreID
|
||||
}
|
||||
if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 {
|
||||
storeParams.StationName = jxutils.ComposeStoreName(store.Name, model.VendorIDJD)
|
||||
if store.VendorStoreName != "" {
|
||||
storeParams.StationName = store.VendorStoreName
|
||||
} else {
|
||||
storeParams.StationName = jxutils.ComposeStoreName(store.Name, model.VendorIDJD)
|
||||
}
|
||||
}
|
||||
if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreAddress) != 0 {
|
||||
storeParams.StationAddress = store.Address
|
||||
@@ -170,7 +175,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
||||
storeParams.City = storeParams.County
|
||||
storeParams.County = specialDistrictMap[storeParams.County]
|
||||
}
|
||||
|
||||
storeParams.StoreNotice = store.PromoteInfo
|
||||
modifyCloseStatus := false
|
||||
if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagDeletedMask|model.SyncFlagStoreStatus) != 0 {
|
||||
modifyCloseStatus = true
|
||||
|
||||
@@ -64,7 +64,7 @@ func (c *PurchaseHandler) callbackMsg2Waybill(msg *jdapi.CallbackDeliveryStatusM
|
||||
StatusTime: utils.Str2Time(msg.DeliveryStatusTime),
|
||||
Remark: msg.Remark,
|
||||
|
||||
VendorOrgCode: appKey2OrgCode(msg.AppKey),
|
||||
VendorOrgCode: AppKey2OrgCode(msg.AppKey),
|
||||
}
|
||||
return retVal
|
||||
}
|
||||
|
||||
@@ -152,13 +152,30 @@ func CreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64,
|
||||
outJxOrder.OrderID = GenOrderNo(ctx)
|
||||
order, err2 := jxOrder2GoodsOrder(ctx, outJxOrder, deliveryAddress)
|
||||
if err = err2; err == nil {
|
||||
order.Status = model.OrderStatusCreated
|
||||
order.Status = model.OrderStatusWait4Pay
|
||||
callNewOrder(order)
|
||||
}
|
||||
}
|
||||
return outJxOrder, err
|
||||
}
|
||||
|
||||
// 买家取消(或申请取消)订单
|
||||
func BuyerCancelOrder(ctx *jxcontext.Context, orderID int64) (canceled bool, err error) {
|
||||
order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX)
|
||||
if err == nil {
|
||||
if order.Status < model.OrderStatusNew {
|
||||
order.Status = model.OrderStatusCanceled
|
||||
order.VendorStatus = utils.Int2Str(model.OrderStatusCanceled)
|
||||
if err = partner.CurOrderManager.UpdateOrderFields(order, []string{model.FieldStatus, "VendorStatus"}); err == nil {
|
||||
canceled = true
|
||||
}
|
||||
} else {
|
||||
err = changeOrderStatus(utils.Int64ToStr(orderID), model.OrderStatusApplyCancel, fmt.Sprintf("用户%s主动取消", ctx.GetUserName()))
|
||||
}
|
||||
}
|
||||
return canceled, err
|
||||
}
|
||||
|
||||
func Pay4Order(ctx *jxcontext.Context, orderID int64, payType int, vendorPayType string) (orderPay *model.OrderPay, err error) {
|
||||
order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX)
|
||||
if err == nil {
|
||||
@@ -255,6 +272,10 @@ func GenOrderNo(ctx *jxcontext.Context) (orderNo int64) {
|
||||
return orderNo
|
||||
}
|
||||
|
||||
func GenPayOrderID(order *model.GoodsOrder) (payOrderID int64) {
|
||||
return utils.Str2Int64(order.VendorOrderID)
|
||||
}
|
||||
|
||||
func GenRefundID(order *model.GoodsOrder) (refundID int64) {
|
||||
const suffix = 100000
|
||||
refundID = utils.Str2Int64(order.VendorOrderID) * suffix
|
||||
@@ -385,7 +406,7 @@ func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64
|
||||
Count: v.Count,
|
||||
SalePrice: int64(storeSkuBind.JxPrice), // todo 考虑活动价
|
||||
Weight: sku.Weight,
|
||||
Name: jxutils.ComposeSkuName(sku.Prefix, sku.Name, sku.Comment, sku.Unit, sku.SpecQuality, sku.SpecUnit, 0),
|
||||
Name: jxutils.ComposeSkuName(sku.Prefix, sku.Name, sku.Comment, sku.Unit, sku.SpecQuality, sku.SpecUnit, 0, sku.ExPrefix, sku.ExPrefixBegin, sku.ExPrefixEnd),
|
||||
}
|
||||
if storeSkuBind.ActPrice != 0 && storeSkuBind.ActPrice < storeSkuBind.JxPrice {
|
||||
jxSku.SalePrice = int64(storeSkuBind.ActPrice)
|
||||
@@ -490,6 +511,10 @@ func AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName stri
|
||||
return changeOrderStatus(order.VendorOrderID, status, "")
|
||||
}
|
||||
|
||||
func AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
|
||||
return changeOrderStatus(order.VendorOrderID, model.OrderStatusFinishedPickup, "")
|
||||
}
|
||||
@@ -510,8 +535,9 @@ func CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string)
|
||||
errList := errlist.New()
|
||||
for _, orderPay := range payList {
|
||||
if orderPay.Status == model.PayStatusYes {
|
||||
refundID := utils.Int64ToStr(GenRefundID(order))
|
||||
orderPayRefund, err2 := refundOrderByWX(ctx, orderPay, refundID)
|
||||
// refundID := utils.Int64ToStr(GenRefundID(order))
|
||||
refundID := order.VendorOrderID
|
||||
orderPayRefund, err2 := refundOrderByWX(ctx, orderPay, refundID, orderPay.TotalFee, reason)
|
||||
if err2 == nil {
|
||||
dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName())
|
||||
errList.AddErr(dao.CreateEntity(dao.GetDB(), orderPayRefund))
|
||||
@@ -535,6 +561,15 @@ func CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string)
|
||||
return err
|
||||
}
|
||||
|
||||
func AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
|
||||
if isAgree {
|
||||
err = CancelOrder(ctx, order, reason)
|
||||
} else {
|
||||
err = changeOrderStatus(order.VendorOrderID, model.OrderStatusVendorRejectCancel, reason)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// todo 消息用异步可能导致丢失,单同步又有重入相关的问题
|
||||
func callNewOrder(order *model.GoodsOrder) (err error) {
|
||||
jxutils.CallMsgHandlerAsync(func() {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/wxpay"
|
||||
"git.rosy.net.cn/baseapi/platformapi/wxpayapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
@@ -25,16 +25,16 @@ func getOrderBrief(order *model.GoodsOrder) string {
|
||||
|
||||
func pay4OrderByWX(ctx *jxcontext.Context, order *model.GoodsOrder, vendorPayType string) (orderPay *model.OrderPay, err error) {
|
||||
payCreatedAt := time.Now()
|
||||
param := &wxpay.CreateOrderParam{
|
||||
param := &wxpayapi.CreateOrderParam{
|
||||
OutTradeNo: utils.Int64ToStr(GenPayOrderID(order)),
|
||||
Body: getOrderBrief(order),
|
||||
NotifyURL: globals.WxpayNotifyURL,
|
||||
OutTradeNo: order.VendorOrderID,
|
||||
SpbillCreateIP: ctx.GetRealRemoteIP(),
|
||||
TradeType: vendorPayType2WxpayType(vendorPayType),
|
||||
TotalFee: int(order.ActualPayPrice),
|
||||
|
||||
TimeStart: wxpay.Time2PayTime(payCreatedAt),
|
||||
// TimeExpire: wxpay.Time2PayTime(payCreatedAt.Add(PayWaitingTime)),
|
||||
TimeStart: wxpayapi.Time2PayTime(payCreatedAt),
|
||||
// TimeExpire: wxpayapi.Time2PayTime(payCreatedAt.Add(PayWaitingTime)),
|
||||
}
|
||||
if authInfo, err := ctx.GetV2AuthInfo(); err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini {
|
||||
param.OpenID = authInfo.GetAuthID()
|
||||
@@ -42,10 +42,12 @@ func pay4OrderByWX(ctx *jxcontext.Context, order *model.GoodsOrder, vendorPayTyp
|
||||
result, err := api.WxpayAPI.CreateUnifiedOrder(param)
|
||||
if err == nil {
|
||||
orderPay = &model.OrderPay{
|
||||
VendorOrderID: order.VendorOrderID,
|
||||
VendorID: order.VendorID,
|
||||
PayOrderID: param.OutTradeNo,
|
||||
PayType: model.PayTypeWX,
|
||||
VendorPayType: vendorPayType,
|
||||
|
||||
VendorOrderID: order.VendorOrderID,
|
||||
VendorID: order.VendorID,
|
||||
Status: 0,
|
||||
PayCreatedAt: payCreatedAt,
|
||||
PrepayID: result.PrepayID,
|
||||
@@ -56,37 +58,35 @@ func pay4OrderByWX(ctx *jxcontext.Context, order *model.GoodsOrder, vendorPayTyp
|
||||
return orderPay, err
|
||||
}
|
||||
|
||||
func OnWxPayCallback(msg *wxpay.CallbackMsg) (err error) {
|
||||
func OnWxPayCallback(msg *wxpayapi.CallbackMsg) (err error) {
|
||||
globals.SugarLogger.Debugf("OnWxPayCallback msg:%s", utils.Format4Output(msg, true))
|
||||
switch msg.MsgType {
|
||||
case wxpay.MsgTypePay:
|
||||
err = onWxpayFinished(msg.Data.(*wxpay.PayResultMsg))
|
||||
case wxpay.MsgTypeRefund:
|
||||
err = onWxpayRefund(msg.Data.(*wxpay.RefundResultMsg))
|
||||
case wxpayapi.MsgTypePay:
|
||||
err = onWxpayFinished(msg.Data.(*wxpayapi.PayResultMsg))
|
||||
case wxpayapi.MsgTypeRefund:
|
||||
err = onWxpayRefund(msg.Data.(*wxpayapi.RefundResultMsg))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func onWxpayFinished(msg *wxpay.PayResultMsg) (err error) {
|
||||
func onWxpayFinished(msg *wxpayapi.PayResultMsg) (err error) {
|
||||
orderPay := &model.OrderPay{
|
||||
VendorOrderID: msg.OutTradeNo,
|
||||
VendorID: jxutils.GetPossibleVendorIDFromVendorOrderID(msg.OutTradeNo),
|
||||
PayType: model.PayTypeWX,
|
||||
PayOrderID: msg.OutTradeNo,
|
||||
PayType: model.PayTypeWX,
|
||||
}
|
||||
orderPay.DeletedAt = utils.DefaultTimeValue
|
||||
db := dao.GetDB()
|
||||
if err = dao.GetEntity(db, orderPay, "VendorOrderID", "VendorID", "PayType", "DeletedAt"); err == nil {
|
||||
orderPay.VendorPayType = msg.TradeType
|
||||
orderPay.PayFinishedAt = utils.Time2Pointer(wxpay.PayTime2Time(msg.TimeEnd))
|
||||
if err = dao.GetEntity(db, orderPay, "PayOrderID", "PayType", "DeletedAt"); err == nil {
|
||||
orderPay.PayFinishedAt = utils.Time2Pointer(wxpayapi.PayTime2Time(msg.TimeEnd))
|
||||
orderPay.TransactionID = msg.TransactionID
|
||||
orderPay.OriginalData = utils.Format4Output(msg, true)
|
||||
if msg.ResultCode == wxpay.ResponseCodeSuccess {
|
||||
if msg.ResultCode == wxpayapi.ResponseCodeSuccess {
|
||||
orderPay.Status = model.PayStatusYes
|
||||
} else {
|
||||
orderPay.Status = model.PayStatusFailed
|
||||
}
|
||||
dao.UpdateEntity(db, orderPay)
|
||||
if msg.ResultCode == wxpay.ResponseCodeSuccess {
|
||||
if msg.ResultCode == wxpayapi.ResponseCodeSuccess {
|
||||
err = OnPayFinished(orderPay)
|
||||
}
|
||||
} else {
|
||||
@@ -95,13 +95,13 @@ func onWxpayFinished(msg *wxpay.PayResultMsg) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func onWxpayRefund(msg *wxpay.RefundResultMsg) (err error) {
|
||||
func onWxpayRefund(msg *wxpayapi.RefundResultMsg) (err error) {
|
||||
orderPayRefund := &model.OrderPayRefund{
|
||||
RefundID: msg.ReqInfoObj.OutRefundNo,
|
||||
}
|
||||
db := dao.GetDB()
|
||||
if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil {
|
||||
if msg.ResultCode == wxpay.ResponseCodeSuccess {
|
||||
if msg.ResultCode == wxpayapi.ResponseCodeSuccess {
|
||||
orderPayRefund.Status = model.RefundStatusYes
|
||||
} else {
|
||||
orderPayRefund.Status = model.RefundStatusFailed
|
||||
@@ -126,13 +126,14 @@ func onWxpayRefund(msg *wxpay.RefundResultMsg) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func refundOrderByWX(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string) (orderPayRefund *model.OrderPayRefund, err error) {
|
||||
result, err := api.WxpayAPI.PayRefund(&wxpay.PayRefundParam{
|
||||
func refundOrderByWX(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) {
|
||||
result, err := api.WxpayAPI.PayRefund(&wxpayapi.PayRefundParam{
|
||||
OutTradeNo: orderPay.VendorOrderID,
|
||||
NotifyURL: globals.WxpayNotifyURL,
|
||||
OutRefundNo: refundID,
|
||||
TotalFee: orderPay.TotalFee,
|
||||
RefundFee: orderPay.TotalFee,
|
||||
RefundFee: refundFee,
|
||||
RefundDesc: wxpayapi.CData(refundDesc),
|
||||
})
|
||||
if err == nil {
|
||||
orderPayRefund = &model.OrderPayRefund{
|
||||
|
||||
@@ -16,9 +16,18 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) {
|
||||
order, err = partner.CurOrderManager.LoadOrder(orderID, model.VendorIDJX)
|
||||
return order, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) {
|
||||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJX)
|
||||
if err == nil {
|
||||
status = order.Status
|
||||
}
|
||||
return status, err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
|
||||
var status int
|
||||
if isAcceptIt {
|
||||
@@ -86,6 +95,10 @@ func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *mode
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
|
||||
if model.IsOrderJXTemp(order) {
|
||||
} else {
|
||||
err = localjx.AgreeOrRefuseCancel(ctx, order, isAgree, reason)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -99,6 +112,10 @@ func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.Goods
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
||||
if model.IsOrderJXTemp(order) {
|
||||
} else {
|
||||
err = localjx.AdjustOrder(ctx, order, removedSkuList, reason)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -106,14 +123,6 @@ func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode strin
|
||||
return vendorOrderIDs, err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder) (tipFee int64, err error) {
|
||||
return tipFee, err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) AddWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee2Add int64) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID, selfTakeCode string) (err error) {
|
||||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJX)
|
||||
if err == nil {
|
||||
|
||||
@@ -9,25 +9,25 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/business/partner"
|
||||
)
|
||||
|
||||
func (p *PurchaseHandler) CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||
return err
|
||||
}
|
||||
// func (p *PurchaseHandler) CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||
// return err
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*partner.BareCategoryInfo, err error) {
|
||||
return cats, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error {
|
||||
return nil
|
||||
}
|
||||
// func (p *PurchaseHandler) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error {
|
||||
return nil
|
||||
}
|
||||
// func (p *PurchaseHandler) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error) {
|
||||
return err
|
||||
}
|
||||
// func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error) {
|
||||
// return err
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) {
|
||||
return err
|
||||
@@ -45,21 +45,21 @@ func (p *PurchaseHandler) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCo
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
return err
|
||||
}
|
||||
// func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// func (p *PurchaseHandler) ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) {
|
||||
// return skuNameExt, err
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
return err
|
||||
}
|
||||
// func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
// return err
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
return err
|
||||
}
|
||||
// func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||
// return err
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) {
|
||||
return err
|
||||
|
||||
@@ -13,6 +13,17 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/globals/api"
|
||||
)
|
||||
|
||||
func jxActType2Mtwm(actType int) int {
|
||||
if actType == model.ActSkuDirectDown {
|
||||
actType = mtwmapi.RetailActTypeDirectDown
|
||||
} else if actType == model.ActSkuSecKill {
|
||||
actType = mtwmapi.RetailActTypeSecKill
|
||||
} else {
|
||||
actType = 0
|
||||
}
|
||||
return actType
|
||||
}
|
||||
|
||||
func actOrderRules2Mtwm(actOrderRules []*model.ActOrderRule) (actDetails []*mtwmapi.FullDiscountActDetail) {
|
||||
for _, v := range actOrderRules {
|
||||
actDetails = append(actDetails, &mtwmapi.FullDiscountActDetail{
|
||||
@@ -73,7 +84,7 @@ func createOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*mode
|
||||
actData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate)
|
||||
if len(actData) > 0 {
|
||||
if globals.EnableMtwmStoreWrite {
|
||||
actResult, err2 := api.MtwmAPI.RetailDiscountBatchSave(vendorStoreID, actData)
|
||||
actResult, err2 := api.MtwmAPI.RetailDiscountBatchSave(vendorStoreID, jxActType2Mtwm(act.Type), actData)
|
||||
globals.SugarLogger.Debugf("mtwm createOneShopAct err2:%v", err2)
|
||||
if err = err2; err != nil {
|
||||
return err
|
||||
@@ -96,10 +107,10 @@ func createOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*mode
|
||||
return err
|
||||
}
|
||||
|
||||
func cancelOneShopAct(ctx *jxcontext.Context, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||
func cancelOneShopAct(ctx *jxcontext.Context, act *model.Act2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||
if list := storeSku2ActData4Delete(actStoreSku, nil /*model.IsSyncStatusNeedDelete*/); len(list) > 0 {
|
||||
if globals.EnableMtwmStoreWrite {
|
||||
err = api.MtwmAPI.RetailDiscountDelete(actStoreSku[0].VendorStoreID, list)
|
||||
err = api.MtwmAPI.RetailDiscountDelete(actStoreSku[0].VendorStoreID, jxActType2Mtwm(act.Type), list)
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -129,13 +140,13 @@ func createSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.A
|
||||
return getActStoreSkuFromTaskResult(result), err
|
||||
}
|
||||
|
||||
func cancelSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, actStoreSku []*model.ActStoreSku2) (canceledList []*model.ActStoreSku2, err error) {
|
||||
func cancelSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (canceledList []*model.ActStoreSku2, err error) {
|
||||
globals.SugarLogger.Debugf("mtwm cancelSkuAct")
|
||||
actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku)
|
||||
task := tasksch.NewParallelTask("mtwm cancelSkuAct", nil, ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
actStoreSkuList := batchItemList[0].([]*model.ActStoreSku2)
|
||||
if err = cancelOneShopAct(ctx, actStoreSkuList); err == nil {
|
||||
if err = cancelOneShopAct(ctx, act, actStoreSkuList); err == nil {
|
||||
retVal = []interface{}{actStoreSkuList}
|
||||
}
|
||||
return retVal, err
|
||||
@@ -162,7 +173,7 @@ func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITa
|
||||
}
|
||||
err = func() (err error) {
|
||||
if model.IsSyncStatusDelete(act.SyncStatus) {
|
||||
canceledList, err2 := cancelSkuAct(ctx, nil, actStoreSkuList)
|
||||
canceledList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList)
|
||||
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, canceledList, model.SyncFlagModifiedMask)...)
|
||||
if err = err2; err == nil {
|
||||
updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask))
|
||||
@@ -183,7 +194,7 @@ func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITa
|
||||
}
|
||||
}
|
||||
if len(actStoreSkuList4Delete) > 0 {
|
||||
deletedList, err2 := cancelSkuAct(ctx, nil, actStoreSkuList4Delete)
|
||||
deletedList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList4Delete)
|
||||
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, deletedList, model.SyncFlagDeletedMask)...)
|
||||
if err = err2; err != nil {
|
||||
return err
|
||||
|
||||
@@ -65,7 +65,7 @@ var (
|
||||
|
||||
fakeFinishedPickup: model.OrderStatusFinishedPickup,
|
||||
fakeOrderAdjustFinished: model.OrderStatusAdjust,
|
||||
fakeRefuseUserApplyCancel: model.OrderStatusUnlocked,
|
||||
fakeRefuseUserApplyCancel: model.OrderStatusVendorRejectCancel,
|
||||
fakeUserApplyCancel: model.OrderStatusApplyCancel,
|
||||
fakeUserUndoApplyCancel: model.OrderStatusUndoApplyCancel,
|
||||
fakeMerchantAgreeApplyCancel: model.OrderStatusCanceled,
|
||||
@@ -99,6 +99,14 @@ func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *
|
||||
return order, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) {
|
||||
status, err = api.MtwmAPI.OrderViewStatus(utils.Str2Int64(vendorOrderID))
|
||||
if err == nil {
|
||||
status = p.getStatusFromVendorStatus(utils.Int2Str(status))
|
||||
}
|
||||
return status, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
|
||||
result := orderData
|
||||
vendorOrderID := utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"]))
|
||||
@@ -127,6 +135,7 @@ func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
||||
OrderCreatedAt: getTimeFromTimestamp(utils.MustInterface2Int64(result["ctime"])),
|
||||
OriginalData: string(utils.MustMarshal(result)),
|
||||
ActualPayPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(result["total"])),
|
||||
BaseFreightMoney: jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["shipping_fee"], 0)),
|
||||
|
||||
InvoiceTitle: utils.Interface2String(result["invoice_title"]),
|
||||
InvoiceTaxerID: utils.Interface2String(result["taxpayer_id"]),
|
||||
@@ -746,3 +755,18 @@ func (p *PurchaseHandler) onNumberDowngrade(msg *mtwmapi.CallbackMsg) (response
|
||||
tasksch.HandleTask(task, nil, true).Run()
|
||||
return response
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) {
|
||||
orderInfo, err := api.MtwmAPI.GetDistributeOrderDetail(vendorOrderID, vendorStoreID)
|
||||
if err == nil {
|
||||
tipFee = jxutils.StandardPrice2Int(orderInfo.TipAmount)
|
||||
}
|
||||
return tipFee, err
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) {
|
||||
if globals.EnableMtwmStoreWrite {
|
||||
err = api.MtwmAPI.OrderModityTips(vendorOrderID, vendorStoreID, jxutils.IntPrice2Standard(tipFee))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -18,6 +18,14 @@ func TestGetOrder(t *testing.T) {
|
||||
t.Log(utils.Format4Output(result, false))
|
||||
}
|
||||
|
||||
func TestGetOrderStatus(t *testing.T) {
|
||||
result, err := CurPurchaseHandler.GetOrderStatus("", "71884881906304496")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(utils.Format4Output(result, false))
|
||||
}
|
||||
|
||||
func TestListOrders(t *testing.T) {
|
||||
result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "", nil, time.Now(), "4626746")
|
||||
if err != nil {
|
||||
|
||||
@@ -101,6 +101,7 @@ func (p *PurchaseHandler) CreateStore(db *dao.DaoDB, storeID int, userName strin
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) {
|
||||
var name string
|
||||
if db == nil {
|
||||
db = dao.GetDB()
|
||||
}
|
||||
@@ -115,10 +116,16 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
||||
return err
|
||||
}
|
||||
mergedStoreStatus := jxutils.MergeStoreStatus(storeDetail.Status, storeDetail.VendorStatus)
|
||||
name = remoteStoreInfo.Name
|
||||
if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 {
|
||||
if storeDetail.VendorStoreName != "" {
|
||||
name = storeDetail.VendorStoreName
|
||||
}
|
||||
}
|
||||
// openLevel, isOnline := bizStatusJX2Mtwm(mergedStoreStatus)
|
||||
params := map[string]interface{}{
|
||||
"name": remoteStoreInfo.Name, //jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM),
|
||||
"address": storeDetail.Address, // 美团好像地址也不能改的?
|
||||
"name": name, //jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM),
|
||||
"address": storeDetail.Address, // 美团好像地址也不能改的?
|
||||
"longitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Longitude)),
|
||||
"latitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Latitude)),
|
||||
"phone": storeDetail.Tel1,
|
||||
@@ -127,6 +134,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
||||
"open_level": remoteStoreInfo.OpenLevel,
|
||||
"is_online": remoteStoreInfo.IsOnline,
|
||||
"third_tag_name": remoteStoreInfo.ThirdTagName,
|
||||
"promotion_info": storeDetail.PromoteInfo,
|
||||
}
|
||||
// globals.SugarLogger.Debug(utils.Format4Output(params, false))
|
||||
if globals.EnableMtwmStoreWrite {
|
||||
|
||||
@@ -44,7 +44,7 @@ func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) {
|
||||
case partner.FuncCreateStoreSkus:
|
||||
batchSize = 1 // 可考虑用批量操作
|
||||
case partner.FuncUpdateStoreSkus:
|
||||
batchSize = mtwmapi.MaxStoreSkuBatchSize
|
||||
batchSize = 1 // mtwmapi.MaxStoreSkuBatchSize
|
||||
case partner.FuncGetStoreSkusFullInfo:
|
||||
batchSize = 1
|
||||
}
|
||||
@@ -291,7 +291,9 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
|
||||
skus[0]["price"] = foodData["price"]
|
||||
}
|
||||
skus[0]["stock"] = stockCount2Mtwm(model.MaxStoreSkuStockQty)
|
||||
skus[0]["upc"] = storeSku.Upc
|
||||
if storeSku.Upc != "" {
|
||||
skus[0]["upc"] = storeSku.Upc
|
||||
}
|
||||
if foodData["tag_id"] != nil {
|
||||
skus[0]["weight"] = storeSku.Weight // weight字段仅限服饰鞋帽、美妆、日用品、母婴、生鲜果蔬、生活超市下的便利店/超市门店品类的商家使用
|
||||
}
|
||||
@@ -432,7 +434,9 @@ func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTas
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
skuNameList = append(skuNameList, vendorSku2Jx(skuInfo))
|
||||
if skuName := vendorSku2Jx(skuInfo); skuName != nil {
|
||||
skuNameList = append(skuNameList, skuName)
|
||||
}
|
||||
} else {
|
||||
var storeSkuMap map[string]*partner.StoreSkuInfo
|
||||
if storeSkuList != nil {
|
||||
@@ -449,7 +453,9 @@ func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTas
|
||||
} else {
|
||||
for _, v := range result {
|
||||
if storeSkuMap[v.AppFoodCode] != nil {
|
||||
skuNameList = append(skuNameList, vendorSku2Jx(v))
|
||||
if skuName := vendorSku2Jx(v); skuName != nil {
|
||||
skuNameList = append(skuNameList, skuName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -462,6 +468,10 @@ func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTas
|
||||
}
|
||||
|
||||
func vendorSku2Jx(appFood *mtwmapi.AppFood) (skuName *partner.SkuNameInfo) {
|
||||
if len(appFood.SkuList) == 0 {
|
||||
globals.SugarLogger.Warnf("vendorSku2Jx, strange appFood:%s", utils.Format4Output(appFood, true))
|
||||
return nil
|
||||
}
|
||||
prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(appFood.Name)
|
||||
vendorSku := appFood.SkuList[0]
|
||||
weight := int(utils.Str2Int64WithDefault(vendorSku.Weight, 0))
|
||||
@@ -507,7 +517,9 @@ func vendorSku2Jx(appFood *mtwmapi.AppFood) (skuName *partner.SkuNameInfo) {
|
||||
|
||||
func vendorSkuList2Jx(appFoodList []*mtwmapi.AppFood) (skuNameList []*partner.SkuNameInfo) {
|
||||
for _, appFood := range appFoodList {
|
||||
skuNameList = append(skuNameList, vendorSku2Jx(appFood))
|
||||
if skuName := vendorSku2Jx(appFood); skuName != nil {
|
||||
skuNameList = append(skuNameList, skuName)
|
||||
}
|
||||
}
|
||||
return skuNameList
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package wsc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/weimobapi"
|
||||
@@ -108,6 +109,10 @@ func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *
|
||||
return order, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) {
|
||||
return 0, fmt.Errorf("未实现")
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
|
||||
result := orderData
|
||||
vendorOrderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderNo"]))
|
||||
|
||||
@@ -246,7 +246,7 @@ func GetRecipeDetail(ctx *jxcontext.Context, recipeID int) (recipeDetail *FoodRe
|
||||
}
|
||||
choiceMap := make(map[int8][]*dao.FoodRecipeItemChoiceExt)
|
||||
for _, v := range itemChoiceList {
|
||||
v.SkuName = jxutils.ComposeSkuName(v.Prefix, v.SkuNameName, v.Comment, v.Unit, v.SpecQuality, v.SpecUnit, 0)
|
||||
v.SkuName = jxutils.ComposeSkuNameOriginal(v.Prefix, v.SkuNameName, v.Comment, v.Unit, v.SpecQuality, v.SpecUnit, 0)
|
||||
choiceMap[v.Index] = append(choiceMap[v.Index], v)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ dadaAppSecret = "2c717ad914767d6e2beb3f743db9e477"
|
||||
mtwmAppID = "589"
|
||||
mtwmSecret = "a81eb3df418d83d6a1a4b7c572156d2f"
|
||||
mtwmCallbackURL = "http://callback.jxc4.com"
|
||||
mtwmCookieStr = "_lxsdk_cuid=16eb02a8a02c8-0a92cb9af9798c-3d375b01-15f900-16eb02a8a02c8; _lxsdk=16eb02a8a02c8-0a92cb9af9798c-3d375b01-15f900-16eb02a8a02c8; device_uuid=!aaa93749-2445-4e1e-b178-956ac0ea5e45; pushToken=0sMxJkF87HeJFNGInMgnpvQ3ohIqeo_UMZ8VDif29S6s*; _lx_utm=utm_source%3DBaidu%26utm_medium%3Dorganic; wpush_server_url=wss://wpush.meituan.com; acctId=26599188; token=0o7UnNs2yauqdj86R145ow78W9cT9krlWpKPmCan2z7Q*; brandId=-1; wmPoiId=-1; isOfflineSelfOpen=0; city_id=0; isChain=1; existBrandPoi=true; ignore_set_router_proxy=true; region_id=; region_version=0; newCategory=false; bsid=PgNahlgfXvqnBiqv9tIi9zg7LDWtV8n70tkl_GhfueXgrLxV9BEb1rP9emUMnUUKPI6rANs_Y-chSdYLZS3KCA; cityId=510100; provinceId=510000; city_location_id=0; location_id=0; JSESSIONID=uht6v2iau9s6fx86r1ue6vzd; set_info=%7B%22wmPoiId%22%3A-1%2C%22ignoreSetRouterProxy%22%3Atrue%7D; igateApp=shangouepc; LX_SC_CONSTANT=c_nehoktcu; shopCategory=food; _lxsdk_s=16f40af4486-049-a66-a48%7C26337904%7C37"
|
||||
|
||||
autonaviKey = "ef64f638f31e05cb7bde28790f7309fe"
|
||||
|
||||
@@ -58,8 +59,8 @@ wxpayNotifyURL = "http://callback.test.jxc4.com/wxpay/msg/"
|
||||
backstageHost = "http://www.jxc4.com"
|
||||
wxBackstageHost = "http://wx.jxc4.com"
|
||||
|
||||
jdStorePageCookie = "OPJQMA7B3FTKCAUGO7FHCH5NMBGAWGGXYRNLEHYYZNGNPNIBCAM4IOEPG3NT3RIA44G5C3535Q5LGG4F4SR4AZVLGYKYTKFJJKEAOXENVBL5VXNILRP3GLNVVWA26XZ3VGSYOHA72RICMVZS3G53DTEH3LYUCSS54VI6WPOAGGDK532VYPEWWVCXUFRWENWDI4PEKM7SXBZ5BJO6DBLLERUA74YR2CVCGP4WUROCAHAMXKJ2VBGHTZYRL2DHR3BMXAHCTBAHYQLL24K5YI2PULRJL2UGAVD7VFRMEYTOXYHWCYVDXJ6HYFIPWIN3ULLXDDLN2ICON4GRK"
|
||||
jd2StorePageCookie = "CK5GE5MR2UIOBOZC7BBZLLSI7MVDWPEQ4BRJTJQ2OP3ZFKYDDYTHXLZR3RDCQD6WXIWTDOSXTP3AQEC2D3ZS24VYF7PTTKKUKN7G4XBQS3QOBGUDNLQNEY7CLSNLWZCC7LNI6GZOWOOEN72AWG53MMCURHIQRBG7CGEGVIZQNRKV2NAWXHUA2REY6NP2B3GHPO6S4H35ST5KQXRJWL5LJSIWZHXGPYA3OGPRNAHBLVVNTQE6OL2RPMHQYNXCFMU5QQERDWPFLIWKB7W4GI7GHKLYDY"
|
||||
jdStorePageCookie = "YYJV3NHVBPHLD36FWP6F3EM5PTXJ2XZQS7U4HWRIDPP4IWGUKUIB4XG5N26CZRDLDF7PKOXBPD6BNTUAJLETLZOIWMCVFI3K6MYZIY4QBIXIMXYDJNUKFGJVQTN5356SAD6WPCIHWNQAG7DDMF7L7S3SHD6O37OTAHUCKU6ALXATYTGMHNFLM4XRLVSFUQAJR77M4URSZRKVO55243TDVXLO25PP4UYSPTTPMNRUFXDNP4WPE566Q6V4AH32F7HT"
|
||||
jd2StorePageCookie = "CK5GE5MR2UIOBOZC7BBZLLSI7MVDWPEQ4BRJTJQ2OP3ZFKYDDYTFFV4XOXKLERC2UXFT44TMCUMRFP3C25HD6W3PYONTQCOML6YIZA5Z37P62UXFE655IRGYJ4ZLQIEBYQM32FABIN5RVJYZWPQWSRTZURNRLYV57XJEDWZT5UVZRYUBTN3AT6JJJJ22YHE6ZHCN6LCH27JHSRO55YA6TJH6G54IF72X3UAXCKW5P2G2MT3U6I3527NQFMAFLHXBZKQFFMYUKUHUU4GZWD4O7GO45Y"
|
||||
|
||||
ebaiStorePageCookieWMUSS = "B0AAFQCAAAGbhkuMCsvcyYBDkkyAxBGIBlgXAQYVwc7VwYZFkx2HDoPSmo5eV1femopWgJRawhgAALG04cg1RUmhUakBbJRdgPS0tNEhnQhNRewwuWwYYBDEFPCQSDXV5YWA6PAVRHUJ9SnVGMThYAjNjLw9pRxIbS04-XFo05AQgBl%7ERLA33vWcR73gEAKZ"
|
||||
ebaiStorePageCookieWMSTOKEN = "gAALgNAAAGfBI5YEBHSQdZY1InIS8CVQU9aBU1f3VLWVQqKHAAAc5LnRLZ1QLLx0S5IuzCSX8ZQ7oUwAAUr-GEm9JpRc9AQAAsLkLHHXzuhh2lZkbyrcAAAWBESKg3ZA"
|
||||
@@ -198,7 +199,7 @@ jdOrgCode = "339032"
|
||||
jdToken = "84541069-fbe2-424b-b625-9b2ba1d4c9e6"
|
||||
jdAppKey = "5d5577a2506f41b8b4ec520ba83490f5"
|
||||
jdSecret = "0b01b9eeb15b41dab1c3d05d95c17a26"
|
||||
jdStorePageCookie = "YDYCWYUGKSROMV3MKJQIFINJ5CLPYH6IRVFUMFJD3JI6VQKHX3YPHTWDIDBNMCBUKSY3P7SKAHHKR7PHQDSFRXZEWXA4XOUTALIQDGDYIEUCMDPWSYGDVT42DJ27CD27QKCR3UN7KF7EPIHGPR7GCRTBD5DAHYMIODMDYESTI4PQWPK4CSWXGB2U4Y7R57ZUWN2T5LH4LE5SSAFFJCY53F5ZPCFR2RAUWYMCKHC4Y4QRFKYYLPHHZ2B3SCDWNLTVJOU24WJL4PVF3PPYDNTOLLXDABUFAZSE6C6CNOMI6L2TAK43JJIJQRQAQUQSU537ZFLVPGBYFDJYY"
|
||||
jdStorePageCookie = "YDYCWYUGKSROMV3MKJQIFINJ5CLPYH6IRVFUMFJD3JI6VQKHX3YPHTWDIDBNMCBUKSY3P7SKAHHKR7PHQDSFRXZEWXA4XOUTALIQDGDYIEUCMDPWSYGDVT42DJ27CD27QKCR3UN7KF7EPIHGPR7GCRTBD5YGNZW4AIACY4HXDMCETEWCPFKOTM4HRJBSMMQJ77SR62PYMP6RCG33IRQGP6PRCKAO4M7FUA7G2ZM2SFQ6F6WUNO5GXDJSVUELLBJT"
|
||||
|
||||
ebaiSource = "35957"
|
||||
ebaiSecret = "10013fbb7c2ddad7"
|
||||
@@ -208,6 +209,7 @@ ebaiStorePageCookieWMSTOKEN = "gAAA4OkFSZBsOayRIAnRqd24YRRVvWgRFE2w2CGtjKlAIsYg1
|
||||
mtwmAppID = "4123"
|
||||
mtwmSecret = "df2c88338b85f830cebce2a9eab56628"
|
||||
mtwmCallbackURL = "http://callback-jxgy.jxc4.com"
|
||||
mtwmCookieStr = "_lxsdk_cuid=16f413bd94fc8-0daccb808f461b-1d336b5a-13c680-16f413bd94fc8; _lxsdk=16f413bd94fc8-0daccb808f461b-1d336b5a-13c680-16f413bd94fc8; uuid=d1e8adb3d2774b89fe6e.1577347439.1.0.0; uuid_update=true; wpush_server_url=wss://wpush.meituan.com; acctId=62884810; token=0LhaIAAgrL1Hy0DDATjZqt4lRHauN_bBL3q0AvxUFUWo*; brandId=-1; wmPoiId=-1; isOfflineSelfOpen=0; city_id=0; isChain=1; existBrandPoi=true; ignore_set_router_proxy=true; region_id=; region_version=0; newCategory=false; bsid=SUVq2IfzZ53EHaTVoCE3UsmKkH5ZevxTjkwpNcaLKkbUOBkEyuZp8mPFwhgqkxsCGNjZILNj5aV8uVSQc888bg; device_uuid=!625e0297-431a-49ad-8b18-a0562c38a8eb; cityId=510100; provinceId=510000; city_location_id=0; location_id=0; pushToken=0LhaIAAgrL1Hy0DDATjZqt4lRHauN_bBL3q0AvxUFUWo*; set_info=%7B%22wmPoiId%22%3A-1%2C%22ignoreSetRouterProxy%22%3Atrue%7D; igateApp=shangouepc; LX_SC_CONSTANT=c_nehoktcu; shopCategory=food; JSESSIONID=unlrbu07lvm2s734eyedxr0j; _lxsdk_s=16f413bd950-189-8bb-8df%7C%7C33"
|
||||
|
||||
enableStoreWrite = true
|
||||
enableJdStoreWrite = true
|
||||
@@ -284,6 +286,10 @@ jdStorePageCookie = "5EOCZRXVCRXBTYD5EPV6FOXRCQWFFQO75FRMJ3BAKZ5JXY6XTJECMWXK5OZ
|
||||
|
||||
ebaiSource = "62289"
|
||||
ebaiSecret = "d3ec2358d6a819ea"
|
||||
ebaiStorePageCookieWMUSS = "AHYHAAApIX5oBXUFKFsXKEdObiclRUhTFRZ1MUh7KEMiClB7MnB5G3VvIB5KN0USAABjQ4KngBfQ4Wcj9ebWYiEHBxCyNiBT1Yc111PhQ7UBluCENnCUB0HjIzfCAaHjAKEDoscT8sDL8JDDuQD81NaQ1dW3kN1MS9DeFMPgwC2YYROVy7AV3cKhMPkQrBwA"
|
||||
ebaiStorePageCookieWMSTOKEN = "UAABRL3ZhLykdGFQBBDxXVDBuYisaB3tQHjUmHlQ5cEAs5dxMdG0R-EwVILAy_CV1Vlw_nbQAA0ijuEe-F2xUzAQAAAdujHKzhohkrxY0c5LsAAH0CeSGnywAHBQAAMA"
|
||||
|
||||
mtwmCookieStr = "_lxsdk_cuid=169b7bc1b9fc8-05092471a96611-12376d51-1fa400-169b7bc1b9fc8; _lxsdk=169b7bc1b9fc8-05092471a96611-12376d51-1fa400-169b7bc1b9fc8; uuid=7a6a1345b4a3f7aa5f81.1553565752.1.0.0; _ga=GA1.2.285163436.1559264188; uuid_update=true; pushToken=0sz3wYPQoNug6okzOjEacuvrEWGRhuv6gL5ZWX98prCw*; device_uuid=!88124822-2b68-4425-865d-a3ffffe355af; wpush_server_url=wss://wpush.meituan.com; acctId=26535718; token=0vt6ufSF1X8GXpVq3N5zhE5FhcgONSuNTg4LiqkqEyTM*; brandId=-1; wmPoiId=2523687; isOfflineSelfOpen=0; city_id=999999; isChain=0; existBrandPoi=false; ignore_set_router_proxy=false; region_id=2000000001; region_version=1522820107; newCategory=false; bsid=g54gdBCxg9fu4t99gGLf770bFzBT_eUQXA3_FWLgDeCWrEtsNdXkJtckKTvMEthURtXVg_j0mhDauKPgDUgZyQ; cityId=510100; provinceId=510000; city_location_id=10000004; location_id=10000005; set_info=%7B%22wmPoiId%22%3A2523687%2C%22region_id%22%3A%222000000001%22%2C%22region_version%22%3A1522820107%7D; igateApp=shangouepc; shopCategory=market; LX_SC_CONSTANT=c_nehoktcu; JSESSIONID=43y9tjdcnjh2kojf6qfehvdy; _lxsdk_s=16f4145a84c-d6a-c22-64c%7C%7C19"
|
||||
|
||||
mtpsAppKey = "25e816550bc9484480642f19a95f13fd"
|
||||
mtpsSecret = "r4$HqrKx9~=7?2Jfo,$Z~a7%~k!Au&pEdI2)oPJvSbH2ao@2N0[8wSIvtuumh_J^"
|
||||
|
||||
@@ -287,6 +287,7 @@ func (c *ActController) RefreshPageActs() {
|
||||
// @Param token header string true "认证token"
|
||||
// @Param skuIDs query string true "skuID列表"
|
||||
// @Param vendorID query int true "厂商ID"
|
||||
// @Param types query string false "活动类型列表"
|
||||
// @Param isAsync query bool false "是否异步"
|
||||
// @Param isContinueWhenError query bool false "单个同步失败是否继续,缺省false"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
@@ -294,9 +295,9 @@ func (c *ActController) RefreshPageActs() {
|
||||
// @router /DeleteSkusFromAct [delete]
|
||||
func (c *ActController) DeleteSkusFromAct() {
|
||||
c.callDeleteSkusFromAct(func(params *tActDeleteSkusFromActParams) (retVal interface{}, errCode string, err error) {
|
||||
var skuIDs []int
|
||||
if err = jxutils.Strings2Objs(params.SkuIDs, &skuIDs); err == nil {
|
||||
retVal, err = act.DeleteSkusFromAct(params.Ctx, params.VendorID, skuIDs, params.IsAsync, params.IsContinueWhenError)
|
||||
var skuIDs, types []int
|
||||
if err = jxutils.Strings2Objs(params.SkuIDs, &skuIDs, params.Types, &types); err == nil {
|
||||
retVal, err = act.DeleteSkusFromAct(params.Ctx, params.VendorID, types, skuIDs, params.IsAsync, params.IsContinueWhenError)
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
@@ -308,6 +309,7 @@ func (c *ActController) DeleteSkusFromAct() {
|
||||
// @Param type formData int true "活动类型,3:直降,4:秒杀(美团当前不支持秒杀)"
|
||||
// @Param vendorID formData int true "厂商ID,当前只支持,京东:0,京西(用于记录活动信息):9"
|
||||
// @Param actStoreSkuList formData string true "活动门店商品信息"
|
||||
// @Param lockTime formData string false "平台价格锁定截止时间"
|
||||
// @Param isAsync formData bool false "是否异步,缺省否(暂时只支持同步)"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
@@ -316,7 +318,10 @@ func (c *ActController) ForceUpdateVendorPrice() {
|
||||
c.callForceUpdateVendorPrice(func(params *tActForceUpdateVendorPriceParams) (retVal interface{}, errCode string, err error) {
|
||||
var actStoreSkuList []*act.ActStoreSkuParam
|
||||
if err = jxutils.Strings2Objs(params.ActStoreSkuList, &actStoreSkuList); err == nil {
|
||||
retVal, err = act.ForceUpdateVendorPrice(params.Ctx, params.VendorID, params.Type, actStoreSkuList, params.IsAsync)
|
||||
timeList, err2 := jxutils.BatchStr2Time(params.LockTime)
|
||||
if err = err2; err == nil {
|
||||
retVal, err = act.ForceUpdateVendorPrice(params.Ctx, params.VendorID, params.Type, actStoreSkuList, timeList[0], params.IsAsync)
|
||||
}
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
|
||||
@@ -191,6 +191,9 @@ func (c *SkuController) UpdateSkuName() {
|
||||
// dummySkuName := &model.SkuName{}
|
||||
payload := make(map[string]interface{})
|
||||
if err = utils.UnmarshalUseNumber([]byte(params.Payload), &payload); err == nil {
|
||||
delete(payload, "exPrefix")
|
||||
delete(payload, "exPrefixBegin")
|
||||
delete(payload, "exPrefixEnd")
|
||||
retVal, err = cms.UpdateSkuName(params.Ctx, params.NameID, payload)
|
||||
}
|
||||
return retVal, "", err
|
||||
@@ -375,3 +378,40 @@ func (c *SkuController) GetStoreSkuSalesInfo() {
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 根据名字查询京东商品UPC信息
|
||||
// @Description 根据名字查询京东商品UPC信息
|
||||
// @Param token header string true "认证token"
|
||||
// @Param name query string false "商品名"
|
||||
// @Param upcCode query string false "upcCode,不支持模糊"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetJdUpcCodeByName [get]
|
||||
func (c *SkuController) GetJdUpcCodeByName() {
|
||||
c.callGetJdUpcCodeByName(func(params *tSkuGetJdUpcCodeByNameParams) (retVal interface{}, errCode string, err error) {
|
||||
retVal, err = cms.GetJdUpcCodeByName(params.Ctx, params.Name, params.UpcCode)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 批量设置商品额外前缀
|
||||
// @Description 批量设置商品额外前缀
|
||||
// @Param token header string true "认证token"
|
||||
// @Param nameIDs formData string true "商品nameIDs"
|
||||
// @Param exPrefix formData string true "商品额外前缀"
|
||||
// @Param fromDate formData string true "生效开始时间,格式 2006-01-01 "
|
||||
// @Param toDate formData string true "生效结束时间,格式 2006-01-01 "
|
||||
// @Param isAsync formData bool false "是否异步"
|
||||
// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /UpdateSkuNamesExPrefix [put]
|
||||
func (c *SkuController) UpdateSkuNamesExPrefix() {
|
||||
c.callUpdateSkuNamesExPrefix(func(params *tSkuUpdateSkuNamesExPrefixParams) (retVal interface{}, errCode string, err error) {
|
||||
var skuIDList []int
|
||||
if err = jxutils.Strings2Objs(params.NameIDs, &skuIDList); err == nil {
|
||||
retVal, err = cms.UpdateSkuNamesExPrefix(params.Ctx, skuIDList, params.ExPrefix, params.FromDate, params.ToDate, params.IsAsync, params.IsContinueWhenError)
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -589,20 +589,21 @@ func (c *StoreController) GetVendorStoreInfo() {
|
||||
// @Description 查询门店价格评分
|
||||
// @Param token header string true "认证token"
|
||||
// @Param storeIDs formData string false "门店列表"
|
||||
// @Param vendorIDs formData string false "厂商列表"
|
||||
// @Param snapDate formData string true "时间,默认前一天(格式2006-01-02"
|
||||
// @Param fromScore formData int false "分数范围开始 默认0"
|
||||
// @Param toScore formData int false "分数范围结束 默认100"
|
||||
// @Param sort formData int false "排序,默认降序,0为降序,1为升序"
|
||||
// @Param sort formData int false "分数排序,-1降序,-升序 ,直降排序,-2降序,2升序,秒杀排序,-3降序,3升序"
|
||||
// @Param offset formData int false "门店列表起始序号(以0开始,缺省为0)"
|
||||
// @Param pageSize formData int false "门店列表页大小(缺省为50,-1表示全部)"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetStorePriceScore [post]
|
||||
func (c *StoreController) GetStorePriceScore() {
|
||||
var storeIDList []int
|
||||
var storeIDList, vendorIDList []int
|
||||
c.callGetStorePriceScore(func(params *tStoreGetStorePriceScoreParams) (retVal interface{}, errCode string, err error) {
|
||||
if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil {
|
||||
retVal, err = cms.GetStorePriceScore(params.Ctx, storeIDList, params.FromScore, params.ToScore, params.Sort, params.SnapDate, params.Offset, params.PageSize)
|
||||
if jxutils.Strings2Objs(params.StoreIDs, &storeIDList, params.VendorIDs, &vendorIDList); err == nil {
|
||||
retVal, err = cms.GetStorePriceScore(params.Ctx, storeIDList, vendorIDList, params.FromScore, params.ToScore, params.Sort, params.SnapDate, params.Offset, params.PageSize)
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
@@ -611,13 +612,25 @@ func (c *StoreController) GetStorePriceScore() {
|
||||
// @Title 生成门店价格分数表
|
||||
// @Description 生成门店价格分数表
|
||||
// @Param token header string true "认证token"
|
||||
// @Param forRefresh formData bool true "是否是刷新中位价重新生成分数表"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /CreateStorePriceScore [post]
|
||||
func (c *StoreController) CreateStorePriceScore() {
|
||||
c.callCreateStorePriceScore(func(params *tStoreCreateStorePriceScoreParams) (retVal interface{}, errCode string, err error) {
|
||||
err = cms.CreateStorePriceScore(params.Ctx, params.ForRefresh)
|
||||
err = cms.CreateStorePriceScore(params.Ctx)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 刷新store_map的京东等级
|
||||
// @Description 刷新store_map的京东等级
|
||||
// @Param token header string true "认证token"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /RefreshJdLevel [post]
|
||||
func (c *StoreController) RefreshJdLevel() {
|
||||
c.callRefreshJdLevel(func(params *tStoreRefreshJdLevelParams) (retVal interface{}, errCode string, err error) {
|
||||
err = cms.RefreshJdLevel(params.Ctx)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ type StoreSkuController struct {
|
||||
// @Param jdSyncStatus query int false "京东同步标识"
|
||||
// @Param ebaiSyncStatus query int false "饿百同步标识"
|
||||
// @Param mtwmSyncStatus query int false "美团外卖同步标识"
|
||||
// @Param lockTime query string false "价格锁定时间"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetStoreSkus [get]
|
||||
@@ -83,6 +84,7 @@ func (c *StoreSkuController) GetStoreSkus() {
|
||||
// @Param jdSyncStatus query int false "京东同步标识"
|
||||
// @Param ebaiSyncStatus query int false "饿百同步标识"
|
||||
// @Param mtwmSyncStatus query int false "美团外卖同步标识"
|
||||
// @Param lockTime query string false "价格锁定时间"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetStoresSkus [get,post]
|
||||
@@ -448,7 +450,7 @@ func (c *StoreSkuController) GetMissingStoreSkuFromOrder() {
|
||||
|
||||
// @Title 根据门店信息查找推荐商品(按销量)
|
||||
// @Description 根据门店信息查找推荐商品(按销量)
|
||||
// @Param token header string false "认证token"
|
||||
// @Param token header string true "认证token"
|
||||
// @Param storeIDs query string true "门店列表"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
@@ -463,18 +465,33 @@ func (c *StoreSkuController) GetTopSkusByStoreIDs() {
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 根据城市信息查找推荐商品(按销量)
|
||||
// @Description 根据城市信息查找推荐商品(按销量)
|
||||
// @Param token header string true "认证token"
|
||||
// @Param cityCode query int true "城市id"
|
||||
// @Param storeID query int false "门店id"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetTopSkusByCityCode [get]
|
||||
func (c *StoreSkuController) GetTopSkusByCityCode() {
|
||||
c.callGetTopSkusByCityCode(func(params *tStoreSkuGetTopSkusByCityCodeParams) (retVal interface{}, errCode string, err error) {
|
||||
retVal, err = cms.GetTopSkusByCityCode(params.Ctx, params.CityCode, params.StoreID)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 根据门店信息查找推荐分类(按商品销量)
|
||||
// @Description 根据门店信息查找推荐分类(按商品销量)
|
||||
// @Param token header string false "认证token"
|
||||
// @Param token header string true "认证token"
|
||||
// @Param storeIDs query string true "门店列表"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetTopCategorysByStoreIDs [get]
|
||||
func (c *StoreSkuController) GetTopCategorysByStoreIDs() {
|
||||
// @router /GetTopCategoriesByStoreIDs [get]
|
||||
func (c *StoreSkuController) GetTopCategoriesByStoreIDs() {
|
||||
var storeIDList []int
|
||||
c.callGetTopCategorysByStoreIDs(func(params *tStoreSkuGetTopCategorysByStoreIDsParams) (retVal interface{}, errCode string, err error) {
|
||||
c.callGetTopCategoriesByStoreIDs(func(params *tStoreSkuGetTopCategoriesByStoreIDsParams) (retVal interface{}, errCode string, err error) {
|
||||
if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil {
|
||||
retVal, err = cms.GetTopCategorysByStoreIDs(params.Ctx, storeIDList)
|
||||
retVal, err = cms.GetTopCategoriesByStoreIDs(params.Ctx, storeIDList)
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
@@ -517,3 +534,77 @@ func (c *StoreSkuController) RefreshJxPriceByExcel() {
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 根据Excel中SkuID批量关注商品
|
||||
// @Description 根据Excel中SkuID批量关注商品
|
||||
// @Param token header string true "认证token"
|
||||
// @Param isAsync formData bool true "是否异步,缺省是同步"
|
||||
// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /FocusStoreSkusByExcel [post]
|
||||
func (c *StoreSkuController) FocusStoreSkusByExcel() {
|
||||
c.callFocusStoreSkusByExcel(func(params *tStoreSkuFocusStoreSkusByExcelParams) (retVal interface{}, errCode string, err error) {
|
||||
r := c.Ctx.Request
|
||||
files := r.MultipartForm.File["userfiles"]
|
||||
retVal, err = cms.FocusStoreSkusByExcel(params.Ctx, files, params.IsAsync, params.IsContinueWhenError)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 得到门店的分类列表
|
||||
// @Description 得到门店的分类列表(按商品销量)
|
||||
// @Param token header string true "认证token"
|
||||
// @Param storeID query int true "门店ID"
|
||||
// @Param parentID query int false "父分类id"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetStoreCategories [get]
|
||||
func (c *StoreSkuController) GetStoreCategories() {
|
||||
c.callGetStoreCategories(func(params *tStoreSkuGetStoreCategoriesParams) (retVal interface{}, errCode string, err error) {
|
||||
if params.MapData["parentID"] == nil {
|
||||
params.ParentID = -1
|
||||
}
|
||||
retVal, err = cms.GetStoreCategories(params.Ctx, params.StoreID, params.ParentID)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 获取各平台所有门店某商品的价格
|
||||
// @Description 获取各平台所有门店某商品的价格
|
||||
// @Param token header string true "认证token"
|
||||
// @Param skuID formData int true "商品ID"
|
||||
// @Param vendorIDs formData string true "厂商ID列表"
|
||||
// @Param isAsync formData bool true "是否异步,缺省是同步"
|
||||
// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetVendorStoreSkuPrice [post]
|
||||
func (c *StoreSkuController) GetVendorStoreSkuPrice() {
|
||||
var vendorIDList []int
|
||||
c.callGetVendorStoreSkuPrice(func(params *tStoreSkuGetVendorStoreSkuPriceParams) (retVal interface{}, errCode string, err error) {
|
||||
if jxutils.Strings2Objs(params.VendorIDs, &vendorIDList); err == nil {
|
||||
retVal, err = cms.GetVendorStoreSkuPrice(params.Ctx, vendorIDList, params.SkuID, params.IsAsync, params.IsContinueWhenError)
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 根据skuID关注商品,价格为中位价,部分可售
|
||||
// @Description 根据skuID关注商品,价格为中位价,部分可售
|
||||
// @Param token header string true "认证token"
|
||||
// @Param skuIDs formData string true "商品ID列表"
|
||||
// @Param isAsync formData bool true "是否异步,缺省是同步"
|
||||
// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /FocusStoreSkusBySku [post]
|
||||
func (c *StoreSkuController) FocusStoreSkusBySku() {
|
||||
var skuIDList []int
|
||||
c.callFocusStoreSkusBySku(func(params *tStoreSkuFocusStoreSkusBySkuParams) (retVal interface{}, errCode string, err error) {
|
||||
if jxutils.Strings2Objs(params.SkuIDs, &skuIDList); err == nil {
|
||||
retVal, err = cms.FocusStoreSkusBySku(params.Ctx, skuIDList, params.IsAsync, params.IsContinueWhenError)
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ func (c *SyncController) SyncSkuNames() {
|
||||
}
|
||||
|
||||
// @Title 删除本地没有的平台门店商品信息
|
||||
// @Description 删除本地没有的平台门店商品信息
|
||||
// @Description 删除本地没有的平台门店商品信息(已废弃)
|
||||
// @Param token header string true "认证token"
|
||||
// @Param storeIDs query string true "门店ID列表"
|
||||
// @Param vendorIDs query string true "厂商ID列表"
|
||||
@@ -225,7 +225,7 @@ func (c *SyncController) PruneMissingStoreSkus() {
|
||||
}
|
||||
|
||||
// @Title 把京西有,平台无且没有待创建标记的商品加上待创建标记
|
||||
// @Description 把京西有,平台无且没有待创建标记的商品加上待创建标记
|
||||
// @Description 把京西有,平台无且没有待创建标记的商品加上待创建标记(已废弃)
|
||||
// @Param token header string true "认证token"
|
||||
// @Param storeIDs formData string false "门店ID列表"
|
||||
// @Param vendorIDs formData string false "运营商ID列表(京东0 美团1 饿百3)"
|
||||
@@ -244,6 +244,28 @@ func (c *SyncController) AddCreateFlagForJxStoreSku() {
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 把京西有,平台无且没有待创建标记的商品加上待创建标记
|
||||
// @Description 把京西有,平台无且没有待创建标记的商品加上待创建标记
|
||||
// @Param token header string true "认证token"
|
||||
// @Param storeIDs formData string false "门店ID列表"
|
||||
// @Param vendorIDs formData string false "运营商ID列表(京东0 美团1 饿百3)"
|
||||
// @Param optType formData int true "操作方式"
|
||||
// @Param isForce formData bool false "是否强制刷新"
|
||||
// @Param isAsync formData bool false "是否异步操作"
|
||||
// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /AmendAndPruneStoreStuff [post]
|
||||
func (c *SyncController) AmendAndPruneStoreStuff() {
|
||||
c.callAmendAndPruneStoreStuff(func(params *tSyncAmendAndPruneStoreStuffParams) (retVal interface{}, errCode string, err error) {
|
||||
var storeIDs, vendorIDs []int
|
||||
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err == nil {
|
||||
retVal, err = cms.CurVendorSync.AmendAndPruneStoreStuff(params.Ctx, vendorIDs, storeIDs, params.IsAsync, params.IsContinueWhenError, params.OptType, params.IsForce)
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 初始化多门店平台商品库(及商家分类)
|
||||
// @Description 初始化多门店平台商品库(及商家分类)
|
||||
// @Param token header string true "认证token"
|
||||
|
||||
@@ -3,8 +3,10 @@ package controllers
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/dadaapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/delivery/dada"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"git.rosy.net.cn/jx-callback/globals/api"
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
@@ -30,3 +32,21 @@ func (c *DadaDeliveryController) Msg() {
|
||||
c.Abort("404")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *DadaDeliveryController) Notify() {
|
||||
if c.Ctx.Input.Method() == http.MethodPost {
|
||||
obj, notifyResponse := api.DadaAPI.GetNotifyMsg(c.Ctx.Input.RequestBody)
|
||||
if notifyResponse == nil {
|
||||
err := api.DadaAPI.ConfirmRidderCancel(obj.MessageObj.OrderID, obj.MessageObj.DadaOrderID, true)
|
||||
globals.SugarLogger.Debugf("dada notify, obj:%s, err:%v", utils.Format4Output(obj, false), err)
|
||||
}
|
||||
if notifyResponse == nil {
|
||||
notifyResponse = dadaapi.SuccessNotifyResponse
|
||||
} else {
|
||||
c.Data["json"] = notifyResponse
|
||||
c.ServeJSON()
|
||||
}
|
||||
} else {
|
||||
c.Abort("404")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ type DjswController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
func (c *DjswController) handleMsg(isNeedDecode bool, handler func(*jdapi.API, interface{}) *jdapi.CallbackResponse) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackMsg, mapData, callbackResponse := jdapi.GetCallbackMsg2(getUsefulRequest(c.Ctx))
|
||||
func (c *DjswController) handleMsg(handler func(*jdapi.API, interface{}) *jdapi.CallbackResponse) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackMsg, mapData, callbackResponse := jdapi.GetCallbackMsg(getUsefulRequest(c.Ctx))
|
||||
globals.SugarLogger.Debug(utils.Format4Output(callbackMsg, true))
|
||||
if callbackResponse == nil {
|
||||
if jdAPI := jd.GetAPIByAppKey(callbackMsg.AppKey); jdAPI != nil {
|
||||
if callbackResponse = jdAPI.CheckCallbackValidation2(mapData, callbackMsg.Sign); callbackResponse == nil {
|
||||
if jdAPI := jd.GetAPI(jd.AppKey2OrgCode(callbackMsg.AppKey)); jdAPI != nil {
|
||||
if callbackResponse = jdAPI.CheckCallbackValidation(mapData, callbackMsg.Sign); callbackResponse == nil {
|
||||
callbackResponse = handler(jdAPI, callbackMsg.Param)
|
||||
}
|
||||
} else {
|
||||
@@ -34,9 +34,9 @@ func (c *DjswController) handleMsg(isNeedDecode bool, handler func(*jdapi.API, i
|
||||
return callbackResponse
|
||||
}
|
||||
|
||||
func (c *DjswController) orderStatus(isCancelOrder bool) {
|
||||
func (c *DjswController) orderStatus() {
|
||||
if c.Ctx.Input.Method() == http.MethodPost {
|
||||
callbackResponse := c.handleMsg(isCancelOrder, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackResponse := c.handleMsg(func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackResponse = jd.OnOrderMsg(obj.(*jdapi.CallbackOrderMsg))
|
||||
return callbackResponse
|
||||
})
|
||||
@@ -48,48 +48,52 @@ func (c *DjswController) orderStatus(isCancelOrder bool) {
|
||||
}
|
||||
|
||||
func (c *DjswController) NewOrder() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) OrderAdjust() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) OrderWaitOutStore() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) PickFinishOrder() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) DeliveryOrder() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) FinishOrder() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) LockOrder() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) UnlockOrder() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) UserCancelOrder() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) ApplyCancelOrder() {
|
||||
c.orderStatus(true)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) VenderAuditApplyCancelOrder() {
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) PushDeliveryStatus() {
|
||||
if c.Ctx.Input.Method() == http.MethodPost {
|
||||
callbackResponse := c.handleMsg(true, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackResponse := c.handleMsg(func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackResponse = jd.OnWaybillMsg(obj.(*jdapi.CallbackDeliveryStatusMsg))
|
||||
return callbackResponse
|
||||
})
|
||||
@@ -101,7 +105,7 @@ func (c *DjswController) PushDeliveryStatus() {
|
||||
}
|
||||
|
||||
func (c *DjswController) OrderCommentPush() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) Token() {
|
||||
@@ -116,7 +120,7 @@ func (c *DjswController) Token() {
|
||||
func (c *DjswController) StockIsHave() {
|
||||
// globals.SugarLogger.Info(string(c.Ctx.Input.RequestBody))
|
||||
if c.Ctx.Input.Method() == http.MethodPost {
|
||||
callbackResponse := c.handleMsg(true, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackResponse := c.handleMsg(func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
return callbackResponse
|
||||
})
|
||||
c.Data["json"] = c.transferResponse("StockIsHave", callbackResponse)
|
||||
@@ -128,7 +132,7 @@ func (c *DjswController) StockIsHave() {
|
||||
|
||||
func (c *DjswController) SinglePromoteCreate() {
|
||||
if c.Ctx.Input.Method() == http.MethodPost {
|
||||
callbackResponse := c.handleMsg(false, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackResponse := c.handleMsg(func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackResponse = jd.OnActMsg(obj.(*jdapi.CallbackOrderMsg))
|
||||
return callbackResponse
|
||||
})
|
||||
@@ -141,7 +145,7 @@ func (c *DjswController) SinglePromoteCreate() {
|
||||
|
||||
func (c *DjswController) StoreCrud() {
|
||||
if c.Ctx.Input.Method() == http.MethodPost {
|
||||
callbackResponse := c.handleMsg(false, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackResponse := c.handleMsg(func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) {
|
||||
callbackResponse = jd.OnStoreMsg(obj.(*jdapi.CallbackOrderMsg))
|
||||
return callbackResponse
|
||||
})
|
||||
@@ -188,11 +192,11 @@ func (c *DjswController) NewAfterSaleBill() {
|
||||
}
|
||||
|
||||
func (c *DjswController) AfterSaleBillStatus() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func (c *DjswController) OrderAccounting() {
|
||||
c.orderStatus(false)
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
func getUsefulRequest(ctx *context.Context) *http.Request {
|
||||
@@ -208,3 +212,7 @@ func (c *DjswController) nullOperation() {
|
||||
func (c *DjswController) UpdateSku() {
|
||||
c.nullOperation()
|
||||
}
|
||||
|
||||
func (c *DjswController) OrderAddTips() {
|
||||
c.orderStatus()
|
||||
}
|
||||
|
||||
@@ -220,12 +220,29 @@ func (c *OrderController) GetOrderInfo() {
|
||||
// @Param vendorOrderID query string true "订单ID"
|
||||
// @Param vendorID query int true "订单所属的厂商ID"
|
||||
// @Param isNotEnded query bool false "是否只是没有结束的运单"
|
||||
// @Param isGetPos query bool false "是否得到骑手位置"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetOrderWaybillInfo [get]
|
||||
func (c *OrderController) GetOrderWaybillInfo() {
|
||||
c.callGetOrderWaybillInfo(func(params *tOrderGetOrderWaybillInfoParams) (retVal interface{}, errCode string, err error) {
|
||||
retVal, err = orderman.FixedOrderManager.GetOrderWaybillInfo(params.Ctx, params.VendorOrderID, params.VendorID, params.IsNotEnded)
|
||||
retVal, err = orderman.FixedOrderManager.GetOrderWaybillInfo(params.Ctx, params.VendorOrderID, params.VendorID, params.IsNotEnded, params.IsGetPos)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 补全遗漏的订单
|
||||
// @Description 补全遗漏的订单
|
||||
// @Param token header string true "认证token"
|
||||
// @Param vendorOrderID formData string true "订单ID"
|
||||
// @Param vendorID formData int true "订单所属的厂商ID"
|
||||
// @Param tipFee formData int true "小费"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /UpdateOrderWaybillTip [post]
|
||||
func (c *OrderController) UpdateOrderWaybillTip() {
|
||||
c.callUpdateOrderWaybillTip(func(params *tOrderUpdateOrderWaybillTipParams) (retVal interface{}, errCode string, err error) {
|
||||
err = defsch.FixedScheduler.SetOrderWaybillTip(params.Ctx, params.VendorOrderID, params.VendorID, int64(params.TipFee))
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
@@ -514,7 +531,7 @@ func (c *OrderController) GetPrinterStatus() {
|
||||
})
|
||||
}
|
||||
|
||||
func skuList2Map(skuList []*model.OrderSku) (skuCount int, skuMap map[int64]*model.OrderSku) {
|
||||
func skuList2Map(skuList []*model.OrderSku) (skuCount int, skuMap map[int64]*model.OrderSku, outSkuList []*model.OrderSku) {
|
||||
skuMap = make(map[int64]*model.OrderSku)
|
||||
for _, sku := range skuList {
|
||||
skuCount += sku.Count
|
||||
@@ -524,12 +541,13 @@ func skuList2Map(skuList []*model.OrderSku) (skuCount int, skuMap map[int64]*mod
|
||||
if skuMap[index] == nil {
|
||||
tmpSku := *sku
|
||||
skuMap[index] = &tmpSku
|
||||
outSkuList = append(outSkuList, skuMap[index])
|
||||
} else {
|
||||
skuMap[index].Count += sku.Count
|
||||
}
|
||||
}
|
||||
}
|
||||
return skuCount, skuMap
|
||||
return skuCount, skuMap, outSkuList
|
||||
}
|
||||
|
||||
func getSkuFromMap(skuMap map[int64]*model.OrderSku, skuID, actID int) (sku *model.OrderSku) {
|
||||
@@ -554,6 +572,7 @@ func (c *OrderController) AdjustOrder() {
|
||||
var skuList []*model.OrderSku
|
||||
err = jxutils.Strings2Objs(params.RemovedSkuInfo, &skuList)
|
||||
if err == nil {
|
||||
_, _, skuList = skuList2Map(skuList)
|
||||
var order *model.GoodsOrder
|
||||
order, err = partner.CurOrderManager.LoadOrder(params.VendorOrderID, params.VendorID)
|
||||
if err == nil {
|
||||
@@ -780,6 +799,7 @@ func (c *OrderController) PartRefundOrder() {
|
||||
var skuList []*model.OrderSku
|
||||
err = jxutils.Strings2Objs(params.RefundSkuList, &skuList)
|
||||
if err == nil {
|
||||
_, _, skuList = skuList2Map(skuList)
|
||||
var order *model.GoodsOrder
|
||||
order, err = partner.CurOrderManager.LoadOrder(params.VendorOrderID, params.VendorID)
|
||||
if err == nil {
|
||||
@@ -798,7 +818,7 @@ func (c *OrderController) PartRefundOrder() {
|
||||
}
|
||||
|
||||
func fillSkuList(skuList, orderSkuList []*model.OrderSku) (isSame bool, err error) {
|
||||
skuCount, orderSkuMap := skuList2Map(orderSkuList)
|
||||
skuCount, orderSkuMap, _ := skuList2Map(orderSkuList)
|
||||
skuCount2 := 0
|
||||
for _, sku := range skuList {
|
||||
skuCount2 += sku.Count
|
||||
@@ -875,3 +895,33 @@ func (c *OrderController) RefreshOrdersWithoutJxStoreID() {
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 获取投诉原因
|
||||
// @Description 获取投诉原因
|
||||
// @Param token header string true "认证token"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetComplaintReasons [get]
|
||||
func (c *OrderController) GetComplaintReasons() {
|
||||
c.callGetComplaintReasons(func(params *tOrderGetComplaintReasonsParams) (retVal interface{}, errCode string, err error) {
|
||||
retVal = orderman.GetComplaintReasons()
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 投诉骑手(三方运送)
|
||||
// @Description 投诉骑手(三方运送)
|
||||
// @Param token header string true "认证token"
|
||||
// @Param vendorOrderID formData string true "订单ID"
|
||||
// @Param vendorID formData int true "订单所属厂商ID"
|
||||
// @Param waybillVendorID formData int true "运单所属厂商ID"
|
||||
// @Param complaintID formData int true "投诉原因ID"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /ComplaintRider [post]
|
||||
func (c *OrderController) ComplaintRider() {
|
||||
c.callComplaintRider(func(params *tOrderComplaintRiderParams) (retVal interface{}, errCode string, err error) {
|
||||
err = orderman.ComplaintRider(params.Ctx, params.VendorOrderID, params.VendorID, params.WaybillVendorID, params.ComplaintID)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/wxpay"
|
||||
"git.rosy.net.cn/baseapi/platformapi/wxpayapi"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/jx/localjx"
|
||||
"git.rosy.net.cn/jx-callback/globals/api"
|
||||
"github.com/astaxie/beego"
|
||||
@@ -17,19 +17,19 @@ type WXPayController struct {
|
||||
func (c *WXPayController) Msg() {
|
||||
if c.Ctx.Input.Method() == http.MethodPost {
|
||||
msg, callbackResponse := api.WxpayAPI.GetCallbackMsg(c.Ctx.Request)
|
||||
// globals.SugarLogger.Debugf("wxpay callback msg:%s, callbackResponse:%s, %t", utils.Format4Output(msg, true), utils.Format4Output(callbackResponse, true), callbackResponse == nil)
|
||||
// globals.SugarLogger.Debugf("wxpayapi callback msg:%s, callbackResponse:%s, %t", utils.Format4Output(msg, true), utils.Format4Output(callbackResponse, true), callbackResponse == nil)
|
||||
var err error
|
||||
if callbackResponse == nil {
|
||||
if msg.MsgType == wxpay.MsgTypeUnkown {
|
||||
if msg.MsgType == wxpayapi.MsgTypeUnkown {
|
||||
err = fmt.Errorf("未知的微信支付回调类型:%d", msg.MsgType)
|
||||
} else {
|
||||
err = localjx.OnWxPayCallback(msg)
|
||||
}
|
||||
}
|
||||
if callbackResponse == nil {
|
||||
callbackResponse = wxpay.SuccessResponse
|
||||
callbackResponse = wxpayapi.SuccessResponse
|
||||
} else if err != nil {
|
||||
callbackResponse = wxpay.Err2CallbackResponse(err, "")
|
||||
callbackResponse = wxpayapi.Err2CallbackResponse(err, "")
|
||||
}
|
||||
c.Data["xml"] = callbackResponse
|
||||
c.ServeXML()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user