更新
This commit is contained in:
@@ -5,6 +5,7 @@ namespace app\adminapi\logic\doctor;
|
||||
use app\common\logic\BaseLogic;
|
||||
use app\common\model\doctor\Appointment;
|
||||
use app\common\model\doctor\Roster;
|
||||
use app\common\service\doctor\RosterSegmentService;
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\api\logic\ChatNotifyLogic;
|
||||
@@ -70,72 +71,46 @@ class AppointmentLogic extends BaseLogic
|
||||
return ['slots' => []];
|
||||
}
|
||||
|
||||
// 2. 根据排班时段生成时间段
|
||||
// 2. 按每段排班的起止时间与号源间隔生成时间段
|
||||
$slots = [];
|
||||
|
||||
|
||||
foreach ($rosters as $roster) {
|
||||
// 再次确认状态为出诊(双重检查)
|
||||
if ($roster['status'] != 1) {
|
||||
if ((int) $roster['status'] !== 1) {
|
||||
\think\facade\Log::warning('跳过非出诊排班', [
|
||||
'roster_id' => $roster['id'],
|
||||
'status' => $roster['status']
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$periodValue = $roster['period'];
|
||||
|
||||
\think\facade\Log::info('处理排班时段', [
|
||||
'roster_id' => $roster['id'],
|
||||
'period' => $periodValue,
|
||||
'status' => $roster['status'],
|
||||
'period_type' => gettype($periodValue)
|
||||
]);
|
||||
|
||||
// 根据时段生成时间段(支持数字和字符串格式)
|
||||
$startHour = null;
|
||||
$endHour = null;
|
||||
|
||||
if ($periodValue == 1 || $periodValue === 'morning' || $periodValue === '上午') {
|
||||
// 上午:9:00-12:00
|
||||
$startHour = 9;
|
||||
$endHour = 12;
|
||||
\think\facade\Log::info('识别为上午时段', ['period' => $periodValue]);
|
||||
} elseif ($periodValue == 2 || $periodValue === 'afternoon' || $periodValue === '下午') {
|
||||
// 下午:14:00-18:00
|
||||
$startHour = 14;
|
||||
$endHour = 18;
|
||||
\think\facade\Log::info('识别为下午时段', ['period' => $periodValue]);
|
||||
} else {
|
||||
\think\facade\Log::warning('未知的时段值,跳过此记录', [
|
||||
'roster_id' => $roster['id'],
|
||||
'period' => $periodValue,
|
||||
'period_type' => gettype($periodValue)
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 确保startHour和endHour已设置
|
||||
if ($startHour === null || $endHour === null) {
|
||||
\think\facade\Log::error('时段参数未正确设置', [
|
||||
'roster_id' => $roster['id'],
|
||||
'period' => $periodValue
|
||||
'status' => $roster['status'],
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 生成15分钟间隔的时间段
|
||||
for ($hour = $startHour; $hour < $endHour; $hour++) {
|
||||
for ($minute = 0; $minute < 60; $minute += 15) {
|
||||
$time = sprintf('%02d:%02d', $hour, $minute);
|
||||
|
||||
$slots[] = [
|
||||
'time' => $time,
|
||||
'available' => true,
|
||||
'quota' => 1,
|
||||
'period' => $periodValue
|
||||
];
|
||||
}
|
||||
$window = RosterSegmentService::resolveWindow($roster);
|
||||
if ($window === null) {
|
||||
\think\facade\Log::warning('无法解析排班起止时间,跳过', [
|
||||
'roster_id' => $roster['id'],
|
||||
'period' => $roster['period'] ?? null,
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
[$startHm, $endHm] = $window;
|
||||
$slotMinutes = RosterSegmentService::normalizeSlotMinutes($roster['slot_minutes'] ?? 15);
|
||||
$times = RosterSegmentService::generateSlotTimes($startHm, $endHm, $slotMinutes);
|
||||
$times = RosterSegmentService::applyQuotaCap($times, (int) ($roster['quota'] ?? 0));
|
||||
|
||||
\think\facade\Log::info('处理排班时段', [
|
||||
'roster_id' => $roster['id'],
|
||||
'window' => $window,
|
||||
'slot_minutes' => $slotMinutes,
|
||||
'slot_count' => count($times),
|
||||
]);
|
||||
|
||||
foreach ($times as $time) {
|
||||
$slots[] = [
|
||||
'time' => $time,
|
||||
'available' => true,
|
||||
'quota' => 1,
|
||||
'period' => $roster['period'] ?? 'segment',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,14 +139,8 @@ class AppointmentLogic extends BaseLogic
|
||||
|
||||
\think\facade\Log::info('生成的时间段数量(去重后)', [
|
||||
'count' => count($slots),
|
||||
'morning_slots' => count(array_filter($slots, function($s) {
|
||||
return $s['time'] < '12:00';
|
||||
})),
|
||||
'afternoon_slots' => count(array_filter($slots, function($s) {
|
||||
return $s['time'] >= '14:00';
|
||||
})),
|
||||
'first_3_slots' => array_slice($slots, 0, 3),
|
||||
'last_3_slots' => array_slice($slots, -3)
|
||||
'last_3_slots' => array_slice($slots, -3),
|
||||
]);
|
||||
|
||||
// 4. 查询已预约的时间段
|
||||
@@ -237,6 +206,7 @@ class AppointmentLogic extends BaseLogic
|
||||
}
|
||||
$data = [
|
||||
'patient_id' => $params['patient_id'],
|
||||
'assistant_id'=>$params['assistant_id'],
|
||||
'doctor_id' => $params['doctor_id'],
|
||||
'roster_id' => 0, // 不再关联排班表
|
||||
'appointment_date' => $params['appointment_date'],
|
||||
@@ -244,6 +214,7 @@ class AppointmentLogic extends BaseLogic
|
||||
'appointment_time' => $appointmentTime,
|
||||
'appointment_type' => $params['appointment_type'] ?? 'video',
|
||||
'remark' => $params['remark'] ?? '',
|
||||
'channel_source' => $params['channel_source'] ?? '',
|
||||
'status' => 1,
|
||||
'create_time' => time(),
|
||||
'update_time' => time(),
|
||||
@@ -339,28 +310,41 @@ class AppointmentLogic extends BaseLogic
|
||||
public static function getDoctorAvailability($doctorId, $date)
|
||||
{
|
||||
try {
|
||||
$totalAvailable = 0;
|
||||
|
||||
// 查询上午和下午的排班
|
||||
$rosters = Roster::where([
|
||||
'doctor_id' => $doctorId,
|
||||
'date' => $date,
|
||||
'status' => 1 // 出诊
|
||||
])->select();
|
||||
'status' => 1,
|
||||
])->select()->toArray();
|
||||
|
||||
if (empty($rosters)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$bookedHm = Appointment::where([
|
||||
'doctor_id' => $doctorId,
|
||||
'appointment_date' => $date,
|
||||
'status' => 1,
|
||||
])->column('appointment_time');
|
||||
$bookedHm = array_map(static function ($t) {
|
||||
return substr((string) $t, 0, 5);
|
||||
}, $bookedHm);
|
||||
$bookedSet = array_fill_keys($bookedHm, true);
|
||||
|
||||
$totalAvailable = 0;
|
||||
|
||||
foreach ($rosters as $roster) {
|
||||
// 查询该时段已预约数量
|
||||
$appointmentCount = Appointment::where([
|
||||
'doctor_id' => $doctorId,
|
||||
'appointment_date' => $date,
|
||||
'period' => $roster->period,
|
||||
'status' => 1
|
||||
])->count();
|
||||
|
||||
// 计算剩余号源
|
||||
$remaining = $roster->quota - $appointmentCount;
|
||||
if ($remaining > 0) {
|
||||
$totalAvailable += $remaining;
|
||||
$window = RosterSegmentService::resolveWindow($roster);
|
||||
if ($window === null) {
|
||||
continue;
|
||||
}
|
||||
[$startHm, $endHm] = $window;
|
||||
$slotMinutes = RosterSegmentService::normalizeSlotMinutes($roster['slot_minutes'] ?? 15);
|
||||
$times = RosterSegmentService::generateSlotTimes($startHm, $endHm, $slotMinutes);
|
||||
$times = RosterSegmentService::applyQuotaCap($times, (int) ($roster['quota'] ?? 0));
|
||||
foreach ($times as $t) {
|
||||
if (empty($bookedSet[$t])) {
|
||||
++$totalAvailable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user