Files
anmo/server/app/common/logic/CoachLogic.php
2025-08-19 14:16:51 +08:00

341 lines
13 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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;
}
}