diff --git a/business/jxcallback/orderman/orderman_ext.go b/business/jxcallback/orderman/orderman_ext.go index 858a62124..74a2f0293 100644 --- a/business/jxcallback/orderman/orderman_ext.go +++ b/business/jxcallback/orderman/orderman_ext.go @@ -861,12 +861,225 @@ func (c *OrderManager) GetOrdersFinancial(ctx *jxcontext.Context, fromDateStr, t } func (c *OrderManager) GetStoresOrderSaleInfo(ctx *jxcontext.Context, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*dao.StoresOrderSaleInfo, err error) { - // if globals.IsProductEnv() { - // return dao.GetStoresOrderSaleInfo(dao.GetDB(), storeIDList, fromTime, toTime, statusList) - // } + //if globals.IsProductEnv() { + // return dao.GetStoresOrderSaleInfo(dao.GetDB(), storeIDList, fromTime, toTime, statusList) + //} return c.GetStoresOrderSaleInfoNew(ctx, storeIDList, fromTime, toTime, statusList) } +func (c *OrderManager) GetStoresOrderSaleInfo2(ctx *jxcontext.Context, fromTime time.Time, toTime time.Time, statusList []int) (map[string]interface{}, error) { + storeStatus, err := dao.StatisticsStoreInfo() + if err != nil { + return nil, err + } + + orderStatus, err := c.GetOrderStatistics(ctx, nil, fromTime, toTime, statusList) + return map[string]interface{}{"storeStatus": storeStatus, "orderStatus": orderStatus}, nil +} + +func (c *OrderManager) GetOrderStatistics(ctx *jxcontext.Context, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*dao.StoresOrderSaleInfo, err error) { + db := dao.GetDB() + var isLongTime = false + if toTime.Sub(fromTime).Hours() > 24 { + isLongTime = true + } + + orderIDMap := make(map[string]struct{}) + var vendorOrderIDs []string + orderSkuList, err := dao.GetStoreOrderSkuList(db, storeIDList, fromTime, toTime, nil, true, 0) // 所有订单 + if err != nil { + return nil, err + } + for _, v := range orderSkuList { + orderIDMap[v.VendorOrderID] = struct{}{} + } + for k, _ := range orderIDMap { + vendorOrderIDs = append(vendorOrderIDs, k) + } + var afsSkuList []*model.OrderSkuFinancial + var orderSkuList4Afs []*dao.OrderSkuWithActualPayPrice + if len(vendorOrderIDs) > 0 { + afsSkuList, err = dao.GetStoreAfsOrderSkuList2(db, vendorOrderIDs) + orderSkuList4Afs, err = dao.GetStoreOrderSkuList4Afs2(db, vendorOrderIDs) + } + + orderSkuHandler := func(skuList []*dao.OrderSkuWithActualPayPrice) (orderMap map[string]*model.GoodsOrder, orderSkuMap map[string]*dao.OrderSkuWithActualPayPrice, saleInfoMap map[int64]*dao.StoresOrderSaleInfo) { + orderMap = make(map[string]*model.GoodsOrder) + orderSkuMap = make(map[string]*dao.OrderSkuWithActualPayPrice) + saleInfoMap = make(map[int64]*dao.StoresOrderSaleInfo) + var flagVendorOrderID string + if len(skuList) > 0 { + flagVendorOrderID = skuList[0].VendorOrderID + } + for k, v := range skuList { + storeDetail, _ := dao.GetStoreDetail(db, v.StoreID, v.VendorID, "") + if v.EarningPrice == 0 { + v.EarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, v.SalePrice, v.PayPercentage) + } + + status := v.Status + if status < model.OrderStatusEndBegin { + status = 0 + } + index := jxutils.Combine2Int(v.StoreID, v.VendorID)*1000 + int64(status) + saleInfo := saleInfoMap[index] + if saleInfo == nil { + saleInfo = &dao.StoresOrderSaleInfo{ + StoreID: v.StoreID, + VendorID: v.VendorID, + Status: status, + } + saleInfoMap[index] = saleInfo + } + //成都菜市 + if beego.BConfig.RunMode == "prod" || beego.BConfig.RunMode == "beta" { + if v.EarningType == model.EarningTypeQuote { + saleInfo.RealEarningPrice += v.EarningPrice * int64(v.Count) + } + } else { + if v.OrderPayPercentage == 100 { + saleInfo.RealEarningPrice += v.ShopPrice * int64(v.Count) + } + } + saleInfo.ShopPrice += v.ShopPrice * int64(v.Count) + saleInfo.VendorPrice += v.VendorPrice * int64(v.Count) + saleInfo.SalePrice += v.SalePrice * int64(v.Count) + // saleInfo.EarningPrice += v.EarningPrice * int64(v.Count) + if v.VendorOrderID == flagVendorOrderID { + if k == 0 { + saleInfo.EarningPrice = v.NewEarningPrice + if beego.BConfig.RunMode == "prod" || beego.BConfig.RunMode == "beta" { + if v.EarningType == model.EarningTypePoints { + if storeDetail.VendorPayPercentage != 0 && !isLongTime { + saleInfo.RealEarningPrice += 0 + } else { + saleInfo.RealEarningPrice += v.NewEarningPrice + } + } + } else { + if v.OrderPayPercentage < 100 { + saleInfo.RealEarningPrice += v.NewEarningPrice + } + } + } + } else { + flagVendorOrderID = v.VendorOrderID + saleInfo.EarningPrice += v.NewEarningPrice + if beego.BConfig.RunMode == "prod" || beego.BConfig.RunMode == "beta" { + if v.EarningType == model.EarningTypePoints { + if storeDetail.VendorPayPercentage != 0 && !isLongTime { + saleInfo.RealEarningPrice += 0 + } else { + // && v.VendorID != model.VendorIDJD && v.CityCode != 510100 + saleInfo.RealEarningPrice += v.NewEarningPrice + } + } + } else { + if v.OrderPayPercentage < 100 { + saleInfo.RealEarningPrice += v.NewEarningPrice + } + } + } + + universalOrderID := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID) + if orderMap[universalOrderID] == nil { + orderMap[universalOrderID] = &model.GoodsOrder{ + StoreID: v.StoreID, + VendorID: v.VendorID, + ActualPayPrice: v.ActualPayPrice, + } + saleInfo.ActualPayPrice += v.ActualPayPrice + saleInfo.Count++ + + saleInfo.DistanceFreightMoney += v.DistanceFreightMoney + saleInfo.WaybillTipMoney += v.WaybillTipMoney + } + orderMap[universalOrderID].SkuCount += v.Count + + universalOrderSkuID := universalOrderID + "/" + utils.Int2Str(jxutils.GetSkuIDFromOrderSku(&v.OrderSku)) + if orderSkuMap[universalOrderSkuID] == nil { + orderSkuMap[universalOrderSkuID] = v + } + } + return orderMap, orderSkuMap, saleInfoMap + } + _, _, saleInfoMap := orderSkuHandler(orderSkuList) // 所有订单的支付金额 + orderMap, orderSkuMap, _ := orderSkuHandler(orderSkuList4Afs) + + afsOrderMap := make(map[string]*model.GoodsOrder) + for _, v := range afsSkuList { + universalOrderID := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID) + universalOrderSkuID := universalOrderID + "/" + utils.Int2Str(jxutils.GetSkuIDFromOrderSkuFinancial(v)) + order := afsOrderMap[universalOrderID] + if order == nil { + order = &model.GoodsOrder{ + StoreID: v.JxStoreID, + VendorID: v.VendorID, + } + if order.StoreID == 0 { + order.StoreID = v.StoreID + } + if orderSku := orderSkuMap[universalOrderSkuID]; orderSku != nil { + order.ActualPayPrice = orderSku.ActualPayPrice + } + afsOrderMap[universalOrderID] = order + } + order.SkuCount += v.Count + + if orderSku := orderSkuMap[universalOrderSkuID]; orderSku != nil { + order.ShopPrice += orderSku.ShopPrice * int64(v.Count) + order.VendorPrice += orderSku.VendorPrice * int64(v.Count) + order.SalePrice += orderSku.SalePrice * int64(v.Count) + order.EarningPrice += orderSku.EarningPrice * int64(v.Count) + } else { + // globals.SugarLogger.Debug(utils.Format4Output(v, true)) + } + } + for universalOrderID, v := range afsOrderMap { + if orderMap[universalOrderID] != nil && orderMap[universalOrderID].SkuCount == v.SkuCount { + v.EarningPrice = orderMap[universalOrderID].ActualPayPrice + } + status := -1 + index := jxutils.Combine2Int(v.StoreID, v.VendorID)*1000 + int64(status) + saleInfo := saleInfoMap[index] + if saleInfo == nil { + saleInfo = &dao.StoresOrderSaleInfo{ + StoreID: v.StoreID, + VendorID: v.VendorID, + Status: status, + } + saleInfoMap[index] = saleInfo + } + saleInfo.ActualPayPrice += v.ActualPayPrice + saleInfo.ShopPrice += v.ShopPrice + saleInfo.VendorPrice += v.VendorPrice + saleInfo.SalePrice += v.SalePrice + saleInfo.EarningPrice += v.EarningPrice + saleInfo.Count++ + } + for _, v := range saleInfoMap { + if v.Status == model.OrderStatusFinished { + // 计算平台计算 + settle, _ := dao.GetPlatformSettlement(db, storeIDList, fromTime, toTime) + for _, s := range settle { + if v.VendorID == s.VendorID { + v.PlatformSettlement = s.TotalShopMoney + } + } + + // 计算三方配送 + fee, _ := dao.GetPlatformDesiredFee(db, storeIDList, fromTime, toTime) + for _, f := range fee { + if v.VendorID == f.VendorID { + v.ActualFee = f.ActualFee + } + } + } + saleInfoList = append(saleInfoList, v) + } + return saleInfoList, err +} + func (c *OrderManager) GetStoresOrderSaleInfoNew(ctx *jxcontext.Context, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*dao.StoresOrderSaleInfo, err error) { db := dao.GetDB() var isLongTime = false diff --git a/business/jxcallback/orderman/waybill.go b/business/jxcallback/orderman/waybill.go index 73722a7b3..851c5853e 100644 --- a/business/jxcallback/orderman/waybill.go +++ b/business/jxcallback/orderman/waybill.go @@ -121,32 +121,32 @@ func (w *OrderManager) OnWaybillStatusChanged(bill *model.Waybill) (err error) { if err2 == nil { bill.DeliveryFlag = existingBill.DeliveryFlag } - if bill.Status == model.WaybillStatusAccepted { // 处理美团配送丢失新运单消息的情况 - if err2 != nil { - if dao.IsNoRowsError(err2) || err2 == ErrCanNotFindWaybill { - existingBill = bill - billCopy := *bill - billCopy.Status = model.WaybillStatusNew - if isDuplicated, err = w.OnWaybillNew(&billCopy, db); err != nil { - dao.Rollback(db, txDB) - return err - } - dao.Commit(db, txDB) - // 进运单调度器OnWaybillStatusChanged之前要确保事务是提交了的,否则会导致死锁 - // 加载数据到当前系统调度器当中 - scheduler.CurrentScheduler.OnWaybillStatusChanged(&billCopy, false) - dao.Begin(db) - } else { + //if bill.Status == model.WaybillStatusAccepted { // 处理美团配送丢失新运单消息的情况 + if err2 != nil { + if dao.IsNoRowsError(err2) || err2 == ErrCanNotFindWaybill { + existingBill = bill + billCopy := *bill + billCopy.Status = model.WaybillStatusNew + if isDuplicated, err = w.OnWaybillNew(&billCopy, db); err != nil { dao.Rollback(db, txDB) - return err2 + return err } - } - // 运单消息错序,之前已经结束了,直接返回 - if existingBill.Status >= model.WaybillStatusEndBegin { dao.Commit(db, txDB) - return nil + // 进运单调度器OnWaybillStatusChanged之前要确保事务是提交了的,否则会导致死锁 + // 加载数据到当前系统调度器当中 + scheduler.CurrentScheduler.OnWaybillStatusChanged(&billCopy, false) + dao.Begin(db) + } else { + dao.Rollback(db, txDB) + return err2 } } + // 运单消息错序,之前已经结束了,直接返回 + if existingBill.Status >= model.WaybillStatusEndBegin { + dao.Commit(db, txDB) + return nil + } + //} addParams := orm.Params{} if bill.Status >= model.WaybillStatusAccepted { if bill.Status == model.WaybillStatusAccepted { diff --git a/business/jxstore/misc/misc.go b/business/jxstore/misc/misc.go index 163b4a6ad..0e0b2bdd8 100644 --- a/business/jxstore/misc/misc.go +++ b/business/jxstore/misc/misc.go @@ -2,7 +2,6 @@ package misc import ( "fmt" - "git.rosy.net.cn/jx-callback/business/jxutils/enterprise_msg" "sync" "time" @@ -650,11 +649,6 @@ func syncStoreSkuTao() { db := dao.GetDB() switch step { case 0: - - if err := ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "淘鲜达消息:", utils.Format4Output("开始同步", false)); err != nil { - globals.SugarLogger.Debugf("SendUserMessage := %s", utils.Format4Output(err, false)) - } - enterprise_msg.SendUserMessage("18981810340", "淘鲜达同步消息", utils.Format4Output("开始同步", false), utils.Format4Output("开始同步", false)) _, err = cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{model.VendorIDTaoVegetable}, nil, false, nil, nil, syncFlag, true, true) errList.AddErr(err) case 1: diff --git a/business/model/dao/store.go b/business/model/dao/store.go index d52d68171..78eae67bd 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -1691,3 +1691,19 @@ func GetStoreBaseByVendorStoreID(vendorStoreID string, vendorID int) (storeDetai } return storeDetail, err } + +type StatisticsStore struct { + Count int64 `json:"count"` // 条数 + Status int `json:"status"` // 状态 +} + +// StatisticsStoreInfo 统计所有的门店信息 +func StatisticsStoreInfo() ([]*StatisticsStore, error) { + statistics := make([]*StatisticsStore, 0, 0) + + sql := ` select count(s.status) , s.status from store s GROUP BY s.status ` + if err := GetRows(GetDB(), &statistics, sql, nil); err != nil { + return nil, err + } + return statistics, nil +} diff --git a/controllers/jx_order.go b/controllers/jx_order.go index 2c59ab300..f6f7a4f2c 100644 --- a/controllers/jx_order.go +++ b/controllers/jx_order.go @@ -479,6 +479,28 @@ func (c *OrderController) GetStoresOrderSaleInfo() { }) } +// @Title 首页统计信息[(营业门店,休息门店,禁用门店),(订单状态订单数量统计,售后单+时间),(预计收益)] +// @Description 首页统计信息 +// @Param token header string true "认证token" +// @Param fromTime query string true "起始时间" +// @Param toTime query string true "结束时间" +// @Param statuss query string false "订单状态列表[1,2,3],缺省不限制" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /StaleIndexInfo [get] +func (c *OrderController) StaleIndexInfo() { + c.callStaleIndexInfo(func(params *tOrderStaleIndexInfoParams) (retVal interface{}, code string, err error) { + timeList, err := jxutils.BatchStr2Time(params.FromTime, params.ToTime) + if err == nil { + var statusList []int + if err = jxutils.Strings2Objs(params.Statuss, &statusList); err == nil { + retVal, err = orderman.FixedOrderManager.GetStoresOrderSaleInfo2(params.Ctx, timeList[0], timeList[1], statusList) + } + } + return retVal, "", err + }) +} + // @Title 刷新订单真实手机号 // @Description 刷新订单真实手机号 // @Param token header string true "认证token" diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index b59d985b8..06d2ad0bb 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1474,6 +1474,16 @@ func init() { Filters: nil, Params: nil}) + // 首页统计信息 + web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], + web.ControllerComments{ + Method: "StaleIndexInfo", + Router: `/StaleIndexInfo`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], web.ControllerComments{ Method: "GetWaybills",