初始版本

This commit is contained in:
贾祥聪
2025-08-19 14:16:51 +08:00
commit f937a1f9b9
4373 changed files with 359728 additions and 0 deletions

View File

@@ -0,0 +1,341 @@
<?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;
}
}