You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

837 lines
33 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers\API\Admin;
use App\Http\Controllers\Controller;
use App\Services\UserService;
use Illuminate\Http\Request;
use App\Lib\Rs;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
class ModelController extends Controller
{
private $userService;
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
/**
* 获取号源模板列表
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function list(Request $request)
{
$payload = $request->attributes->get('payload');
if (!$payload) {
return Rs::error('用户信息无效', 401);
}
$user = $this->userService->getUserInfoFromPayload($payload);
if (!$user) {
return Rs::error('用户不存在', 401);
}
$isAdmin = $this->userService->isAdmin($payload);
$userDeptId = $user->dept_id ?? null;
$departmentId = $request->input('department_id', null);
$modelTypeId = $request->input('model_type_id', null);
$resourceId = $request->input('resource_id', null);
$slotMode = $request->input('slot_mode', null);
$weekname = $request->input('weekname', null);
$page = $request->input('page', 1);
$pageSize = $request->input('page_size', 10);
$query = DB::table('plan_model')
->leftJoin('plan_model_type', 'plan_model.model_type_id', '=', 'plan_model_type.id')
->leftJoin('department', 'plan_model.department_id', '=', 'department.id')
->leftJoin('department_resource', 'plan_model.resource_id', '=', 'department_resource.id')
->where('plan_model.deleted', 0)
->select(
'plan_model.id',
'plan_model.model_type_id',
'plan_model_type.name as model_type_name',
'plan_model.department_id',
'department.name as department_name',
'plan_model.resource_id',
'department_resource.name as resource_name',
'department_resource.slot_mode',
'plan_model.total_quota',
'plan_model.weekname',
'plan_model.patient_type_mask',
'plan_model.start_time',
'plan_model.end_time',
'plan_model.cutoff_time',
'plan_model.status',
'plan_model.created_at',
'plan_model.updated_at'
);
// 权限控制:非管理员只能查看自己科室的模板
if (!$isAdmin) {
if (empty($userDeptId)) {
return Rs::error('请先绑定科室');
}
$query->where('plan_model.department_id', $userDeptId);
// 如果用户传入了科室参数,需要验证是否属于自己科室
if ($departmentId !== null && $departmentId !== '') {
if ($departmentId != $userDeptId) {
return Rs::error('无权限访问其他科室的数据');
}
}
}
if ($modelTypeId !== null && $modelTypeId !== '') {
$query->where('plan_model.model_type_id', $modelTypeId);
}
if ($slotMode !== null && $slotMode !== '') {
$query->where('plan_model.slot_mode', $slotMode);
}
if ($resourceId !== null && $resourceId !== '') {
$query->where('plan_model.resource_id', $resourceId);
}
if ($weekname !== null && $weekname !== '') {
$query->where('plan_model.weekname', $weekname);
}
if ($departmentId !== null && $departmentId !== '' && $isAdmin) {
// 管理员或无科室限制的用户可以根据科室筛选
$query->where('plan_model.department_id', $departmentId);
}
$total = $query->count();
$models = $query->orderBy('plan_model.id', 'desc')
->skip(($page - 1) * $pageSize)
->take($pageSize)
->get();
// 获取每个模板的渠道配额信息(包含公共池)
foreach ($models as $model) {
$channelQuotas = DB::table('plan_model_channel_quota as pmcq')
->leftJoin('channel', 'pmcq.channel_id', '=', 'channel.id')
->where('pmcq.model_id', $model->id)
->where('pmcq.deleted', 0)
->select(
'pmcq.id',
'pmcq.channel_id',
'channel.name as channel_name',
'channel.short_name',
'pmcq.total_quota',
'pmcq.allow_overuse_public_pool'
)
->get();
$model->channel_quotas = $channelQuotas;
}
$data = [
'list' => $models,
'total' => $total,
'page' => $page,
'page_size' => $pageSize,
'total_pages' => ceil($total / $pageSize)
];
return Rs::success($data);
}
/**
* 保存号源模板
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function Save(Request $request)
{
$payload = $request->attributes->get('payload');
if (!$payload) {
return Rs::error('用户信息无效', 401);
}
$user = $this->userService->getUserInfoFromPayload($payload);
if (!$user) {
return Rs::error('用户不存在', 401);
}
$isAdmin = $this->userService->isAdmin($payload);
$userDeptId = $user->dept_id ?? null;
$data = $request->validate([
'id' => 'nullable|integer',
'model_type_id' => 'required|integer',
'department_id' => 'required|integer',
'resource_id' => 'required|integer',
'slot_mode' => 'nullable|integer|in:1,2',
'total_quota' => 'required|integer|min:0',
'weekname' => 'required|string',
'patient_type_mask' => 'required|integer|min:1',
'start_time' => 'required|date_format:H:i:s',
'end_time' => 'required|date_format:H:i:s',
'cutoff_time' => 'nullable|date_format:H:i:s',
'allow_overuse_public_pool' => 'nullable|integer|in:0,1',
'status' => 'required|integer|in:0,1',
'channel_quotas' => 'nullable|array',
'channel_quotas.*.channel_id' => 'nullable|integer',
'channel_quotas.*.total_quota' => 'nullable|integer|min:0',
'channel_quotas.*.allow_overuse_public_pool' => 'nullable|integer|in:0,1',
]);
// 如果没有 id 或 id 为空,默认为 0新建
if (!isset($data['id']) || $data['id'] === null) {
$data['id'] = 0;
}
// 验证时间逻辑
$startTime = strtotime('2000-01-01 ' . $data['start_time']);
$endTime = strtotime('2000-01-01 ' . $data['end_time']);
if ($endTime <= $startTime) {
return Rs::error('结束时间必须晚于开始时间');
}
// 如果没有设置截止预约时间,默认使用结束时间
if (empty($data['cutoff_time'])) {
$data['cutoff_time'] = $data['end_time'];
}
// 如果是时间点模式,验证是否能整除
if ($data['slot_mode'] == 2) {
$totalMinutes = ($endTime - $startTime) / 60;
if ($totalMinutes % $data['total_quota'] !== 0) {
return Rs::error('时间点模式下,时间段总时长必须能被号源数量整除');
}
}
// 验证科室和资源是否匹配
$resource = DB::table('department_resource')
->where('id', $data['resource_id'])
->where('department_id', $data['department_id'])
->first();
if (!$resource) {
return Rs::error('资源不属于该科室');
}
// 验证模板类型是否属于该科室
$modelType = DB::table('plan_model_type')
->where('id', $data['model_type_id'])
->first();
if (!$modelType) {
return Rs::error('模板类型不存在');
}
if ($modelType->department_id != $data['department_id']) {
return Rs::error('模板类型不属于该科室');
}
// 验证时间交集:同一模板分类下,同资源、相同星期的时间段不能有交集
$weeknames = explode(',', $data['weekname']);
$newStartTime = strtotime('2000-01-01 ' . $data['start_time']);
$newEndTime = strtotime('2000-01-01 ' . $data['end_time']);
foreach ($weeknames as $weekname) {
// 查询同一模板分类、同资源、同星期下已存在的模板(排除当前编辑的记录)
$query = DB::table('plan_model')
->where('model_type_id', $data['model_type_id'])
->where('resource_id', $data['resource_id'])
->where('weekname', $weekname)
->where('deleted', 0);
// 如果是编辑操作,排除当前记录
if ($data['id'] > 0) {
$query->where('id', '!=', $data['id']);
}
$existingModels = $query->get();
foreach ($existingModels as $existingModel) {
$existingStartTime = strtotime('2000-01-01 ' . $existingModel->start_time);
$existingEndTime = strtotime('2000-01-01 ' . $existingModel->end_time);
// 判断时间是否有交集:新时间段与已存在时间段重叠
if (!($newEndTime <= $existingStartTime || $newStartTime >= $existingEndTime)) {
return Rs::error('该资源在周' . $weekname . '已存在冲突的时间段');
}
}
}
// 权限控制:非管理员只能操作自己科室的模板
if (!$isAdmin) {
if (empty($userDeptId)) {
return Rs::error('请先绑定科室');
}
if ($data['department_id'] != $userDeptId) {
return Rs::error('无权限操作其他科室的数据');
}
// 如果是更新操作,检查模板是否属于该科室
if ($data['id'] > 0) {
$model = DB::table('plan_model')
->where('id', $data['id'])
->first();
if (!$model) {
return Rs::error('模板不存在');
}
if ($model->department_id != $userDeptId) {
return Rs::error('无权限操作该模板');
}
}
}
$conditions = ['id' => $data['id']];
$values = [
'model_type_id' => $data['model_type_id'],
'department_id' => $data['department_id'],
'resource_id' => $data['resource_id'],
'slot_mode' => $data['slot_mode'] ?? null,
'total_quota' => $data['total_quota'],
'weekname' => $data['weekname'],
'patient_type_mask' => $data['patient_type_mask'],
'start_time' => $data['start_time'],
'end_time' => $data['end_time'],
'cutoff_time' => $data['cutoff_time'],
'status' => $data['status'],
];
$channelQuotas = $data['channel_quotas'] ?? [];
// 校验渠道配额之和等于 total_quota
if (!empty($channelQuotas)) {
$channelTotal = 0;
foreach ($channelQuotas as $quota) {
if (isset($quota['total_quota'])) {
$channelTotal += $quota['total_quota'];
}
}
if ($channelTotal != $data['total_quota']) {
return Rs::error('渠道配额之和(' . $channelTotal . ')与号源总数(' . $data['total_quota'] . ')不相等,请检查后重试');
}
}
try {
DB::beginTransaction();
// 解析星期列表
$weeknames = explode(',', $data['weekname']);
if ($data['id'] == 0) {
// 新增操作:为每个星期创建一条记录
$modelIds = [];
foreach ($weeknames as $weekname) {
$values['weekname'] = $weekname;
$values['created_at'] = now();
$values['updated_at'] = now();
$modelId = DB::table('plan_model')->insertGetId($values);
$modelIds[] = $modelId;
// 插入渠道配额
if (!empty($channelQuotas)) {
foreach ($channelQuotas as $quota) {
if (isset($quota['channel_id']) && isset($quota['total_quota']) && $quota['total_quota'] > 0) {
DB::table('plan_model_channel_quota')->insert([
'model_id' => $modelId,
'channel_id' => $quota['channel_id'],
'total_quota' => $quota['total_quota'],
'allow_overuse_public_pool' => $quota['allow_overuse_public_pool'] ?? 0,
'deleted' => 0,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
}
}
DB::commit();
// 返回第一个modelId
return Rs::success(['id' => $modelIds[0] ?? 0, 'model_ids' => $modelIds]);
} else {
// 更新操作
$values['updated_at'] = now();
$updated = DB::table('plan_model')
->where('id', $data['id'])
->update($values);
if ($updated === false) {
DB::rollBack();
return Rs::error('操作失败:模板不存在');
}
$modelId = $data['id'];
// 删除旧的渠道配额
DB::table('plan_model_channel_quota')
->where('model_id', $modelId)
->update(['deleted' => 1]);
// 插入新的渠道配额
if (!empty($channelQuotas)) {
foreach ($channelQuotas as $quota) {
if (isset($quota['channel_id']) && isset($quota['total_quota']) && $quota['total_quota'] > 0) {
DB::table('plan_model_channel_quota')->insert([
'model_id' => $modelId,
'channel_id' => $quota['channel_id'],
'total_quota' => $quota['total_quota'],
'allow_overuse_public_pool' => $quota['allow_overuse_public_pool'] ?? 0,
'deleted' => 0,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
}
DB::commit();
return Rs::success(['id' => $modelId]);
}
} catch (\Exception $e) {
DB::rollBack();
return Rs::error('保存失败:' . $e->getMessage());
}
}
/**
* 删除号源模板
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function Delete(Request $request)
{
$payload = $request->attributes->get('payload');
if (!$payload) {
return Rs::error('用户信息无效', 401);
}
$user = $this->userService->getUserInfoFromPayload($payload);
if (!$user) {
return Rs::error('用户不存在', 401);
}
$isAdmin = $this->userService->isAdmin($payload);
$userDeptId = $user->dept_id ?? null;
$data = $request->validate([
'id' => 'required|integer',
]);
// 查询模板信息
$model = DB::table('plan_model')
->where('id', $data['id'])
->first();
if (!$model) {
return Rs::error('模板不存在');
}
// 权限控制:非管理员只能删除自己科室的模板
if (!$isAdmin) {
if (empty($userDeptId)) {
return Rs::error('请先绑定科室');
}
if ($model->department_id != $userDeptId) {
return Rs::error('无权限删除该模板');
}
}
try {
DB::beginTransaction();
// 获取要删除的模板信息
$model = DB::table('plan_model')
->where('id', $data['id'])
->first();
if (!$model) {
DB::rollBack();
return Rs::error('模板不存在');
}
// 软删除模板(只删除这一条记录)
DB::table('plan_model')
->where('id', $data['id'])
->update(['deleted' => 1, 'updated_at' => now()]);
// 删除对应的渠道配额
DB::table('plan_model_channel_quota')
->where('model_id', $data['id'])
->update(['deleted' => 1]);
DB::commit();
return Rs::success();
} catch (\Exception $e) {
DB::rollBack();
return Rs::error('删除失败:' . $e->getMessage());
}
}
/**
* 生成号源
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function generatePlanBatch(Request $request)
{
$payload = $request->attributes->get('payload');
if (!$payload) {
return Rs::error('用户信息无效', 401);
}
$user = $this->userService->getUserInfoFromPayload($payload);
if (!$user) {
return Rs::error('用户不存在', 401);
}
$isAdmin = $this->userService->isAdmin($payload);
$userDeptId = $user->dept_id ?? null;
$data = $request->validate([
'start_date' => 'required|date',
'end_date' => 'required|date|after_or_equal:start_date',
'models' => 'required|array|min:1',
'models.*.model_id' => 'required|integer',
'models.*.start_time' => 'required|date_format:H:i:s',
'models.*.end_time' => 'required|date_format:H:i:s',
'models.*.weekname' => 'required|string',
]);
try {
DB::beginTransaction();
$startDate = $data['start_date'];
$endDate = $data['end_date'];
$models = $data['models'];
// ========== 1. 预加载节假日数据 ==========
$holidayMap = [];
$holidayRecords = DB::table('holiday')
->where('deleted', 0)
->where('status', 1)
->whereRaw('date BETWEEN ? AND ?', [$startDate, $endDate])
->get();
foreach ($holidayRecords as $h) {
$holidayMap[$h->date] = $h->type;
}
// ========== 2. 预加载所有模板、模板类型、渠道配额 ==========
$modelIds = array_column($models, 'model_id');
$modelRecords = DB::table('plan_model')
->whereIn('id', $modelIds)
->where('deleted', 0)
->get()
->keyBy('id');
$modelTypeIds = $modelRecords->pluck('model_type_id')->unique()->toArray();
$modelTypeRecords = DB::table('plan_model_type')
->whereIn('id', $modelTypeIds)
->where('deleted', 0)
->get()
->keyBy('id');
$channelQuotaMap = [];
$channelQuotaRecords = DB::table('plan_model_channel_quota')
->whereIn('model_id', $modelIds)
->where('deleted', 0)
->select('id', 'model_id', 'channel_id', 'total_quota', 'allow_overuse_public_pool')
->get();
foreach ($channelQuotaRecords as $cq) {
$channelQuotaMap[$cq->model_id][] = $cq;
}
// ========== 3. 预校验:存在性、权限、状态、时间点整除 ==========
foreach ($models as $modelInfo) {
$modelId = $modelInfo['model_id'];
$model = $modelRecords->get($modelId);
if (!$model) {
DB::rollBack();
return Rs::error('模板不存在:' . $modelId);
}
if ($model->status != 1) {
DB::rollBack();
return Rs::error('模板 ' . $modelId . ' 已停用,不能生成号源');
}
if (!$isAdmin) {
if (empty($userDeptId)) {
DB::rollBack();
return Rs::error('请先绑定科室');
}
if ($model->department_id != $userDeptId) {
DB::rollBack();
return Rs::error('无权限操作该模板');
}
}
if ($model->slot_mode == 2) {
$modelStartTime = strtotime('2000-01-01 ' . $model->start_time);
$modelEndTime = strtotime('2000-01-01 ' . $model->end_time);
$totalMinutes = ($modelEndTime - $modelStartTime) / 60;
if ($totalMinutes % $model->total_quota !== 0) {
DB::rollBack();
return Rs::error('时间点模式下,时间段总时长必须能被号源数量整除。当前模板时长 ' . $totalMinutes . ' 分钟,号源数量 ' . $model->total_quota . ',无法整除,请修改模板后再试');
}
}
}
// ========== 4. 预加载冲突检测所需的所有已有号源批次 ==========
$resourceIds = $modelRecords->pluck('resource_id')->unique()->toArray();
$existingBatches = DB::table('plan_batch')
->whereIn('resource_id', $resourceIds)
->where('plan_date', '>=', $startDate)
->where('plan_date', '<=', $endDate)
->where('deleted', 0)
->select('id', 'resource_id', 'plan_date', 'start_time', 'end_time')
->get();
$existingByResourceAndDate = [];
foreach ($existingBatches as $eb) {
$key = $eb->resource_id . '_' . $eb->plan_date;
$existingByResourceAndDate[$key][] = $eb;
}
// ========== 5. 冲突检测 ==========
$allConflicts = [];
foreach ($models as $modelInfo) {
$model = $modelRecords->get($modelInfo['model_id']);
$modelType = $modelTypeRecords->get($model->model_type_id);
$allowedDateRanges = $this->resolveDateRanges($modelType);
$holidayMode = $modelType->holiday_mode ?? 0;
$currentDate = new \DateTime($startDate);
$endDateTime = new \DateTime($endDate);
while ($currentDate <= $endDateTime) {
$planDate = $currentDate->format('Y-m-d');
$shouldGenerate = $this->shouldGenerateForDate($currentDate, $model, $allowedDateRanges, $holidayMode, $holidayMap);
if ($shouldGenerate) {
$key = $model->resource_id . '_' . $planDate;
$existing = $existingByResourceAndDate[$key] ?? [];
$newStartTime = strtotime('2000-01-01 ' . $model->start_time);
$newEndTime = strtotime('2000-01-01 ' . $model->end_time);
foreach ($existing as $plan) {
$existingStartTime = strtotime('2000-01-01 ' . $plan->start_time);
$existingEndTime = strtotime('2000-01-01 ' . $plan->end_time);
if (!($newEndTime <= $existingStartTime || $newStartTime >= $existingEndTime)) {
$allConflicts[] = $planDate . ' ' . $model->start_time . '-' . $model->end_time;
}
}
}
$currentDate->modify('+1 day');
}
}
if (!empty($allConflicts)) {
$uniqueConflicts = array_unique($allConflicts);
sort($uniqueConflicts);
DB::rollBack();
return Rs::error('以下时间段已存在号源,无法生成:' . implode('、', $uniqueConflicts));
}
// ========== 6. 生成号源 ==========
$totalCount = 0;
$skippedDates = [];
foreach ($models as $modelInfo) {
$model = $modelRecords->get($modelInfo['model_id']);
$modelType = $modelTypeRecords->get($model->model_type_id);
$allowedDateRanges = $this->resolveDateRanges($modelType);
$hasDateLimit = !empty($modelType->date_info);
$holidayMode = $modelType->holiday_mode ?? 0;
$channelQuotas = collect($channelQuotaMap[$model->id] ?? []);
$currentDate = new \DateTime($startDate);
$endDateTime = new \DateTime($endDate);
while ($currentDate <= $endDateTime) {
$planDate = $currentDate->format('Y-m-d');
$shouldGenerate = $this->shouldGenerateForDate($currentDate, $model, $allowedDateRanges, $holidayMode, $holidayMap);
if ($shouldGenerate) {
$hasChannelQuota = $channelQuotas->where('channel_id', '>', 0)->isNotEmpty();
$batchId = DB::table('plan_batch')->insertGetId([
'model_id' => $model->id,
'slot_mode' => $model->slot_mode,
'plan_date' => $planDate,
'weekname' => $currentDate->format('N'),
'department_id' => $model->department_id,
'resource_id' => $model->resource_id,
'patient_type_mask' => $model->patient_type_mask,
'total_quota' => $model->total_quota,
'used_quota' => 0,
'start_time' => $model->start_time,
'end_time' => $model->end_time,
'cutoff_time' => $model->cutoff_time,
'status' => $model->status,
'enable_channel_quota' => $hasChannelQuota ? 1 : 0,
'adduser' => $user->id,
'deleted' => 0,
'created_at' => now(),
'updated_at' => now(),
]);
if ($model->slot_mode == 1) {
DB::table('plan')->insert([
'batch_id' => $batchId,
'start_time' => $model->start_time,
'end_time' => $model->end_time,
'total_quota' => $model->total_quota,
'used_quota' => 0,
'status' => $model->status,
'created_at' => now(),
'updated_at' => now(),
]);
$totalCount++;
} else {
$modelStartTime = strtotime('2000-01-01 ' . $model->start_time);
$modelEndTime = strtotime('2000-01-01 ' . $model->end_time);
$totalMinutes = ($modelEndTime - $modelStartTime) / 60;
$intervalMinutes = $totalMinutes / $model->total_quota;
for ($i = 0; $i < $model->total_quota; $i++) {
$pointStartTime = $modelStartTime + ($i * $intervalMinutes * 60);
$pointEndTime = $pointStartTime + ($intervalMinutes * 60);
DB::table('plan')->insert([
'batch_id' => $batchId,
'start_time' => date('H:i:s', $pointStartTime),
'end_time' => date('H:i:s', $pointEndTime),
'total_quota' => 1,
'used_quota' => 0,
'status' => $model->status,
'created_at' => now(),
'updated_at' => now(),
]);
$totalCount++;
}
}
foreach ($channelQuotas as $quota) {
DB::table('plan_batch_channel_quota')->insert([
'batch_id' => $batchId,
'channel_id' => $quota->channel_id,
'total_quota' => $quota->total_quota,
'used_quota' => 0,
'created_at' => now(),
'updated_at' => now(),
]);
}
} else {
$skipReason = null;
$planMonthDay = $currentDate->format('m-d');
if ($hasDateLimit && !empty($allowedDateRanges)) {
$dateAllowed = false;
foreach ($allowedDateRanges as $range) {
if ($planMonthDay >= $range[0] && $planMonthDay <= $range[1]) {
$dateAllowed = true;
break;
}
}
if (!$dateAllowed) {
$skipReason = '不在模板类型允许的日期范围内';
}
}
if (!$skipReason && !in_array($currentDate->format('N'), explode(',', $model->weekname))) {
$skipReason = '星期不匹配';
}
if ($skipReason) {
$skippedDates[$planDate] = $skipReason;
}
}
$currentDate->modify('+1 day');
}
}
DB::commit();
$resultData = [
'count' => $totalCount,
'skipped_dates' => $skippedDates
];
$message = '成功生成 ' . $totalCount . ' 个号源';
if (!empty($skippedDates)) {
$skippedCount = count($skippedDates);
$message .= ",跳过 {$skippedCount} 个日期(不符合模板类型的日期范围限制)";
}
return Rs::success($resultData, $message);
} catch (\Exception $e) {
DB::rollBack();
return Rs::error('生成号源失败:' . $e->getMessage());
}
}
private function resolveDateRanges($modelType): array
{
$allowedDateRanges = [];
if ($modelType && !empty($modelType->date_info)) {
$dateInfo = json_decode($modelType->date_info, true);
if ($modelType->type == 1) {
if (is_array($dateInfo) && count($dateInfo) > 0) {
if (is_array($dateInfo[0]) && count($dateInfo[0]) == 2) {
$allowedDateRanges = $dateInfo;
} else {
$allowedDateRanges = [$dateInfo];
}
}
} else {
if (is_array($dateInfo) && count($dateInfo) > 0) {
foreach ($dateInfo as $date) {
$allowedDateRanges[] = [$date, $date];
}
}
}
}
return $allowedDateRanges;
}
private function shouldGenerateForDate(\DateTime $currentDate, $model, array $allowedDateRanges, int $holidayMode, array $holidayMap): bool
{
$planDate = $currentDate->format('Y-m-d');
$planMonthDay = $currentDate->format('m-d');
$dayOfWeek = $currentDate->format('N');
$dateAllowed = false;
if (empty($allowedDateRanges)) {
$dateAllowed = true;
} else {
foreach ($allowedDateRanges as $range) {
if ($planMonthDay >= $range[0] && $planMonthDay <= $range[1]) {
$dateAllowed = true;
break;
}
}
}
$isHoliday = isset($holidayMap[$planDate]) && $holidayMap[$planDate] == 1;
$isMakeupWork = isset($holidayMap[$planDate]) && $holidayMap[$planDate] == 2;
$weeknameMatch = in_array($dayOfWeek, explode(',', $model->weekname));
if ($holidayMode == 1) {
return $dateAllowed && $weeknameMatch;
} elseif ($holidayMode == 2) {
return $dateAllowed && $isHoliday;
} else {
if ($isHoliday) {
return false;
} elseif ($isMakeupWork) {
return $dateAllowed;
} else {
return $dateAllowed && $weeknameMatch;
}
}
}
}