یلدا ادامه داره... ❤️ ۴۰ درصد تخفیف همه دورهها
استفاده از تخفیفهاسلام دوستان.
من یه سایت نوبت دهی پزشکان دارم.
جدولی که نوبت ها داخلش ثبت میشه به این صورت هست.
Schema::create('turns', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreignId('doctor_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->integer('hour');
$table->timestamps();
});
حالا من میخوام وقتی کاربر طبق عکس زیر مثلا میاد ساعت 8 از دکتری که میخواد نوبت گرفت دیگه اون ساعت واسه اون دکتر به کاربرای دیگه نمایش داده نشه، در واقع یه کاربر دیگه دوباره نیاد ساعت 8 از همون دکتر نوبت بگیر و فقط ساعت 8:10 نمایش داده بشه.
برای انجام اینکار کوئریمو چطور باید بنویسم؟
درود
شما چند روش دارید
اگر هر روز فقط 2 نوبت داده میشه
به نظر من بهتره 2 تا سطون ایجاد کنید
مثلا ستون reserv1 ,و ستون reserv2
Schema::create('turns', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreignId('doctor_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->integer('res1')->default(0); //* مثلا نوبت ساعت 8 *//
$table->integer('res2')->default(0); //* مثلا نوبت ساعت 8:30 *//
$table->date('date'); //* تاریخ حضور *//
$table->timestamps();
});```
که اگر کاربر نوبت ساعت 8 تاریخ 1400/11/29 نتخواب کرد اطلاعات ذخیره و ستون reserv1 مقدار 1 بگیره
قبل ثبت اطلاعات هم یه چک کنید ببینید ایا تاریخ 1400/11/29 نوبتی ثبت شده و یا اگر ثبت شده کدوم ستون هستش اگر برابر با زمان انتخوابی کاربر بود ارور رزرو شده است نمایش بده
همین کار رو هم زمان نوبت گرفتن در تگ select پیاده کنید که تاریخ حضور فلان از 2 تا ستون رزرومون کدومش برابر با 0 هستش و اون زمان نشون بده در این صورت کاربر نمیتونه زمانی که رزرو شده رو ببینه و انتخواب کنه یه جور فیلتر 2 جانبه هم زمان ذخیره هم زمان نمایش
سلام ، این حالت رو با یه فیلد reserved میتونی هندل کنی .
طبق جدولی که داری userid , doctorid , hour . یعنی یه فیلد تحت عنوان reserve اضافه کنی راحت میتونی کوئری بزنی .به این شکل :
Schema::create('turns', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreignId('doctor_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->integer('hour');
$table->boolean('reserved')->default(0);
$table->timestamps();
})
همچنین کوئری هم به این شکل میتونی بنویسی :
$doctor_times = Turn::where(['doctor_id' => $doctor_id , 'reserved' => 0])->get();
@ghost
@hossein.azeemi
ببنید دوستان من یه جدول جدا دارم به اسم hours به صورت زیر که ادمین داخلش ساعت add میکنه.
Schema::create('hours', function (Blueprint $table) {
$table->id();
$table->string('hour')->unique();
$table->timestamps();
});
و زمانی که ادمین میخواد یه دکتر ایجاد کنه ساعت هایی که دکتر هست رو انتخاب میکنه و رابطه بین دکتر و ساعت چند به چند هست که داخل جدول دیگه ای به صورت زیر ذخیره میشه.
Schema::create('doctor_hour', function (Blueprint $table) {
$table->id();
$table->foreignId('doctor_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreignId('hour_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->timestamps();
});
و زمانی که کاربر مثلا ساعت 8 رو انتخاب میکنه اطلاعات مطابق عکس زیر وارد جدول turns میشه.
همچنین داخل اون عکسی که در صورت سوال قرار دادم، من ساعت های حضور هر دکتر رو به صورت زیر نمایش میدم.
<div class="form-group">
<select class="form-control" name="hour">
@foreach($doctor->hours as $hour)
<option value="{{ $hour->hour }}">{{ $hour->hour }}</option>
@endforeach
</select>
</div>
@hossein.azeemi
حالا طبق چیزی که شما گفتین با اضاضه کردن فیلد reserved و اون کوئری، ساعت هایی که گرفته شدن نمایش داده میشه ولی من میخوام اون ساعت هایی که رزرو شدن دیگه داخل بلید نمایش داده نشن.
@ghost
لیست ساعت برای هر دکتر مشخص نیست به خاطر همین کاری که شما گفتین رو انجام ندادم.
سلام ، برای جدول doctorhour که داری ساعات کاری هر دکتر رو مشخص میکنی .
مثلا آقای دکتر محمد رضایی ساعت های 12 ، 13 ، 18 و 22 فعالیت میکنه ( با این وجود شما 4 تا رکورد برای این دکتر توی جدول doctorhour داری و میخوای کاری کنی که اگر یکی یا چندتا ازاین ساعت ها قبلا توسط بیمار دیگه ای رزرو شده بود ، دیگه قابلیت رزرو به بیمار جدیدی رو نداشته باشه همچنین توی لیستی که برای دریافت نوبت هم میاره نشونش نده ) . این کل چیزی بود که من از توضیحات شما برداشت کردم .
حالا تنها کاری که نیاز هست انجام بدی اینه که توی جدول doctorhour یه فیلد با هرعنوانی که میخوای ، من اسمشو میزارم reserved . بسازی و هرموقع هرکدوم از ساعت های اون دکتر توسط یه کاربر رزرو شد ، مقدار فیلد رو 1 کنی و وقتی میخوای توی بلید لیست ساعت های آزاد یک دکتر رو نشون بدی به این شکل کوئریتو بنویس :
$doctor_free_times = DoctorHour::where(['doctor_id' => $doctor->id , 'reserved' => 0])->get();
با فرض اینکه اطلاعات دکتر در آبجکت doctor وجود داره .
این کوئری رو به روش های دیگه ای هم میتونی بنویسی ، من راحت ترین حالتش رو نوشتم . میتونی از کنترولر اینو پاس بدی به ویو
@hossein.azeemi
الان من داخل بلید به صورت زیر نوشتم و به درستی داره نمایش میده.
<select class="form-control" name="hour">
@if($free_times = \App\Models\DoctorHour::where(['doctor_id' => $doctor->id, 'reserved' => 0])->get())
@foreach($free_times as $hour)
<option value="{{ $hour->hour->hour }}">{{ $hour->hour->hour }}</option>
@endforeach
@endif
</select>
و فانکشن ثبت نوبت هم به صورت زیر هست.
public function turn(Request $request) {
$doctor = Doctor::findOrFail($request->doctor_id);
$doctor_hours = DoctorHour::where('doctor_id', $doctor->id);
Turn::create([
'user_id' => Auth::user()->id,
'doctor_id' => $doctor->user->id,
'hour' => $request->hour
]);
$doctor_hours->update(['reserved' => '1']);
session()->flash('status', 'نوبت شما با موفقیت ثبت شد');
return redirect()->route('patient.turn');
}
اما وقتی رو باتن دریافت نوبت کلیک میکنم با ارور زیر مواجه میشم.
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
در واقع به خط زیر داره گیر میده:
'hour' => $request->hour
خروجی کد زیر:
dd($request->hour);
"8:00"
سلام :
'doctor_id' => $doctor->user->id,
یه عکس از جداولت بفرست
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('role')->default('user');
$table->string('fullName');
$table->string('mobile')->unique();
$table->string('idNumber')->unique();
$table->string('password');
$table->timestamps();
});
Schema::create('hours', function (Blueprint $table) {
$table->id();
$table->string('hour')->unique();
$table->timestamps();
});
Schema::create('specialities', function (Blueprint $table) {
$table->id();
$table->string('speciality');
$table->timestamps();
});
Schema::create('doctors', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreignId('speciality_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->string('date');
$table->string('degree');
$table->string('image');
$table->timestamps();
});
Schema::create('doctor_hour', function (Blueprint $table) {
$table->id();
$table->foreignId('doctor_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreignId('hour_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->boolean('reserved')->default(0);
$table->timestamps();
});
Schema::create('turns', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreignId('doctor_id')->constrained()->onDelete('CASCADE')->onUpdate('CASCADE');
$table->integer('hour');
$table->timestamps();
});
ثبت یک دکتر هم به صورت زیر هست:
public function store(CreateDoctorRequest $request)
{
$data = $request->validated();
$image = $this->uploadImage();
if ($request->hasFile('image')) {
$data['image'] = $image;
}
$doctor = Doctor::create($data);
$doctor->hours()->attach($request->input('hour'));
session()->flash('status', 'دکتر مورد نظر با موفقیت ثبت شد');
return redirect()->route('doctors.index');
}
اگر به چیز دیگه ای نیاز هست بفرمایید تا بفرستم
سلام ، دیتابیسی که داری زیاد بهینه نیست اما طبق همون برات توضیح میدم :
برای به دست آوردن لیست ساعت های آزاد یک دکتر :
$doctor_free_times = DoctorHour::where(['doctor_id' => $doctor->id , 'reserved' => 0])->get();
در صورتی که مقدار فیلد reserved برابر با عدد 1 باشه یعنی این ساعت قبلا رزرو شده است و میتونی با یه where به راحتی این رو هندل کنی
با فرض اینکه آبجکت $doctor حاوی اطلاعات اون دکتر است
برای اینکه توی ویو نمایش بدی ، اول آی دی دکتر رو میفرستی سمت کنترولر تا بتونی تمامی ساعت های آزادش رو به دست بیاری و به view پاس بدی ، به این شکل :
// Doctor Controller
public function doctorFreeTimes($doctor_id){
$doctor_free_times = DoctorHour::where(['doctor_id' => $doctor_id , 'reserved' => 0])->with('hour')->get();
return view('reserve' , compact('doctor_free_times'));
}
حالا توی ویو به شکل زیر میتونی ساعت های آزاد این دکتر رو به کاربر نشون بدی :
<select name="hour">
<option value="0"> لطفا ساعت مورد نظر را انتخاب کنید </option>
@foreach($doctor_free_times as $item)
<option value="{{ $item->hour->id }}">{{ $item->hour->hour }}</option>
@endforeach
</select>
کد بالا رو به دقت ببین ، من فرض رو بر این گرفتم که توی مدل DoctorHour یه ریلیشن با نام hour موجود هست که اطلاعات اون ساعت رو بهت میده . به همین صورت با دستور with دریافتش کردم و توی foreach اطلاعات مربوطه به همون ساعت رو به کابر نشون دادم یعنی آی دی و عنوان.
نیاز به تکمیل کردن و بهینه کردن داره این کد ، یکی دوتا if احتیاج هست که چک کنی اگر آرایه free_doctor_times حاوی اطلاعات بود و یا وجود داشت و ...
امیدوارم که مشکلت حل بشه با این ، تمام چیزی که نیاز داری برای انجام دادن کارت همین بود . در پایان بعد از اینکه بیمار یک ساعت رو رزرو کرد ، باید بری توی جدول DoctorHour و فیلد reserved مربوط به اون ساعت رو به عدد 1 تغییر بدی
@hossein.azeemi
مشکل حل شد، فانکشن مربوط به ثبت نوبت هم به صورت زیر تغییر دادم:
public function turn(Request $request) {
$doctor = Doctor::findOrFail($request->doctor_id);
$hour = Hour::findOrFail($request->hour);
$doctor_hours = DoctorHour::where(['doctor_id' => $doctor->id, 'hour_id' => $hour->id]);
Turn::create([
'user_id' => Auth::user()->id,
'doctor_id' => $doctor->id
]);
$doctor_hours->update(['reserved' => 1]);
session()->flash('status', 'نوبت شما با موفقیت ثبت شد');
return redirect()->route('patient.turn');
}
ولی چند تا سوال:
1- من نتونستم
$doctor_free_times
رو از کنترلر به بلید پاس بدم، به خاطر اینکه من لیست دکترها رو دارم داخل صفحه اصلی سایت نمایش میدم که روتم به صورت زیر است.
Route::get('/', [HomeController::class, 'index'])->name('home');
و فانکشن مربوط به این روت ،به صورت زیر است.
public function index() {
$doctors = Doctor::all();
$articles = Article::all();
return view('Home.index', compact('doctors', 'articles'));
}
و داخل همون بلید نوشتم که ممنون میشم با توجه به کدم بگید چطور کاری که شما گفتین رو انجام بدم.
2- وقتی میخوام داخل پنل بیمار به هر بیمار نشون بدم که از کدوم دکتر نوبت گرفته کدمو به صورت زیر نوشتم:
public function patientPanelList() {
$turns = auth()->user()->turn()->latest()->paginate(12);
return view('Panel.patientTurn', compact('turns'));
}
و داخل بلید مثلا وقتی میخوام اسم اون دکتری که کاربر ازش وقت گرفته رو طبق روابطی که تعریف کردم به صورت زیر نوشتم:
{{ $turn->doctor->user->fullName }}
اما مشکل من نمایش ساعت است که به صورت زیر نوشتم:
{{ $turn->doctor->hours->hour }}
ولی این ارور رو بهم نمایش میده:
Property [hour] does not exist on this collection instance.
3- وقتی میخوام داخل پنل دکتر به هر دکتر نشون بدم که کدوم بیمار ازش نوبت گرفته کدمو به صورت زیر نوشتم:
public function doctorPanelList() {
$turns = Turn::where('doctor_id', auth()->user()->id)->latest()->paginate(12);
return view('Panel.doctorTurn', compact('turns'));
}
ولی واسه یکی از دکترا نمایش میده ولی واسه یکی دیگه نمایش نمیده، همچنین ساعت رو چجوری باید نمایش بدم؟ در دکتر بدونه که چه بیماری رو چه ساعتی باید ویزیت کنه.
شرمنده خیلی طولانی شد، اگر میدونید که با انی دسک راحت تر میتونید کمکم کنید بهم بگید تا کد انی دسکو بهتون بدم.
تشکر فراوان.
سلام خسته نباشید
ببین میتونی راه های زیادی بری
برای مثال یکیش اینکه بیای یه فیلد بزاری با نوع boolean بعد بیای true و false کنی
$table->boolearn('reserved')->default(0);
یه راه دیگه هم هست بیای بگی از نوع enum و بیای وضعیت مشخص کنی
$table->enum('status', ['active', 'inactive'])->default('active');
باز راه های دیکه هست ولی بهترین راه ها این ها هست
@arminrahmati999
سلام :
{{ $turn->doctor->hours->hour }}
وقتی موقع دریافت اطلاعات از سرور ، محتویات ریلیشن رو دریافت نکردی چه انتظاری از لاراول داری که بهت نشونش بده ؟
برای بخش اول که گفتی اطلاعات رو یجا داری توی ویو استفاده میکنی و زمان های ازاد دکتر رو نداری ، میتونی بجای اینکه کل اطلاعات رو بفرستی سمت ویو ، فقط لیست دکتر ها رو بفرستی و بعد از انتخاب هر دکتر یه درخواست ایجکسی به سرور بزنی و لیست ساعت های آزادش رو به دست بیاری
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟