diff --git a/business/jxcallback/scheduler/basesch/basesch_ext.go b/business/jxcallback/scheduler/basesch/basesch_ext.go index 640a16796..b305a96ce 100644 --- a/business/jxcallback/scheduler/basesch/basesch_ext.go +++ b/business/jxcallback/scheduler/basesch/basesch_ext.go @@ -18,7 +18,7 @@ import ( func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order *model.GoodsOrder, courierVendorIDs, excludeCourierVendorIDs []int, policyHandler partner.CreateWaybillPolicyFunc, createOnlyOne bool) (bills []*model.Waybill, err error) { userName := ctx.GetUserName() globals.SugarLogger.Infof("CreateWaybillOnProviders orderID:%s userName:%s, courierVendorIDs:%v, excludeCourierVendorIDs:%v", order.VendorOrderID, userName, courierVendorIDs, excludeCourierVendorIDs) - storeCourierList, err := dao.GetStoreCourierList(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), model.StoreStatusOpened) + storeCourierList, err := dao.GetStoreCourierList(dao.GetDB(), []int{jxutils.GetSaleStoreIDFromOrder(order)}, model.StoreStatusOpened) if err != nil { return nil, err } diff --git a/business/jxcallback/scheduler/defsch/defsch_ext.go b/business/jxcallback/scheduler/defsch/defsch_ext.go index 8a930124e..4c59befb2 100644 --- a/business/jxcallback/scheduler/defsch/defsch_ext.go +++ b/business/jxcallback/scheduler/defsch/defsch_ext.go @@ -213,7 +213,7 @@ func (s *DefScheduler) QueryOrderWaybillFeeInfoEx(ctx *jxcontext.Context, vendor if order.DeliveryType == model.OrderDeliveryTypeSelfTake { return nil, fmt.Errorf("订单:%s是自提单", vendorOrderID) } - storeCourierList, err := dao.GetStoreCourierList(db, jxutils.GetSaleStoreIDFromOrder(order), model.StoreStatusAll) + storeCourierList, err := dao.GetStoreCourierList(db, []int{jxutils.GetSaleStoreIDFromOrder(order)}, model.StoreStatusAll) if err != nil { return nil, err } diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index 933b0bf8a..95088a846 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -107,101 +107,25 @@ var ( } ) -// todo 门店绑定信息可以考虑以数组形式返回,而不是现在这样 -func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interface{}, offset, pageSize int, orderTimeFrom, orderTimeTo time.Time, orderCountFrom, orderCountTo int) (retVal *StoresInfo, err error) { - sql := ` - SELECT SQL_CALC_FOUND_ROWS - CAST(t1.lng AS DECIMAL(15,6))/1000000 float_lng, - CAST(t1.lat AS DECIMAL(15,6))/1000000 float_lat, - t1.id, - t1.created_at, - t1.updated_at, - t1.last_operator, - t1.deleted_at, - t1.name, - t1.city_code, - t1.district_code, - t1.address, - t1.tel1, - t1.tel2, - t1.open_time1, - t1.close_time1, - t1.open_time2, - t1.close_time2, - t1.delivery_range_type, - t1.delivery_range, - t1.status, - t1.change_price_type, - t1.sms_notify, - - t1.id_card_front, - t1.id_card_back, - t1.id_card_hand, - t1.licence, - t1.licence_code, - t1.printer_sn, - t1.printer_key, - t1.printer_vendor_id, - - t1.licence_type, - t1.licence_corp_name, - t1.licence_owner_name, - t1.licence_address, - t1.licence_valid, - t1.licence_expire, - t1.id_name, - t1.id_code, - t1.id_valid, - t1.id_expire, - t1.licence2_image, - t1.licence2_code, - t1.licence2_valid, - t1.licence2_expire, - IF(mm.name <> '', mm.name, mm.user_id2) market_man_name, - t1.market_man_phone, - t1.jx_brand_fee_factor, - t1.market_add_fee_factor, - t1.payee_name, - t1.payee_account_no, - t1.payee_bank_branch_name, - t1.payee_bank_code, - bank.value payee_bank_name, - - t1.pay_percentage, - IF(om.name <> '', om.name, om.user_id2) operator_name, - t1.operator_phone, - t1.printer_disabled, - - t1.market_man_role, - t1.operator_role, - t1.operator_role2, - t1.printer_font_size, - - province.code province_code, - province.name province_name, - city.name city_name, - district.name district_name, - CONCAT('[', GROUP_CONCAT(DISTINCT CONCAT('{"vendorStoreID":"', m1.vendor_store_id, '", "vendorID":', m1.vendor_id, - ', "status":', m1.status, ', "pricePercentage":', m1.price_percentage, ', "pricePercentagePack":"', m1.price_percentage_pack, '", "vendorStoreName":"', m1.store_name, - '", "isSync":', m1.is_sync, - ', "fakeOpenStart":', m1.fake_open_start, ', "fakeOpenStop":', m1.fake_open_stop, '}')), ']') store_map_str, - CONCAT('[', GROUP_CONCAT(DISTINCT CONCAT('{"vendorStoreID":"', m2.vendor_store_id, '", "vendorID":', m2.vendor_id, - ', "status":', m2.status, '}')), ']') courier_map_str +func getStoresSql(ctx *jxcontext.Context, keyword string, params map[string]interface{}, orderTimeFrom, orderTimeTo time.Time) (sql string, sqlParams []interface{}, sqlFrom string, sqlFromParams []interface{}, err error) { + sqlFrom = ` FROM store t1 LEFT JOIN new_config bank ON bank.deleted_at = ? AND bank.type = ? AND bank.key = t1.payee_bank_code LEFT JOIN place city ON t1.city_code = city.code AND city.level = 2 LEFT JOIN place province ON province.code = city.parent_code AND province.level = 1 LEFT JOIN place district ON t1.district_code = district.code AND district.level = 3 + /* LEFT JOIN store_map m1 ON t1.id = m1.store_id AND m1.deleted_at = ? LEFT JOIN store_courier_map m2 ON t1.id = m2.store_id AND m2.deleted_at = ? + */ LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = t1.market_man_phone AND mm.deleted_at = ? LEFT JOIN user om ON om.mobile <> '' AND om.mobile = t1.operator_phone AND om.deleted_at = ? ` - sqlParams := []interface{}{ + sqlFromParams = []interface{}{ utils.DefaultTimeValue, model.ConfigTypeBank, - utils.DefaultTimeValue, - utils.DefaultTimeValue, + // utils.DefaultTimeValue, + // utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, } @@ -220,7 +144,7 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa if mapCondsStr != "" { var vendorStoreConds map[string]int if err = utils.UnmarshalUseNumber([]byte(mapCondsStr), &vendorStoreConds); err != nil { - return nil, err + return "", nil, "", nil, err } sqlVendorStoreCond := "" for vendor, cond := range vendorStoreConds { @@ -233,8 +157,8 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa sqlVendorStoreCond += " AND ( 1 = 0" } } - sql += "\nLEFT JOIN " + tableName + " " + tableAlias + " ON " + tableAlias + ".vendor_id = ? AND " + tableAlias + ".store_id = t1.id AND " + tableAlias + ".deleted_at = ?" - sqlParams = append(sqlParams, vendor, utils.DefaultTimeValue) + sqlFrom += "\nLEFT JOIN " + tableName + " " + tableAlias + " ON " + tableAlias + ".vendor_id = ? AND " + tableAlias + ".store_id = t1.id AND " + tableAlias + ".deleted_at = ?" + sqlFromParams = append(sqlFromParams, vendor, utils.DefaultTimeValue) if cond == 1 { sqlVendorStoreCond += " " + mapCond + " " + tableAlias + ".id IS NOT NULL" } else { @@ -281,7 +205,7 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa var storeIDs []int if params["storeIDs"] != nil { if err = jxutils.Strings2Objs(utils.Interface2String("storeIDs"), &storeIDs); err != nil { - return nil, err + return "", nil, "", nil, err } } if params["storeID"] != nil { @@ -325,7 +249,7 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa if params["statuss"] != nil { var statuss []int if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil { - return nil, err + return "", nil, "", nil, err } if len(statuss) > 0 { sqlWhere += " AND t1.status IN (" + dao.GenQuestionMarks(len(statuss)) + ")" @@ -333,75 +257,115 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa } } - sql += sqlWhere + ` - GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, - 41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65 - ORDER BY t1.id DESC - /*LIMIT ? OFFSET ?*/` - pageSize = jxutils.FormalizePageSize(pageSize) - if offset < 0 { - offset = 0 - } + sql = sqlFrom + sqlWhere + sqlParams = append(sqlParams, sqlFromParams...) sqlParams = append(sqlParams, sqlWhereParams...) - // sqlParams = append(sqlParams, pageSize, offset) - retVal = &StoresInfo{} - db := dao.GetDB() - // dao.Begin(db) - // defer func() { - // if r := recover(); r != nil { - // dao.Rollback(db) - // panic(r) - // } - // }() - // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) - // globals.SugarLogger.Debug(sql) - var storeList []*StoreExt - mapLimit := false - needConver2Baidu := int(utils.Interface2Int64WithDefault(params["coordinateType"], 0)) == model.CoordinateTypeBaiDu + return sql, sqlParams, sqlFrom, sqlFromParams, nil +} +func setStoreMapInfo(ctx *jxcontext.Context, db *dao.DaoDB, storesInfo *StoresInfo, storeIDs []int) (err error) { + storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll, model.StoreIsSyncAll, "") + if err != nil { + return err + } + storeCourierList, err := dao.GetStoreCourierList(db, storeIDs, model.StoreStatusAll) + if err != nil { + return err + } + + storeMapMap := make(map[int][]*model.StoreMap) + for _, v := range storeMapList { + storeMapMap[v.StoreID] = append(storeMapMap[v.StoreID], v) + } + storeCourierMap := make(map[int][]*model.StoreCourierMap) + for _, v := range storeCourierList { + storeCourierMap[v.StoreID] = append(storeCourierMap[v.StoreID], v) + } + + for _, v := range storesInfo.Stores { + for _, v2 := range storeMapMap[v.ID] { + v.StoreMaps = append(v.StoreMaps, utils.Struct2FlatMap(v2)) + } + for _, v2 := range storeCourierMap[v.ID] { + v.CourierMaps = append(v.CourierMaps, utils.Struct2FlatMap(v2)) + } + } + return nil +} + +// todo 门店绑定信息可以考虑以数组形式返回,而不是现在这样 +func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interface{}, offset, pageSize int, orderTimeFrom, orderTimeTo time.Time, orderCountFrom, orderCountTo int) (retVal *StoresInfo, err error) { + sql, sqlParams, _, _, err := getStoresSql(ctx, keyword, params, orderTimeFrom, orderTimeTo) + + if err != nil { + return nil, err + } + sql = ` + SELECT + DISTINCT t1.*, + CAST(t1.lng AS DECIMAL(15,6))/1000000 float_lng, + CAST(t1.lat AS DECIMAL(15,6))/1000000 float_lat, + IF(mm.name <> '', mm.name, mm.user_id2) market_man_name, + bank.value payee_bank_name, + IF(om.name <> '', om.name, om.user_id2) operator_name, + province.code province_code, + province.name province_name, + city.name city_name, + district.name district_name + ` + sql + ` + ORDER BY t1.id DESC + ` + db := dao.GetDB() + retVal = &StoresInfo{} + + var storeIDs []int + var storeList []*StoreExt + offset = jxutils.FormalizePageOffset(offset) + pageSize = jxutils.FormalizePageSize(pageSize) + mapLimit := false if err = dao.GetRows(db, &storeList, sql, sqlParams...); err == nil { - // retVal.TotalCount = dao.GetLastTotalRowCount(db) - // dao.Commit(db) - // globals.SugarLogger.Debugf("GetStores, len(storeList):%d", len(storeList)) - var ( - mapLatitude, mapLongitude float64 - mapRadius int - ) + // 地图区域限制过滤 if mapLongitude2, ok := params["mapLongitude"].(string); ok { + var ( + mapLatitude, mapLongitude float64 + mapRadius int + ) mapLimit = true mapLongitude = utils.Str2Float64(mapLongitude2) mapLatitude = utils.Str2Float64(params["mapLatitude"].(string)) mapRadius = params["mapRadius"].(int) - } - for _, v := range storeList { - valid := !mapLimit - if mapLimit { - valid = jxutils.EarthDistance(mapLongitude, mapLatitude, v.FloatLng, v.FloatLat)*1000 <= float64(mapRadius) - } - if valid { - if v.StoreMapStr != "" { - if err = utils.UnmarshalUseNumber([]byte(v.StoreMapStr), &v.StoreMaps); err != nil { - return nil, err - } + for _, v := range storeList { + valid := !mapLimit + if mapLimit { + valid = jxutils.EarthDistance(mapLongitude, mapLatitude, v.FloatLng, v.FloatLat)*1000 <= float64(mapRadius) } - if v.CourierMapStr != "" { - if err = utils.UnmarshalUseNumber([]byte(v.CourierMapStr), &v.CourierMaps); err != nil { - return nil, err - } + if valid { + retVal.Stores = append(retVal.Stores, v) } - retVal.Stores = append(retVal.Stores, v) } - } - retVal.Stores, err = filterStoreByOrderInfo(db, retVal.Stores, orderTimeFrom, orderTimeTo, orderCountFrom, orderCountTo) - retVal.TotalCount = len(retVal.Stores) - if offset >= retVal.TotalCount { - retVal.Stores = nil } else { - if offset+pageSize > retVal.TotalCount { - pageSize = retVal.TotalCount - offset - } - retVal.Stores = retVal.Stores[offset : offset+pageSize] + retVal.Stores = storeList } + + // 订单情况过滤 + storeList, err = filterStoreByOrderInfo(db, retVal.Stores, orderTimeFrom, orderTimeTo, orderCountFrom, orderCountTo) + if err != nil { + return nil, err + } + + // 分页 + retVal.TotalCount = len(storeList) + retVal.Stores = nil + for i := offset; i < offset+pageSize && i < len(storeList); i++ { + storeIDs = append(storeIDs, storeList[i].ID) + retVal.Stores = append(retVal.Stores, storeList[i]) + } + if len(storeIDs) == 0 { + return retVal, nil + } + + // 导出门店地图标信息时,可能会需要转换门店坐标 + needConver2Baidu := int(utils.Interface2Int64WithDefault(params["coordinateType"], 0)) == model.CoordinateTypeBaiDu if needConver2Baidu { task := tasksch.NewParallelTask("坐标转换", tasksch.NewParallelConfig().SetParallelCount(4).SetBatchSize(autonavi.MaxConvertCount), ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { @@ -427,14 +391,12 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa task.Run() task.GetResult(0) } - // if mapLimit { - // retVal.TotalCount = len(retVal.Stores)f - // } } else { - // dao.Rollback(db) + return nil, err } - retVal.Stores = append(retVal.Stores, &StoreExt{}) + if len(retVal.Stores) > 0 { + setStoreMapInfo(ctx, db, retVal, storeIDs) retVal.MapCenterLng, retVal.MapCenterLat = getMapCenter(retVal.Stores) } return retVal, err @@ -493,7 +455,7 @@ func getMapCenter(storeList []*StoreExt) (lng, lat float64) { newStoreList := []*StoreExt{} for _, store := range storeList { dist := math.Sqrt((store.FloatLng-lngAvg)*(store.FloatLng-lngAvg) + (store.FloatLat-latAvg)*(store.FloatLat-latAvg)) - if dist < maxDist { + if dist <= maxDist { lng += store.FloatLng lat += store.FloatLat newStoreList = append(newStoreList, store) @@ -502,10 +464,10 @@ func getMapCenter(storeList []*StoreExt) (lng, lat float64) { if len(newStoreList) == len(storeList) { lng = lng / float64(len(newStoreList)) lat = lat / float64(len(newStoreList)) - for _, store := range storeList { - globals.SugarLogger.Debugf("store:%s, lng:%f, lat:%f", store.Name, store.FloatLng, store.FloatLat) - } - globals.SugarLogger.Debugf("lng:%f, lat:%f", lng, lat) + // for _, store := range storeList { + // globals.SugarLogger.Debugf("store:%s, lng:%f, lat:%f", store.Name, store.FloatLng, store.FloatLat) + // } + // globals.SugarLogger.Debugf("lng:%f, lat:%f", lng, lat) return lng, lat } return getMapCenter(newStoreList) diff --git a/business/model/dao/store.go b/business/model/dao/store.go index 1206d6d0e..13e0e565d 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -199,15 +199,18 @@ func GetStoreDetail2(db *DaoDB, storeID int, vendorStoreID string, vendorID int) return storeDetail, err } -func GetStoreCourierList(db *DaoDB, storeID, status int) (courierStoreList []*model.StoreCourierMap, err error) { +func GetStoreCourierList(db *DaoDB, storeIDs []int, status int) (courierStoreList []*model.StoreCourierMap, err error) { sql := ` SELECT t1.* FROM store_courier_map t1 - WHERE t1.deleted_at = ? AND t1.store_id = ? + WHERE t1.deleted_at = ? ` sqlParams := []interface{}{ utils.DefaultTimeValue, - storeID, + } + if len(storeIDs) > 0 { + sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" + sqlParams = append(sqlParams, storeIDs) } if status != model.StoreStatusAll { sql += " AND t1.status = ?" diff --git a/business/model/dao/store_test.go b/business/model/dao/store_test.go index 6905a1c0f..9bb051281 100644 --- a/business/model/dao/store_test.go +++ b/business/model/dao/store_test.go @@ -17,7 +17,7 @@ func TestGetStoreDetail(t *testing.T) { } func TestGetStoreCourierList(t *testing.T) { - storeCourierList, err := GetStoreCourierList(GetDB(), 100119, model.StoreStatusOpened) + storeCourierList, err := GetStoreCourierList(GetDB(), []int{100119}, model.StoreStatusOpened) if err != nil { t.Fatal(err) }