341 lines
13 KiB
PHP
Executable File
341 lines
13 KiB
PHP
Executable File
<?php
|
||
namespace app\common\logic;
|
||
use app\common\enum\coach\CoachEnum;
|
||
use app\common\enum\OrderEnum;
|
||
use app\common\model\coach\Coach;
|
||
use app\common\model\coach\CoachServerTime;
|
||
use app\common\model\deposit\DepositPackage;
|
||
use app\common\model\goods\Goods;
|
||
use app\common\model\goods\GoodsComment;
|
||
use app\common\model\order\Order;
|
||
use app\common\model\shop\Shop;
|
||
use app\common\service\ConfigService;
|
||
use DateTime;
|
||
use think\Exception;
|
||
|
||
/**
|
||
* 技师逻辑类
|
||
* Class CoachLogic
|
||
* @package app\common\logic
|
||
*/
|
||
class CoachLogic
|
||
{
|
||
|
||
|
||
/**
|
||
* @notes 获取技师订单时间
|
||
* @param int $coachId
|
||
* @return array
|
||
* @throws \Exception
|
||
* @author cjhao
|
||
* @date 2024/9/8 17:36
|
||
*/
|
||
public static function getCoachOrderAppoint(int $coachId)
|
||
{
|
||
$appointOrderList = Order::where(['coach_id'=>$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;
|
||
}
|
||
|
||
|
||
} |