|
|
@@ -100,29 +100,48 @@ class AutomaticDispatch extends Command
|
|
|
* 派单给平台工程师
|
|
|
*/
|
|
|
protected function platformWorker($item) {
|
|
|
- $real_distance = Db::raw("ST_Distance_Sphere(
|
|
|
- POINT({$item['lon']}, {$item['lat']}),
|
|
|
- POINT(lon, lat)
|
|
|
- ) AS real_distance");
|
|
|
+
|
|
|
+ // 定义地球半径(单位:千米)
|
|
|
+ $earthRadius = 6371;
|
|
|
+
|
|
|
+ // 定义 Haversine 公式计算距离的 SQL 片段
|
|
|
+ $distanceCalculation = "{$earthRadius} * 2 * ASIN(SQRT(
|
|
|
+ POWER(SIN((RADIANS({$item['lat']}) - RADIANS(a.lat)) / 2), 2) +
|
|
|
+ COS(RADIANS({$item['lat']})) * COS(RADIANS(a.lat)) *
|
|
|
+ POWER(SIN((RADIANS({$item['lon']}) - RADIANS(a.lon)) / 2), 2)
|
|
|
+ ))";
|
|
|
+ // 计算距离的字段定义
|
|
|
+ $real_distance = Db::raw("{$distanceCalculation} AS real_distance");
|
|
|
+
|
|
|
// 获取符合条件的工程师
|
|
|
- $worker = MasterWorker::alias('a')->leftJoin('master_worker_score b','a.id = b.worker_id')
|
|
|
- ->where([
|
|
|
- ['is_disable','=',0],
|
|
|
- ['work_status','=',0],
|
|
|
- ['accept_order_status','=',1],
|
|
|
- ['city','=',$item['city']],
|
|
|
- ['tenant_id','=',0]
|
|
|
- ])
|
|
|
- ->whereRaw('FIND_IN_SET('.$item['goods_category_id'].', a.category_ids)')
|
|
|
- ->whereRaw("ST_Distance_Sphere(
|
|
|
- POINT({$item['lon']}, {$item['lat']}),
|
|
|
- POINT(lon, lat)
|
|
|
- ) <= distance")
|
|
|
- ->field(['a.id','a.tenant_id','a.distance','a.lon','a.lat','a.worker_number','a.real_name','b.comprehensive_score','b.weight_score',$real_distance])
|
|
|
- ->orderRaw('(b.comprehensive_score + b.weight_score) desc')
|
|
|
- ->limit(100)
|
|
|
- ->select()
|
|
|
- ->toArray();
|
|
|
+ $worker = MasterWorker::alias('a')
|
|
|
+ ->leftJoin('master_worker_score b', 'a.id = b.worker_id')
|
|
|
+ ->where([
|
|
|
+ ['is_disable', '=', 0],
|
|
|
+ ['work_status', '=', 0],
|
|
|
+ ['accept_order_status', '=', 1],
|
|
|
+ ['city', '=', $item['city']],
|
|
|
+ ['tenant_id', '=', 0]
|
|
|
+ ])
|
|
|
+ ->whereRaw('FIND_IN_SET(' . $item['goods_category_id'] . ', a.category_ids)')
|
|
|
+ ->whereRaw("{$distanceCalculation} <= a.distance")
|
|
|
+ ->field([
|
|
|
+ 'a.id',
|
|
|
+ 'a.tenant_id',
|
|
|
+ 'a.distance',
|
|
|
+ 'a.lon',
|
|
|
+ 'a.lat',
|
|
|
+ 'a.worker_number',
|
|
|
+ 'a.real_name',
|
|
|
+ 'b.comprehensive_score',
|
|
|
+ 'b.weight_score',
|
|
|
+ $real_distance
|
|
|
+ ])
|
|
|
+ ->orderRaw('(b.comprehensive_score + b.weight_score) desc')
|
|
|
+ ->limit(100)
|
|
|
+ ->select()
|
|
|
+ ->toArray();
|
|
|
+
|
|
|
$queue = [];
|
|
|
foreach($worker as $key => $value) {
|
|
|
//过滤已接过此单的师傅
|
|
|
@@ -187,29 +206,55 @@ class AutomaticDispatch extends Command
|
|
|
* 派单给门店负责人
|
|
|
*/
|
|
|
protected function teamWorker($item) {
|
|
|
- $real_distance = Db::raw("ST_Distance_Sphere(
|
|
|
- POINT({$item['lon']}, {$item['lat']}),
|
|
|
- POINT(lon, lat)
|
|
|
- ) AS real_distance");
|
|
|
+
|
|
|
+ // 地球半径,单位:千米
|
|
|
+ $earthRadius = 6371;
|
|
|
+
|
|
|
+ // 定义 Haversine 公式计算距离的 SQL 片段
|
|
|
+ $distanceCalculation = "{$earthRadius} * 2 * ASIN(SQRT(
|
|
|
+ POWER(SIN((RADIANS({$item['lat']}) - RADIANS(lat)) / 2), 2) +
|
|
|
+ COS(RADIANS({$item['lat']})) * COS(RADIANS(lat)) *
|
|
|
+ POWER(SIN((RADIANS({$item['lon']}) - RADIANS(lon)) / 2), 2)
|
|
|
+ ))";
|
|
|
+
|
|
|
+ // 计算距离的字段定义
|
|
|
+ $real_distance = Db::raw("{$distanceCalculation} AS real_distance");
|
|
|
|
|
|
- $isAm = date("H",strtotime($item['appointment_time'])) < 12 ? 1 : 0;
|
|
|
+ // 判断预约时间是上午还是下午
|
|
|
+ $isAm = date("H", strtotime($item['appointment_time'])) < 12 ? 1 : 0;
|
|
|
+ // 根据上午或下午构建查询条件
|
|
|
$whereRaw = $isAm ? 'am_order < am_limit' : 'pm_order < pm_limit';
|
|
|
- // 获取符合条件的工程师
|
|
|
+
|
|
|
+ // 获取符合条件的工程师团队
|
|
|
$worker = MasterWorkerTeam::where([
|
|
|
- ['accept_order_status','=',1],
|
|
|
- ['city','=',$item['city']],
|
|
|
+ ['accept_order_status', '=', 1],
|
|
|
+ ['city', '=', $item['city']],
|
|
|
])
|
|
|
->whereRaw($whereRaw)
|
|
|
- ->whereRaw('FIND_IN_SET('.$item['goods_category_id'].', goods_category_ids)')
|
|
|
- ->whereRaw("ST_Distance_Sphere(
|
|
|
- POINT({$item['lon']}, {$item['lat']}),
|
|
|
- POINT(lon, lat)
|
|
|
- ) <= distance")
|
|
|
- ->field(['id','lon','lat','distance','tenant_id','team_name','master_worker_id','am_order','am_limit','pm_order','pm_limit','min_order','comprehensive_score', $real_distance])
|
|
|
- ->order('comprehensive_score','desc')
|
|
|
+ ->whereRaw('FIND_IN_SET(' . $item['goods_category_id'] . ', goods_category_ids)')
|
|
|
+ // 使用 Haversine 公式替换 ST_Distance_Sphere 函数进行距离筛选
|
|
|
+ ->whereRaw("{$distanceCalculation} <= distance")
|
|
|
+ ->field([
|
|
|
+ 'id',
|
|
|
+ 'lon',
|
|
|
+ 'lat',
|
|
|
+ 'distance',
|
|
|
+ 'tenant_id',
|
|
|
+ 'team_name',
|
|
|
+ 'master_worker_id',
|
|
|
+ 'am_order',
|
|
|
+ 'am_limit',
|
|
|
+ 'pm_order',
|
|
|
+ 'pm_limit',
|
|
|
+ 'min_order',
|
|
|
+ 'comprehensive_score',
|
|
|
+ $real_distance
|
|
|
+ ])
|
|
|
+ ->order('comprehensive_score', 'desc')
|
|
|
->limit(100)
|
|
|
->select()
|
|
|
->toArray();
|
|
|
+
|
|
|
$minQueue = [];
|
|
|
$queue = [];
|
|
|
foreach($worker as $key => $value) {
|