$coachId]) ->where('order_status','not in',[OrderEnum::ORDER_STATUS_SERVER_FINISH,OrderEnum::ORDER_STATUS_CLOSE]) ->column('id,appoint_time,total_duration,server_finish_time'); $appointLists = []; foreach ($appointOrderList as $appointOrder) { $appointTime = $appointOrder['appoint_time']; $totalDuration = $appointOrder['total_duration']; $dateTime = new DateTime(date('Y-m-d H:i:s',$appointTime)); if(30 < $dateTime->format('i') && 0 != $dateTime->format('i')){ $dateTime->modify('+30 minutes'); } if($dateTime->format('i') > 30 ){ $surplusMinute = 60 - $dateTime->format('i'); $dateTime->modify('+'.$surplusMinute.' minutes'); } $dateHi = $dateTime->format('H:i'); $dateMd = $dateTime->format('m-d'); $appointLists[$dateMd][] = $dateHi; $nums = intval($totalDuration / 30); for ($i = 0;$nums > $i;$i++){ $dateHi = $dateTime->format('H:i'); //特殊时段,跨天 if( "23:00" == $dateHi){ $dateTime->modify('+1 day'); } $dateTime->modify('+30 minutes'); $dateMd = $dateTime->format('m-d'); $dateHi = $dateTime->format('H:i'); $appointLists[$dateMd][] = $dateHi; } } return $appointLists; } /** * @notes 获取技师的服务时间 * @param $coachId * @param $coachId * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author cjhao * @date 2024/9/9 14:38 */ public static function getCoachServerTime($coachId,$goodsId = 0) { $advanceAppoint = ConfigService::get('server_setting', 'advance_appoint'); $timestampLists[date('m-d',time())] = time()+60*60; for ($i = 1;$i < $advanceAppoint;$i++){ $timestampLists[date('m-d',strtotime('+ '.$i.' days'))] = strtotime('+ '.$i.' days midnight'); } $intervalsLists = []; foreach ($timestampLists as $date => $timestamp){ $intervalsLists[$date] = get_hour_to_midnight($timestamp); } //订单预约时间 $orderAppointLists = CoachLogic::getCoachOrderAppoint($coachId); //师傅空闲时间 $serverTimeLists = []; //师傅忙碌时间 $serverTimeBusyLists = []; $coachServerTime = CoachServerTime::where(['coach_id'=>$coachId]) ->field('date,time,status') ->select(); foreach ($coachServerTime as $time) { if(1 == $time['status']){ $serverTimeLists[$time['date']][] = $time['time']; }else{ $serverTimeBusyLists[$time['date']][] = $time['time']; } } $nowMd = date('m-d'); //往后一个小时可预约 $nowHi = date('H:i',strtotime('+1 hour')); $goods = []; if($goodsId){ $goods = Goods::where(['id'=>$goodsId])->field('appoint_start_time,appoint_end_time')->findOrEmpty()->toArray(); $appointMd = date('m-d',convert_to_time($goods['appoint_end_time'])); $goods['appoint_start_time'] = date('H:i',convert_to_time($goods['appoint_start_time'])); $goods['appoint_end_time'] = date('H:i',convert_to_time($goods['appoint_end_time'])); if( '00:00' == $goods['appoint_end_time'] && $nowMd != $appointMd){ $goods['appoint_end_time'] = "24:00"; } } foreach ($intervalsLists as $date => $intervals){ foreach ($intervals as $key => $interval){ $orderAppoint = $orderAppointLists[$date] ?? []; $serverTime = $serverTimeLists[$date] ?? []; $serverTimeBusy = $serverTimeBusyLists[$date]?? []; // $intervalsLists[$date][$key]['status'] = 0; //(不在服务时间) //空闲时间 if(in_array($interval['time'],$serverTime) || empty($serverTime)){ $intervals[$key]['status'] = 1; } //忙 if(in_array($interval['time'],$serverTimeBusy)){ $intervals[$key]['status'] = 2; } //已预约 if(in_array($interval['time'],$orderAppoint)){ $intervals[$key]['status'] = 3; } if($goods){ if($goods['appoint_start_time'] > $interval['time'] || $goods['appoint_end_time'] < $interval['time']){ // $intervalsLists[$date][$key]['status'] = 4; unset($intervals[$key]); } } //不可预约4(超过当前时间,或者不在服务时间) // if($date == $nowMd){ // if($nowHi > $interval['time']){ // $intervalsLists[$date][$key]['status'] = 4; // } // } } // if(empty($intervals)){ // unset($intervalsLists[$date]); // }else{ $intervalsLists[$date] = array_values($intervals); // } } return $intervalsLists; } /** * @notes 获取空闲技师 * @param $coachId :技师 * @param $startTime :空闲开始时间段 * @param $endTime :空闲结束时间段 * @return array * @author cjhao * @date 2024/10/9 16:37 */ public static function getLeisureCoach(int $coachId = 0,int $startTime = 0,int $endTime = 0,$order = [],$keyword = '') { $where = []; $where[] = ['audit_status','=',CoachEnum::AUDIT_STATUS_PASS]; $where[] = ['work_status','=',CoachEnum::WORK_STATUS_ONLINE]; $where[] = ['server_status','=',CoachEnum::WORK_STATUS_NORMAL]; if($coachId){ $where[] = ['id','<>',$coachId]; } if($keyword){ $where[] = ['name','like','%'.$keyword.'%']; } $longitude = $order['address_snap']['longitude']; $latitude = $order['address_snap']['latitude']; $coachLists = Coach::where($where) ->field('id,order_num,work_photo,good_comment,location,name,longitude,latitude,longitude_location,latitude_location') ->select()->toArray(); $coachServerScope = ConfigService::get('server_setting', 'coach_server_scope'); $startTimeDay = date('m-d',$startTime); $endTimeDay = date('m-d',$endTime); $startTimeHour = date('H:i',$startTime); $endTimeHour = date('H:i',$endTime); $leisureLists = []; foreach ($coachLists as $key => $coach){ $filed = 'round(st_distance_sphere(point('.$longitude.','.$latitude.'), point(longitude_location, latitude_location))/1000,2) as distance'; if(empty($coach['longitude_location'])){ $filed = 'round(st_distance_sphere(point('.$longitude.','.$latitude.'), point(longitude, latitude))/1000,2) as distance'; } $distance = Coach::where(['id'=>$coach['id']]) ->value($filed); if(empty($distance)){ continue; } if($distance > $coachServerScope){ continue; } $coachServerLists = self::getCoachServerTime($coach['id']); $startTimeLists = $coachServerLists[$startTimeDay] ?? []; $endTimeLists = $coachServerLists[$endTimeDay] ?? []; $startTimeLists = array_column($startTimeLists,null,'time'); $endTimeLists = array_column($endTimeLists,null,'time'); $startTimeData = $startTimeLists[$startTimeHour] ?? []; $endTimeData = $endTimeLists[$endTimeHour] ?? []; if(empty($startTimeData)){ continue; } if(1 != $startTimeData['status'] && 1 != $endTimeData['status']){ continue; } $coach['wait_serve_num'] = Order::where(['coach_id'=>$coach['id']]) ->where('order_status','>',OrderEnum::ORDER_STATUS_WAIT_RECEIVING) ->where('order_status','<',OrderEnum::ORDER_STATUS_SERVER_FINISH) ->count(); $leisureLists[] = $coach; } return $leisureLists; } /** * @notes * @param int $coachId * @return string * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author cjhao * @date 2024/11/22 17:43 */ public static function getLatelyLeisureTime(int $coachId) { $serverTime = self::getCoachServerTime($coachId); $today = date('m-d'); if(isset($serverTime[$today])){ return $serverTime[$today][0]['time'] ?? ''; } $tomorrow = date('m-d',strtotime("+1 day")); if(isset($serverTime[$tomorrow])){ return '明天:'.$serverTime[$tomorrow][0]['time'] ?? ''; } $dayafter = date('m-d',strtotime("+2 day")); if(isset($serverTime[$dayafter])){ return '后天:'.$serverTime[$dayafter][0]['time'] ?? ''; } $dayKey = array_key_first($serverTime); $time = $serverTime[$dayKey][0]['time']; return $dayKey.' '.$time; } /** * @notes 验证技师的接单数量 * @param $coach * @return void * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author cjhao * @date 2024/11/26 23:44 */ public static function ckechCoachTakeOrderNum($coach){ $deposit = $coach['deposit']; $depositPackageLists = []; $takeOrderNum = ConfigService::get('server_setting', 'shop_order_limit'); if($coach['shop_id']){ $deposit = Shop::where(['id'=>$coach['shop_id']])->value('deposit'); $where[] = ['type','=',2]; $orderNum = Order::where(['shop_id'=>$coach['shop_id'],'coach_id'=>$coach['id']]) ->where('order_status','in',[OrderEnum::ORDER_STATUS_WAIT_DEPART,OrderEnum::ORDER_STATUS_DEPART,OrderEnum::ORDER_STATUS_ARRIVE,OrderEnum::ORDER_STATUS_START_SERVER,OrderEnum::ORDER_STATUS_SERVER_FINISH]) ->whereDay('create_time')->count(); }else{ $where[] = ['type','=',1]; $orderNum = Order::where(['coach_id'=>$coach['id']]) ->where('order_status','in',[OrderEnum::ORDER_STATUS_WAIT_DEPART,OrderEnum::ORDER_STATUS_DEPART,OrderEnum::ORDER_STATUS_ARRIVE,OrderEnum::ORDER_STATUS_START_SERVER,OrderEnum::ORDER_STATUS_SERVER_FINISH]) ->whereDay('create_time')->count(); } $depositPackageLists = DepositPackage::where($where)->order('money desc')->select()->toArray(); //套餐列表 $depositPackageTakeOrderNum = 0; foreach ($depositPackageLists as $depositPackage){ if($deposit >= $depositPackage['money']){ $depositPackageTakeOrderNum = $depositPackage['order_limit']; break; } } $takeOrderNum += $depositPackageTakeOrderNum; if($orderNum >= $takeOrderNum){ throw new Exception('今日接单数量已达上限'); } } /** * @notes 更新技师评论分数 * @param $coachId * @return true * @author cjhao * @date 2024/12/6 12:30 */ public static function updateCoachComment($coachId) { //技师的好评 $allComment = GoodsComment::where(['coach_id'=>$coachId])->count(); $goodsComment = GoodsComment::where(['coach_id'=>$coachId]) ->where('service_comment','>=',3) ->count(); $coachGoodsComment = 0; if($goodsComment){ $coachGoodsComment = round($goodsComment/$allComment,2) * 100; } //更新技师的好评率 Coach::update(['good_comment'=>$coachGoodsComment],['id'=>$coachId]); return true; } }